diff --git a/src/add-ons/kernel/drivers/audio/ice1712/debug.h b/src/add-ons/kernel/drivers/audio/ice1712/debug.h index 126496e220..a8564661f4 100644 --- a/src/add-ons/kernel/drivers/audio/ice1712/debug.h +++ b/src/add-ons/kernel/drivers/audio/ice1712/debug.h @@ -11,8 +11,6 @@ #ifndef _DEBUG_ICE1712_H_ #define _DEBUG_ICE1712_H_ -#include - #ifdef TRACE # undef TRACE #endif @@ -24,6 +22,11 @@ # define TRACE(a...) ; #endif -#define ICE1712_VERY_VERBOSE 0 +//#define ICE1712_VERY_VERBOSE +#ifdef ICE1712_VERY_VERBOSE +# define TRACE_VV(a...) dprintf("\33[34mice1712:\33[0m " a) +#else +# define TRACE_VV(a...) ; +#endif #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 9aa4f6c825..db68dcb8b2 100644 --- a/src/add-ons/kernel/drivers/audio/ice1712/ice1712.c +++ b/src/add-ons/kernel/drivers/audio/ice1712/ice1712.c @@ -18,13 +18,13 @@ #include #include -#include "debug.h" #include "ice1712.h" #include "ice1712_reg.h" #include "io.h" #include "multi.h" #include "util.h" +#include "debug.h" //------------------------------------------------------ //------------------------------------------------------ @@ -65,10 +65,6 @@ 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) @@ -164,27 +160,39 @@ ice1712_setup(ice1712 *ice) write_ccs_uint8(ice, CCS_SERR_SHADOW, 0x01); //Write all configurations register from EEProm - 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->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("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]); + 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("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]); + 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 - (pci->write_pci_config)(ice->info.bus, ice->info.device, ice->info.function, 0x60, 1, ice->eeprom_data[E2PROM_MAP_CONFIG]); - (pci->write_pci_config)(ice->info.bus, ice->info.device, ice->info.function, 0x61, 1, ice->eeprom_data[E2PROM_MAP_ACL]); - (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]); + (pci->write_pci_config)(ice->info.bus, ice->info.device, + ice->info.function, 0x60, 1, ice->eeprom_data[E2PROM_MAP_CONFIG]); + (pci->write_pci_config)(ice->info.bus, ice->info.device, + ice->info.function, 0x61, 1, ice->eeprom_data[E2PROM_MAP_ACL]); + (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("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 // @@ -215,7 +223,8 @@ ice1712_setup(ice1712 *ice) ice->nb_MPU401 = (reg8 & 0x1) + 1; for (i = 0; i < ice->nb_MPU401; i++) { - sprintf(ice->midi_interf[i].name, "midi/ice1712/%ld/%d", ice - cards + 1, i + 1); + sprintf(ice->midi_interf[i].name, "midi/ice1712/%ld/%d", + ice - cards + 1, i + 1); names[num_names++] = ice->midi_interf[i].name; } @@ -225,31 +234,35 @@ ice1712_setup(ice1712 *ice) switch (ice->product) { case ICE1712_SUBDEVICE_DELTA66 : case ICE1712_SUBDEVICE_DELTA44 : - 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; + 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->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; + 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->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; + 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->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; + 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; } @@ -291,8 +304,6 @@ 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->frames_count = 0; @@ -307,15 +318,15 @@ ice1712_setup(ice1712 *ice) ice->total_input_channels += 2; //Write bits in the GPIO - write_cci_uint8(ice, CCI_GPIO_WRITE_MASK, ~(ice->commlines.cs_mask)); + write_cci_uint8(ice, CCI_GPIO_WRITE_MASK, ~(ice->CommLines.cs_mask)); //Deselect CS - write_cci_uint8(ice, CCI_GPIO_DATA, ice->commlines.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_PSDOUT, 0x0101); // write_mt_uint16(ice, MT_ROUTING_CONTROL_SPDOUT, 0x0005); //Just to route all input to all output @@ -432,8 +443,6 @@ ice_1712_shutdown(ice1712 *ice) delete_area(ice->mem_id_rec); codec_write(ice, AK45xx_RESET_REGISTER, 0x00); - - save_settings(ice); } @@ -519,7 +528,8 @@ ice_1712_control(void *cookie, uint32 op, void *arg, size_t len) switch (op) { case B_MULTI_GET_DESCRIPTION : TRACE("B_MULTI_GET_DESCRIPTION\n"); - return ice1712_get_description((ice1712 *)cookie, (multi_description*)arg); + return ice1712_get_description((ice1712 *)cookie, + (multi_description*)arg); case B_MULTI_GET_EVENT_INFO : TRACE("B_MULTI_GET_EVENT_INFO\n"); return B_ERROR; @@ -531,16 +541,20 @@ ice_1712_control(void *cookie, uint32 op, void *arg, size_t len) return B_ERROR; case B_MULTI_GET_ENABLED_CHANNELS : TRACE("B_MULTI_GET_ENABLED_CHANNELS\n"); - return ice1712_get_enabled_channels((ice1712*)cookie, (multi_channel_enable*)arg); + return ice1712_get_enabled_channels((ice1712*)cookie, + (multi_channel_enable*)arg); case B_MULTI_SET_ENABLED_CHANNELS : TRACE("B_MULTI_SET_ENABLED_CHANNELS\n"); - return ice1712_set_enabled_channels((ice1712*)cookie, (multi_channel_enable*)arg); + return ice1712_set_enabled_channels((ice1712*)cookie, + (multi_channel_enable*)arg); case B_MULTI_GET_GLOBAL_FORMAT : TRACE("B_MULTI_GET_GLOBAL_FORMAT\n"); - return ice1712_get_global_format((ice1712*)cookie, (multi_format_info *)arg); + return ice1712_get_global_format((ice1712*)cookie, + (multi_format_info *)arg); case B_MULTI_SET_GLOBAL_FORMAT : TRACE("B_MULTI_SET_GLOBAL_FORMAT\n"); - return ice1712_set_global_format((ice1712*)cookie, (multi_format_info *)arg); + return ice1712_set_global_format((ice1712*)cookie, + (multi_format_info *)arg); case B_MULTI_GET_CHANNEL_FORMATS : TRACE("B_MULTI_GET_CHANNEL_FORMATS\n"); return B_ERROR; @@ -549,22 +563,28 @@ ice_1712_control(void *cookie, uint32 op, void *arg, size_t len) return B_ERROR; case B_MULTI_GET_MIX : TRACE("B_MULTI_GET_MIX\n"); - return ice1712_get_mix((ice1712*)cookie, (multi_mix_value_info *)arg); + return ice1712_get_mix((ice1712*)cookie, + (multi_mix_value_info *)arg); case B_MULTI_SET_MIX : TRACE("B_MULTI_SET_MIX\n"); - return ice1712_set_mix((ice1712*)cookie, (multi_mix_value_info *)arg); + return ice1712_set_mix((ice1712*)cookie, + (multi_mix_value_info *)arg); case B_MULTI_LIST_MIX_CHANNELS : TRACE("B_MULTI_LIST_MIX_CHANNELS\n"); - return ice1712_list_mix_channels((ice1712*)cookie, (multi_mix_channel_info *)arg); + return ice1712_list_mix_channels((ice1712*)cookie, + (multi_mix_channel_info *)arg); case B_MULTI_LIST_MIX_CONTROLS : TRACE("B_MULTI_LIST_MIX_CONTROLS\n"); - return ice1712_list_mix_controls((ice1712*)cookie, (multi_mix_control_info *)arg); + return ice1712_list_mix_controls((ice1712*)cookie, + (multi_mix_control_info *)arg); case B_MULTI_LIST_MIX_CONNECTIONS : TRACE("B_MULTI_LIST_MIX_CONNECTIONS\n"); - return ice1712_list_mix_connections((ice1712*)cookie, (multi_mix_connection_info *)arg); + return ice1712_list_mix_connections((ice1712*)cookie, + (multi_mix_connection_info *)arg); case B_MULTI_GET_BUFFERS : TRACE("B_MULTI_GET_BUFFERS\n"); - return ice1712_get_buffers((ice1712*)cookie, (multi_buffer_list*)arg); + return ice1712_get_buffers((ice1712*)cookie, + (multi_buffer_list*)arg); case B_MULTI_SET_BUFFERS : TRACE("B_MULTI_SET_BUFFERS\n"); return B_ERROR; @@ -573,7 +593,8 @@ ice_1712_control(void *cookie, uint32 op, void *arg, size_t len) return B_ERROR; case B_MULTI_BUFFER_EXCHANGE : // TRACE("B_MULTI_BUFFER_EXCHANGE\n"); - return ice1712_buffer_exchange((ice1712*)cookie, (multi_buffer_info *)arg); + return ice1712_buffer_exchange((ice1712*)cookie, + (multi_buffer_info *)arg); case B_MULTI_BUFFER_FORCE_STOP : TRACE("B_MULTI_BUFFER_FORCE_STOP\n"); return ice1712_buffer_force_stop((ice1712*)cookie); @@ -613,7 +634,8 @@ ice_1712_read(void *cookie, off_t position, void *buf, size_t *num_bytes) static status_t -ice_1712_write(void *cookie, off_t position, const void *buffer, size_t *num_bytes) +ice_1712_write(void *cookie, off_t position, const void *buffer, + size_t *num_bytes) { TRACE("===write()===\n"); *num_bytes = 0; @@ -674,57 +696,22 @@ find_device(const char * name) //----------------------------------------------------------------------------- -status_t -load_settings(ice1712 *ice) -{ - int i; - for (i = 0; i < 10; i++) { - ice->settings.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) +applySettings(ice1712 *card) { int i; uint16 val; - for (i = 0; i < 10; i++) { + for (i = 0; i < MAX_HARDWARE_VOLUME; i++) { //Select the channel write_mt_uint8(card, MT_VOLUME_CONTROL_CHANNEL_INDEX, i); - if (card->settings.playback[i].mute) { + 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; + 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; @@ -735,18 +722,18 @@ apply_settings(ice1712 *card) } write_mt_uint16(card, MT_LR_VOLUME_CONTROL, val); - if (ICE1712_VERY_VERBOSE) - TRACE("Apply Settings %d : 0x%x\n", i, val); + TRACE_VV("Apply Settings %d : 0x%x\n", i, val); } - for (i = 0; i < 10; i++) { + for (i = 0; i < MAX_HARDWARE_VOLUME; i++) { //Select the channel - write_mt_uint8(card, MT_VOLUME_CONTROL_CHANNEL_INDEX, i + 10); + write_mt_uint8(card, MT_VOLUME_CONTROL_CHANNEL_INDEX, + i + MAX_HARDWARE_VOLUME); - if (card->settings.record[i].mute == true) { + 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; + 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; @@ -757,9 +744,10 @@ apply_settings(ice1712 *card) } write_mt_uint16(card, MT_LR_VOLUME_CONTROL, val); + TRACE_VV("Apply Settings %d : 0x%x\n", i, val); } + //Output selection 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 2afb222e71..cb9bdd7017 100644 --- a/src/add-ons/kernel/drivers/audio/ice1712/ice1712.h +++ b/src/add-ons/kernel/drivers/audio/ice1712/ice1712.h @@ -1,266 +1,265 @@ -/* - * 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. - */ - -#ifndef _ICE1712_H_ -#define _ICE1712_H_ - -#include - -#define DRIVER_NAME "ice1712" -#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, - ICE1712_SUBDEVICE_DELTA66 = 0x121432d6, - ICE1712_SUBDEVICE_DELTA44 = 0x121433d6, - ICE1712_SUBDEVICE_AUDIOPHILE_2496 = 0x121434d6, - ICE1712_SUBDEVICE_DELTA410 = 0x121438d6, - ICE1712_SUBDEVICE_DELTA1010LT = 0x12143bd6, - ICE1712_SUBDEVICE_VX442 = 0x12143cd6, -} product_t; - -#define NUM_CARDS 4 -#define MAX_ADC 12 // + the output of the Digital mixer -#define MAX_DAC 10 -#define SWAPPING_BUFFERS 2 -#define SAMPLE_SIZE 4 -#define MIN_BUFFER_FRAMES 256 -#define MAX_BUFFER_FRAMES 2048 - -#define PLAYBACK_BUFFER_SIZE (MAX_BUFFER_FRAMES * MAX_DAC * SAMPLE_SIZE) -#define RECORD_BUFFER_SIZE (MAX_BUFFER_FRAMES * MAX_ADC * SAMPLE_SIZE) - -#define PLAYBACK_BUFFER_TOTAL_SIZE (PLAYBACK_BUFFER_SIZE * SWAPPING_BUFFERS) -#define RECORD_BUFFER_TOTAL_SIZE (RECORD_BUFFER_SIZE * SWAPPING_BUFFERS) - -#define SPDIF_LEFT 8 -#define SPDIF_RIGHT 9 -#define MIXER_OUT_LEFT 10 -#define MIXER_OUT_RIGHT 11 - - -typedef enum { - NO_IN_NO_OUT = 0, - NO_IN_YES_OUT = 1, - YES_IN_NO_OUT = 2, - YES_IN_YES_OUT = 3, -} _spdif_config_ ; - - -typedef struct _midi_dev { - struct _ice1712_ *card; - void *driver; - void *cookie; - int32 count; - char name[64]; -} midi_dev; - - -typedef struct _codec_commlines -{ - uint8 clock; - uint8 data_in; - uint8 data_out; - uint8 cs_mask; //a Mask for removing all Chip select - uint8 reserved[4]; -} codec_comm_lines; - - -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; - char name[128]; - - midi_dev midi_interf[2]; - - uint32 Controller; //PCI_10 - uint32 DDMA; //PCI_14 - uint32 DMA_Path; //PCI_18 - uint32 Multi_Track; //PCI_1C - - uint8 eeprom_data[32]; - - int8 nb_ADC; //Mono Channel - int8 nb_DAC; //Mono Channel - _spdif_config_ spdif_config; - int8 nb_MPU401; - - product_t product; - - //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; - uint8 total_output_channels; - - //Input - area_id mem_id_rec; - void *phys_addr_rec, *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_settings settings; -} ice1712; - - -status_t apply_settings(ice1712 *card); - - -//For midi.c -extern int32 num_cards; -extern ice1712 cards[NUM_CARDS]; - -//??????? -#define GPIO_SPDIF_STATUS 0x02 //Status -#define GPIO_SPDIF_CCLK 0x04 //data Clock -#define GPIO_SPDIF_DOUT 0x08 //data output - -//For Delta 66 / Delta 44 -#define DELTA66_DOUT 0x10 // data output -#define DELTA66_CLK 0x20 // clock -#define DELTA66_CODEC_CS_0 0x40 // AK4524 #0 -#define DELTA66_CODEC_CS_1 0x80 // AK4524 #1 - -//For AudioPhile 2496 / Delta 410 -#define AP2496_CLK 0x02 // clock -#define AP2496_DIN 0x04 // data input -#define AP2496_DOUT 0x08 // data output -#define AP2496_SPDIF_CS 0x10 // CS8427 chip select -#define AP2496_CODEC_CS 0x20 // AK4528 chip select - -//For Delta 1010 LT -#define DELTA1010LT_CLK 0x02 // clock -#define DELTA1010LT_DIN 0x04 // data input -#define DELTA1010LT_DOUT 0x08 // data output -#define DELTA1010LT_CODEC_CS_0 0x00 // AK4524 #0 -#define DELTA1010LT_CODEC_CS_1 0x10 // AK4524 #1 -#define DELTA1010LT_CODEC_CS_2 0x20 // AK4524 #2 -#define DELTA1010LT_CODEC_CS_3 0x30 // AK4524 #3 -#define DELTA1010LT_SPDIF_CS 0x40 // CS8427 -#define DELTA1010LT_CS_NONE 0x50 // All CS deselected - -//For VX442 -#define VX442_CLK 0x02 // clock -#define VX442_DIN 0x04 // data input -#define VX442_DOUT 0x08 // data output -#define VX442_SPDIF_CS 0x10 // CS8427 -#define VX442_CODEC_CS_0 0x20 // ?? #0 -#define VX442_CODEC_CS_1 0x40 // ?? #1 - -#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_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... - -//Register definition for the CS84xx codec (xx = 27) -#define CS84xx_CHIP_ADDRESS 0x10 //Chip address of the codec -#define CS84xx_CONTROL_1_PORT_REG 0x01 -#define CS84xx_CONTROL_2_PORT_REG 0x02 -#define CS84xx_DATA_FLOW_CONTROL_REG 0x03 -#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... - - -/* A default switch for all suported product - switch (card->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 : - break; - case ICE1712_SUBDEVICE_DELTA410 : - break; - case ICE1712_SUBDEVICE_DELTA1010LT : - break; - case ICE1712_SUBDEVICE_VX442 : - break; - } -*/ - -//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 - -#endif +/* + * 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. + */ + +#ifndef _ICE1712_H_ +#define _ICE1712_H_ + +#include +#include "hmulti_audio.h" + +#define DRIVER_NAME "ice1712" +#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, + ICE1712_SUBDEVICE_DELTA66 = 0x121432d6, + ICE1712_SUBDEVICE_DELTA44 = 0x121433d6, + ICE1712_SUBDEVICE_AUDIOPHILE_2496 = 0x121434d6, + ICE1712_SUBDEVICE_DELTA410 = 0x121438d6, + ICE1712_SUBDEVICE_DELTA1010LT = 0x12143bd6, + ICE1712_SUBDEVICE_VX442 = 0x12143cd6, +} product_t; + +#define NUM_CARDS 4 +#define MAX_ADC 12 // + the output of the Digital mixer +#define MAX_DAC 10 +#define SWAPPING_BUFFERS 2 +#define SAMPLE_SIZE 4 +#define MIN_BUFFER_FRAMES 64 +#define MAX_BUFFER_FRAMES 2048 + +#define MAX_HARDWARE_VOLUME 10 + +#define PLAYBACK_BUFFER_SIZE (MAX_BUFFER_FRAMES * MAX_DAC * SAMPLE_SIZE) +#define RECORD_BUFFER_SIZE (MAX_BUFFER_FRAMES * MAX_ADC * SAMPLE_SIZE) + +#define PLAYBACK_BUFFER_TOTAL_SIZE (PLAYBACK_BUFFER_SIZE * SWAPPING_BUFFERS) +#define RECORD_BUFFER_TOTAL_SIZE (RECORD_BUFFER_SIZE * SWAPPING_BUFFERS) + +#define SPDIF_LEFT 8 +#define SPDIF_RIGHT 9 +#define MIXER_OUT_LEFT 10 +#define MIXER_OUT_RIGHT 11 + +typedef enum { + NO_IN_NO_OUT = 0, + NO_IN_YES_OUT = 1, + YES_IN_NO_OUT = 2, + YES_IN_YES_OUT = 3, +} _spdif_config_ ; + +typedef struct _midi_dev { + struct _ice1712_ *card; + void *driver; + void *cookie; + int32 count; + char name[64]; +} midi_dev; + +typedef struct _codecCommLines +{ + uint8 clock; + uint8 data_in; + uint8 data_out; + uint8 cs_mask; //a Mask for removing all Chip select + uint8 reserved[4]; +} codecCommLines; + +typedef struct ChannelVolume +{ + float Volume; + bool Mute; +} ChannelVolume; + +typedef struct Ice1712_Settings +{ + ChannelVolume Playback[MAX_HARDWARE_VOLUME]; + ChannelVolume Record[MAX_HARDWARE_VOLUME]; + + //General Settings + uint8 Clock; //an index + uint8 BufferSize; //an index + uint8 DebugMode; //an index for debugging + + //S/PDif Settings + uint8 OutFormat; //an index + uint8 Emphasis; //an index + uint8 CopyMode; //an index + + //Output settings + uint8 Output[5]; //an index + + uint8 Reserved[32]; +} Ice1712_Settings; + +typedef struct ice1712 +{ + uint32 irq; + pci_info info; + char name[128]; + + midi_dev midi_interf[2]; + + uint32 Controller; //PCI_10 + uint32 DDMA; //PCI_14 + uint32 DMA_Path; //PCI_18 + uint32 Multi_Track; //PCI_1C + + uint8 eeprom_data[32]; + + int8 nb_ADC; //Mono Channel + int8 nb_DAC; //Mono Channel + _spdif_config_ spdif_config; + int8 nb_MPU401; + + product_t product; + + //We hope all manufacturers will use same + //communication lines for speaking with codec + codecCommLines 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; + uint8 total_output_channels; + + //Input + area_id mem_id_rec; + void *phys_addr_rec, *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_Settings settings; +} ice1712; + +status_t applySettings(ice1712 *card); + +//For midi.c +extern int32 num_cards; +extern ice1712 cards[NUM_CARDS]; + +//??????? +#define GPIO_SPDIF_STATUS 0x02 //Status +#define GPIO_SPDIF_CCLK 0x04 //data Clock +#define GPIO_SPDIF_DOUT 0x08 //data output + +//For Delta 66 / Delta 44 +#define DELTA66_DOUT 0x10 // data output +#define DELTA66_CLK 0x20 // clock +#define DELTA66_CODEC_CS_0 0x40 // AK4524 #0 +#define DELTA66_CODEC_CS_1 0x80 // AK4524 #1 + +//For AudioPhile 2496 / Delta 410 +#define AP2496_CLK 0x02 // clock +#define AP2496_DIN 0x04 // data input +#define AP2496_DOUT 0x08 // data output +#define AP2496_SPDIF_CS 0x10 // CS8427 chip select +#define AP2496_CODEC_CS 0x20 // AK4528 chip select + +//For Delta 1010 LT +#define DELTA1010LT_CLK 0x02 // clock +#define DELTA1010LT_DIN 0x04 // data input +#define DELTA1010LT_DOUT 0x08 // data output +#define DELTA1010LT_CODEC_CS_0 0x00 // AK4524 #0 +#define DELTA1010LT_CODEC_CS_1 0x10 // AK4524 #1 +#define DELTA1010LT_CODEC_CS_2 0x20 // AK4524 #2 +#define DELTA1010LT_CODEC_CS_3 0x30 // AK4524 #3 +#define DELTA1010LT_SPDIF_CS 0x40 // CS8427 +#define DELTA1010LT_CS_NONE 0x50 // All CS deselected + +//For VX442 +#define VX442_CLK 0x02 // clock +#define VX442_DIN 0x04 // data input +#define VX442_DOUT 0x08 // data output +#define VX442_SPDIF_CS 0x10 // CS8427 +#define VX442_CODEC_CS_0 0x20 // ?? #0 +#define VX442_CODEC_CS_1 0x40 // ?? #1 + +#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_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... + +//Register definition for the CS84xx codec (xx = 27) +#define CS84xx_CHIP_ADDRESS 0x10 //Chip address of the codec +#define CS84xx_CONTROL_1_PORT_REG 0x01 +#define CS84xx_CONTROL_2_PORT_REG 0x02 +#define CS84xx_DATA_FLOW_CONTROL_REG 0x03 +#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... + + +/* A default switch for all suported product + switch (card->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 : + break; + case ICE1712_SUBDEVICE_DELTA410 : + break; + case ICE1712_SUBDEVICE_DELTA1010LT : + break; + case ICE1712_SUBDEVICE_VX442 : + break; + } +*/ + +//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 + +#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 b1a0ef5928..d8c87af2e6 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,167 @@ -/* - * ice1712 BeOS/Haiku Driver for VIA - VT1712 Multi Channel Audio Controller - * - * Copyright (c) 2007, Jerome Leveque (leveque.jerome@neuf.fr) - * - * All rights reserved - * Distributed under the terms of the MIT license. - */ - -#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 -*/ -//------------------------------------------------------ -//------------------------------------------------------ -//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 -//------------------------------------------------------ -//------------------------------------------------------ -//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 -//------------------------------------------------------ -//------------------------------------------------------ -//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 -//------------------------------------------------------ -//------------------------------------------------------ -//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 -//------------------------------------------------------ -//------------------------------------------------------ - -//------------------------------------------------------ -//------------------------------------------------------ - -//------------------------------------------------------ -//------------------------------------------------------ - -//------------------------------------------------------ -//------------------------------------------------------ - -//------------------------------------------------------ -//------------------------------------------------------ - -//------------------------------------------------------ -//------------------------------------------------------ - -//------------------------------------------------------ -//------------------------------------------------------ - -//------------------------------------------------------ -//------------------------------------------------------ - -//------------------------------------------------------ -//------------------------------------------------------ - -//------------------------------------------------------ -//------------------------------------------------------ - -#endif +/* + * ice1712 BeOS/Haiku Driver for VIA - VT1712 Multi Channel Audio Controller + * + * Copyright (c) 2007, Jerome Leveque (leveque.jerome@neuf.fr) + * + * All rights reserved + * Distributed under the terms of the MIT license. + */ + +#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 +*/ +//------------------------------------------------------ +//------------------------------------------------------ +//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 +//------------------------------------------------------ +//------------------------------------------------------ +//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 +//------------------------------------------------------ +//------------------------------------------------------ +//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 +//------------------------------------------------------ +//------------------------------------------------------ +//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 +//------------------------------------------------------ +//------------------------------------------------------ + +//------------------------------------------------------ +//------------------------------------------------------ + +//------------------------------------------------------ +//------------------------------------------------------ + +//------------------------------------------------------ +//------------------------------------------------------ + +//------------------------------------------------------ +//------------------------------------------------------ + +//------------------------------------------------------ +//------------------------------------------------------ + +//------------------------------------------------------ +//------------------------------------------------------ + +//------------------------------------------------------ +//------------------------------------------------------ + +//------------------------------------------------------ +//------------------------------------------------------ + +//------------------------------------------------------ +//------------------------------------------------------ + +#endif diff --git a/src/add-ons/kernel/drivers/audio/ice1712/io.c b/src/add-ons/kernel/drivers/audio/ice1712/io.c index 0e696f6154..b9a842d310 100644 --- a/src/add-ons/kernel/drivers/audio/ice1712/io.c +++ b/src/add-ons/kernel/drivers/audio/ice1712/io.c @@ -1,551 +1,549 @@ -/* - * 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 "io.h" -#include "ice1712_reg.h" -#include "debug.h" - -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 -read_ccs_uint8(ice1712 *ice, int8 regno) -{ - return pci->read_io_8(ice->Controller + regno); -}; - - -uint16 -read_ccs_uint16(ice1712 *ice, int8 regno) -{ - return pci->read_io_16(ice->Controller + regno); -}; - - -uint32 -read_ccs_uint32(ice1712 *ice, int8 regno) -{ - return pci->read_io_32(ice->Controller + regno); -}; - - -void -write_ccs_uint8(ice1712 *ice, int8 regno, uint8 value) -{ - pci->write_io_8(ice->Controller + regno, value); -}; - - -void -write_ccs_uint16(ice1712 *ice, int8 regno, uint16 value) -{ - pci->write_io_16(ice->Controller + regno, value); -}; - - -void -write_ccs_uint32(ice1712 *ice, int8 regno, uint32 value) -{ - pci->write_io_32(ice->Controller + regno, value); -}; - - -uint8 -read_cci_uint8(ice1712 *ice, int8 index) -{ - write_ccs_uint8(ice, CCS_CCI_INDEX, index); - return read_ccs_uint8(ice, CCS_CCI_DATA); -}; - - -void -write_cci_uint8(ice1712 *ice, int8 index, uint8 value) -{ - write_ccs_uint8(ice, CCS_CCI_INDEX, index); - write_ccs_uint8(ice, CCS_CCI_DATA, value); -}; - -//-------------------------------------------------- -//-------------------------------------------------- -//Address are [PCI_14] + xx - -uint8 -read_ddma_uint8(ice1712 *ice, int8 regno) -{ - return pci->read_io_8(ice->DDMA + regno); -}; - - -uint16 -read_ddma_uint16(ice1712 *ice, int8 regno) -{ - return pci->read_io_16(ice->DDMA + regno); -}; - - -uint32 -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) -{ - pci->write_io_8(ice->DDMA + regno, value); -}; - - -void -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) -{ - pci->write_io_32(ice->DDMA + regno, value); -}; - - -//-------------------------------------------------- -//-------------------------------------------------- -//Address are [PCI_18] + x -uint8 -read_ds_uint8(ice1712 *ice, int8 regno) -{ - return pci->read_io_8(ice->DMA_Path + regno); -}; - - -uint16 -read_ds_uint16(ice1712 *ice, int8 regno) -{ - return pci->read_io_16(ice->DMA_Path + regno); -}; - - -uint32 -read_ds_uint32(ice1712 *ice, int8 regno) -{ - return pci->read_io_32(ice->DMA_Path + regno); -}; - - -void -write_ds_uint8(ice1712 *ice, int8 regno, uint8 value) -{ - pci->write_io_8(ice->DMA_Path + regno, value); -}; - - -void -write_ds_uint16(ice1712 *ice, int8 regno, uint16 value) -{ - pci->write_io_16(ice->DMA_Path + regno, value); -}; - - -void -write_ds_uint32(ice1712 *ice, int8 regno, uint32 value) -{ - pci->write_io_32(ice->DMA_Path + regno, value); -}; - - -uint32 -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); - return read_ds_uint32(ice, DS_CHANNEL_DATA); -} - - -void -write_ds_channel_data(ice1712 *ice, uint8 channel, ds8_register index, uint32 data) -{ - uint8 ds8_channel_index = channel << 4 | 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) -{ - return pci->read_io_8(ice->Multi_Track + regno); -}; - - -uint16 -read_mt_uint16(ice1712 *ice, int8 regno) -{ - return pci->read_io_16(ice->Multi_Track + regno); -}; - - -uint32 -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) -{ - pci->write_io_8(ice->Multi_Track + regno, value); -}; - - -void -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) -{ - pci->write_io_32(ice->Multi_Track + regno, value); -}; - - -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); - write_ccs_uint8(ice, CCS_I2C_DEV_ADDRESS, dev_addr); - snooze(1000); - return read_ccs_uint8(ice, CCS_I2C_DATA); -} - - -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; - - write_ccs_uint8(ice, CCS_I2C_BYTE_ADDRESS, byte_addr); - write_ccs_uint8(ice, CCS_I2C_DEV_ADDRESS, dev_addr); - write_ccs_uint8(ice, CCS_I2C_DATA, value); - return 0; -} - - -int16 read_eeprom(ice1712 *ice, uint8 eeprom[32]) -{ - int i; - int16 tmp; - - for (i = 0; i < 6; i++) { - tmp = read_i2c(ice, I2C_EEPROM_ADDRESS_READ, i); - if (tmp >= 0) - eeprom[i] = (uint8)tmp; - else - return -1; - } - if (eeprom[4] > 32) - return -1; - for (i = 6; i < eeprom[4]; i++) { - tmp = read_i2c(ice, I2C_EEPROM_ADDRESS_READ, i); - if (tmp >= 0) - eeprom[i] = (uint8)tmp; - else - return -1; - } - return eeprom[4]; -} - - -void -codec_write(ice1712 *ice, uint8 reg_addr, uint8 data) -{ - 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: - ak45xx_write_gpio(ice, reg_addr, data, AP2496_CODEC_CS); - break; - 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: - ak45xx_write_gpio(ice, reg_addr, data, VX442_CODEC_CS_0); - ak45xx_write_gpio(ice, reg_addr, data, VX442_CODEC_CS_1); - break; - } -} - - -void -spdif_write(ice1712 *ice, uint8 reg_addr, uint8 data) -{ - 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: - cs84xx_write_gpio(ice, reg_addr, data, AP2496_SPDIF_CS); - break; - case ICE1712_SUBDEVICE_DELTA410: - break; - case ICE1712_SUBDEVICE_DELTA1010LT: - cs84xx_write_gpio(ice, reg_addr, data, DELTA1010LT_SPDIF_CS); - break; - 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) -{ - uint8 tmp; - - tmp = read_gpio(ice); - tmp |= ice->commlines.cs_mask; - tmp &= ~(chip_select); - - write_gpio(ice, tmp); - snooze(GPIO_I2C_DELAY); - - 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(GPIO_I2C_DELAY); -} - - -void -cs84xx_write_gpio(ice1712 *ice, uint8 reg_addr, uint8 data, uint8 chip_select) -{ - uint8 tmp; - - 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); - write_gpio_byte(ice, reg_addr & 0x7f, tmp); //Do not Increment - write_gpio_byte(ice, data, tmp); - - tmp |= chip_select; - write_gpio(ice, tmp); - 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; -} - - -uint8 -read_gpio(ice1712 *ice) -{//return -1 if error else return an uint8 - return read_cci_uint8(ice, CCI_GPIO_DATA); -} - - -void -write_gpio(ice1712 *ice, uint8 value) -{//return -1 if error else return 0 - write_cci_uint8(ice, CCI_GPIO_DATA, value); -} - +/* + * 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 "io.h" +#include "ice1712_reg.h" +#include "debug.h" + +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 +read_ccs_uint8(ice1712 *ice, int8 regno) +{ + return pci->read_io_8(ice->Controller + regno); +}; + + +uint16 +read_ccs_uint16(ice1712 *ice, int8 regno) +{ + return pci->read_io_16(ice->Controller + regno); +}; + + +uint32 +read_ccs_uint32(ice1712 *ice, int8 regno) +{ + return pci->read_io_32(ice->Controller + regno); +}; + + +void +write_ccs_uint8(ice1712 *ice, int8 regno, uint8 value) +{ + pci->write_io_8(ice->Controller + regno, value); +}; + + +void +write_ccs_uint16(ice1712 *ice, int8 regno, uint16 value) +{ + pci->write_io_16(ice->Controller + regno, value); +}; + + +void +write_ccs_uint32(ice1712 *ice, int8 regno, uint32 value) +{ + pci->write_io_32(ice->Controller + regno, value); +}; + + +uint8 +read_cci_uint8(ice1712 *ice, int8 index) +{ + write_ccs_uint8(ice, CCS_CCI_INDEX, index); + return read_ccs_uint8(ice, CCS_CCI_DATA); +}; + + +void +write_cci_uint8(ice1712 *ice, int8 index, uint8 value) +{ + write_ccs_uint8(ice, CCS_CCI_INDEX, index); + write_ccs_uint8(ice, CCS_CCI_DATA, value); +}; + +//-------------------------------------------------- +//-------------------------------------------------- +//Address are [PCI_14] + xx + +uint8 +read_ddma_uint8(ice1712 *ice, int8 regno) +{ + return pci->read_io_8(ice->DDMA + regno); +}; + + +uint16 +read_ddma_uint16(ice1712 *ice, int8 regno) +{ + return pci->read_io_16(ice->DDMA + regno); +}; + + +uint32 +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) +{ + pci->write_io_8(ice->DDMA + regno, value); +}; + + +void +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) +{ + pci->write_io_32(ice->DDMA + regno, value); +}; + + +//-------------------------------------------------- +//-------------------------------------------------- +//Address are [PCI_18] + x +uint8 +read_ds_uint8(ice1712 *ice, int8 regno) +{ + return pci->read_io_8(ice->DMA_Path + regno); +}; + + +uint16 +read_ds_uint16(ice1712 *ice, int8 regno) +{ + return pci->read_io_16(ice->DMA_Path + regno); +}; + + +uint32 +read_ds_uint32(ice1712 *ice, int8 regno) +{ + return pci->read_io_32(ice->DMA_Path + regno); +}; + + +void +write_ds_uint8(ice1712 *ice, int8 regno, uint8 value) +{ + pci->write_io_8(ice->DMA_Path + regno, value); +}; + + +void +write_ds_uint16(ice1712 *ice, int8 regno, uint16 value) +{ + pci->write_io_16(ice->DMA_Path + regno, value); +}; + + +void +write_ds_uint32(ice1712 *ice, int8 regno, uint32 value) +{ + pci->write_io_32(ice->DMA_Path + regno, value); +}; + + +uint32 +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); + return read_ds_uint32(ice, DS_CHANNEL_DATA); +} + + +void +write_ds_channel_data(ice1712 *ice, uint8 channel, + ds8_register index, uint32 data) +{ + uint8 ds8_channel_index = channel << 4 | 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) +{ + return pci->read_io_8(ice->Multi_Track + regno); +}; + + +uint16 +read_mt_uint16(ice1712 *ice, int8 regno) +{ + return pci->read_io_16(ice->Multi_Track + regno); +}; + + +uint32 +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) +{ + pci->write_io_8(ice->Multi_Track + regno, value); +}; + + +void +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) +{ + pci->write_io_32(ice->Multi_Track + regno, value); +}; + + +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); + write_ccs_uint8(ice, CCS_I2C_DEV_ADDRESS, dev_addr); + snooze(1000); + return read_ccs_uint8(ice, CCS_I2C_DATA); +} + + +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; + + write_ccs_uint8(ice, CCS_I2C_BYTE_ADDRESS, byte_addr); + write_ccs_uint8(ice, CCS_I2C_DEV_ADDRESS, dev_addr); + write_ccs_uint8(ice, CCS_I2C_DATA, value); + return 0; +} + + +int16 read_eeprom(ice1712 *ice, uint8 eeprom[32]) +{ + int i; + int16 tmp; + + for (i = 0; i < 6; i++) { + tmp = read_i2c(ice, I2C_EEPROM_ADDRESS_READ, i); + if (tmp >= 0) + eeprom[i] = (uint8)tmp; + else + return -1; + } + if (eeprom[4] > 32) + return -1; + for (i = 6; i < eeprom[4]; i++) { + tmp = read_i2c(ice, I2C_EEPROM_ADDRESS_READ, i); + if (tmp >= 0) + eeprom[i] = (uint8)tmp; + else + return -1; + } + return eeprom[4]; +} + + +void +codec_write(ice1712 *ice, uint8 reg_addr, uint8 data) +{ + 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: + ak45xx_write_gpio(ice, reg_addr, data, AP2496_CODEC_CS); + break; + 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: + ak45xx_write_gpio(ice, reg_addr, data, VX442_CODEC_CS_0); + ak45xx_write_gpio(ice, reg_addr, data, VX442_CODEC_CS_1); + break; + } +} + + +void +spdif_write(ice1712 *ice, uint8 reg_addr, uint8 data) +{ + 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: + cs84xx_write_gpio(ice, reg_addr, data, AP2496_SPDIF_CS); + break; + case ICE1712_SUBDEVICE_DELTA410: + break; + case ICE1712_SUBDEVICE_DELTA1010LT: + cs84xx_write_gpio(ice, reg_addr, data, DELTA1010LT_SPDIF_CS); + break; + 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) +{ + uint8 tmp; + + tmp = read_gpio(ice); + tmp |= ice->CommLines.cs_mask; + tmp &= ~(chip_select); + + write_gpio(ice, tmp); + snooze(GPIO_I2C_DELAY); + + 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(GPIO_I2C_DELAY); +} + +void +cs84xx_write_gpio(ice1712 *ice, uint8 reg_addr, uint8 data, uint8 chip_select) +{ + uint8 tmp; + + 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); + write_gpio_byte(ice, reg_addr & 0x7F, tmp); //Do not Increment + write_gpio_byte(ice, data, tmp); + + tmp |= chip_select; + write_gpio(ice, tmp); + 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; +} + + +uint8 +read_gpio(ice1712 *ice) +{//return -1 if error else return an uint8 + return read_cci_uint8(ice, CCI_GPIO_DATA); +} + + +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 6985c6fdeb..4cffffc29b 100644 --- a/src/add-ons/kernel/drivers/audio/ice1712/io.h +++ b/src/add-ons/kernel/drivers/audio/ice1712/io.h @@ -1,108 +1,109 @@ -/* - * 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. - */ - -#ifndef _IO_H_ -#define _IO_H_ - -#include "ice1712.h" - -#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); - -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); - -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); - -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, - DS8_REGISTER_BUFFER_0_BASE_COUNT, - DS8_REGISTER_BUFFER_1_BASE_ADDRESS, - DS8_REGISTER_BUFFER_1_BASE_COUNT, - DS8_REGISTER_CONTROL_AND_STATUS, - DS8_REGISTER_SAMPLING_RATE, - 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); -//------------------------------------------------------ -//------------------------------------------------------ -//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); - -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); -//return -1 if error else return an uint8 - -int16 write_i2c(ice1712 *ice, uint8 dev_addr, uint8 byte_addr, uint8 value); -//return -1 if error else return 0 - -//------------------------------------------------------ - -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); - -//------------------------------------------------------ - -uint8 read_gpio(ice1712 *ice); -//return -1 if error else return an uint8 - -void write_gpio(ice1712 *ice, uint8 value); - -#endif +/* + * 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. + */ + +#ifndef _IO_H_ +#define _IO_H_ + +#include "ice1712.h" + +#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); + +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); + +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); + +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, + DS8_REGISTER_BUFFER_0_BASE_COUNT, + DS8_REGISTER_BUFFER_1_BASE_ADDRESS, + DS8_REGISTER_BUFFER_1_BASE_COUNT, + DS8_REGISTER_CONTROL_AND_STATUS, + DS8_REGISTER_SAMPLING_RATE, + 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); +//------------------------------------------------------ +//------------------------------------------------------ +//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); + +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); +//return -1 if error else return an uint8 + +int16 write_i2c(ice1712 *ice, uint8 dev_addr, uint8 byte_addr, uint8 value); +//return -1 if error else return 0 + +//------------------------------------------------------ + +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); + +//------------------------------------------------------ + +uint8 read_gpio(ice1712 *ice); +//return -1 if error else return an uint8 + +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 index f59a443487..6da8f3037e 100644 --- a/src/add-ons/kernel/drivers/audio/ice1712/midi.c +++ b/src/add-ons/kernel/drivers/audio/ice1712/midi.c @@ -37,7 +37,7 @@ void midi_interrupt_op(int32 op, void * data) // set_indirect(port->card, 0x2A, 0x04, 0xff); // release_spinlock(&port->card->hardware); restore_interrupts(cp); - + //real code cp = lock(); // emuxki_reg_write_32(&(port->card->config), EMU_INTE, @@ -58,7 +58,7 @@ void midi_interrupt_op(int32 op, void * data) // decrement_interrupt_handler(port->card); // release_spinlock(&port->card->hardware); restore_interrupts(cp); - + //real code // cpu_status status; cp = lock(); @@ -74,8 +74,8 @@ static status_t midi_close(void *cookie); static status_t midi_free(void *cookie); static status_t midi_control(void *cookie, uint32 op, void *data, size_t len); static status_t midi_read(void *cookie, off_t pos, void *data, size_t *len); -static status_t midi_write(void *cookie, off_t pos, const void *data, size_t *len); - +static status_t midi_write(void *cookie, off_t pos, const void *data, + size_t *len); device_hooks midi_hooks = { &midi_open, @@ -90,7 +90,6 @@ device_hooks midi_hooks = { NULL /* writev */ }; - static status_t midi_open(const char * name, uint32 flags, void ** cookie) { int i, ix, used_midi = -1; @@ -106,14 +105,16 @@ static status_t midi_open(const char * name, uint32 flags, void ** cookie) break; } } - + if (ix >= num_cards) { TRACE("bad device\n"); return ENODEV; } - TRACE("mpu401: %p open(): %p driver: %p\n", mpu401, mpu401->open_hook, cards[ix].midi_interf[used_midi].driver); - ret = (*mpu401->open_hook)(cards[ix].midi_interf[used_midi].driver, flags, cookie); + TRACE("mpu401: %p open(): %p driver: %p\n", mpu401, + mpu401->open_hook, cards[ix].midi_interf[used_midi].driver); + ret = (*mpu401->open_hook)(cards[ix].midi_interf[used_midi].driver, + flags, cookie); if (ret >= B_OK) { cards[ix].midi_interf[used_midi].cookie = *cookie; atomic_add(&cards[ix].midi_interf[used_midi].count, 1); @@ -164,7 +165,8 @@ static status_t midi_read(void * cookie, off_t pos, void * ptr, size_t * nread) } -static status_t midi_write(void * cookie, off_t pos, const void * ptr, size_t * nwritten) +static status_t midi_write(void * cookie, off_t pos, const void * ptr, + size_t * nwritten) { return (*mpu401->write_hook)(cookie, pos, ptr, nwritten); } diff --git a/src/add-ons/kernel/drivers/audio/ice1712/multi.c b/src/add-ons/kernel/drivers/audio/ice1712/multi.c index b423c5036b..bf11e29a3b 100644 --- a/src/add-ons/kernel/drivers/audio/ice1712/multi.c +++ b/src/add-ons/kernel/drivers/audio/ice1712/multi.c @@ -9,36 +9,42 @@ * Distributed under the terms of the MIT license. */ -#include "debug.h" #include "ice1712_reg.h" #include "io.h" #include "multi.h" #include "util.h" #include +#include "debug.h" + #define AUTHORIZED_RATE (B_SR_SAME_AS_INPUT | B_SR_IS_GLOBAL | B_SR_96000 \ | B_SR_88200 | B_SR_48000 | B_SR_44100) -#define AUTHORIZED_SAMPLE_SIZE (B_FMT_32BIT) +#define AUTHORIZED_SAMPLE_SIZE (B_FMT_24BIT) +#define MAX_CONTROL 32 -static void +static void start_DMA(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); - write_mt_uint16(card, MT_PROF_PB_DMA_COUNT_ADDRESS, (size * SWAPPING_BUFFERS) - 1); + write_mt_uint32(card, MT_PROF_PB_DMA_BASE_ADDRESS, + (uint32)card->phys_addr_pb); + 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("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); - write_mt_uint16(card, MT_PROF_REC_DMA_COUNT_ADDRESS, (size * SWAPPING_BUFFERS) - 1); + 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("SIZE DMA RECORD %#x\n", size); @@ -97,11 +103,10 @@ start_DMA(ice1712 *card) write_mt_uint8(card, MT_PROF_PB_CONTROL, 5); } - -status_t +status_t ice1712_get_description(ice1712 *card, multi_description *data) { - int chan = 0, i; + int chan = 0, i, size; data->interface_version = B_CURRENT_INTERFACE_VERSION; data->interface_minimum = B_CURRENT_INTERFACE_VERSION; @@ -131,78 +136,94 @@ ice1712_get_description(ice1712 *card, multi_description *data) case ICE1712_SUBDEVICE_VX442: strncpy(data->friendly_name, "VX 442", 32); break; + default: strncpy(data->friendly_name, "Unknow device", 32); break; } - - strncpy(data->vendor_info, "Jerome Leveque", 32); - + + strncpy(data->vendor_info, "Haiku OS", 32); + data->output_channel_count = card->total_output_channels; data->input_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); + size = data->output_channel_count + + data->input_channel_count + + data->output_bus_channel_count + + data->input_bus_channel_count + + data->aux_bus_channel_count; - if (data->request_channel_count >= (card->total_output_channels - + card->total_input_channels)) { + TRACE_VV("request_channel_count = %ld\n", data->request_channel_count); + + if (size <= data->request_channel_count) { for (i = 0; i < card->nb_DAC; i++) { //Analog STEREO output data->channels[chan].channel_id = chan; - data->channels[chan].kind = B_MULTI_OUTPUT_BUS; + data->channels[chan].kind = B_MULTI_OUTPUT_CHANNEL; data->channels[chan].designations = B_CHANNEL_STEREO_BUS | ((i & 1) == 0) ? B_CHANNEL_LEFT : B_CHANNEL_RIGHT; - data->channels[chan++].connectors = B_CHANNEL_RCA; + data->channels[chan].connectors = 0; + chan++; } if (card->spdif_config & NO_IN_YES_OUT) { //SPDIF STEREO output data->channels[chan].channel_id = chan; - data->channels[chan].kind = B_MULTI_OUTPUT_BUS; - data->channels[chan].designations = B_CHANNEL_STEREO_BUS + data->channels[chan].kind = B_MULTI_OUTPUT_CHANNEL; + data->channels[chan].designations = B_CHANNEL_STEREO_BUS | B_CHANNEL_LEFT; - data->channels[chan].connectors = B_CHANNEL_COAX_SPDIF; + data->channels[chan].connectors = 0; chan++; data->channels[chan].channel_id = chan; - data->channels[chan].kind = B_MULTI_OUTPUT_BUS; + data->channels[chan].kind = B_MULTI_OUTPUT_CHANNEL; data->channels[chan].designations = B_CHANNEL_STEREO_BUS | B_CHANNEL_RIGHT; - data->channels[chan++].connectors = B_CHANNEL_COAX_SPDIF; + data->channels[chan].connectors = 0; + chan++; } for (i = 0; i < card->nb_ADC; i++) { //Analog STEREO input data->channels[chan].channel_id = chan; - 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 = B_CHANNEL_RCA; + data->channels[chan].kind = B_MULTI_INPUT_CHANNEL; + data->channels[chan].designations = B_CHANNEL_STEREO_BUS + | ((i & 1) == 0) ? B_CHANNEL_LEFT : B_CHANNEL_RIGHT; + data->channels[chan].connectors = 0; + chan++; } if (card->spdif_config & YES_IN_NO_OUT) { //SPDIF STEREO input data->channels[chan].channel_id = chan; - data->channels[chan].kind = B_MULTI_INPUT_BUS; - data->channels[chan].designations = B_CHANNEL_STEREO_BUS | B_CHANNEL_LEFT; - data->channels[chan++].connectors = B_CHANNEL_COAX_SPDIF; + data->channels[chan].kind = B_MULTI_INPUT_CHANNEL; + data->channels[chan].designations = B_CHANNEL_STEREO_BUS + | B_CHANNEL_LEFT; + data->channels[chan].connectors = 0; + chan++; data->channels[chan].channel_id = chan; - data->channels[chan].kind = B_MULTI_INPUT_BUS; - data->channels[chan].designations = B_CHANNEL_STEREO_BUS | B_CHANNEL_RIGHT; - data->channels[chan++].connectors = B_CHANNEL_COAX_SPDIF; + data->channels[chan].kind = B_MULTI_INPUT_CHANNEL; + data->channels[chan].designations = B_CHANNEL_STEREO_BUS + | B_CHANNEL_RIGHT; + data->channels[chan].connectors = 0; + chan++; } - //The digital mixer output + //The digital mixer output (it's an Input for Haiku) data->channels[chan].channel_id = chan; - data->channels[chan].kind = B_MULTI_INPUT_BUS; - data->channels[chan].designations = B_CHANNEL_STEREO_BUS | B_CHANNEL_LEFT; - data->channels[chan++].connectors = B_CHANNEL_SPDIF_HEADER; + data->channels[chan].kind = B_MULTI_INPUT_CHANNEL; + data->channels[chan].designations = B_CHANNEL_STEREO_BUS + | B_CHANNEL_LEFT; + data->channels[chan].connectors = 0; + chan++; data->channels[chan].channel_id = chan; - data->channels[chan].kind = B_MULTI_INPUT_BUS; - data->channels[chan].designations = B_CHANNEL_STEREO_BUS | B_CHANNEL_RIGHT; - data->channels[chan++].connectors = B_CHANNEL_SPDIF_HEADER; + data->channels[chan].kind = B_MULTI_INPUT_CHANNEL; + data->channels[chan].designations = B_CHANNEL_STEREO_BUS + | B_CHANNEL_RIGHT; + data->channels[chan].connectors = 0; + chan++; } TRACE("output_channel_count = %ld\n", data->output_channel_count); @@ -211,13 +232,13 @@ ice1712_get_description(ice1712 *card, multi_description *data) 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; - data->max_cvsr_rate = 96000; + data->min_cvsr_rate = data->max_cvsr_rate = 0; data->output_formats = data->input_formats = AUTHORIZED_SAMPLE_SIZE; data->lock_sources = B_MULTI_LOCK_INTERNAL | B_MULTI_LOCK_SPDIF; data->timecode_sources = 0; - data->interface_flags = B_MULTI_INTERFACE_PLAYBACK | B_MULTI_INTERFACE_RECORD; + data->interface_flags = B_MULTI_INTERFACE_PLAYBACK + | B_MULTI_INTERFACE_RECORD; data->start_latency = 0; strcpy(data->control_panel,""); @@ -226,12 +247,14 @@ ice1712_get_description(ice1712 *card, multi_description *data) } -status_t +status_t ice1712_get_enabled_channels(ice1712 *card, multi_channel_enable *data) { - int i; + int i, total_channel; uint8 reg; - for (i = 0; i < (card->total_output_channels + card->total_input_channels); i++) + + total_channel = card->total_output_channels + card->total_input_channels; + for (i = 0; i < total_channel; i++) B_SET_CHANNEL(data->enable_bits, i, true); reg = read_mt_uint8(card, MT_SAMPLING_RATE_SELECT); @@ -245,17 +268,20 @@ ice1712_get_enabled_channels(ice1712 *card, multi_channel_enable *data) } -status_t +status_t 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("set_enabled_channels %d : %s\n", 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, 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); - + if (data->lock_source == B_MULTI_LOCK_SPDIF) write_mt_uint8(card, MT_SAMPLING_RATE_SELECT, 0x10); else @@ -267,11 +293,11 @@ ice1712_set_enabled_channels(ice1712 *card, multi_channel_enable *data) } -status_t +status_t ice1712_get_global_format(ice1712 *card, multi_format_info *data) { uint8 sr = read_mt_uint8(card, MT_SAMPLING_RATE_SELECT); - + switch (sr) { case 0x0: data->input.rate = data->output.rate = B_SR_48000; @@ -285,34 +311,32 @@ ice1712_get_global_format(ice1712 *card, multi_format_info *data) 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; } - + data->timecode_kind = 0; 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); + TRACE("Sampling Rate = %f\n", data->input.cvsr); return B_OK; } -status_t +status_t ice1712_set_global_format(ice1712 *card, multi_format_info *data) { uint8 i; - TRACE("Input Sampling Rate = %#x\n", (int)data->input.rate); - TRACE("Output Sampling Rate = %#x\n", (int)data->output.rate); + TRACE("Input Sampling Rate = %d\n", (int)data->input.rate); + TRACE("Output Sampling Rate = %d\n", (int)data->output.rate); - if ((data->input.rate == data->output.rate) - && (card->lock_source == B_MULTI_LOCK_INTERNAL)) { - switch (data->input.rate) { + if (card->lock_source == B_MULTI_LOCK_INTERNAL) { + switch (data->output.rate) { case B_SR_96000: card->sampling_rate = 0x07; break; @@ -329,39 +353,201 @@ 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("RATE = %#x\n", i); + TRACE("New rate = %#x\n", i); + + //We can't have a different rate for input and output + data->input.rate = data->output.rate; return B_OK; } +static uint32 +get_combo_cb(ice1712 *card, uint32 index) +{ + uint32 value = 0; -status_t + TRACE_VV(" get_combo_cb: %ld, %ld\n", index, value); + + switch (index) { + case 0: + value = card->settings.Clock; + break; + + case 1: + value = card->settings.BufferSize; + break; + + case 2: + value = card->settings.OutFormat; + break; + + case 3: + value = card->settings.Emphasis; + break; + + case 4: + 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 < 6) { + card->settings.BufferSize = value; +// card->buffer_size = 64 * (1 << value); +// ice1712_buffer_force_stop(card); +// start_DMA(card); + } + break; + + case 2: + if (value < 2) + card->settings.OutFormat = value; + break; + + case 3: + if (value < 3) + card->settings.Emphasis = value; + break; + + case 4: + 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) +{ + ChannelVolume *vol; + uint32 chan = ICE1712_MULTI_GET_CHANNEL(mmv->id); + + TRACE_VV(" get_volume_cb\n"); + + if (chan < MAX_HARDWARE_VOLUME) { + vol = card->settings.Playback; + } + else { + vol = card->settings.Record; + chan -= MAX_HARDWARE_VOLUME; + } + + //chan is normaly <= MAX_HARDWARE_VOLUME + switch (ICE1712_MULTI_GET_INDEX(mmv->id)) { + case 0: //Mute + mmv->u.enable = vol[chan].Mute | vol[chan + 1].Mute; + TRACE_VV(" Get 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(" Get Volume %f for channel %d\n", + mmv->u.gain, (int)chan); + break; + } +} + +static void +set_volume_cb(ice1712 *card, multi_mix_value *mmv) +{ + ChannelVolume *vol; + uint32 chan = ICE1712_MULTI_GET_CHANNEL(mmv->id); + + TRACE_VV(" set_volume_cb\n"); + + if (chan < MAX_HARDWARE_VOLUME) { + vol = card->settings.Playback; + } + else { + vol = card->settings.Record; + chan -= MAX_HARDWARE_VOLUME; + } + + //chan is normaly <= MAX_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(" Change 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(" Change 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(" Asking to get %ld control(s)\n", data->item_count); + 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]); - - 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; + 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_VOLUME_REC: - mmv->u.gain = card->settings.record[mmv->id & ICE1712_MULTI_CONTROL_CHANNEL_MASK].volume; + case ICE1712_MULTI_CONTROL_TYPE_VOLUME: + get_volume_cb(card, mmv); 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; + case ICE1712_MULTI_CONTROL_TYPE_OUTPUT: + mmv->u.mux = get_output_cb(card, + ICE1712_MULTI_GET_CHANNEL(mmv->id)); 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; + default: + TRACE_VV(" default 0x%x\n", (unsigned int)mmv->id); break; } } @@ -369,145 +555,175 @@ ice1712_get_mix(ice1712 *card, multi_mix_value_info *data) return B_OK; } - -status_t +status_t ice1712_set_mix(ice1712 *card, multi_mix_value_info *data) { int i; - TRACE(" Asking to set %ld control(s)\n", data->item_count); - + + 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]); - - 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); + 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_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); + case ICE1712_MULTI_CONTROL_TYPE_VOLUME: + set_volume_cb(card, mmv); 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); + case ICE1712_MULTI_CONTROL_TYPE_OUTPUT: + set_output_cb(card, ICE1712_MULTI_GET_CHANNEL(mmv->id), + mmv->u.mux); 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); + TRACE_VV(" default 0x%x\n", (unsigned int)mmv->id); break; } } - return apply_settings(card); + return applySettings(card); } -status_t +status_t ice1712_list_mix_channels(ice1712 *card, multi_mix_channel_info *data) {//Not Implemented 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 *Clock[] = { + "Internal", + "Digital", + NULL, +}; +static const char *BufferSize[] = { + "64", + "128", + "256", + "512", + "1024", + "2048", + NULL, +}; -static const char **SettingsGeneral[] = { Clock, SampleRate, BufferSize, -#if 0 - Debug, -#endif - NULL }; +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, + BufferSize, + NULL, +}; + +static const char **SettingsDigital[] = { + DigitalFormat, + DigitalEmphasis, + DigitalCopyMode, + NULL, +}; + +static const char *string_list[] = { + "Setup", + "General", + "Digital", + "Output Selection", + + "Internal Mixer", -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", + "Master clock", + "Buffer size", + "Debug", //Digital settings - "Output format", "Emphasis", "Copy mode", + "Output format", + "Emphasis", + "Copy mode", //Output Selection - "Output 1", //12 - "Output 2", + "Output 1", //11 + "Output 2", "Output 3", "Output 4", - "Digital Output", //16 + "Digital Output", //15 - "Haiku output", //17 + "Haiku output", //16 - "Input 1", //18 + "Input 1", //17 "Input 2", "Input 3", "Input 4", - "Digital Input", //22 - "Internal mixer", //23 + "Digital Input", //21 + "Internal mixer", //22 }; static int32 nb_control_created; - //This will create a Tab static int32 -create_group_control(multi_mix_control **p_mmc, int32 offset, int32 parent, +create_group_control(multi_mix_control **p_mmc, int32 index, 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; + 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; mmc->master = CONTROL_IS_MASTER; mmc->string = string; + group = mmc->id; + if (name != NULL) strcpy(mmc->name, name); + TRACE_VV("Create ID %#x\n", (unsigned int)mmc->id); + nb_control_created++; mmc++; (*p_mmc) = mmc; return group; } - //This will create a Slider with a "Mute" CheckBox static void -create_channel_control(multi_mix_control **p_mmc, int32 offset, int32 parent, +create_channel_control(multi_mix_control **p_mmc, int32 channel, int32 parent, const char* name) { + int32 id = ICE1712_MULTI_CONTROL_FIRSTID + + ICE1712_MULTI_CONTROL_TYPE_VOLUME + + ICE1712_MULTI_SET_CHANNEL(channel); 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; @@ -515,177 +731,232 @@ create_channel_control(multi_mix_control **p_mmc, int32 offset, int32 parent, control.u.gain.granularity = 1.5; //The Mute Checkbox - control.id = ICE1712_MULTI_CONTROL_FIRSTID + ICE1712_MULTI_CONTROL_MUTE + offset; + control.id = id++; control.flags = B_MULTI_MIX_ENABLE; control.string = S_MUTE; *mmc = control; mmc++; + TRACE_VV("Create ID %#x\n", (unsigned int)control.id); + //The Left Slider control.string = S_null; - control.id = ICE1712_MULTI_CONTROL_FIRSTID + offset; + control.id = id++; control.flags = B_MULTI_MIX_GAIN; if (name != NULL) strcpy(control.name, name); *mmc = control; mmc++; + TRACE_VV("Create ID %#x\n", (unsigned int)control.id); + //The Right Slider control.master = control.id; //The Id of the Left Slider - control.id++; + control.id = id++; *mmc = control; mmc++; + TRACE_VV("Create ID %#x\n", (unsigned int)control.id); + nb_control_created += 3; (*p_mmc) = mmc; } - static void -create_combo_control(multi_mix_control **p_mmc, const char *values[], - int32 parent, const char *name) +create_combo_control(multi_mix_control **p_mmc, const char *values[], + int32 parent, int32 nb_combo, const char *name) { + int32 id = ICE1712_MULTI_CONTROL_FIRSTID + + ICE1712_MULTI_CONTROL_TYPE_COMBO + + ICE1712_MULTI_SET_CHANNEL(nb_combo); multi_mix_control *mmc = *p_mmc; int32 parentControl, i; + TRACE_VV("Create ID create_combo_control\n"); + //The label - parentControl = mmc->id = ICE1712_MULTI_CONTROL_FIRSTID + ICE1712_MULTI_CONTROL_MUX + nb_control_created; + 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); + nb_control_created++; mmc++; //The values for (i = 0; values[i] != NULL; i++) { - mmc->id = ICE1712_MULTI_CONTROL_FIRSTID + nb_control_created; + mmc->id = id++; mmc->flags = B_MULTI_MIX_MUX_VALUE; mmc->parent = parentControl; strcpy(mmc->name, values[i]); + + TRACE_VV("Create ID %#x\n", (unsigned int)mmc->id); + 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) +create_output_choice(ice1712 *card, multi_mix_control **p_mmc, + int32 output, int32 parent) { + int32 id = ICE1712_MULTI_CONTROL_FIRSTID + + ICE1712_MULTI_CONTROL_TYPE_OUTPUT + + ICE1712_MULTI_SET_CHANNEL(output); multi_mix_control *mmc = *p_mmc; int32 parentControl, i; + TRACE_VV("Create ID create_output_choice\n"); + //The label - parentControl = mmc->id = ICE1712_MULTI_CONTROL_FIRSTID + ICE1712_MULTI_CONTROL_MUX + nb_control_created; + parentControl = mmc->id = id++; mmc->flags = B_MULTI_MIX_MUX; mmc->parent = parent; - strcpy(mmc->name, string_list[12 + output]); + strcpy(mmc->name, string_list[11 + output]); nb_control_created++; mmc++; + TRACE_VV("Create ID %#x\n", (unsigned int)parentControl); + //Haiku output - mmc->id = ICE1712_MULTI_CONTROL_FIRSTID + nb_control_created; + mmc->id = id++; mmc->flags = B_MULTI_MIX_MUX_VALUE; mmc->parent = parentControl; - strcpy(mmc->name, string_list[17]); + strcpy(mmc->name, string_list[16]); + + TRACE_VV("Create ID %#x\n", (unsigned int)mmc->id); + 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->id = id++; mmc->flags = B_MULTI_MIX_MUX_VALUE; mmc->parent = parentControl; - strcpy(mmc->name, string_list[18 + (i / 2)]); - nb_control_created++; mmc++; - } - - //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]); + strcpy(mmc->name, string_list[17 + (i / 2)]); + + TRACE_VV("Create ID %#x\n", (unsigned int)mmc->id); + 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; + //Physical Digital Input + if (card->spdif_config & YES_IN_NO_OUT) { + mmc->id = id++; mmc->flags = B_MULTI_MIX_MUX_VALUE; mmc->parent = parentControl; - strcpy(mmc->name, string_list[23]); + strcpy(mmc->name, string_list[21]); + + TRACE_VV("Create ID %#x\n", (unsigned int)mmc->id); + + nb_control_created++; mmc++; + } + + //Internal mixer only for Output 1 and Digital Output + if ((output == 0) || (output == 4)) { + mmc->id = id++; + mmc->flags = B_MULTI_MIX_MUX_VALUE; + mmc->parent = parentControl; + strcpy(mmc->name, string_list[22]); + + TRACE_VV("Create ID %#x\n", (unsigned int)mmc->id); + nb_control_created++; mmc++; } (*p_mmc) = mmc; } - status_t ice1712_list_mix_controls(ice1712 *card, multi_mix_control_info *mmci) { - int32 i, parentTab, parentTabColumn; + uint32 i, parentTab, parentTabColumn; multi_mix_control *mmc = mmci->controls; + uint32 group = 0, combo = 0, channel = 0; nb_control_created = 0; - TRACE("count = %ld\n", mmci->control_count); + TRACE_VV("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); + parentTab = create_group_control(&mmc, group++, + 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]); + parentTabColumn = create_group_control(&mmc, group++, parentTab, + S_null, string_list[1]); + for (i = 0; SettingsGeneral[i] != NULL; i++) { + create_combo_control(&mmc, SettingsGeneral[i], parentTabColumn, + combo++, 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]); + parentTabColumn = create_group_control(&mmc, group++, parentTab, + S_null, string_list[2]); + for (i = 0; SettingsDigital[i] != NULL; i++) { + create_combo_control(&mmc, SettingsDigital[i], parentTabColumn, + combo++, string_list[8 + 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]); - + parentTabColumn = create_group_control(&mmc, group++, parentTab, + S_null, string_list[3]); 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); + create_output_choice(card, &mmc, i / 2, parentTabColumn); } 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); + create_output_choice(card, &mmc, 4, parentTabColumn); } - TRACE("Return %ld control(s)\n", nb_control_created); + //Internal Mixer Tab + //Output + parentTab = create_group_control(&mmc, group++, CONTROL_IS_MASTER, + S_null, string_list[4]); + + for (i = 0; i < card->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); + } + + if (card->spdif_config & NO_IN_YES_OUT) { + parentTabColumn = create_group_control(&mmc, group++, parentTab, + S_null, string_list[15]); + create_channel_control(&mmc, MAX_HARDWARE_VOLUME - 2, + parentTabColumn, NULL); + } + + //Input + channel = MAX_HARDWARE_VOLUME; + for (i = 0; i < card->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); + } + + if (card->spdif_config & YES_IN_NO_OUT) { + parentTabColumn = create_group_control(&mmc, group++, parentTab, + S_null, string_list[21]); + create_channel_control(&mmc, 2 * MAX_HARDWARE_VOLUME - 2, + parentTabColumn, NULL); + } + + TRACE_VV("Return %ld control(s)\n", nb_control_created); mmci->control_count = nb_control_created; return B_OK; } -status_t +status_t ice1712_list_mix_connections(ice1712 *card, multi_mix_connection_info *data) {//Not Implemented data->actual_count = 0; @@ -693,219 +964,201 @@ ice1712_list_mix_connections(ice1712 *card, multi_mix_connection_info *data) } -status_t +status_t ice1712_get_buffers(ice1712 *card, multi_buffer_list *data) { int buff, chan_i = 0, chan_o = 0; - 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->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; - - // 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; + TRACE_VV("flags = %#x\n", (int)data->flags); + TRACE_VV("request_playback_buffers = %d\n", + (int)data->request_playback_buffers); + TRACE_VV("request_playback_channels = %d\n", + (int)data->request_playback_channels); + TRACE_VV("request_playback_buffer_size = %#x\n", + (int)data->request_playback_buffer_size); + TRACE_VV("request_record_buffers = %d\n", + (int)data->request_record_buffers); + TRACE_VV("request_record_channels = %d\n", + (int)data->request_record_channels); + TRACE_VV("request_record_buffer_size = %#x\n", + (int)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->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 = card->log_addr_pb + + buf_o * buff + SAMPLE_SIZE * chan_o; data->playback_buffers[buff][chan_o].stride = stride_o; - if (ICE1712_VERY_VERBOSE) - TRACE("pb_buffer[%d][%d] = %#x\n", (int)buff, (int)chan_o, (int)data->playback_buffers[buff][chan_o].base); + TRACE_VV("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) { //SPDIF STEREO output data->playback_buffers[buff][chan_o].base = card->log_addr_pb - + buf_o * buff + SAMPLE_SIZE * SPDIF_LEFT; + + buf_o * buff + SAMPLE_SIZE * SPDIF_LEFT; data->playback_buffers[buff][chan_o].stride = stride_o; - if (ICE1712_VERY_VERBOSE) - TRACE("pb_buffer[%d][%d] = %#x\n", (int)buff, (int)chan_o, (int)data->playback_buffers[buff][chan_o].base); + TRACE_VV("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; + + buf_o * buff + SAMPLE_SIZE * SPDIF_RIGHT; data->playback_buffers[buff][chan_o].stride = stride_o; - if (ICE1712_VERY_VERBOSE) - TRACE("pb_buffer[%d][%d] = %#x\n", (int)buff, (int)chan_o, (int)data->playback_buffers[buff][chan_o].base); + TRACE_VV("pb_buffer[%d][%d] = %#x\n", (int)buff, (int)chan_o, + (int)data->playback_buffers[buff][chan_o].base); chan_o++; } } - + if (data->request_record_channels == card->total_input_channels) { for (chan_i = 0; chan_i < card->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; + + buf_i * buff + SAMPLE_SIZE * chan_i; data->record_buffers[buff][chan_i].stride = stride_i; - if (ICE1712_VERY_VERBOSE) - TRACE("rec_buffer[%d][%d] = %#x\n", (int)buff, (int)chan_i, (int)data->record_buffers[buff][chan_i].base); + TRACE_VV("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) { //SPDIF STEREO input data->record_buffers[buff][chan_i].base = card->log_addr_rec - + buf_i * buff + SAMPLE_SIZE * SPDIF_LEFT; + + buf_i * buff + SAMPLE_SIZE * SPDIF_LEFT; data->record_buffers[buff][chan_i].stride = stride_i; - if (ICE1712_VERY_VERBOSE) - TRACE("rec_buffer[%d][%d] = %#x\n", (int)buff, (int)chan_i, (int)data->record_buffers[buff][chan_i].base); + TRACE_VV("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; + + buf_i * buff + SAMPLE_SIZE * SPDIF_RIGHT; data->record_buffers[buff][chan_i].stride = stride_i; - if (ICE1712_VERY_VERBOSE) - TRACE("rec_buffer[%d][%d] = %#x\n", (int)buff, (int)chan_i, (int)data->record_buffers[buff][chan_i].base); + TRACE_VV("rec_buffer[%d][%d] = %#x\n", (int)buff, (int)chan_i, + (int)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; + + buf_i * buff + SAMPLE_SIZE * MIXER_OUT_LEFT; data->record_buffers[buff][chan_i].stride = stride_i; - if (ICE1712_VERY_VERBOSE) - TRACE("rec_buffer[%d][%d] = %#x\n", (int)buff, (int)chan_i, (int)data->record_buffers[buff][chan_i].base); - + TRACE_VV("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; + + buf_i * buff + SAMPLE_SIZE * MIXER_OUT_RIGHT; data->record_buffers[buff][chan_i].stride = stride_i; - if (ICE1712_VERY_VERBOSE) - TRACE("rec_buffer[%d][%d] = %#x\n", (int)buff, (int)chan_i, (int)data->record_buffers[buff][chan_i].base); + TRACE_VV("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->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); + + TRACE("return_playback_buffers = %d\n", + (int)data->return_playback_buffers); + TRACE("return_playback_channels = %d\n", + (int)data->return_playback_channels); + TRACE("return_playback_buffer_size = %d\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->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); - + + TRACE("return_record_buffers = %d\n",(int)data->return_record_buffers); + TRACE("return_record_channels = %d\n", (int)data->return_record_channels); + TRACE("return_record_buffer_size = %d\n", + (int)data->return_record_buffer_size); + start_DMA(card); return B_OK; } -status_t +status_t ice1712_buffer_exchange(ice1712 *card, multi_buffer_info *data) { - int cpu_status = 0, status; -/* unsigned char peak[MAX_ADC]; - int i; -*/ -// TRACE("Avant Exchange p : %d, r : %d\n", data->playback_buffer_cycle, data->record_buffer_cycle); + int cpu_status; - status = acquire_sem_etc(card->buffer_ready_sem, 1, B_RELATIVE_TIMEOUT | B_CAN_INTERRUPT, 50000); - switch (status) { - case B_NO_ERROR: -// TRACE("B_NO_ERROR\n"); - cpu_status = disable_interrupts(); + multi_buffer_info buffer_info; - // 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 +#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 - // 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 + buffer_info.flags = B_MULTI_BUFFER_PLAYBACK | B_MULTI_BUFFER_RECORD; - data->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"); + }; - restore_interrupts(cpu_status); - break; + cpu_status = lock(); - case B_BAD_SEM_ID: - TRACE("B_BAD_SEM_ID\n"); - break; + // 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 - case B_INTERRUPTED: - TRACE("B_INTERRUPTED\n"); - break; + // 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 - case B_BAD_VALUE: - TRACE("B_BAD_VALUE\n"); - break; + unlock(cpu_status); - case B_WOULD_BLOCK: - TRACE("B_WOULD_BLOCK\n"); - break; - - case B_TIMED_OUT: - TRACE("B_TIMED_OUT\n"); - start_DMA(card); - - cpu_status = lock(); - - data->played_real_time = card->played_time; - data->playback_buffer_cycle = 0; - data->played_frames_count += card->buffer_size; - - data->recorded_real_time = card->played_time; - data->record_buffer_cycle = 0; - data->recorded_frames_count += card->buffer_size; - data->flags = B_MULTI_BUFFER_PLAYBACK | B_MULTI_BUFFER_RECORD; - - unlock(cpu_status); - break; - - default: - TRACE("Default\n"); - break; - } - - if ((card->buffer % 1500) == 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("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 a49a8ef0e9..194403d691 100644 --- a/src/add-ons/kernel/drivers/audio/ice1712/multi.h +++ b/src/add-ons/kernel/drivers/audio/ice1712/multi.h @@ -16,26 +16,56 @@ #include -#define ICE1712_MULTI_CONTROL_FIRSTID (0x08000000) +#define ICE1712_MULTI_CONTROL_FIRSTID (0x80000000) + +#define ICE1712_MULTI_CONTROL_TYPE_MASK (0x70000000) +#define ICE1712_MULTI_CONTROL_TYPE_COMBO (0x10000000) +#define ICE1712_MULTI_CONTROL_TYPE_VOLUME (0x20000000) +#define ICE1712_MULTI_CONTROL_TYPE_OUTPUT (0x30000000) +#define ICE1712_MULTI_CONTROL_TYPE_OTHER4 (0x40000000) +#define ICE1712_MULTI_CONTROL_TYPE_OTHER5 (0x50000000) +#define ICE1712_MULTI_CONTROL_TYPE_OTHER6 (0x60000000) +#define ICE1712_MULTI_CONTROL_TYPE_OTHER7 (0x70000000) + +#define ICE1712_MULTI_CONTROL_CHANNEL_MASK (0x0FF00000) +#define ICE1712_MULTI_CONTROL_INDEX_MASK (0x00000FFF) + +#define ICE1712_MULTI_SET_CHANNEL(_c_) ((_c_ << 20) & \ + ICE1712_MULTI_CONTROL_CHANNEL_MASK) +#define ICE1712_MULTI_GET_CHANNEL(_c_) ((_c_ & \ + ICE1712_MULTI_CONTROL_CHANNEL_MASK) >> 20) + +#define ICE1712_MULTI_SET_INDEX(_i_) (_i_ & \ + ICE1712_MULTI_CONTROL_INDEX_MASK) +#define ICE1712_MULTI_GET_INDEX(_i_) (_i_ & \ + ICE1712_MULTI_CONTROL_INDEX_MASK) + +/* #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); +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_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); diff --git a/src/add-ons/kernel/drivers/audio/ice1712/util.c b/src/add-ons/kernel/drivers/audio/ice1712/util.c index b3e02dddda..c036e73fec 100644 --- a/src/add-ons/kernel/drivers/audio/ice1712/util.c +++ b/src/add-ons/kernel/drivers/audio/ice1712/util.c @@ -76,7 +76,8 @@ alloc_mem(void **phy, void **log, size_t size, const char *name) *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); + TRACE("area = %d, size = %#08X, log = %#08X, phy = %#08X\n", + (int)areaid, (int)size, (int)logadr, (int)pe.address); return areaid; }