Ticket #9074: 0001-ice1712-Refactoring.patch

File 0001-ice1712-Refactoring.patch, 180.1 KB (added by jerl1, 10 years ago)
  • src/add-ons/kernel/drivers/audio/ice1712/Jamfile

    From 9627e22c6018be6d8e1904448c981ed53591bb13 Mon Sep 17 00:00:00 2001
    From: Jerome Leveque <leveque.jerome@gmail.com>
    Date: Mon, 2 Feb 2015 22:15:37 +0100
    Subject: [PATCH 1/2] ice1712 - Refactoring
    
    - Change C source code to C++
    - Fix build warning for x86 and x86_64 version
    - Re-organize source code
    - Change copyright
    ---
     src/add-ons/kernel/drivers/audio/ice1712/Jamfile   |   10 +-
     src/add-ons/kernel/drivers/audio/ice1712/debug.h   |   31 +-
     src/add-ons/kernel/drivers/audio/ice1712/ice1712.c |  851 --------------
     .../kernel/drivers/audio/ice1712/ice1712.cpp       |  829 ++++++++++++++
     src/add-ons/kernel/drivers/audio/ice1712/ice1712.h |  170 ++-
     .../kernel/drivers/audio/ice1712/ice1712_reg.h     |  257 ++---
     src/add-ons/kernel/drivers/audio/ice1712/io.c      |  601 ----------
     src/add-ons/kernel/drivers/audio/ice1712/io.cpp    |  611 ++++++++++
     src/add-ons/kernel/drivers/audio/ice1712/io.h      |   95 +-
     src/add-ons/kernel/drivers/audio/ice1712/midi.c    |  148 ---
     src/add-ons/kernel/drivers/audio/ice1712/midi.cpp  |  167 +++
     src/add-ons/kernel/drivers/audio/ice1712/multi.c   | 1156 -------------------
     src/add-ons/kernel/drivers/audio/ice1712/multi.cpp | 1186 ++++++++++++++++++++
     src/add-ons/kernel/drivers/audio/ice1712/multi.h   |   57 +-
     src/add-ons/kernel/drivers/audio/ice1712/util.c    |   83 --
     src/add-ons/kernel/drivers/audio/ice1712/util.cpp  |   79 ++
     src/add-ons/kernel/drivers/audio/ice1712/util.h    |   20 +-
     17 files changed, 3157 insertions(+), 3194 deletions(-)
     delete mode 100644 src/add-ons/kernel/drivers/audio/ice1712/ice1712.c
     create mode 100644 src/add-ons/kernel/drivers/audio/ice1712/ice1712.cpp
     delete mode 100644 src/add-ons/kernel/drivers/audio/ice1712/io.c
     create mode 100644 src/add-ons/kernel/drivers/audio/ice1712/io.cpp
     delete mode 100644 src/add-ons/kernel/drivers/audio/ice1712/midi.c
     create mode 100644 src/add-ons/kernel/drivers/audio/ice1712/midi.cpp
     delete mode 100644 src/add-ons/kernel/drivers/audio/ice1712/multi.c
     create mode 100644 src/add-ons/kernel/drivers/audio/ice1712/multi.cpp
     delete mode 100644 src/add-ons/kernel/drivers/audio/ice1712/util.c
     create mode 100644 src/add-ons/kernel/drivers/audio/ice1712/util.cpp
    
    diff --git a/src/add-ons/kernel/drivers/audio/ice1712/Jamfile b/src/add-ons/kernel/drivers/audio/ice1712/Jamfile
    index 1e11dc0..d21536d 100644
    a b SetSubDirSupportedPlatformsBeOSCompatible ;  
    55UsePrivateHeaders media ;
    66
    77KernelAddon ice1712 :
    8     ice1712.c
    9     io.c
    10     midi.c
    11     multi.c
    12     util.c
     8    ice1712.cpp
     9    io.cpp
     10    midi.cpp
     11    multi.cpp
     12    util.cpp
    1313;
    1414
  • src/add-ons/kernel/drivers/audio/ice1712/debug.h

    diff --git a/src/add-ons/kernel/drivers/audio/ice1712/debug.h b/src/add-ons/kernel/drivers/audio/ice1712/debug.h
    index c684bc0..f75da2c 100644
    a b  
    11/*
    2  * ice1712 BeOS/Haiku Driver for VIA - VT1712 Multi Channel Audio Controller
     2 * Copyright 2004-2015 Haiku, Inc. All rights reserved.
     3 * Distributed under the terms of the MIT License.
    34 *
    4  * Copyright (c) 2002, Jerome Duval     (jerome.duval@free.fr)
    5  * Copyright (c) 2003, Marcus Overhagen (marcus@overhagen.de)
    6  * Copyright (c) 2007, Jerome Leveque   (leveque.jerome@neuf.fr)
    7  *
    8  * All rights reserved
    9  * Distributed under the terms of the MIT license.
     5 * Authors:
     6 *      Jérôme Duval, jerome.duval@free.fr
     7 *      Marcus Overhagen, marcus@overhagen.de
     8 *      Jérôme Lévêque, leveque.jerome@gmail.com
    109 */
     10
     11
    1112#ifndef _DEBUG_ICE1712_H_
    1213#define _DEBUG_ICE1712_H_
    1314
    14 #ifdef TRACE
    15 #   undef TRACE
    16 #endif
    17 
    1815//#define ICE1712_VERBOSE
    1916#ifdef ICE1712_VERBOSE
    20 #   define TRACE(a...) dprintf("\33[34mice1712:\33[0m " a)
     17#   define ITRACE(a...) dprintf("ice1712: " a)
    2118#else
    22 #   define TRACE(a...) ;
     19#   define ITRACE(a...) (void)0
    2320#endif
    2421
    2522//#define ICE1712_VERY_VERBOSE
    2623#ifdef ICE1712_VERY_VERBOSE
    27 #   define TRACE_VV(a...) dprintf("\33[34mice1712:\33[0m " a)
     24#   define ITRACE_VV(a...) ITRACE(a)
    2825#else
    29 #   define TRACE_VV(a...) ;
     26#   define ITRACE_VV(a...) (void)0
    3027#endif
    3128
    32 #define ASSERT(a) if (a) {} else TRACE("ASSERT failed! file = %s, line = %d\n",\
    33     __FILE__,__LINE__)
    34    
    35 
    3629#endif // _DEBUG_ICE1712_H_
  • deleted file src/add-ons/kernel/drivers/audio/ice1712/ice1712.c

    diff --git a/src/add-ons/kernel/drivers/audio/ice1712/ice1712.c b/src/add-ons/kernel/drivers/audio/ice1712/ice1712.c
    deleted file mode 100644
    index 1a6dd4d..0000000
    + -  
    1 /*
    2  * ice1712 BeOS/Haiku Driver for VIA - VT1712 Multi Channel Audio Controller
    3  *
    4  * Copyright (c) 2002, Jerome Duval     (jerome.duval@free.fr)
    5  * Copyright (c) 2003, Marcus Overhagen (marcus@overhagen.de)
    6  * Copyright (c) 2007, Jerome Leveque   (leveque.jerome@neuf.fr)
    7  *
    8  * All rights reserved
    9  * Distributed under the terms of the MIT license.
    10  */
    11 
    12 
    13 #include "ice1712.h"
    14 #include "ice1712_reg.h"
    15 #include "io.h"
    16 #include "multi.h"
    17 #include "util.h"
    18 
    19 #include <KernelExport.h>
    20 #include <Drivers.h>
    21 #include <OS.h>
    22 #include <midi_driver.h>
    23 #include <drivers/driver_settings.h>
    24 
    25 #include <fcntl.h>
    26 #include <stdlib.h>
    27 #include <string.h>
    28 
    29 
    30 status_t init_hardware(void);
    31 status_t init_driver(void);
    32 void uninit_driver(void);
    33 const char **publish_devices(void);
    34 device_hooks *find_device(const char *);
    35 status_t load_settings(ice1712 *card);
    36 int32 ice_1712_int(void *arg);
    37 
    38 pci_module_info *pci;
    39 generic_mpu401_module *mpu401;
    40 
    41 int32 num_cards = 0;
    42 ice1712 cards[NUM_CARDS];
    43 int32 num_names = 0;
    44 char *names[NUM_CARDS*20+1];
    45 int32 api_version = B_CUR_DRIVER_API_VERSION;
    46 
    47 #define HMULTI_AUDIO_DEV_PATH "audio/hmulti/ice1712"
    48 
    49 
    50 status_t
    51 init_hardware(void)
    52 {
    53     int ix = 0;
    54     pci_info info;
    55 
    56     memset(cards, 0, sizeof(ice1712) * NUM_CARDS);
    57     TRACE("@@init_hardware()\n");
    58 
    59     if (get_module(B_PCI_MODULE_NAME, (module_info **)&pci))
    60         return ENOSYS;
    61 
    62     while ((*pci->get_nth_pci_info)(ix, &info) == B_OK) {
    63         if ((info.vendor_id == ICE1712_VENDOR_ID) &&
    64             (info.device_id == ICE1712_DEVICE_ID)) {
    65             TRACE("Found at least 1 card\n");
    66             put_module(B_PCI_MODULE_NAME);
    67             return B_OK;
    68         }
    69         ix++;
    70     }
    71     put_module(B_PCI_MODULE_NAME);
    72     return ENODEV;
    73 }
    74 
    75 
    76 int32
    77 ice_1712_int(void *arg)
    78 {
    79     ice1712 *ice = arg;
    80     uint8 reg8 = 0;
    81     uint16 reg16 = 0;
    82     uint32 status = B_UNHANDLED_INTERRUPT;
    83 
    84     // interrupt from DMA PATH
    85     reg8 = read_mt_uint8(ice, MT_DMA_INT_MASK_STATUS);
    86     if (reg8 != 0) {
    87         ice->buffer++;
    88         ice->played_time = system_time();
    89         ice->frames_count += ice->buffer_size;
    90 
    91         release_sem_etc(ice->buffer_ready_sem, 1, B_DO_NOT_RESCHEDULE);
    92         write_mt_uint8(ice, MT_DMA_INT_MASK_STATUS, reg8);
    93         status = B_HANDLED_INTERRUPT;
    94     }
    95 
    96     // interrupt from Controller Registers
    97     reg8 = read_ccs_uint8(ice, CCS_INTERRUPT_STATUS);
    98     if (reg8 != 0) {
    99         bool ret;
    100         if (reg8 & CCS_INTERRUPT_MIDI_1) {
    101             ret = (*mpu401->interrupt_hook)(ice->midi_interf[0].mpu401device);
    102             if (ret) {
    103                 //Do not ack, cause more datas are available
    104                 reg8 &= ~CCS_INTERRUPT_MIDI_1;
    105             }
    106         }
    107 
    108         if (reg8 & CCS_INTERRUPT_MIDI_2) {
    109             ret = (*mpu401->interrupt_hook)(ice->midi_interf[1].mpu401device);
    110             if (ret) {
    111                 //Do not ack, cause more datas are available
    112                 reg8 &= ~CCS_INTERRUPT_MIDI_2;
    113             }
    114         }
    115 
    116         if (reg8 != 0) {
    117             write_ccs_uint8(ice, CCS_INTERRUPT_STATUS, reg8);
    118             status = B_HANDLED_INTERRUPT;
    119         }
    120     }
    121 
    122     // interrupt from DS PATH
    123     reg16 = read_ds_uint16(ice, DS_DMA_INT_STATUS);
    124     if (reg16 != 0) {
    125         //Ack interrupt
    126         write_ds_uint16(ice, DS_DMA_INT_STATUS, reg16);
    127         status = B_HANDLED_INTERRUPT;
    128     }
    129 
    130     return status;
    131 }
    132 
    133 
    134 static status_t
    135 ice1712_setup(ice1712 *ice)
    136 {
    137     int i;
    138     uint8 reg8 = 0;
    139     uint16 mute;
    140 
    141     ice->irq            = ice->info.u.h0.interrupt_line;
    142     ice->Controller     = ice->info.u.h0.base_registers[0];
    143     ice->DDMA           = ice->info.u.h0.base_registers[1];
    144     ice->DMA_Path       = ice->info.u.h0.base_registers[2];
    145     ice->Multi_Track    = ice->info.u.h0.base_registers[3];
    146 
    147     // Soft Reset
    148     write_ccs_uint8(ice, CCS_CONTROL_STATUS, 0x81);
    149     snooze(200000);
    150     write_ccs_uint8(ice, CCS_CONTROL_STATUS, 0x01);
    151     snooze(200000);
    152 
    153     read_eeprom(ice, ice->eeprom_data);
    154 
    155 /*  TRACE("EEprom -> ");
    156     for (i = 0; i < 32; i++)
    157         TRACE("%x, ", eeprom_data[i]);
    158     TRACE("<- EEprom\n");*/
    159 
    160     write_ccs_uint8(ice, CCS_SERR_SHADOW, 0x01);
    161 
    162     //Write all configurations register from EEProm
    163     ice->info.device_id = ice->eeprom_data[E2PROM_MAP_SUBVENDOR_HIGH] << 8
    164         | ice->eeprom_data[E2PROM_MAP_SUBVENDOR_LOW];
    165     ice->info.vendor_id = ice->eeprom_data[E2PROM_MAP_SUBDEVICE_HIGH] << 8
    166         | ice->eeprom_data[E2PROM_MAP_SUBDEVICE_LOW];
    167     ice->product = ice->info.vendor_id << 16 | ice->info.device_id;
    168     TRACE("Product ID : 0x%x\n", ice->product);
    169 
    170     write_cci_uint8(ice, CCI_GPIO_WRITE_MASK,
    171         ice->eeprom_data[E2PROM_MAP_GPIOMASK]);
    172     write_cci_uint8(ice, CCI_GPIO_DATA,
    173         ice->eeprom_data[E2PROM_MAP_GPIOSTATE]);
    174     write_cci_uint8(ice, CCI_GPIO_DIRECTION_CONTROL,
    175         ice->eeprom_data[E2PROM_MAP_GPIODIR]);
    176 
    177     TRACE("CCI_GPIO_WRITE_MASK : 0x%x\n",
    178         ice->eeprom_data[E2PROM_MAP_GPIOMASK]);
    179     TRACE("CCI_GPIO_DATA : 0x%x\n",
    180         ice->eeprom_data[E2PROM_MAP_GPIOSTATE]);
    181     TRACE("CCI_GPIO_DIRECTION_CONTROL : 0x%x\n",
    182         ice->eeprom_data[E2PROM_MAP_GPIODIR]);
    183 
    184 
    185     //Write Configuration in the PCI configuration Register
    186     (pci->write_pci_config)(ice->info.bus, ice->info.device,
    187         ice->info.function, 0x60, 1, ice->eeprom_data[E2PROM_MAP_CONFIG]);
    188     (pci->write_pci_config)(ice->info.bus, ice->info.device,
    189         ice->info.function, 0x61, 1, ice->eeprom_data[E2PROM_MAP_ACL]);
    190     (pci->write_pci_config)(ice->info.bus, ice->info.device,
    191         ice->info.function, 0x62, 1, ice->eeprom_data[E2PROM_MAP_I2S]);
    192     (pci->write_pci_config)(ice->info.bus, ice->info.device,
    193         ice->info.function, 0x63, 1, ice->eeprom_data[E2PROM_MAP_SPDIF]);
    194 
    195     TRACE("E2PROM_MAP_CONFIG : 0x%x\n", ice->eeprom_data[E2PROM_MAP_CONFIG]);
    196     reg8 = ice->eeprom_data[E2PROM_MAP_CONFIG];
    197     //Bits signification for E2PROM_MAP_CONFIG Byte
    198     //
    199     // 8   7   6   5   4   3   2   1   0
    200     //           |-D-|-C-|---B---|---A---
    201     //
    202     // D : MPU401 number minus 1
    203     // C : AC'97
    204     // B : Stereo ADC number minus 1 (=> 1 to 4)
    205     // A : Stereo DAC number minus 1 (=> 1 to 4)
    206 
    207     ice->config.nb_DAC = ((reg8 & 0x03) + 1) * 2;
    208     reg8 >>= 2;
    209     ice->config.nb_ADC = ((reg8 & 0x03) + 1) * 2;
    210     reg8 >>= 2;
    211 
    212     if ((reg8 & 0x01) != 0) {//Consumer AC'97 Exist
    213         TRACE("Consumer AC'97 does exist\n");
    214         //For now do nothing
    215 /*      write_ccs_uint8(ice, CCS_CONS_AC97_COMMAND_STATUS, 0x40);
    216         snooze(10000);
    217         write_ccs_uint8(ice, CCS_CONS_AC97_COMMAND_STATUS, 0x00);
    218         snooze(20000);
    219 */  } else {
    220         TRACE("Consumer AC'97 does NOT exist\n");
    221     }
    222     reg8 >>= 1;
    223     ice->config.nb_MPU401 = (reg8 & 0x1) + 1;
    224 
    225     if (ice->config.nb_MPU401 > 0) {
    226         sprintf(ice->midi_interf[0].name, "midi/ice1712/%ld/1",
    227             ice - cards + 1);
    228 
    229         (*mpu401->create_device)(ice->Controller + CCS_MIDI_1_DATA,
    230             &ice->midi_interf[0].mpu401device,
    231             0x14121712,
    232             ice_1712_midi_interrupt_op,
    233             &ice->midi_interf[0]);
    234 
    235         names[num_names++] = ice->midi_interf[0].name;
    236         ice->midi_interf[0].card = ice;
    237         ice->midi_interf[0].int_mask = CCS_INTERRUPT_MIDI_1;
    238     }
    239 
    240     if (ice->config.nb_MPU401 > 1) {
    241         sprintf(ice->midi_interf[1].name, "midi/ice1712/%ld/2",
    242             ice - cards + 1);
    243 
    244         (*mpu401->create_device)(ice->Controller + CCS_MIDI_2_DATA,
    245             &ice->midi_interf[1].mpu401device,
    246             0x14121712,
    247             ice_1712_midi_interrupt_op,
    248             &ice->midi_interf[1]);
    249 
    250         names[num_names++] = ice->midi_interf[1].name;
    251         ice->midi_interf[1].card = ice;
    252         ice->midi_interf[1].int_mask = CCS_INTERRUPT_MIDI_2;
    253     }
    254 
    255     TRACE("E2PROM_MAP_SPDIF : 0x%x\n", ice->eeprom_data[E2PROM_MAP_SPDIF]);
    256     ice->config.spdif = ice->eeprom_data[E2PROM_MAP_SPDIF];
    257 
    258     switch (ice->product) {
    259         case ICE1712_SUBDEVICE_DELTA66 :
    260         case ICE1712_SUBDEVICE_DELTA44 :
    261             ice->CommLines.clock = DELTA66_CLK;
    262             ice->CommLines.data_in = 0;
    263             ice->CommLines.data_out = DELTA66_DOUT;
    264             ice->CommLines.cs_mask = DELTA66_CLK | DELTA66_DOUT
    265                 | DELTA66_CS_MASK;
    266             break;
    267         case ICE1712_SUBDEVICE_DELTA410 :
    268         case ICE1712_SUBDEVICE_AUDIOPHILE_2496 :
    269         case ICE1712_SUBDEVICE_DELTADIO2496 :
    270             ice->CommLines.clock = AP2496_CLK;
    271             ice->CommLines.data_in = AP2496_DIN;
    272             ice->CommLines.data_out = AP2496_DOUT;
    273             ice->CommLines.cs_mask = AP2496_CLK | AP2496_DIN
    274                 | AP2496_DOUT | AP2496_CS_MASK;
    275             break;
    276         case ICE1712_SUBDEVICE_DELTA1010 :
    277         case ICE1712_SUBDEVICE_DELTA1010LT :
    278             ice->CommLines.clock = DELTA1010LT_CLK;
    279             ice->CommLines.data_in = DELTA1010LT_DIN;
    280             ice->CommLines.data_out = DELTA1010LT_DOUT;
    281             ice->CommLines.cs_mask = DELTA1010LT_CLK | DELTA1010LT_DIN
    282                 | DELTA1010LT_DOUT | DELTA1010LT_CS_NONE;
    283             break;
    284         case ICE1712_SUBDEVICE_VX442 :
    285             ice->CommLines.clock = VX442_CLK;
    286             ice->CommLines.data_in = VX442_DIN;
    287             ice->CommLines.data_out = VX442_DOUT;
    288             ice->CommLines.cs_mask = VX442_CLK | VX442_DIN | VX442_DOUT
    289                 | VX442_CS_MASK;
    290             break;
    291     }
    292 
    293     sprintf(ice->name, "%s/%ld", HMULTI_AUDIO_DEV_PATH, ice - cards + 1);
    294     names[num_names++] = ice->name;
    295     names[num_names] = NULL;
    296 
    297     ice->buffer_ready_sem = create_sem(0, "Buffer Exchange");
    298     if (ice->buffer_ready_sem < B_OK) {
    299         return ice->buffer_ready_sem;
    300     }
    301 
    302 //  TRACE("installing interrupt : %0x\n", ice->irq);
    303     install_io_interrupt_handler(ice->irq, ice_1712_int, ice, 0);
    304 
    305     ice->mem_id_pb = alloc_mem(&ice->phys_addr_pb, &ice->log_addr_pb,
    306                                 PLAYBACK_BUFFER_TOTAL_SIZE,
    307                                 "playback buffer");
    308     if (ice->mem_id_pb < B_OK) {
    309         remove_io_interrupt_handler(ice->irq, ice_1712_int, ice);
    310         delete_sem(ice->buffer_ready_sem);
    311         return ice->mem_id_pb;
    312     }
    313 
    314     ice->mem_id_rec = alloc_mem(&ice->phys_addr_rec, &ice->log_addr_rec,
    315                                 RECORD_BUFFER_TOTAL_SIZE,
    316                                 "record buffer");
    317     if (ice->mem_id_rec < B_OK) {
    318         remove_io_interrupt_handler(ice->irq, ice_1712_int, ice);
    319         delete_sem(ice->buffer_ready_sem);
    320         delete_area(ice->mem_id_pb);
    321         return(ice->mem_id_rec);
    322     }
    323 
    324     memset(ice->log_addr_pb, 0, PLAYBACK_BUFFER_TOTAL_SIZE);
    325     memset(ice->log_addr_rec, 0, RECORD_BUFFER_TOTAL_SIZE);
    326 
    327     ice->sampling_rate = 0x08;
    328     ice->buffer = 0;
    329     ice->frames_count = 0;
    330     ice->buffer_size = ice->settings.bufferSize;
    331 
    332     ice->total_output_channels = ice->config.nb_DAC;
    333     if (ice->config.spdif & SPDIF_OUT_PRESENT)
    334         ice->total_output_channels += 2;
    335 
    336     ice->total_input_channels = ice->config.nb_ADC + 2;
    337     if (ice->config.spdif & SPDIF_IN_PRESENT)
    338         ice->total_input_channels += 2;
    339 
    340     //Write bits in the GPIO
    341     write_cci_uint8(ice, CCI_GPIO_WRITE_MASK, ~(ice->CommLines.cs_mask));
    342     //Deselect CS
    343     write_cci_uint8(ice, CCI_GPIO_DATA, ice->CommLines.cs_mask);
    344 
    345     //Set the rampe volume to a faster one
    346     write_mt_uint16(ice, MT_VOLUME_CONTROL_RATE, 0x01);
    347 
    348     //All Analog outputs from DMA
    349     write_mt_uint16(ice, MT_ROUTING_CONTROL_PSDOUT, 0x0000);
    350     //All Digital output from DMA
    351     write_mt_uint16(ice, MT_ROUTING_CONTROL_SPDOUT, 0x0000);
    352 
    353     //Just to route all input to all output
    354 //  write_mt_uint16(ice, MT_ROUTING_CONTROL_PSDOUT, 0xAAAA);
    355 //  write_mt_uint32(ice, MT_CAPTURED_DATA,  0x76543210);
    356 
    357     //Just to route SPDIF Input to DAC 0
    358 //  write_mt_uint16(ice, MT_ROUTING_CONTROL_PSDOUT, 0xAAAF);
    359 //  write_mt_uint32(ice, MT_CAPTURED_DATA,  0x76543280);
    360 
    361     //Mute all input
    362     mute = (ICE1712_MUTE_VALUE << 0) | (ICE1712_MUTE_VALUE << 8);
    363     for (i = 0; i < 2 * ICE1712_HARDWARE_VOLUME; i++) {
    364         write_mt_uint8(ice, MT_VOLUME_CONTROL_CHANNEL_INDEX, i);
    365         write_mt_uint16(ice, MT_VOLUME_CONTROL_CHANNEL_INDEX, mute);
    366     }
    367 
    368     //Unmask Interrupt
    369     write_ccs_uint8(ice, CCS_CONTROL_STATUS, 0x41);
    370 
    371     reg8 = read_ccs_uint8(ice, CCS_INTERRUPT_MASK);
    372     TRACE("-----CCS----- = %x\n", reg8);
    373     write_ccs_uint8(ice, CCS_INTERRUPT_MASK, 0xEF);
    374 
    375 /*  reg16 = read_ds_uint16(ice, DS_DMA_INT_MASK);
    376     TRACE("-----DS_DMA----- = %x\n", reg16);
    377     write_ds_uint16(ice, DS_DMA_INT_MASK, 0x0000);
    378 */
    379     reg8 = read_mt_uint8(ice, MT_DMA_INT_MASK_STATUS);
    380     TRACE("-----MT_DMA----- = %x\n", reg8);
    381     write_mt_uint8(ice, MT_DMA_INT_MASK_STATUS, 0x00);
    382 
    383     return B_OK;
    384 };
    385 
    386 
    387 status_t
    388 init_driver(void)
    389 {
    390     int i = 0;
    391     status_t err;
    392     num_cards = 0;
    393 
    394     TRACE("@@init_driver()\n");
    395 
    396     if (get_module(B_PCI_MODULE_NAME, (module_info **)&pci))
    397         return ENOSYS;
    398 
    399     if (get_module(B_MPU_401_MODULE_NAME, (module_info **) &mpu401)) {
    400         put_module(B_PCI_MODULE_NAME);
    401         return ENOSYS;
    402     }
    403 
    404     while ((*pci->get_nth_pci_info)(i, &cards[num_cards].info) == B_OK) {
    405         //TODO check other Vendor_ID and DEVICE_ID
    406         if ((cards[num_cards].info.vendor_id == ICE1712_VENDOR_ID)
    407             && (cards[num_cards].info.device_id == ICE1712_DEVICE_ID)) {
    408             if (num_cards == NUM_CARDS) {
    409                 TRACE("Too many ice1712 cards installed!\n");
    410                 break;
    411             }
    412 
    413             if ((err = (*pci->reserve_device)(cards[num_cards].info.bus,
    414                 cards[num_cards].info.device, cards[num_cards].info.function,
    415                 DRIVER_NAME, &cards[num_cards])) < B_OK) {
    416                 dprintf("%s: failed to reserve_device(%d, %d, %d,): %s\n",
    417                     DRIVER_NAME, cards[num_cards].info.bus,
    418                     cards[num_cards].info.device,
    419                     cards[num_cards].info.function, strerror(err));
    420                 continue;
    421             }
    422 
    423             load_settings(&cards[num_cards]);
    424 
    425             if (ice1712_setup(&cards[num_cards]) != B_OK) {
    426             //Vendor_ID and Device_ID has been modified
    427                 TRACE("Setup of ice1712 %d failed\n", (int)(num_cards + 1));
    428                 (*pci->unreserve_device)(cards[num_cards].info.bus,
    429                     cards[num_cards].info.device,
    430                     cards[num_cards].info.function,
    431                     DRIVER_NAME, &cards[num_cards]);
    432             } else {
    433                 num_cards++;
    434             }
    435         }
    436         i++;
    437     }
    438 
    439     TRACE("Number of succesfully initialised card : %d\n", (int)num_cards);
    440 
    441     if (num_cards == 0) {
    442         put_module(B_PCI_MODULE_NAME);
    443         put_module(B_MPU_401_MODULE_NAME);
    444         return ENODEV;
    445     }
    446     return B_OK;
    447 }
    448 
    449 
    450 static void
    451 ice_1712_shutdown(ice1712 *ice)
    452 {
    453     delete_sem(ice->buffer_ready_sem);
    454 
    455     remove_io_interrupt_handler(ice->irq, ice_1712_int, ice);
    456 
    457     if (ice->mem_id_pb != B_ERROR)
    458         delete_area(ice->mem_id_pb);
    459 
    460     if (ice->mem_id_rec != B_ERROR)
    461         delete_area(ice->mem_id_rec);
    462 
    463     codec_write(ice, AK45xx_RESET_REGISTER, 0x00);
    464 }
    465 
    466 
    467 void
    468 uninit_driver(void)
    469 {
    470     int ix, cnt = num_cards;
    471 
    472     TRACE("@@uninit_driver()\n");
    473 
    474     num_cards = 0;
    475 
    476     for (ix = 0; ix < cnt; ix++) {
    477         ice_1712_shutdown(&cards[ix]);
    478         (*pci->unreserve_device)(cards[ix].info.bus,
    479             cards[ix].info.device, cards[ix].info.function,
    480             DRIVER_NAME, &cards[ix]);
    481     }
    482     memset(&cards, 0, sizeof(cards));
    483     put_module(B_MPU_401_MODULE_NAME);
    484     put_module(B_PCI_MODULE_NAME);
    485 }
    486 
    487 
    488 const char **
    489 publish_devices(void)
    490 {
    491     int ix = 0;
    492     TRACE("@@publish_devices()\n");
    493 
    494     for (ix=0; names[ix]; ix++) {
    495         TRACE("publish %s\n", names[ix]);
    496     }
    497     return (const char **)names;
    498 }
    499 
    500 
    501 static status_t
    502 ice_1712_open(const char *name, uint32 flags, void **cookie)
    503 {
    504     int ix;
    505     ice1712 *card = NULL;
    506     TRACE("**open()\n");
    507 
    508     for (ix=0; ix<num_cards; ix++) {
    509         if (!strcmp(cards[ix].name, name)) {
    510             card = &cards[ix];
    511         }
    512     }
    513 
    514     if (card == NULL) {
    515         TRACE("open() card not found %s\n", name);
    516         for (ix=0; ix<num_cards; ix++) {
    517             TRACE("open() card available %s\n", cards[ix].name);
    518         }
    519         return B_ERROR;
    520     }
    521     *cookie = cards;
    522     return B_OK;
    523 }
    524 
    525 
    526 static status_t
    527 ice_1712_close(void *cookie)
    528 {
    529     TRACE("**close()\n");
    530     return B_OK;
    531 }
    532 
    533 
    534 static status_t
    535 ice_1712_free(void *cookie)
    536 {
    537     TRACE("**free()\n");
    538     return B_OK;
    539 }
    540 
    541 
    542 static status_t
    543 ice_1712_control(void *cookie, uint32 op, void *arg, size_t len)
    544 {
    545     switch (op) {
    546         case B_MULTI_GET_DESCRIPTION :
    547             TRACE("B_MULTI_GET_DESCRIPTION\n");
    548             return ice1712_get_description((ice1712 *)cookie,
    549                 (multi_description*)arg);
    550         case B_MULTI_GET_EVENT_INFO :
    551             TRACE("B_MULTI_GET_EVENT_INFO\n");
    552             return B_ERROR;
    553         case B_MULTI_SET_EVENT_INFO :
    554             TRACE("B_MULTI_SET_EVENT_INFO\n");
    555             return B_ERROR;
    556         case B_MULTI_GET_EVENT :
    557             TRACE("B_MULTI_GET_EVENT\n");
    558             return B_ERROR;
    559         case B_MULTI_GET_ENABLED_CHANNELS :
    560             TRACE("B_MULTI_GET_ENABLED_CHANNELS\n");
    561             return ice1712_get_enabled_channels((ice1712*)cookie,
    562                 (multi_channel_enable*)arg);
    563         case B_MULTI_SET_ENABLED_CHANNELS :
    564             TRACE("B_MULTI_SET_ENABLED_CHANNELS\n");
    565             return ice1712_set_enabled_channels((ice1712*)cookie,
    566                 (multi_channel_enable*)arg);
    567         case B_MULTI_GET_GLOBAL_FORMAT :
    568             TRACE("B_MULTI_GET_GLOBAL_FORMAT\n");
    569             return ice1712_get_global_format((ice1712*)cookie,
    570                 (multi_format_info *)arg);
    571         case B_MULTI_SET_GLOBAL_FORMAT :
    572             TRACE("B_MULTI_SET_GLOBAL_FORMAT\n");
    573             return ice1712_set_global_format((ice1712*)cookie,
    574                 (multi_format_info *)arg);
    575         case B_MULTI_GET_CHANNEL_FORMATS :
    576             TRACE("B_MULTI_GET_CHANNEL_FORMATS\n");
    577             return B_ERROR;
    578         case B_MULTI_SET_CHANNEL_FORMATS :
    579             TRACE("B_MULTI_SET_CHANNEL_FORMATS\n");
    580             return B_ERROR;
    581         case B_MULTI_GET_MIX :
    582             TRACE("B_MULTI_GET_MIX\n");
    583             return ice1712_get_mix((ice1712*)cookie,
    584                 (multi_mix_value_info *)arg);
    585         case B_MULTI_SET_MIX :
    586             TRACE("B_MULTI_SET_MIX\n");
    587             return ice1712_set_mix((ice1712*)cookie,
    588                 (multi_mix_value_info *)arg);
    589         case B_MULTI_LIST_MIX_CHANNELS :
    590             TRACE("B_MULTI_LIST_MIX_CHANNELS\n");
    591             return ice1712_list_mix_channels((ice1712*)cookie,
    592                 (multi_mix_channel_info *)arg);
    593         case B_MULTI_LIST_MIX_CONTROLS :
    594             TRACE("B_MULTI_LIST_MIX_CONTROLS\n");
    595             return ice1712_list_mix_controls((ice1712*)cookie,
    596                 (multi_mix_control_info *)arg);
    597         case B_MULTI_LIST_MIX_CONNECTIONS :
    598             TRACE("B_MULTI_LIST_MIX_CONNECTIONS\n");
    599             return ice1712_list_mix_connections((ice1712*)cookie,
    600                 (multi_mix_connection_info *)arg);
    601         case B_MULTI_GET_BUFFERS :
    602             TRACE("B_MULTI_GET_BUFFERS\n");
    603             return ice1712_get_buffers((ice1712*)cookie,
    604                 (multi_buffer_list*)arg);
    605         case B_MULTI_SET_BUFFERS :
    606             TRACE("B_MULTI_SET_BUFFERS\n");
    607             return B_ERROR;
    608         case B_MULTI_SET_START_TIME :
    609             TRACE("B_MULTI_SET_START_TIME\n");
    610             return B_ERROR;
    611         case B_MULTI_BUFFER_EXCHANGE :
    612 //          TRACE("B_MULTI_BUFFER_EXCHANGE\n");
    613             return ice1712_buffer_exchange((ice1712*)cookie,
    614                 (multi_buffer_info *)arg);
    615         case B_MULTI_BUFFER_FORCE_STOP :
    616             TRACE("B_MULTI_BUFFER_FORCE_STOP\n");
    617             return ice1712_buffer_force_stop((ice1712*)cookie);
    618         case B_MULTI_LIST_EXTENSIONS :
    619             TRACE("B_MULTI_LIST_EXTENSIONS\n");
    620             return B_ERROR;
    621         case B_MULTI_GET_EXTENSION :
    622             TRACE("B_MULTI_GET_EXTENSION\n");
    623             return B_ERROR;
    624         case B_MULTI_SET_EXTENSION :
    625             TRACE("B_MULTI_SET_EXTENSION\n");
    626             return B_ERROR;
    627         case B_MULTI_LIST_MODES :
    628             TRACE("B_MULTI_LIST_MODES\n");
    629             return B_ERROR;
    630         case B_MULTI_GET_MODE :
    631             TRACE("B_MULTI_GET_MODE\n");
    632             return B_ERROR;
    633         case B_MULTI_SET_MODE :
    634             TRACE("B_MULTI_SET_MODE\n");
    635             return B_ERROR;
    636 
    637         default :
    638             TRACE("ERROR: unknown multi_control %#x\n", (int)op);
    639             return B_ERROR;
    640     }
    641 }
    642 
    643 
    644 static status_t
    645 ice_1712_read(void *cookie, off_t position, void *buf, size_t *num_bytes)
    646 {
    647     TRACE("**read()\n");
    648     *num_bytes = 0;
    649     return B_IO_ERROR;
    650 }
    651 
    652 
    653 static status_t
    654 ice_1712_write(void *cookie, off_t position, const void *buffer,
    655     size_t *num_bytes)
    656 {
    657     TRACE("**write()\n");
    658     *num_bytes = 0;
    659     return B_IO_ERROR;
    660 }
    661 
    662 
    663 device_hooks ice1712_hooks =
    664 {
    665     ice_1712_open,
    666     ice_1712_close,
    667     ice_1712_free,
    668     ice_1712_control,
    669     ice_1712_read,
    670     ice_1712_write,
    671     NULL,
    672     NULL,
    673     NULL,
    674     NULL
    675 };
    676 
    677 
    678 device_hooks ice1712_midi_hooks =
    679 {
    680     ice_1712_midi_open,
    681     ice_1712_midi_close,
    682     ice_1712_midi_free,
    683     ice_1712_midi_control,
    684     ice_1712_midi_read,
    685     ice_1712_midi_write,
    686     NULL,
    687     NULL,
    688     NULL,
    689     NULL
    690 };
    691 
    692 
    693 device_hooks *
    694 find_device(const char * name)
    695 {
    696     int ix, midi;
    697 
    698     TRACE("**find_device(%s)\n", name);
    699 
    700     for (ix=0; ix < num_cards; ix++) {
    701 
    702         for (midi = 0; midi < MAX_MIDI_INTERFACE; midi++) {
    703             if (!strcmp(cards[ix].midi_interf[midi].name, name)) {
    704                 return &ice1712_midi_hooks;
    705             }
    706         }
    707 
    708         if (!strcmp(cards[ix].name, name)) {
    709             return &ice1712_hooks;
    710         }
    711     }
    712     TRACE("!!! failed !!!\n");
    713     return NULL;
    714 }
    715 
    716 status_t
    717 load_settings(ice1712 *card)
    718 {
    719     // get driver settings
    720     void *settings_handle = load_driver_settings("ice1712.settings");
    721 
    722     //Use a large enough value for modern computer
    723     card->settings.bufferSize = 512;
    724 
    725     if (settings_handle != NULL) {
    726         const char *item;
    727         char *end;
    728 
    729         item = get_driver_parameter(settings_handle, "buffer_size",
    730             "512", "512");
    731         if (item) {
    732             uint32 value = strtoul(item, &end, 0);
    733             if ((*end == '\0')
    734                 && (value >= MIN_BUFFER_FRAMES)
    735                 && (value <= MAX_BUFFER_FRAMES)) {
    736                     card->settings.bufferSize = value;
    737             }
    738         }
    739 
    740         unload_driver_settings(settings_handle);
    741     }
    742 
    743     return B_OK;
    744 }
    745 
    746 
    747 status_t
    748 apply_settings(ice1712 *card)
    749 {
    750     int i;
    751     uint16 val, mt30 = 0;
    752     uint32 mt34 = 0;
    753 
    754     for (i = 0; i < ICE1712_HARDWARE_VOLUME; i++) {
    755         //Select the channel
    756         write_mt_uint8(card, MT_VOLUME_CONTROL_CHANNEL_INDEX, i);
    757 
    758         if (card->settings.playback[i].mute == true) {
    759             val = (ICE1712_MUTE_VALUE << 0) | (ICE1712_MUTE_VALUE << 8);
    760         } else {
    761             unsigned char volume = card->settings.playback[i].volume / -1.5;
    762             if (i & 1) {//a right channel
    763                 val = ICE1712_MUTE_VALUE << 0; //Mute left volume
    764                 val |= volume << 8;
    765             } else {//a left channel
    766                 val = ICE1712_MUTE_VALUE << 8; //Mute right volume
    767                 val |= volume << 0;
    768             }
    769         }
    770 
    771         write_mt_uint16(card, MT_LR_VOLUME_CONTROL, val);
    772         TRACE_VV("Apply Settings %d : 0x%x\n", i, val);
    773     }
    774 
    775     for (i = 0; i < ICE1712_HARDWARE_VOLUME; i++) {
    776         //Select the channel
    777         write_mt_uint8(card, MT_VOLUME_CONTROL_CHANNEL_INDEX,
    778             i + ICE1712_HARDWARE_VOLUME);
    779 
    780         if (card->settings.record[i].mute == true) {
    781             val = (ICE1712_MUTE_VALUE << 0) | (ICE1712_MUTE_VALUE << 8);
    782         } else {
    783             uint8 volume = card->settings.record[i].volume / -1.5;
    784             if (i & 1) {//a right channel
    785                 val = ICE1712_MUTE_VALUE << 0; //Mute left volume
    786                 val |= volume << 8;
    787             } else {//a left channel
    788                 val = ICE1712_MUTE_VALUE << 8; //Mute right volume
    789                 val |= volume << 0;
    790             }
    791         }
    792 
    793         write_mt_uint16(card, MT_LR_VOLUME_CONTROL, val);
    794         TRACE_VV("Apply Settings %d : 0x%x\n", i, val);
    795     }
    796 
    797     //Analog output selection
    798     for (i = 0; i < 4; i++) {
    799         uint8 out = card->settings.output[i];
    800         if (out == 0) {
    801             TRACE_VV("Output %d is haiku output\n", i);
    802             //Nothing to do
    803         } else if (out <= (card->config.nb_ADC / 2)) {
    804             uint8 mt34_c;
    805             out--;
    806             TRACE_VV("Output %d is input %d\n", i, out);
    807             mt34_c = (out * 2);
    808             mt34_c |= (out * 2 + 1) << 4;
    809             mt30 |= 0x0202 << (2*i);
    810             mt30 |= mt34_c << (8*i);
    811         } else if (out == ((card->config.nb_ADC / 2) + 1)
    812                 && (card->config.spdif & SPDIF_IN_PRESENT) != 0) {
    813             TRACE_VV("Output %d is digital input\n", i);
    814             mt30 |= 0x0303 << (2*i);
    815             mt34 |= 0x80 << (8*i);
    816         } else {
    817             TRACE_VV("Output %d is digital Mixer\n", i);
    818             mt30 |= 0x0101;
    819         }
    820     }
    821     write_mt_uint16(card, MT_ROUTING_CONTROL_PSDOUT, mt30);
    822     write_mt_uint32(card, MT_CAPTURED_DATA, mt34);
    823 
    824     //Digital output
    825     if ((card->config.spdif & SPDIF_OUT_PRESENT) != 0) {
    826         uint16 mt32 = 0;
    827         uint8 out = card->settings.output[4];
    828         if (out == 0) {
    829             TRACE_VV("Digital output is haiku output\n");
    830             //Nothing to do
    831         } else if (out <= (card->config.nb_ADC / 2)) {
    832             out--;
    833             TRACE_VV("Digital output is input %d\n", out);
    834             mt32 |= 0x0202;
    835             mt32 |= (out * 2) << 8;
    836             mt32 |= (out * 2 + 1) << 12;
    837         } else if (out == ((card->config.nb_ADC / 2) + 1)
    838                 && (card->config.spdif & SPDIF_IN_PRESENT) != 0) {
    839             TRACE_VV("Digital output is digital input\n");
    840             mt32 |= 0x800F;
    841         } else {
    842             TRACE_VV("Digital output is digital Mixer\n");
    843             mt32 |= 0x0005;
    844         }
    845 
    846         write_mt_uint16(card, MT_ROUTING_CONTROL_SPDOUT, mt32);
    847     }
    848 
    849 
    850     return B_OK;
    851 }
  • new file src/add-ons/kernel/drivers/audio/ice1712/ice1712.cpp

    diff --git a/src/add-ons/kernel/drivers/audio/ice1712/ice1712.cpp b/src/add-ons/kernel/drivers/audio/ice1712/ice1712.cpp
    new file mode 100644
    index 0000000..94d182f
    - +  
     1/*
     2 * Copyright 2004-2015 Haiku, Inc. All rights reserved.
     3 * Distributed under the terms of the MIT License.
     4 *
     5 * Authors:
     6 *      Jérôme Duval, jerome.duval@free.fr
     7 *      Marcus Overhagen, marcus@overhagen.de
     8 *      Jérôme Lévêque, leveque.jerome@gmail.com
     9 */
     10
     11
     12#include "ice1712.h"
     13#include "ice1712_reg.h"
     14#include "io.h"
     15#include "multi.h"
     16#include "util.h"
     17
     18#include <KernelExport.h>
     19#include <Drivers.h>
     20#include <OS.h>
     21#include <midi_driver.h>
     22#include <drivers/driver_settings.h>
     23
     24#include <fcntl.h>
     25#include <stdlib.h>
     26#include <string.h>
     27
     28static status_t ice1712Settings_load(ice1712 *card);
     29status_t ice1712Settings_apply(ice1712 *card);
     30static int32 ice1712HW_interrupt(void *arg);
     31static status_t ice1712HW_setup(ice1712 *ice);
     32static void ice1712HW_shutdown(ice1712 *ice);
     33
     34extern device_hooks ice1712Midi_hooks;
     35extern device_hooks ice1712Audio_hooks;
     36void ice1712Midi_interrupt(int32 op, void *data);
     37
     38pci_module_info *pci;
     39generic_mpu401_module *mpu401;
     40
     41int32 num_cards = 0;
     42ice1712 cards[NUM_CARDS];
     43
     44//3 interfaces (2 midi + 1 audio) can be defined for each card
     45static char *names[NUM_CARDS*3+1];
     46static int32 num_names = 0;
     47
     48#define HMULTI_AUDIO_DEV_PATH "audio/hmulti/ice1712"
     49
     50//Haiku Driver API
     51//----------------
     52
     53int32 api_version = B_CUR_DRIVER_API_VERSION;
     54
     55extern "C" status_t
     56init_hardware(void)
     57{
     58    int ix = 0;
     59    pci_info info;
     60
     61    memset(cards, 0, sizeof(ice1712) * NUM_CARDS);
     62    ITRACE("@@ init_hardware()\n");
     63
     64    if (get_module(B_PCI_MODULE_NAME, (module_info **)&pci))
     65        return ENOSYS;
     66
     67    while ((*pci->get_nth_pci_info)(ix, &info) == B_OK) {
     68        if ((info.vendor_id == ICE1712_VENDOR_ID)
     69            && (info.device_id == ICE1712_DEVICE_ID)) {
     70            ITRACE("Found at least 1 card\n");
     71            put_module(B_PCI_MODULE_NAME);
     72            return B_OK;
     73        }
     74        ix++;
     75    }
     76    put_module(B_PCI_MODULE_NAME);
     77    return ENODEV;
     78}
     79
     80
     81extern "C" status_t
     82init_driver(void)
     83{
     84    int i = 0;
     85    status_t err;
     86    num_cards = 0;
     87
     88    ITRACE("@@ init_driver()\n");
     89
     90    if (get_module(B_PCI_MODULE_NAME, (module_info **)&pci))
     91        return ENOSYS;
     92
     93    if (get_module(B_MPU_401_MODULE_NAME, (module_info **) &mpu401)) {
     94        put_module(B_PCI_MODULE_NAME);
     95        return ENOSYS;
     96    }
     97
     98    while ((*pci->get_nth_pci_info)(i, &cards[num_cards].info) == B_OK) {
     99        //TODO check other Vendor_ID and DEVICE_ID
     100        if ((cards[num_cards].info.vendor_id == ICE1712_VENDOR_ID)
     101            && (cards[num_cards].info.device_id == ICE1712_DEVICE_ID)) {
     102            if (num_cards == NUM_CARDS) {
     103                ITRACE("Too many ice1712 cards installed!\n");
     104                break;
     105            }
     106
     107            if ((err = (*pci->reserve_device)(cards[num_cards].info.bus,
     108                cards[num_cards].info.device,
     109                cards[num_cards].info.function,
     110                DRIVER_NAME, &cards[num_cards])) < B_OK) {
     111                ITRACE_VV("%s: failed to reserve_device(%d, %d, %d,): %s\n",
     112                    DRIVER_NAME, cards[num_cards].info.bus,
     113                    cards[num_cards].info.device,
     114                    cards[num_cards].info.function, strerror(err));
     115                continue;
     116            }
     117
     118            ice1712Settings_load(&cards[num_cards]);
     119
     120            if (ice1712HW_setup(&cards[num_cards]) != B_OK) {
     121            //Vendor_ID and Device_ID has been modified
     122                ITRACE("Setup of ice1712 %" B_PRIu32 " failed\n", num_cards + 1);
     123                (*pci->unreserve_device)(cards[num_cards].info.bus,
     124                    cards[num_cards].info.device,
     125                    cards[num_cards].info.function,
     126                    DRIVER_NAME, &cards[num_cards]);
     127            } else {
     128                num_cards++;
     129            }
     130        }
     131        i++;
     132    }
     133
     134    ITRACE("Succesfully initialised card : %" B_PRIu32 "\n", num_cards);
     135
     136    if (num_cards == 0) {
     137        put_module(B_PCI_MODULE_NAME);
     138        put_module(B_MPU_401_MODULE_NAME);
     139        return ENODEV;
     140    }
     141    return B_OK;
     142}
     143
     144
     145extern "C" void
     146uninit_driver(void)
     147{
     148    int ix, cnt = num_cards;
     149
     150    ITRACE("@@ uninit_driver()\n");
     151
     152    num_cards = 0;
     153
     154    for (ix = 0; ix < cnt; ix++) {
     155        ice1712HW_shutdown(&cards[ix]);
     156        (*pci->unreserve_device)(cards[ix].info.bus,
     157            cards[ix].info.device, cards[ix].info.function,
     158            DRIVER_NAME, &cards[ix]);
     159    }
     160    memset(&cards, 0, sizeof(cards));
     161    put_module(B_MPU_401_MODULE_NAME);
     162    put_module(B_PCI_MODULE_NAME);
     163}
     164
     165
     166extern "C" const char **
     167publish_devices(void)
     168{
     169    int ix = 0;
     170    ITRACE("@@ publish_devices()\n");
     171
     172    for (ix = 0; names[ix]; ix++) {
     173        ITRACE("publish %s\n", names[ix]);
     174    }
     175    return (const char **)names;
     176}
     177
     178
     179extern "C" device_hooks *
     180find_device(const char * name)
     181{
     182    int ix, midi;
     183
     184    ITRACE("@@ find_device()\n");
     185
     186    for (ix = 0; ix < num_cards; ix++) {
     187        for (midi = 0; midi < MAX_MIDI_INTERFACE; midi++) {
     188            if (!strcmp(cards[ix].midiItf[midi].name, name)) {
     189                return &ice1712Midi_hooks;
     190            }
     191        }
     192
     193        if (!strcmp(cards[ix].name, name)) {
     194            return &ice1712Audio_hooks;
     195        }
     196    }
     197    ITRACE("!!! failed !!!\n");
     198    return NULL;
     199}
     200
     201//ICE1712 driver - Hardware
     202//-------------------------
     203
     204int32
     205ice1712HW_interrupt(void *arg)
     206{
     207    ice1712 *ice = (ice1712*)arg;
     208    uint8 reg8 = 0;
     209    uint16 reg16 = 0;
     210    uint32 status = B_UNHANDLED_INTERRUPT;
     211
     212    // interrupt from DMA PATH
     213    reg8 = read_mt_uint8(ice, MT_DMA_INT_MASK_STATUS);
     214    if (reg8 != 0) {
     215        ice->buffer++;
     216        ice->played_time = system_time();
     217        ice->frames_count += ice->buffer_size;
     218
     219        release_sem_etc(ice->buffer_ready_sem, 1, B_DO_NOT_RESCHEDULE);
     220        write_mt_uint8(ice, MT_DMA_INT_MASK_STATUS, reg8);
     221        status = B_HANDLED_INTERRUPT;
     222    }
     223
     224    // interrupt from Controller Registers
     225    reg8 = read_ccs_uint8(ice, CCS_INTERRUPT_STATUS);
     226    if (reg8 != 0) {
     227        bool ret;
     228        if (reg8 & CCS_INTERRUPT_MIDI_1) {
     229            ret = (*mpu401->interrupt_hook)(ice->midiItf[0].mpu401device);
     230            if (ret) {
     231                //Do not ack, cause more datas are available
     232                reg8 &= ~CCS_INTERRUPT_MIDI_1;
     233            }
     234        }
     235
     236        if (reg8 & CCS_INTERRUPT_MIDI_2) {
     237            ret = (*mpu401->interrupt_hook)(ice->midiItf[1].mpu401device);
     238            if (ret) {
     239                //Do not ack, cause more datas are available
     240                reg8 &= ~CCS_INTERRUPT_MIDI_2;
     241            }
     242        }
     243
     244        if (reg8 != 0) {
     245            write_ccs_uint8(ice, CCS_INTERRUPT_STATUS, reg8);
     246            status = B_HANDLED_INTERRUPT;
     247        }
     248    }
     249
     250    // interrupt from DS PATH
     251    reg16 = read_ds_uint16(ice, DS_DMA_INT_STATUS);
     252    if (reg16 != 0) {
     253        //Ack interrupt
     254        write_ds_uint16(ice, DS_DMA_INT_STATUS, reg16);
     255        status = B_HANDLED_INTERRUPT;
     256    }
     257
     258    return status;
     259}
     260
     261
     262status_t
     263ice1712HW_setup(ice1712 *ice)
     264{
     265    int i;
     266    uint8 reg8 = 0;
     267    uint16 mute;
     268
     269    ice->irq = ice->info.u.h0.interrupt_line;
     270    ice->Controller = ice->info.u.h0.base_registers[0];
     271    ice->DDMA = ice->info.u.h0.base_registers[1];
     272    ice->DMA_Path = ice->info.u.h0.base_registers[2];
     273    ice->Multi_Track = ice->info.u.h0.base_registers[3];
     274
     275    // Soft Reset
     276    write_ccs_uint8(ice, CCS_CONTROL_STATUS, 0x81);
     277    snooze(200000);
     278    write_ccs_uint8(ice, CCS_CONTROL_STATUS, 0x01);
     279    snooze(200000);
     280
     281    read_eeprom(ice, ice->eeprom_data);
     282
     283    write_ccs_uint8(ice, CCS_SERR_SHADOW, 0x01);
     284
     285    //Write all configurations register from EEProm
     286    ice->info.device_id = ice->eeprom_data[E2PROM_MAP_SUBVENDOR_HIGH] << 8
     287        | ice->eeprom_data[E2PROM_MAP_SUBVENDOR_LOW];
     288    ice->info.vendor_id = ice->eeprom_data[E2PROM_MAP_SUBDEVICE_HIGH] << 8
     289        | ice->eeprom_data[E2PROM_MAP_SUBDEVICE_LOW];
     290    ice->config.product = (ice1712Product)(ice->info.vendor_id << 16
     291        | ice->info.device_id);
     292    ITRACE("Product ID : 0x%x\n", ice->config.product);
     293
     294    write_cci_uint8(ice, CCI_GPIO_WRITE_MASK,
     295        ice->eeprom_data[E2PROM_MAP_GPIOMASK]);
     296    write_cci_uint8(ice, CCI_GPIO_DATA,
     297        ice->eeprom_data[E2PROM_MAP_GPIOSTATE]);
     298    write_cci_uint8(ice, CCI_GPIO_DIRECTION_CONTROL,
     299        ice->eeprom_data[E2PROM_MAP_GPIODIR]);
     300
     301    ITRACE("CCI_GPIO_WRITE_MASK : 0x%x\n",
     302        ice->eeprom_data[E2PROM_MAP_GPIOMASK]);
     303    ITRACE("CCI_GPIO_DATA : 0x%x\n",
     304        ice->eeprom_data[E2PROM_MAP_GPIOSTATE]);
     305    ITRACE("CCI_GPIO_DIRECTION_CONTROL : 0x%x\n",
     306        ice->eeprom_data[E2PROM_MAP_GPIODIR]);
     307
     308    //Write Configuration in the PCI configuration Register
     309    (pci->write_pci_config)(ice->info.bus, ice->info.device,
     310        ice->info.function, 0x60, 1, ice->eeprom_data[E2PROM_MAP_CONFIG]);
     311    (pci->write_pci_config)(ice->info.bus, ice->info.device,
     312        ice->info.function, 0x61, 1, ice->eeprom_data[E2PROM_MAP_ACL]);
     313    (pci->write_pci_config)(ice->info.bus, ice->info.device,
     314        ice->info.function, 0x62, 1, ice->eeprom_data[E2PROM_MAP_I2S]);
     315    (pci->write_pci_config)(ice->info.bus, ice->info.device,
     316        ice->info.function, 0x63, 1, ice->eeprom_data[E2PROM_MAP_SPDIF]);
     317
     318    ITRACE("E2PROM_MAP_CONFIG : 0x%x\n", ice->eeprom_data[E2PROM_MAP_CONFIG]);
     319    reg8 = ice->eeprom_data[E2PROM_MAP_CONFIG];
     320    //Bits signification for E2PROM_MAP_CONFIG Byte
     321    //
     322    // 8   7   6   5   4   3   2   1   0
     323    //           |-D-|-C-|---B---|---A---
     324    //
     325    // D : MPU401 number minus 1
     326    // C : AC'97
     327    // B : Stereo ADC number minus 1 (=> 1 to 4)
     328    // A : Stereo DAC number minus 1 (=> 1 to 4)
     329
     330    ice->config.nb_DAC = ((reg8 & 0x03) + 1) * 2;
     331    reg8 >>= 2;
     332    ice->config.nb_ADC = ((reg8 & 0x03) + 1) * 2;
     333    reg8 >>= 2;
     334
     335    if ((reg8 & 0x01) != 0) {//Consumer AC'97 Exist
     336        ITRACE("Consumer AC'97 does exist\n");
     337        //For now do nothing
     338/*      write_ccs_uint8(ice, CCS_CONS_AC97_COMMAND_STATUS, 0x40);
     339        snooze(10000);
     340        write_ccs_uint8(ice, CCS_CONS_AC97_COMMAND_STATUS, 0x00);
     341        snooze(20000);
     342*/  } else {
     343        ITRACE("Consumer AC'97 does NOT exist\n");
     344    }
     345    reg8 >>= 1;
     346    ice->config.nb_MPU401 = (reg8 & 0x1) + 1;
     347
     348    if (ice->config.nb_MPU401 > 0) {
     349        sprintf(ice->midiItf[0].name, "midi/ice1712/%ld/1", ice - cards + 1);
     350
     351        (*mpu401->create_device)(ice->Controller + CCS_MIDI_1_DATA,
     352            &ice->midiItf[0].mpu401device,
     353            0x14121712,
     354            ice1712Midi_interrupt,
     355            &ice->midiItf[0]);
     356
     357        names[num_names++] = ice->midiItf[0].name;
     358        ice->midiItf[0].card = ice;
     359        ice->midiItf[0].int_mask = CCS_INTERRUPT_MIDI_1;
     360    }
     361
     362    if (ice->config.nb_MPU401 > 1) {
     363        sprintf(ice->midiItf[1].name, "midi/ice1712/%ld/2", ice - cards + 1);
     364
     365        (*mpu401->create_device)(ice->Controller + CCS_MIDI_2_DATA,
     366            &ice->midiItf[1].mpu401device,
     367            0x14121712,
     368            ice1712Midi_interrupt,
     369            &ice->midiItf[1]);
     370
     371        names[num_names++] = ice->midiItf[1].name;
     372        ice->midiItf[1].card = ice;
     373        ice->midiItf[1].int_mask = CCS_INTERRUPT_MIDI_2;
     374    }
     375
     376    ITRACE("E2PROM_MAP_SPDIF : 0x%x\n", ice->eeprom_data[E2PROM_MAP_SPDIF]);
     377    ice->config.spdif = ice->eeprom_data[E2PROM_MAP_SPDIF];
     378
     379    switch (ice->config.product) {
     380        case ICE1712_SUBDEVICE_DELTA66 :
     381        case ICE1712_SUBDEVICE_DELTA44 :
     382            ice->CommLines.clock = DELTA66_CLK;
     383            ice->CommLines.data_in = 0;
     384            ice->CommLines.data_out = DELTA66_DOUT;
     385            ice->CommLines.cs_mask = DELTA66_CLK | DELTA66_DOUT
     386                | DELTA66_CS_MASK;
     387            break;
     388        case ICE1712_SUBDEVICE_DELTA410 :
     389        case ICE1712_SUBDEVICE_AUDIOPHILE_2496 :
     390        case ICE1712_SUBDEVICE_DELTADIO2496 :
     391            ice->CommLines.clock = AP2496_CLK;
     392            ice->CommLines.data_in = AP2496_DIN;
     393            ice->CommLines.data_out = AP2496_DOUT;
     394            ice->CommLines.cs_mask = AP2496_CLK | AP2496_DIN
     395                | AP2496_DOUT | AP2496_CS_MASK;
     396            break;
     397        case ICE1712_SUBDEVICE_DELTA1010 :
     398        case ICE1712_SUBDEVICE_DELTA1010LT :
     399            ice->CommLines.clock = DELTA1010LT_CLK;
     400            ice->CommLines.data_in = DELTA1010LT_DIN;
     401            ice->CommLines.data_out = DELTA1010LT_DOUT;
     402            ice->CommLines.cs_mask = DELTA1010LT_CLK | DELTA1010LT_DIN
     403                | DELTA1010LT_DOUT | DELTA1010LT_CS_NONE;
     404            break;
     405        case ICE1712_SUBDEVICE_VX442 :
     406            ice->CommLines.clock = VX442_CLK;
     407            ice->CommLines.data_in = VX442_DIN;
     408            ice->CommLines.data_out = VX442_DOUT;
     409            ice->CommLines.cs_mask = VX442_CLK | VX442_DIN | VX442_DOUT
     410                | VX442_CS_MASK;
     411            break;
     412    }
     413
     414    sprintf(ice->name, "%s/%ld", HMULTI_AUDIO_DEV_PATH, ice - cards + 1);
     415    names[num_names++] = ice->name;
     416    names[num_names] = NULL;
     417
     418    ice->buffer_ready_sem = create_sem(0, "Buffer Exchange");
     419    if (ice->buffer_ready_sem < B_OK) {
     420        return ice->buffer_ready_sem;
     421    }
     422
     423    install_io_interrupt_handler(ice->irq, ice1712HW_interrupt, ice, 0);
     424
     425    ice->mem_id_pb = alloc_mem(&ice->phys_pb, &ice->log_addr_pb,
     426        PLAYBACK_BUFFER_TOTAL_SIZE, "playback buffer");
     427    if (ice->mem_id_pb < B_OK) {
     428        remove_io_interrupt_handler(ice->irq, ice1712HW_interrupt, ice);
     429        delete_sem(ice->buffer_ready_sem);
     430        return ice->mem_id_pb;
     431    }
     432
     433    ice->mem_id_rec = alloc_mem(&ice->phys_rec, &ice->log_addr_rec,
     434        RECORD_BUFFER_TOTAL_SIZE, "record buffer");
     435    if (ice->mem_id_rec < B_OK) {
     436        remove_io_interrupt_handler(ice->irq, ice1712HW_interrupt, ice);
     437        delete_sem(ice->buffer_ready_sem);
     438        delete_area(ice->mem_id_pb);
     439        return(ice->mem_id_rec);
     440    }
     441
     442    ice->config.samplingRate = 0x08;
     443    ice->buffer = 0;
     444    ice->frames_count = 0;
     445    ice->buffer_size = ice->settings.bufferSize;
     446
     447    ice->total_output_channels = ice->config.nb_DAC;
     448    if (ice->config.spdif & SPDIF_OUT_PRESENT)
     449        ice->total_output_channels += 2;
     450
     451    ice->total_input_channels = ice->config.nb_ADC + 2;
     452    if (ice->config.spdif & SPDIF_IN_PRESENT)
     453        ice->total_input_channels += 2;
     454
     455    //Write bits in the GPIO
     456    write_cci_uint8(ice, CCI_GPIO_WRITE_MASK, ~(ice->CommLines.cs_mask));
     457    //Deselect CS
     458    write_cci_uint8(ice, CCI_GPIO_DATA, ice->CommLines.cs_mask);
     459
     460    //Set the rampe volume to a faster one
     461    write_mt_uint16(ice, MT_VOLUME_CONTROL_RATE, 0x01);
     462
     463    //All Analog outputs from DMA
     464    write_mt_uint16(ice, MT_ROUTING_CONTROL_PSDOUT, 0x0000);
     465    //All Digital output from DMA
     466    write_mt_uint16(ice, MT_ROUTING_CONTROL_SPDOUT, 0x0000);
     467
     468    //Mute all input
     469    mute = (ICE1712_MUTE_VALUE << 0) | (ICE1712_MUTE_VALUE << 8);
     470    for (i = 0; i < 2 * ICE1712_HARDWARE_VOLUME; i++) {
     471        write_mt_uint8(ice, MT_VOLUME_CONTROL_CHANNEL_INDEX, i);
     472        write_mt_uint16(ice, MT_VOLUME_CONTROL_CHANNEL_INDEX, mute);
     473    }
     474
     475    //Unmask Interrupt
     476    write_ccs_uint8(ice, CCS_CONTROL_STATUS, 0x41);
     477
     478    reg8 = read_ccs_uint8(ice, CCS_INTERRUPT_MASK);
     479    ITRACE("-----CCS----- = %x\n", reg8);
     480    write_ccs_uint8(ice, CCS_INTERRUPT_MASK, 0xEF);
     481
     482/*  reg16 = read_ds_uint16(ice, DS_DMA_INT_MASK);
     483    ITRACE("-----DS_DMA----- = %x\n", reg16);
     484    write_ds_uint16(ice, DS_DMA_INT_MASK, 0x0000);
     485*/
     486    reg8 = read_mt_uint8(ice, MT_DMA_INT_MASK_STATUS);
     487    ITRACE("-----MT_DMA----- = %x\n", reg8);
     488    write_mt_uint8(ice, MT_DMA_INT_MASK_STATUS, 0x00);
     489
     490    return B_OK;
     491};
     492
     493
     494void
     495ice1712HW_shutdown(ice1712 *ice)
     496{
     497    delete_sem(ice->buffer_ready_sem);
     498
     499    remove_io_interrupt_handler(ice->irq, ice1712HW_interrupt, ice);
     500
     501    if (ice->mem_id_pb != B_ERROR)
     502        delete_area(ice->mem_id_pb);
     503
     504    if (ice->mem_id_rec != B_ERROR)
     505        delete_area(ice->mem_id_rec);
     506
     507    codec_write(ice, AK45xx_RESET_REGISTER, 0x00);
     508}
     509
     510//ICE1712 driver - Hook
     511//---------------------
     512
     513static status_t
     514ice1712Audio_open(const char *name, uint32 flags, void **cookie)
     515{
     516    int ix;
     517    ice1712 *card = NULL;
     518    ITRACE("** open(): %s\n", name);
     519
     520    for (ix = 0; ix<num_cards; ix++) {
     521        if (!strcmp(cards[ix].name, name)) {
     522            card = &cards[ix];
     523        }
     524    }
     525
     526    if (card == NULL) {
     527        ITRACE("open() card not found %s\n", name);
     528        for (ix=0; ix<num_cards; ix++) {
     529            ITRACE("open() card available %s\n", cards[ix].name);
     530        }
     531        return B_ERROR;
     532    }
     533    *cookie = cards;
     534    return B_OK;
     535}
     536
     537
     538static status_t
     539ice1712Audio_close(void *cookie)
     540{
     541    ITRACE("** close()\n");
     542    return B_OK;
     543}
     544
     545
     546static status_t
     547ice1712Audio_free(void *cookie)
     548{
     549    ITRACE("** free()\n");
     550    return B_OK;
     551}
     552
     553
     554static status_t
     555ice1712Audio_control(void *cookie, uint32 op, void *arg, size_t len)
     556{
     557    switch (op) {
     558        case B_MULTI_GET_DESCRIPTION :
     559            ITRACE("B_MULTI_GET_DESCRIPTION\n");
     560            return ice1712Get_Description((ice1712 *)cookie,
     561                (multi_description*)arg);
     562        case B_MULTI_GET_EVENT_INFO :
     563            ITRACE("B_MULTI_GET_EVENT_INFO\n");
     564            return B_ERROR;
     565        case B_MULTI_SET_EVENT_INFO :
     566            ITRACE("B_MULTI_SET_EVENT_INFO\n");
     567            return B_ERROR;
     568        case B_MULTI_GET_EVENT :
     569            ITRACE("B_MULTI_GET_EVENT\n");
     570            return B_ERROR;
     571        case B_MULTI_GET_ENABLED_CHANNELS :
     572            ITRACE("B_MULTI_GET_ENABLED_CHANNELS\n");
     573            return ice1712Get_Channel((ice1712*)cookie,
     574                (multi_channel_enable*)arg);
     575        case B_MULTI_SET_ENABLED_CHANNELS :
     576            ITRACE("B_MULTI_SET_ENABLED_CHANNELS\n");
     577            return ice1712Set_Channel((ice1712*)cookie,
     578                (multi_channel_enable*)arg);
     579        case B_MULTI_GET_GLOBAL_FORMAT :
     580            ITRACE("B_MULTI_GET_GLOBAL_FORMAT\n");
     581            return ice1712Get_Format((ice1712*)cookie,
     582                (multi_format_info *)arg);
     583        case B_MULTI_SET_GLOBAL_FORMAT :
     584            ITRACE("B_MULTI_SET_GLOBAL_FORMAT\n");
     585            return ice1712Set_Format((ice1712*)cookie,
     586                (multi_format_info *)arg);
     587        case B_MULTI_GET_CHANNEL_FORMATS :
     588            ITRACE("B_MULTI_GET_CHANNEL_FORMATS\n");
     589            return B_ERROR;
     590        case B_MULTI_SET_CHANNEL_FORMATS :
     591            ITRACE("B_MULTI_SET_CHANNEL_FORMATS\n");
     592            return B_ERROR;
     593        case B_MULTI_GET_MIX :
     594            ITRACE("B_MULTI_GET_MIX\n");
     595            return ice1712Get_MixValue((ice1712*)cookie,
     596                (multi_mix_value_info *)arg);
     597        case B_MULTI_SET_MIX :
     598            ITRACE("B_MULTI_SET_MIX\n");
     599            return ice1712Set_MixValue((ice1712*)cookie,
     600                (multi_mix_value_info *)arg);
     601        case B_MULTI_LIST_MIX_CHANNELS :
     602            ITRACE("B_MULTI_LIST_MIX_CHANNELS\n");
     603            return ice1712Get_MixValueChannel((ice1712*)cookie,
     604                (multi_mix_channel_info *)arg);
     605        case B_MULTI_LIST_MIX_CONTROLS :
     606            ITRACE("B_MULTI_LIST_MIX_CONTROLS\n");
     607            return ice1712Get_MixValueControls((ice1712*)cookie,
     608                (multi_mix_control_info *)arg);
     609        case B_MULTI_LIST_MIX_CONNECTIONS :
     610            ITRACE("B_MULTI_LIST_MIX_CONNECTIONS\n");
     611            return ice1712Get_MixValueConnections((ice1712*)cookie,
     612                (multi_mix_connection_info *)arg);
     613        case B_MULTI_GET_BUFFERS :
     614            ITRACE("B_MULTI_GET_BUFFERS\n");
     615            return ice1712Buffer_Get((ice1712*)cookie,
     616                (multi_buffer_list*)arg);
     617        case B_MULTI_SET_BUFFERS :
     618            ITRACE("B_MULTI_SET_BUFFERS\n");
     619            return B_ERROR;
     620        case B_MULTI_SET_START_TIME :
     621            ITRACE("B_MULTI_SET_START_TIME\n");
     622            return B_ERROR;
     623        case B_MULTI_BUFFER_EXCHANGE :
     624//          ITRACE("B_MULTI_BUFFER_EXCHANGE\n");
     625            return ice1712Buffer_Exchange((ice1712*)cookie,
     626                (multi_buffer_info *)arg);
     627        case B_MULTI_BUFFER_FORCE_STOP :
     628            ITRACE("B_MULTI_BUFFER_FORCE_STOP\n");
     629            return ice1712Buffer_Stop((ice1712*)cookie);
     630        case B_MULTI_LIST_EXTENSIONS :
     631            ITRACE("B_MULTI_LIST_EXTENSIONS\n");
     632            return B_ERROR;
     633        case B_MULTI_GET_EXTENSION :
     634            ITRACE("B_MULTI_GET_EXTENSION\n");
     635            return B_ERROR;
     636        case B_MULTI_SET_EXTENSION :
     637            ITRACE("B_MULTI_SET_EXTENSION\n");
     638            return B_ERROR;
     639        case B_MULTI_LIST_MODES :
     640            ITRACE("B_MULTI_LIST_MODES\n");
     641            return B_ERROR;
     642        case B_MULTI_GET_MODE :
     643            ITRACE("B_MULTI_GET_MODE\n");
     644            return B_ERROR;
     645        case B_MULTI_SET_MODE :
     646            ITRACE("B_MULTI_SET_MODE\n");
     647            return B_ERROR;
     648
     649        default :
     650            ITRACE("ERROR: unknown multi_control %#x\n", (int)op);
     651            return B_ERROR;
     652    }
     653}
     654
     655
     656static status_t
     657ice1712Audio_read(void *cookie, off_t position, void *buf,
     658    size_t *num_bytes)
     659{
     660    ITRACE("** read()\n");
     661    *num_bytes = 0;
     662    return B_IO_ERROR;
     663}
     664
     665
     666static status_t
     667ice1712Audio_write(void *cookie, off_t position, const void *buffer,
     668    size_t *num_bytes)
     669{
     670    ITRACE("** write()\n");
     671    *num_bytes = 0;
     672    return B_IO_ERROR;
     673}
     674
     675
     676device_hooks ice1712Audio_hooks =
     677{
     678    ice1712Audio_open,
     679    ice1712Audio_close,
     680    ice1712Audio_free,
     681    ice1712Audio_control,
     682    ice1712Audio_read,
     683    ice1712Audio_write,
     684    NULL,
     685    NULL,
     686    NULL,
     687    NULL
     688};
     689
     690
     691//ICE1712 Drivers - Settings
     692//--------------------------
     693
     694
     695status_t
     696ice1712Settings_load(ice1712 *card)
     697{
     698    // get driver settings
     699    void *settings_handle = load_driver_settings("ice1712.settings");
     700
     701    //Use a large enough value for modern computer
     702    card->settings.bufferSize = 512;
     703
     704    if (settings_handle != NULL) {
     705        const char *item;
     706        char *end;
     707
     708        item = get_driver_parameter(settings_handle,
     709            "buffer_size", "512", "512");
     710        if (item != NULL) {
     711            uint32 value = strtoul(item, &end, 0);
     712            if ((*end == '\0')
     713                && (value >= MIN_BUFFER_FRAMES)
     714                && (value <= MAX_BUFFER_FRAMES)) {
     715                    card->settings.bufferSize = value;
     716            }
     717        }
     718
     719        unload_driver_settings(settings_handle);
     720    }
     721
     722    return B_OK;
     723}
     724
     725
     726status_t
     727ice1712Settings_apply(ice1712 *card)
     728{
     729    int i;
     730    uint16 val, mt30 = 0;
     731    uint32 mt34 = 0;
     732
     733    for (i = 0; i < ICE1712_HARDWARE_VOLUME; i++) {
     734        //Select the channel
     735        write_mt_uint8(card, MT_VOLUME_CONTROL_CHANNEL_INDEX, i);
     736
     737        if (card->settings.playback[i].mute == true) {
     738            val = (ICE1712_MUTE_VALUE << 0) | (ICE1712_MUTE_VALUE << 8);
     739        } else {
     740            uint8 volume = card->settings.playback[i].volume / -1.5;
     741            if (i & 1) {//a right channel
     742                val = ICE1712_MUTE_VALUE << 0; //Mute left volume
     743                val |= volume << 8;
     744            } else {//a left channel
     745                val = ICE1712_MUTE_VALUE << 8; //Mute right volume
     746                val |= volume << 0;
     747            }
     748        }
     749
     750        write_mt_uint16(card, MT_LR_VOLUME_CONTROL, val);
     751        ITRACE_VV("Apply Settings %d : 0x%x\n", i, val);
     752    }
     753
     754    for (i = 0; i < ICE1712_HARDWARE_VOLUME; i++) {
     755        //Select the channel
     756        write_mt_uint8(card, MT_VOLUME_CONTROL_CHANNEL_INDEX,
     757            i + ICE1712_HARDWARE_VOLUME);
     758
     759        if (card->settings.record[i].mute == true) {
     760            val = (ICE1712_MUTE_VALUE << 0) | (ICE1712_MUTE_VALUE << 8);
     761        } else {
     762            uint8 volume = card->settings.record[i].volume / -1.5;
     763            if (i & 1) {//a right channel
     764                val = ICE1712_MUTE_VALUE << 0; //Mute left volume
     765                val |= volume << 8;
     766            } else {//a left channel
     767                val = ICE1712_MUTE_VALUE << 8; //Mute right volume
     768                val |= volume << 0;
     769            }
     770        }
     771
     772        write_mt_uint16(card, MT_LR_VOLUME_CONTROL, val);
     773        ITRACE_VV("Apply Settings %d : 0x%x\n", i, val);
     774    }
     775
     776    //Analog output selection
     777    for (i = 0; i < 4; i++) {
     778        uint8 out = card->settings.output[i];
     779        if (out == 0) {
     780            ITRACE_VV("Output %d is haiku output\n", i);
     781            //Nothing to do
     782        } else if (out <= (card->config.nb_ADC / 2)) {
     783            uint8 mt34_c;
     784            out--;
     785            ITRACE_VV("Output %d is input %d\n", i, out);
     786            mt34_c = (out * 2);
     787            mt34_c |= (out * 2 + 1) << 4;
     788            mt30 |= 0x0202 << (2 * i);
     789            mt30 |= mt34_c << (8 * i);
     790        } else if (out == ((card->config.nb_ADC / 2) + 1)
     791                && (card->config.spdif & SPDIF_IN_PRESENT) != 0) {
     792            ITRACE_VV("Output %d is digital input\n", i);
     793            mt30 |= 0x0303 << (2 * i);
     794            mt34 |= 0x80 << (8 * i);
     795        } else {
     796            ITRACE_VV("Output %d is digital Mixer\n", i);
     797            mt30 |= 0x0101;
     798        }
     799    }
     800    write_mt_uint16(card, MT_ROUTING_CONTROL_PSDOUT, mt30);
     801    write_mt_uint32(card, MT_CAPTURED_DATA, mt34);
     802
     803    //Digital output
     804    if ((card->config.spdif & SPDIF_OUT_PRESENT) != 0) {
     805        uint16 mt32 = 0;
     806        uint8 out = card->settings.output[4];
     807        if (out == 0) {
     808            ITRACE_VV("Digital output is haiku output\n");
     809            //Nothing to do
     810        } else if (out <= (card->config.nb_ADC / 2)) {
     811            out--;
     812            ITRACE_VV("Digital output is input %d\n", out);
     813            mt32 |= 0x0202;
     814            mt32 |= (out * 2) << 8;
     815            mt32 |= (out * 2 + 1) << 12;
     816        } else if (out == ((card->config.nb_ADC / 2) + 1)
     817                && (card->config.spdif & SPDIF_IN_PRESENT) != 0) {
     818            ITRACE_VV("Digital output is digital input\n");
     819            mt32 |= 0x800F;
     820        } else {
     821            ITRACE_VV("Digital output is digital Mixer\n");
     822            mt32 |= 0x0005;
     823        }
     824
     825        write_mt_uint16(card, MT_ROUTING_CONTROL_SPDOUT, mt32);
     826    }
     827
     828    return B_OK;
     829}
  • src/add-ons/kernel/drivers/audio/ice1712/ice1712.h

    diff --git a/src/add-ons/kernel/drivers/audio/ice1712/ice1712.h b/src/add-ons/kernel/drivers/audio/ice1712/ice1712.h
    index ece826a..574b670 100644
    a b  
    11/*
    2  * ice1712 BeOS/Haiku Driver for VIA - VT1712 Multi Channel Audio Controller
     2 * Copyright 2004-2015 Haiku, Inc. All rights reserved.
     3 * Distributed under the terms of the MIT License.
    34 *
    4  * Copyright (c) 2002, Jerome Duval     (jerome.duval@free.fr)
    5  * Copyright (c) 2003, Marcus Overhagen (marcus@overhagen.de)
    6  * Copyright (c) 2007, Jerome Leveque   (leveque.jerome@neuf.fr)
    7  *
    8  * All rights reserved
    9  * Distributed under the terms of the MIT license.
     5 * Authors:
     6 *      Jérôme Duval, jerome.duval@free.fr
     7 *      Marcus Overhagen, marcus@overhagen.de
     8 *      Jérôme Lévêque, leveque.jerome@gmail.com
    109 */
     10
     11
    1112#ifndef _ICE1712_H_
    1213#define _ICE1712_H_
    1314
    14 
    1515#include "debug.h"
    1616#include "hmulti_audio.h"
    1717
    1818#include <PCI.h>
    19 
     19#include <KernelExport.h>
    2020
    2121#define DRIVER_NAME "ice1712"
    22 #define VERSION "0.5"
     22#define VERSION "0.6"
    2323
    24 #define ICE1712_VENDOR_ID           0x1412
    25 #define ICE1712_DEVICE_ID           0x1712
     24#define ICE1712_VENDOR_ID 0x1412
     25#define ICE1712_DEVICE_ID 0x1712
    2626
    27 typedef enum product_t {
     27typedef enum ice1712Product {
    2828    ICE1712_SUBDEVICE_DELTA1010         = 0x121430d6,
    2929    ICE1712_SUBDEVICE_DELTADIO2496      = 0x121431d6,
    3030    ICE1712_SUBDEVICE_DELTA66           = 0x121432d6,
    typedef enum product_t {  
    3333    ICE1712_SUBDEVICE_DELTA410          = 0x121438d6,
    3434    ICE1712_SUBDEVICE_DELTA1010LT       = 0x12143bd6,
    3535    ICE1712_SUBDEVICE_VX442             = 0x12143cd6,
    36 } product_t;
     36} ice1712Product;
    3737
    3838#define NUM_CARDS                   4
    39 #define MAX_ADC                     12  // + the output of the Digital mixer
     39#define MAX_ADC                     12
     40// 5 stereo output + the Digital mixer
    4041#define MAX_DAC                     10
    4142#define MAX_MIDI_INTERFACE          2
    4243#define SWAPPING_BUFFERS            2
    typedef enum product_t {  
    4546#define MAX_BUFFER_FRAMES           2048
    4647
    4748#define ICE1712_HARDWARE_VOLUME     10
    48 #define ICE1712_MUTE_VALUE          0x7F
     49#define ICE1712_MUTE_VALUE          0x7F
    4950
    5051#define PLAYBACK_BUFFER_SIZE        (MAX_BUFFER_FRAMES * MAX_DAC * SAMPLE_SIZE)
    5152#define RECORD_BUFFER_SIZE          (MAX_BUFFER_FRAMES * MAX_ADC * SAMPLE_SIZE)
    typedef enum product_t {  
    6869
    6970struct ice1712;
    7071
    71 typedef struct _midi_dev {
    72     struct ice1712  *card;
    73     void            *mpu401device;
    74     uint8           int_mask;
    75     char            name[64];
    76 } midi_dev;
    77 
    78 void ice_1712_midi_interrupt_op(int32 op, void *data);
    79 status_t ice_1712_midi_open(const char *name,
    80     uint32 flags, void **cookie);
    81 status_t ice_1712_midi_close(void *cookie);
    82 status_t ice_1712_midi_free(void *cookie);
    83 status_t ice_1712_midi_control(void *cookie,
    84     uint32 op, void *data, size_t len);
    85 status_t ice_1712_midi_read(void *cookie,
    86     off_t pos, void *data, size_t *len);
    87 status_t ice_1712_midi_write(void *cookie,
    88     off_t pos, const void *data, size_t *len);
     72typedef struct ice1712Midi {
     73    struct ice1712 *card;
     74    void *mpu401device;
     75    uint8 int_mask;
     76    char name[64];
     77} ice1712Midi;
    8978
    9079typedef struct _codecCommLines
    9180{
    92     uint8   clock;
    93     uint8   data_in;
    94     uint8   data_out;
    95     uint8   cs_mask; //a Mask for removing all Chip select
    96     uint8   reserved[4];
     81    uint8 clock;
     82    uint8 data_in;
     83    uint8 data_out;
     84    uint8 cs_mask;
     85    //a Mask for removing all Chip select
    9786} codecCommLines;
    9887
    99 typedef struct channel_volume
     88typedef struct ice1712Volume
    10089{
    10190    float volume;
    10291    bool mute;
    103 } channel_volume;
     92} ice1712Volume;
    10493
    105 typedef struct ice1712_settings
     94typedef struct ice1712Settings
    10695{
    107     channel_volume playback[ICE1712_HARDWARE_VOLUME];
    108     channel_volume record[ICE1712_HARDWARE_VOLUME];
     96    ice1712Volume playback[ICE1712_HARDWARE_VOLUME];
     97    ice1712Volume record[ICE1712_HARDWARE_VOLUME];
    10998
    11099    uint32 bufferSize;
    111100
    112101    //General Settings
    113     uint8 clock; //an index
     102    uint8 clock;        //an index
    114103
    115104    //S/PDif Settings
    116     uint8 outFormat; //an index
    117     uint8 emphasis; //an index
    118     uint8 copyMode; //an index
     105    uint8 outFormat;    //an index
     106    uint8 emphasis;     //an index
     107    uint8 copyMode;     //an index
    119108
    120109    //Output settings
    121     uint8 output[5]; //an index
     110    uint8 output[5];    //an index
    122111
    123112    uint8 reserved[32];
    124 } ice1712_settings;
     113} ice1712Settings;
    125114
    126 typedef struct ice1712_hconfig
     115typedef struct ice1712HW
    127116{
    128     int8 nb_ADC; //Mono Channel
    129     int8 nb_DAC; //Mono Channel
     117    int8 nb_ADC;        //Mono Channel
     118    int8 nb_DAC;        //Mono Channel
    130119    int8 nb_MPU401;
    131120    int8 spdif;
    132 } ice1712_hconfig;
     121
     122    //in the format of the register
     123    uint8 samplingRate;
     124    uint32 lockSource;
     125
     126    ice1712Product product;
     127} ice1712HW;
    133128
    134129typedef struct ice1712
    135130{
    typedef struct ice1712  
    137132    pci_info info;
    138133    char name[128];
    139134
    140     midi_dev midi_interf[MAX_MIDI_INTERFACE];
     135    ice1712Midi midiItf[MAX_MIDI_INTERFACE];
    141136
    142137    uint32 Controller;  //PCI_10
    143138    uint32 DDMA;        //PCI_14
    typedef struct ice1712  
    146141
    147142    uint8 eeprom_data[32];
    148143
    149     product_t product;
    150 
    151144    //We hope all manufacturers will use same
    152145    //communication lines for speaking with codec
    153146    codecCommLines CommLines;
    typedef struct ice1712  
    159152
    160153    //Output
    161154    area_id mem_id_pb;
    162     void *phys_addr_pb, *log_addr_pb;
     155    physical_entry phys_pb;
     156    addr_t log_addr_pb;
    163157    uint8 total_output_channels;
    164158
    165159    //Input
    166160    area_id mem_id_rec;
    167     void *phys_addr_rec, *log_addr_rec;
     161    physical_entry phys_rec;
     162    addr_t log_addr_rec;
    168163    uint8 total_input_channels;
    169164
    170165    sem_id buffer_ready_sem;
    171166
    172     uint8 sampling_rate; //in the format of the register
    173     uint32 lock_source;
    174 
    175     ice1712_hconfig     config;
    176     ice1712_settings    settings;
     167    ice1712HW config;
     168    ice1712Settings settings;
    177169} ice1712;
    178170
    179 status_t apply_settings(ice1712 *card);
    180 
    181 //For midi.c
    182 extern int32 num_cards;
    183 extern ice1712 cards[NUM_CARDS];
    184 
    185171//CSS_INTERRUPT_MASK
    186172#define CCS_INTERRUPT_MIDI_1            0x80
    187173#define CCS_INTERRUPT_MIDI_2            0x20
    extern ice1712 cards[NUM_CARDS];  
    227213#define VX442_CS_MASK                   0x70    // Chip Select Mask
    228214
    229215#define GPIO_I2C_DELAY                  5       //Clock Delay for writing
    230                                                 //I2C data throw GPIO
     216                                                //I2C data throw GPIO
    231217
    232218//Register definition for the AK45xx codec (xx = 24 or 28)
    233219#define AK45xx_CHIP_ADDRESS             0x02    //Chip address of the codec
    extern ice1712 cards[NUM_CARDS];  
    271257*/
    272258
    273259//This map comes from ALSA sound drivers
    274 #define E2PROM_MAP_SUBVENDOR_LOW    0x00
    275 #define E2PROM_MAP_SUBVENDOR_HIGH   0x01
    276 #define E2PROM_MAP_SUBDEVICE_LOW    0x02
    277 #define E2PROM_MAP_SUBDEVICE_HIGH   0x03
    278 #define E2PROM_MAP_SIZE             0x04
    279 #define E2PROM_MAP_VERSION          0x05
    280 #define E2PROM_MAP_CONFIG           0x06
    281 #define E2PROM_MAP_ACL              0x07
    282 #define E2PROM_MAP_I2S              0x08
    283 #define E2PROM_MAP_SPDIF            0x09
    284 #define E2PROM_MAP_GPIOMASK         0x0A
    285 #define E2PROM_MAP_GPIOSTATE        0x0B
    286 #define E2PROM_MAP_GPIODIR          0x0C
    287 #define E2PROM_MAP_AC97MAIN         0x0D
    288 #define E2PROM_MAP_AC97PCM          0x0F
    289 #define E2PROM_MAP_AC97REC          0x11
    290 #define E2PROM_MAP_AC97REC_SOURCE   0x13
    291 #define E2PROM_MAP_DAC_ID           0x14
    292 #define E2PROM_MAP_ADC_ID           0x18
    293 #define E2PROM_MAP_EXTRA            0x1C
     260typedef enum ice1712EEprom {
     261    E2PROM_MAP_SUBVENDOR_LOW    = 0x00,
     262    E2PROM_MAP_SUBVENDOR_HIGH,
     263    E2PROM_MAP_SUBDEVICE_LOW,
     264    E2PROM_MAP_SUBDEVICE_HIGH,
     265    E2PROM_MAP_SIZE,
     266    E2PROM_MAP_VERSION,
     267    E2PROM_MAP_CONFIG,
     268    E2PROM_MAP_ACL,
     269    E2PROM_MAP_I2S,
     270    E2PROM_MAP_SPDIF,
     271    E2PROM_MAP_GPIOMASK,
     272    E2PROM_MAP_GPIOSTATE,
     273    E2PROM_MAP_GPIODIR,
     274    E2PROM_MAP_AC97MAIN,
     275    E2PROM_MAP_AC97PCM          = 0x0F,
     276    E2PROM_MAP_AC97REC          = 0x11,
     277    E2PROM_MAP_AC97REC_SOURCE   = 0x13,
     278    E2PROM_MAP_DAC_ID           = 0x14,
     279    E2PROM_MAP_ADC_ID           = 0x18,
     280    E2PROM_MAP_EXTRA            = 0x1C
     281} ice1712EEprom;
    294282
    295283#endif
  • src/add-ons/kernel/drivers/audio/ice1712/ice1712_reg.h

    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 d8c87af..e8453bd 100644
    a b  
    11/*
    2  * ice1712 BeOS/Haiku Driver for VIA - VT1712 Multi Channel Audio Controller
     2 * Copyright 2004-2015 Haiku, Inc. All rights reserved.
     3 * Distributed under the terms of the MIT License.
    34 *
    4  * Copyright (c) 2007, Jerome Leveque   (leveque.jerome@neuf.fr)
    5  *
    6  * All rights reserved
    7  * Distributed under the terms of the MIT license.
     5 * Authors:
     6 *      Jérôme Duval, jerome.duval@free.fr
     7 *      Marcus Overhagen, marcus@overhagen.de
     8 *      Jérôme Lévêque, leveque.jerome@gmail.com
    89 */
    910
     11
    1012#ifndef _ICE1712_REG_H_
    1113#define _ICE1712_REG_H_
    1214
    13 //------------------------------------------------------
    14 //------------------------------------------------------
    1515//PCI Interface and Configuration Registers (Page 3.1)
    1616//Table 3.1
    17 /*
    18 #define PCI_VENDOR_ID                   0x00 //2 bytes
    19 #define PCI_DEVICE_ID                   0x02 //2 bytes
    20 #define PCI_COMMAND                     0x04 //2 bytes
    21 #define PCI_DEVICE_STATUS               0x06 //2 bytes
    22 #define PCI_REVISION_ID                 0x08 //1 byte
    23 #define PCI_CLASS_CODE                  0x0A //2 bytes
    24 #define PCI_LATENCY_TIMER               0x0D //1 byte
    25 #define PCI_HEADER_TYPE                 0x0E //1 byte
    26 #define PCI_BIST                        0x0F //1 byte
    27 #define PCI_CONTROLLER_BASE_AD          0x10 //4 bytes
    28 #define PCI_DDMA_BASE_AD                0x14 //4 bytes
    29 #define PCI_DMA_BASE_AD                 0x18 //4 bytes
    30 #define PCI_MULTI_BASE_AD               0x1C //4 bytes
    31 #define PCI_SUB_VENDOR_ID               0x2C //2 bytes
    32 #define PCI_SUB_SYSTEM_ID               0x2E //2 bytes
    33 #define PCI_CAPABILITY_POINTER          0x34 //4 bytes
    34 #define PCI_INT_PIN_LINE                0x3C //2 bytes
    35 #define PCI_LATENCY_GRANT               0x3E //2 bytes
    36 #define PCI_LEGACY_AUDIO_CONTROL        0x40 //2 bytes
    37 #define PCI_LEGACY_CONF_CONTROL         0x42 //2 bytes
    38 #define PCI_HARD_CONF_CONTROL           0x60 //4 bytes
    39 #define PCI_CAPABILITY_ID               0x80 //1 byte
    40 #define PCI_NEXT_ITEM_POINTER           0x81 //1 byte
    41 #define PCI_POWER_CAPABILITY            0x82 //2 bytes
    42 #define PCI_POWER_CONTROL_STATUS        0x84 //2 bytes
    43 #define PCI_PMCSR_EXT_DATA              0x86 //2 bytes
    44 */
    45 //------------------------------------------------------
    46 //------------------------------------------------------
     17#define PCI_VENDOR_ID           0x00 //2 bytes
     18#define PCI_DEVICE_ID           0x02 //2 bytes
     19#define PCI_COMMAND         0x04 //2 bytes
     20#define PCI_DEVICE_STATUS       0x06 //2 bytes
     21#define PCI_REVISION_ID         0x08 //1 byte
     22#define PCI_CLASS_CODE          0x0A //2 bytes
     23#define PCI_LATENCY_TIMER       0x0D //1 byte
     24#define PCI_HEADER_TYPE         0x0E //1 byte
     25#define PCI_BIST            0x0F //1 byte
     26#define PCI_CONTROLLER_BASE_AD      0x10 //4 bytes
     27#define PCI_DDMA_BASE_AD        0x14 //4 bytes
     28#define PCI_DMA_BASE_AD         0x18 //4 bytes
     29#define PCI_MULTI_BASE_AD       0x1C //4 bytes
     30#define PCI_SUB_VENDOR_ID       0x2C //2 bytes
     31#define PCI_SUB_SYSTEM_ID       0x2E //2 bytes
     32#define PCI_CAPABILITY_POINTER      0x34 //4 bytes
     33#define PCI_INT_PIN_LINE        0x3C //2 bytes
     34#define PCI_LATENCY_GRANT       0x3E //2 bytes
     35#define PCI_LEGACY_AUDIO_CONTROL    0x40 //2 bytes
     36#define PCI_LEGACY_CONF_CONTROL     0x42 //2 bytes
     37#define PCI_HARD_CONF_CONTROL       0x60 //4 bytes
     38#define PCI_CAPABILITY_ID       0x80 //1 byte
     39#define PCI_NEXT_ITEM_POINTER       0x81 //1 byte
     40#define PCI_POWER_CAPABILITY        0x82 //2 bytes
     41#define PCI_POWER_CONTROL_STATUS    0x84 //2 bytes
     42#define PCI_PMCSR_EXT_DATA      0x86 //2 bytes
     43
    4744//CCSxx Controller Register Map (Page 4.3)
    4845//Table 4.2
    49 #define CCS_CONTROL_STATUS              0x00 //1 byte
    50 #define CCS_INTERRUPT_MASK              0x01 //1 byte
    51 #define CCS_INTERRUPT_STATUS            0x02 //1 byte
    52 #define CCS_CCI_INDEX                   0x03 //1 byte
    53 #define CCS_CCI_DATA                    0x04 //1 byte
    54 #define CCS_NMI_STATUS_1                0x05 //1 byte
    55 #define CCS_NMI_DATA                    0x06 //1 byte
    56 #define CCS_NMI_INDEX                   0x07 //1 byte
    57 #define CCS_CONS_AC97_INDEX             0x08 //1 byte
    58 #define CCS_CONS_AC97_COMMAND_STATUS    0x09 //1 byte
    59 #define CCS_CONS_AC97_DATA              0x0A //2 bytes
    60 #define CCS_MIDI_1_DATA                 0x0C //1 byte
    61 #define CCS_MIDI_1_COMMAND_STATUS       0x0D //1 byte
    62 #define CCS_NMI_STATUS_2                0x0E //1 byte
    63 #define CCS_GAME_PORT                   0x0F //1 byte
    64 #define CCS_I2C_DEV_ADDRESS             0x10 //1 byte
    65 #define CCS_I2C_BYTE_ADDRESS            0x11 //1 byte
    66 #define CCS_I2C_DATA                    0x12 //1 byte
    67 #define CCS_I2C_CONTROL_STATUS          0x13 //1 byte
    68 #define CCS_CONS_DMA_BASE_ADDRESS       0x14 //4 bytes
    69 #define CCS_CONS_DMA_COUNT_ADDRESS      0x18 //2 bytes
    70 #define CCS_SERR_SHADOW                 0x1B //1 byte
    71 #define CCS_MIDI_2_DATA                 0x1C //1 byte
    72 #define CCS_MIDI_2_COMMAND_STATUS       0x1D //1 byte
    73 #define CCS_TIMER                       0x1E //2 bytes
    74 //------------------------------------------------------
    75 //------------------------------------------------------
     46#define CCS_CONTROL_STATUS      0x00 //1 byte
     47#define CCS_INTERRUPT_MASK      0x01 //1 byte
     48#define CCS_INTERRUPT_STATUS        0x02 //1 byte
     49#define CCS_CCI_INDEX           0x03 //1 byte
     50#define CCS_CCI_DATA            0x04 //1 byte
     51#define CCS_NMI_STATUS_1        0x05 //1 byte
     52#define CCS_NMI_DATA            0x06 //1 byte
     53#define CCS_NMI_INDEX           0x07 //1 byte
     54#define CCS_CONS_AC97_INDEX     0x08 //1 byte
     55#define CCS_CONS_AC97_COMMAND_STATUS    0x09 //1 byte
     56#define CCS_CONS_AC97_DATA      0x0A //2 bytes
     57#define CCS_MIDI_1_DATA         0x0C //1 byte
     58#define CCS_MIDI_1_COMMAND_STATUS   0x0D //1 byte
     59#define CCS_NMI_STATUS_2        0x0E //1 byte
     60#define CCS_GAME_PORT           0x0F //1 byte
     61#define CCS_I2C_DEV_ADDRESS     0x10 //1 byte
     62#define CCS_I2C_BYTE_ADDRESS        0x11 //1 byte
     63#define CCS_I2C_DATA            0x12 //1 byte
     64#define CCS_I2C_CONTROL_STATUS      0x13 //1 byte
     65#define CCS_CONS_DMA_BASE_ADDRESS   0x14 //4 bytes
     66#define CCS_CONS_DMA_COUNT_ADDRESS  0x18 //2 bytes
     67#define CCS_SERR_SHADOW         0x1B //1 byte
     68#define CCS_MIDI_2_DATA         0x1C //1 byte
     69#define CCS_MIDI_2_COMMAND_STATUS   0x1D //1 byte
     70#define CCS_TIMER           0x1E //2 bytes
     71
    7672//Controller Indexed Register (Page 4.12)
    77 #define CCI_PB_TERM_COUNT_HI            0x00 //1 byte
    78 #define CCI_PB_TERM_COUNT_LO            0x01 //1 byte
    79 #define CCI_PB_CONTROL                  0x02 //1 byte
    80 #define CCI_PB_LEFT_VOLUME              0x03 //1 byte
    81 #define CCI_PB_RIGHT_VOLUME             0x04 //1 byte
    82 #define CCI_SOFT_VOLUME                 0x05 //1 byte
    83 #define CCI_PB_SAMPLING_RATE_LO         0x06 //1 byte
    84 #define CCI_PB_SAMPLING_RATE_MI         0x07 //1 byte
    85 #define CCI_PB_SAMPLING_RATE_HI         0x08 //1 byte
    86 #define CCI_REC_TERM_COUNT_HI           0x10 //1 byte
    87 #define CCI_REC_TERM_COUNT_LO           0x11 //1 byte
    88 #define CCI_REC_CONTROL                 0x12 //1 byte
    89 #define CCI_GPIO_DATA                   0x20 //1 byte
    90 #define CCI_GPIO_WRITE_MASK             0x21 //1 byte
    91 #define CCI_GPIO_DIRECTION_CONTROL      0x22 //1 byte
    92 #define CCI_CONS_POWER_DOWN             0x30 //1 byte
    93 #define CCI_MULTI_POWER_DOWN            0x31 //1 byte
    94 //------------------------------------------------------
    95 //------------------------------------------------------
     73#define CCI_PB_TERM_COUNT_HI        0x00 //1 byte
     74#define CCI_PB_TERM_COUNT_LO        0x01 //1 byte
     75#define CCI_PB_CONTROL          0x02 //1 byte
     76#define CCI_PB_LEFT_VOLUME      0x03 //1 byte
     77#define CCI_PB_RIGHT_VOLUME     0x04 //1 byte
     78#define CCI_SOFT_VOLUME         0x05 //1 byte
     79#define CCI_PB_SAMPLING_RATE_LO     0x06 //1 byte
     80#define CCI_PB_SAMPLING_RATE_MI     0x07 //1 byte
     81#define CCI_PB_SAMPLING_RATE_HI     0x08 //1 byte
     82#define CCI_REC_TERM_COUNT_HI       0x10 //1 byte
     83#define CCI_REC_TERM_COUNT_LO       0x11 //1 byte
     84#define CCI_REC_CONTROL         0x12 //1 byte
     85#define CCI_GPIO_DATA           0x20 //1 byte
     86#define CCI_GPIO_WRITE_MASK     0x21 //1 byte
     87#define CCI_GPIO_DIRECTION_CONTROL  0x22 //1 byte
     88#define CCI_CONS_POWER_DOWN     0x30 //1 byte
     89#define CCI_MULTI_POWER_DOWN        0x31 //1 byte
     90
    9691//Consumer Section DMA Channel Registers (Page 4.20)
    9792//Table 4.4
    98 #define DS_DMA_INT_MASK                 0x00 //2 bytes
    99 #define DS_DMA_INT_STATUS               0x02 //2 bytes
    100 #define DS_CHANNEL_DATA                 0x04 //4 bytes
    101 #define DS_CHANNEL_INDEX                0x08 //1 byte
    102 //------------------------------------------------------
    103 //------------------------------------------------------
     93#define DS_DMA_INT_MASK         0x00 //2 bytes
     94#define DS_DMA_INT_STATUS       0x02 //2 bytes
     95#define DS_CHANNEL_DATA         0x04 //4 bytes
     96#define DS_CHANNEL_INDEX        0x08 //1 byte
     97
    10498//Professional Multi-Track Control Registers (Page 4.24)
    10599//Table 4.7
    106 #define MT_DMA_INT_MASK_STATUS          0x00 //1 byte
    107 #define MT_SAMPLING_RATE_SELECT         0x01 //1 byte
    108 #define MT_I2S_DATA_FORMAT              0x02 //1 byte
    109 #define MT_PROF_AC97_INDEX              0x04 //1 byte
    110 #define MT_PROF_AC97_COMMAND_STATUS     0x05 //1 byte
    111 #define MT_PROF_AC97_DATA               0x06 //2 bytes
    112 #define MT_PROF_PB_DMA_BASE_ADDRESS     0x10 //4 bytes
    113 #define MT_PROF_PB_DMA_COUNT_ADDRESS    0x14 //2 bytes
    114 #define MT_PROF_PB_DMA_TERM_COUNT       0x16 //2 bytes
    115 #define MT_PROF_PB_CONTROL              0x18 //1 byte
    116 #define MT_PROF_REC_DMA_BASE_ADDRESS    0x20 //4 bytes
    117 #define MT_PROF_REC_DMA_COUNT_ADDRESS   0x24 //2 bytes
    118 #define MT_PROF_REC_DMA_TERM_COUNT      0x26 //2 bytes
    119 #define MT_PROF_REC_CONTROL             0x28 //1 byte
    120 #define MT_ROUTING_CONTROL_PSDOUT       0x30 //2 bytes
    121 #define MT_ROUTING_CONTROL_SPDOUT       0x32 //2 bytes
    122 #define MT_CAPTURED_DATA                0x34 //4 bytes
    123 #define MT_LR_VOLUME_CONTROL            0x38 //2 bytes
    124 #define MT_VOLUME_CONTROL_CHANNEL_INDEX 0x3A //1 byte
    125 #define MT_VOLUME_CONTROL_RATE          0x3B //1 byte
    126 #define MT_MIXER_MONITOR_RETURN         0x3C //1 byte
    127 #define MT_PEAK_METER_INDEX             0x3E //1 byte
    128 #define MT_PEAK_METER_DATA              0x3F //1 byte
    129 //------------------------------------------------------
    130 //------------------------------------------------------
    131 #define I2C_EEPROM_ADDRESS_READ         0xA0 //1010 0000
    132 #define I2C_EEPROM_ADDRESS_WRITE        0xA1 //1010 0001
    133 //------------------------------------------------------
    134 //------------------------------------------------------
    135 #define SPDIF_STEREO_IN                 0x02 //0000 0010
    136 #define SPDIF_STEREO_OUT                0x01 //0000 0001
    137 //------------------------------------------------------
    138 //------------------------------------------------------
    139 
    140 //------------------------------------------------------
    141 //------------------------------------------------------
    142 
    143 //------------------------------------------------------
    144 //------------------------------------------------------
    145 
    146 //------------------------------------------------------
    147 //------------------------------------------------------
    148 
    149 //------------------------------------------------------
    150 //------------------------------------------------------
    151 
    152 //------------------------------------------------------
    153 //------------------------------------------------------
    154 
    155 //------------------------------------------------------
    156 //------------------------------------------------------
    157 
    158 //------------------------------------------------------
    159 //------------------------------------------------------
     100#define MT_DMA_INT_MASK_STATUS      0x00 //1 byte
     101#define MT_SAMPLING_RATE_SELECT     0x01 //1 byte
     102#define MT_I2S_DATA_FORMAT      0x02 //1 byte
     103#define MT_PROF_AC97_INDEX      0x04 //1 byte
     104#define MT_PROF_AC97_COMMAND_STATUS 0x05 //1 byte
     105#define MT_PROF_AC97_DATA       0x06 //2 bytes
     106#define MT_PROF_PB_DMA_BASE_ADDRESS 0x10 //4 bytes
     107#define MT_PROF_PB_DMA_COUNT_ADDRESS    0x14 //2 bytes
     108#define MT_PROF_PB_DMA_TERM_COUNT   0x16 //2 bytes
     109#define MT_PROF_PB_CONTROL      0x18 //1 byte
     110#define MT_PROF_REC_DMA_BASE_ADDRESS    0x20 //4 bytes
     111#define MT_PROF_REC_DMA_COUNT_ADDRESS   0x24 //2 bytes
     112#define MT_PROF_REC_DMA_TERM_COUNT  0x26 //2 bytes
     113#define MT_PROF_REC_CONTROL     0x28 //1 byte
     114#define MT_ROUTING_CONTROL_PSDOUT   0x30 //2 bytes
     115#define MT_ROUTING_CONTROL_SPDOUT   0x32 //2 bytes
     116#define MT_CAPTURED_DATA        0x34 //4 bytes
     117#define MT_LR_VOLUME_CONTROL        0x38 //2 bytes
     118#define MT_VOLUME_CONTROL_CHANNEL_INDEX 0x3A //1 byte
     119#define MT_VOLUME_CONTROL_RATE      0x3B //1 byte
     120#define MT_MIXER_MONITOR_RETURN     0x3C //1 byte
     121#define MT_PEAK_METER_INDEX     0x3E //1 byte
     122#define MT_PEAK_METER_DATA      0x3F //1 byte
    160123
    161 //------------------------------------------------------
    162 //------------------------------------------------------
     124#define I2C_EEPROM_ADDRESS_READ     0xA0 //1010 0000
     125#define I2C_EEPROM_ADDRESS_WRITE    0xA1 //1010 0001
    163126
    164 //------------------------------------------------------
    165 //------------------------------------------------------
     127#define SPDIF_STEREO_IN         0x02 //0000 0010
     128#define SPDIF_STEREO_OUT        0x01 //0000 0001
    166129
    167130#endif
  • deleted file src/add-ons/kernel/drivers/audio/ice1712/io.c

    diff --git a/src/add-ons/kernel/drivers/audio/ice1712/io.c b/src/add-ons/kernel/drivers/audio/ice1712/io.c
    deleted file mode 100644
    index 81990a2..0000000
    + -  
    1 /*
    2  * ice1712 BeOS/Haiku Driver for VIA - VT1712 Multi Channel Audio Controller
    3  *
    4  * Copyright (c) 2002, Jerome Duval     (jerome.duval@free.fr)
    5  * Copyright (c) 2003, Marcus Overhagen (marcus@overhagen.de)
    6  * Copyright (c) 2007, Jerome Leveque   (leveque.jerome@neuf.fr)
    7  *
    8  * All rights reserved
    9  * Distributed under the terms of the MIT license.
    10  */
    11 
    12 #include "io.h"
    13 #include "ice1712_reg.h"
    14 #include "debug.h"
    15 
    16 extern pci_module_info *pci;
    17 
    18 static void ak45xx_write_gpio(ice1712 *ice, uint8 reg_addr,
    19                             uint8 data, uint8 chip_select, uint8 invert_cs);
    20 
    21 static void cs84xx_write_gpio(ice1712 *ice, uint8 reg_addr,
    22                             uint8 data, uint8 chip_select, uint8 invert_cs);
    23 
    24 static uint8 ak45xx_read_gpio(ice1712 *ice, uint8 reg_addr,
    25                             uint8 chip_select, uint8 invert_cs)
    26             {return 0;} //Unimplemented
    27 
    28 static uint8 cs84xx_read_gpio(ice1712 *ice, uint8 reg_addr,
    29                             uint8 chip_select, uint8 invert_cs);
    30 
    31 static void write_gpio_byte(ice1712 *ice, uint8 data, uint8 gpio_data);
    32 static uint8 read_gpio_byte(ice1712 *ice, uint8 gpio_data);
    33 
    34 
    35 //Address are [PCI_10] + xx
    36 
    37 uint8
    38 read_ccs_uint8(ice1712 *ice, int8 regno)
    39 {
    40     return pci->read_io_8(ice->Controller + regno);
    41 };
    42 
    43 
    44 uint16
    45 read_ccs_uint16(ice1712 *ice, int8 regno)
    46 {
    47     return pci->read_io_16(ice->Controller + regno);
    48 };
    49 
    50 
    51 uint32
    52 read_ccs_uint32(ice1712 *ice, int8 regno)
    53 {
    54     return pci->read_io_32(ice->Controller + regno);
    55 };
    56 
    57 
    58 void
    59 write_ccs_uint8(ice1712 *ice, int8 regno, uint8 value)
    60 {
    61     pci->write_io_8(ice->Controller + regno, value);
    62 };
    63 
    64 
    65 void
    66 write_ccs_uint16(ice1712 *ice, int8 regno, uint16 value)
    67 {
    68     pci->write_io_16(ice->Controller + regno, value);
    69 };
    70 
    71 
    72 void
    73 write_ccs_uint32(ice1712 *ice, int8 regno, uint32 value)
    74 {
    75     pci->write_io_32(ice->Controller + regno, value);
    76 };
    77 
    78 
    79 uint8
    80 read_cci_uint8(ice1712 *ice, int8 index)
    81 {
    82     write_ccs_uint8(ice, CCS_CCI_INDEX, index);
    83     return read_ccs_uint8(ice, CCS_CCI_DATA);
    84 };
    85 
    86 
    87 void
    88 write_cci_uint8(ice1712 *ice, int8 index, uint8 value)
    89 {
    90     write_ccs_uint8(ice, CCS_CCI_INDEX, index);
    91     write_ccs_uint8(ice, CCS_CCI_DATA, value);
    92 };
    93 
    94 //--------------------------------------------------
    95 //--------------------------------------------------
    96 //Address are [PCI_14] + xx
    97 
    98 uint8
    99 read_ddma_uint8(ice1712 *ice, int8 regno)
    100 {
    101     return pci->read_io_8(ice->DDMA + regno);
    102 };
    103 
    104 
    105 uint16
    106 read_ddma_uint16(ice1712 *ice, int8 regno)
    107 {
    108     return pci->read_io_16(ice->DDMA + regno);
    109 };
    110 
    111 
    112 uint32
    113 read_ddma_uint32(ice1712 *ice, int8 regno)
    114 {
    115     return pci->read_io_32(ice->DDMA + regno);
    116 };
    117 
    118 
    119 void
    120 write_ddma_uint8(ice1712 *ice, int8 regno, uint8 value)
    121 {
    122     pci->write_io_8(ice->DDMA + regno, value);
    123 };
    124 
    125 
    126 void
    127 write_ddma_uint16(ice1712 *ice, int8 regno, uint16 value)
    128 {
    129     pci->write_io_16(ice->DDMA + regno, value);
    130 };
    131 
    132 
    133 void
    134 write_ddma_uint32(ice1712 *ice, int8 regno, uint32 value)
    135 {
    136     pci->write_io_32(ice->DDMA + regno, value);
    137 };
    138 
    139 
    140 //--------------------------------------------------
    141 //--------------------------------------------------
    142 //Address are [PCI_18] + x
    143 uint8
    144 read_ds_uint8(ice1712 *ice, int8 regno)
    145 {
    146     return pci->read_io_8(ice->DMA_Path + regno);
    147 };
    148 
    149 
    150 uint16
    151 read_ds_uint16(ice1712 *ice, int8 regno)
    152 {
    153     return pci->read_io_16(ice->DMA_Path + regno);
    154 };
    155 
    156 
    157 uint32
    158 read_ds_uint32(ice1712 *ice, int8 regno)
    159 {
    160     return pci->read_io_32(ice->DMA_Path + regno);
    161 };
    162 
    163 
    164 void
    165 write_ds_uint8(ice1712 *ice, int8 regno, uint8 value)
    166 {
    167     pci->write_io_8(ice->DMA_Path + regno, value);
    168 };
    169 
    170 
    171 void
    172 write_ds_uint16(ice1712 *ice, int8 regno, uint16 value)
    173 {
    174     pci->write_io_16(ice->DMA_Path + regno, value);
    175 };
    176 
    177 
    178 void
    179 write_ds_uint32(ice1712 *ice, int8 regno, uint32 value)
    180 {
    181     pci->write_io_32(ice->DMA_Path + regno, value);
    182 };
    183 
    184 
    185 uint32
    186 read_ds_channel_data(ice1712 *ice, uint8 channel, ds8_register index)
    187 {
    188     uint8 ds8_channel_index = channel << 4 | index;
    189 
    190     write_ds_uint8(ice, DS_CHANNEL_INDEX, ds8_channel_index);
    191     return read_ds_uint32(ice, DS_CHANNEL_DATA);
    192 }
    193 
    194 
    195 void
    196 write_ds_channel_data(ice1712 *ice, uint8 channel, ds8_register index,
    197     uint32 data)
    198 {
    199     uint8 ds8_channel_index = channel << 4 | index;
    200 
    201     write_ds_uint8(ice, DS_CHANNEL_INDEX, ds8_channel_index);
    202     write_ds_uint32(ice, DS_CHANNEL_DATA, data);
    203 }
    204 
    205 
    206 //--------------------------------------------------
    207 //--------------------------------------------------
    208 //Address are [PCI_1C] + xx
    209 
    210 uint8
    211 read_mt_uint8(ice1712 *ice, int8 regno)
    212 {
    213     return  pci->read_io_8(ice->Multi_Track + regno);
    214 };
    215 
    216 
    217 uint16
    218 read_mt_uint16(ice1712 *ice,    int8 regno)
    219 {
    220     return  pci->read_io_16(ice->Multi_Track + regno);
    221 };
    222 
    223 
    224 uint32
    225 read_mt_uint32(ice1712 *ice,    int8 regno)
    226 {
    227     return pci->read_io_32(ice->Multi_Track + regno);
    228 };
    229 
    230 void
    231 write_mt_uint8(ice1712 *ice,    int8 regno, uint8 value)
    232 {
    233     pci->write_io_8(ice->Multi_Track + regno, value);
    234 };
    235 
    236 
    237 void
    238 write_mt_uint16(ice1712 *ice,   int8 regno, uint16 value)
    239 {
    240     pci->write_io_16(ice->Multi_Track + regno, value);
    241 };
    242 
    243 
    244 void
    245 write_mt_uint32(ice1712 *ice,   int8 regno, uint32 value)
    246 {
    247     pci->write_io_32(ice->Multi_Track + regno, value);
    248 };
    249 
    250 
    251 int16
    252 read_i2c(ice1712 *ice, uint8 dev_addr, uint8 byte_addr)
    253 {//return -1 if error else return an uint8
    254 
    255     if (read_ccs_uint8(ice, CCS_I2C_CONTROL_STATUS) != 0x80)
    256         return -1;
    257     write_ccs_uint8(ice, CCS_I2C_BYTE_ADDRESS, byte_addr);
    258     write_ccs_uint8(ice, CCS_I2C_DEV_ADDRESS, dev_addr);
    259     snooze(1000);
    260     return read_ccs_uint8(ice, CCS_I2C_DATA);
    261 }
    262 
    263 
    264 int16
    265 write_i2c(ice1712 *ice, uint8 dev_addr, uint8 byte_addr, uint8 value)
    266 {//return -1 if error else return 0
    267     if (read_ccs_uint8(ice, CCS_I2C_CONTROL_STATUS) != 0x80)
    268         return -1;
    269 
    270     write_ccs_uint8(ice, CCS_I2C_BYTE_ADDRESS, byte_addr);
    271     write_ccs_uint8(ice, CCS_I2C_DEV_ADDRESS, dev_addr);
    272     write_ccs_uint8(ice, CCS_I2C_DATA, value);
    273     return 0;
    274 }
    275 
    276 
    277 int16 read_eeprom(ice1712 *ice, uint8 eeprom[32])
    278 {
    279     int i;
    280     int16 tmp;
    281 
    282     for (i = 0; i < 6; i++) {
    283         tmp = read_i2c(ice, I2C_EEPROM_ADDRESS_READ, i);
    284         if (tmp >= 0)
    285             eeprom[i] = (uint8)tmp;
    286         else
    287             return -1;
    288     }
    289     if (eeprom[4] > 32)
    290         return -1;
    291     for (i = 6; i < eeprom[4]; i++) {
    292         tmp = read_i2c(ice, I2C_EEPROM_ADDRESS_READ, i);
    293         if (tmp >= 0)
    294             eeprom[i] = (uint8)tmp;
    295         else
    296             return -1;
    297     }
    298     return eeprom[4];
    299 }
    300 
    301 
    302 void
    303 codec_write(ice1712 *ice, uint8 reg_addr, uint8 data)
    304 {
    305     switch (ice->product) {
    306         case ICE1712_SUBDEVICE_DELTA66:
    307         case ICE1712_SUBDEVICE_DELTA44:
    308             ak45xx_write_gpio(ice, reg_addr, data, DELTA66_CODEC_CS_0, 0);
    309             ak45xx_write_gpio(ice, reg_addr, data, DELTA66_CODEC_CS_1, 0);
    310             break;
    311         case ICE1712_SUBDEVICE_DELTA410:
    312         case ICE1712_SUBDEVICE_AUDIOPHILE_2496:
    313         case ICE1712_SUBDEVICE_DELTADIO2496:
    314             ak45xx_write_gpio(ice, reg_addr, data, AP2496_CODEC_CS, 0);
    315             break;
    316         case ICE1712_SUBDEVICE_DELTA1010:
    317         case ICE1712_SUBDEVICE_DELTA1010LT:
    318             ak45xx_write_gpio(ice, reg_addr, data, DELTA1010LT_CODEC_CS_0,
    319                     DELTA1010LT_CS_NONE);
    320             ak45xx_write_gpio(ice, reg_addr, data, DELTA1010LT_CODEC_CS_1,
    321                     DELTA1010LT_CS_NONE);
    322             ak45xx_write_gpio(ice, reg_addr, data, DELTA1010LT_CODEC_CS_2,
    323                     DELTA1010LT_CS_NONE);
    324             ak45xx_write_gpio(ice, reg_addr, data, DELTA1010LT_CODEC_CS_3,
    325                     DELTA1010LT_CS_NONE);
    326             break;
    327         case ICE1712_SUBDEVICE_VX442:
    328             ak45xx_write_gpio(ice, reg_addr, data, VX442_CODEC_CS_0, 0);
    329             ak45xx_write_gpio(ice, reg_addr, data, VX442_CODEC_CS_1, 0);
    330             break;
    331     }
    332 }
    333 
    334 
    335 void
    336 spdif_write(ice1712 *ice, uint8 reg_addr, uint8 data)
    337 {
    338     switch (ice->product) {
    339         case ICE1712_SUBDEVICE_DELTA1010:
    340             break;
    341         case ICE1712_SUBDEVICE_DELTADIO2496:
    342             break;
    343         case ICE1712_SUBDEVICE_DELTA66:
    344             break;
    345         case ICE1712_SUBDEVICE_DELTA44:
    346             break;
    347         case ICE1712_SUBDEVICE_AUDIOPHILE_2496:
    348             cs84xx_write_gpio(ice, reg_addr, data, AP2496_SPDIF_CS, 0);
    349             break;
    350         case ICE1712_SUBDEVICE_DELTA410:
    351             break;
    352         case ICE1712_SUBDEVICE_DELTA1010LT:
    353             cs84xx_write_gpio(ice, reg_addr, data, DELTA1010LT_SPDIF_CS,
    354                     DELTA1010LT_CS_NONE);
    355             break;
    356         case ICE1712_SUBDEVICE_VX442:
    357             cs84xx_write_gpio(ice, reg_addr, data, VX442_SPDIF_CS, 0);
    358             break;
    359     }
    360 }
    361 
    362 
    363 uint8
    364 codec_read(ice1712 *ice, uint8 reg_addr)
    365 {
    366     uint8 val = 0xFF;
    367     switch (ice->product) {
    368         case ICE1712_SUBDEVICE_DELTA66:
    369         case ICE1712_SUBDEVICE_DELTA44:
    370             val = ak45xx_read_gpio(ice, reg_addr, DELTA66_CODEC_CS_0, 0);
    371             break;
    372         case ICE1712_SUBDEVICE_DELTA410:
    373         case ICE1712_SUBDEVICE_AUDIOPHILE_2496:
    374         case ICE1712_SUBDEVICE_DELTADIO2496:
    375             val = ak45xx_read_gpio(ice, reg_addr, AP2496_CODEC_CS, 0);
    376             break;
    377         case ICE1712_SUBDEVICE_DELTA1010:
    378         case ICE1712_SUBDEVICE_DELTA1010LT:
    379             val = ak45xx_read_gpio(ice, reg_addr, DELTA1010LT_CODEC_CS_0,
    380                             DELTA1010LT_CS_NONE);
    381             break;
    382         case ICE1712_SUBDEVICE_VX442:
    383             val = ak45xx_read_gpio(ice, reg_addr, VX442_CODEC_CS_0, 0);
    384             break;
    385     }
    386 
    387     return val;
    388 }
    389 
    390 
    391 uint8
    392 spdif_read(ice1712 *ice, uint8 reg_addr)
    393 {
    394     uint8 val = 0xFF;
    395     switch (ice->product) {
    396         case ICE1712_SUBDEVICE_DELTA1010:
    397             break;
    398         case ICE1712_SUBDEVICE_DELTADIO2496:
    399             break;
    400         case ICE1712_SUBDEVICE_DELTA66:
    401             break;
    402         case ICE1712_SUBDEVICE_DELTA44:
    403             break;
    404         case ICE1712_SUBDEVICE_AUDIOPHILE_2496:
    405             val = cs84xx_read_gpio(ice, reg_addr, AP2496_SPDIF_CS, 0);
    406             break;
    407         case ICE1712_SUBDEVICE_DELTA410:
    408             break;
    409         case ICE1712_SUBDEVICE_DELTA1010LT:
    410             val = cs84xx_read_gpio(ice, reg_addr, DELTA1010LT_SPDIF_CS,
    411                             DELTA1010LT_CS_NONE);
    412             break;
    413         case ICE1712_SUBDEVICE_VX442:
    414             val = cs84xx_read_gpio(ice, reg_addr, VX442_SPDIF_CS, 0);
    415             break;
    416     }
    417 
    418     return val;
    419 }
    420 
    421 void
    422 write_gpio_byte(ice1712 *ice, uint8 data, uint8 gpio_data)
    423 {
    424     int i;
    425 
    426     for (i = 7; i >= 0; i--) {
    427         // drop clock and data bits
    428         gpio_data &= ~(ice->CommLines.clock | ice->CommLines.data_out);
    429 
    430         // set data bit if needed
    431         if (data & (1 << i))
    432             gpio_data |= ice->CommLines.data_out;
    433 
    434         write_gpio(ice, gpio_data);
    435         snooze(GPIO_I2C_DELAY);
    436 
    437         // raise clock
    438         gpio_data |= ice->CommLines.clock;
    439         write_gpio(ice, gpio_data);
    440         snooze(GPIO_I2C_DELAY);
    441     }
    442 }
    443 
    444 uint8
    445 read_gpio_byte(ice1712 *ice, uint8 gpio_data)
    446 {
    447     int i;
    448     uint8 data = 0;
    449 
    450     for (i = 7; i >= 0; i--) {
    451         // drop clock
    452         gpio_data &= ~(ice->CommLines.clock);
    453         write_gpio(ice, gpio_data);
    454         snooze(GPIO_I2C_DELAY);
    455 
    456         if (read_gpio(ice) &  ice->CommLines.data_in)
    457             data |= 1 << i;
    458 
    459         gpio_data |= ice->CommLines.clock;
    460 
    461         write_gpio(ice, gpio_data);
    462         snooze(GPIO_I2C_DELAY);
    463     }
    464 
    465     return data;
    466 }
    467 
    468 void
    469 ak45xx_write_gpio(ice1712 *ice, uint8 reg_addr, uint8 data,
    470     uint8 chip_select, uint8 invert_cs)
    471 {
    472     uint8 tmp;
    473 
    474     tmp = read_gpio(ice);
    475     tmp |= ice->CommLines.cs_mask;
    476 
    477     if (invert_cs != 0) {
    478         tmp &= ~invert_cs;
    479         tmp |= chip_select;
    480     } else {
    481         tmp &= ~chip_select;
    482     }
    483 
    484     write_gpio(ice, tmp);
    485     snooze(GPIO_I2C_DELAY);
    486 
    487     write_gpio_byte(ice, ((AK45xx_CHIP_ADDRESS & 0x03) << 6) | 0x20
    488         | (reg_addr & 0x1F), tmp);
    489     write_gpio_byte(ice, data, tmp);
    490 
    491     if (invert_cs != 0) {
    492         tmp |= invert_cs;
    493     } else {
    494         tmp |= chip_select;
    495     }
    496     write_gpio(ice, tmp);
    497     snooze(GPIO_I2C_DELAY);
    498 }
    499 
    500 void
    501 cs84xx_write_gpio(ice1712 *ice, uint8 reg_addr, uint8 data,
    502     uint8 chip_select, uint8 invert_cs)
    503 {
    504     uint8 tmp;
    505 
    506     tmp = read_gpio(ice);
    507     tmp |= ice->CommLines.cs_mask;
    508 
    509     if (invert_cs != 0) {
    510         tmp &= ~invert_cs;
    511         tmp |= chip_select;
    512     } else {
    513         tmp &= ~chip_select;
    514     }
    515 
    516     write_gpio(ice, tmp);
    517     snooze(GPIO_I2C_DELAY);
    518 
    519     write_gpio_byte(ice, (CS84xx_CHIP_ADDRESS & 0x7F) << 1, tmp);
    520     write_gpio_byte(ice, reg_addr & 0x7F, tmp); //Do not Increment
    521     write_gpio_byte(ice, data, tmp);
    522 
    523     if (invert_cs != 0) {
    524         tmp |= invert_cs;
    525     } else {
    526         tmp |= chip_select;
    527     }
    528     write_gpio(ice, tmp);
    529     snooze(GPIO_I2C_DELAY);
    530 }
    531 
    532 uint8
    533 cs84xx_read_gpio(ice1712 *ice, uint8 reg_addr, uint8 chip_select,
    534     uint8 invert_cs)
    535 {
    536     uint8 tmp, data;
    537 
    538     tmp = read_gpio(ice);
    539     tmp |= ice->CommLines.cs_mask;
    540 
    541     if (invert_cs != 0) {
    542         tmp &= ~invert_cs;
    543         tmp |= chip_select;
    544     } else {
    545         tmp &= ~chip_select;
    546     }
    547 
    548     write_gpio(ice, tmp);
    549     snooze(GPIO_I2C_DELAY);
    550 
    551     write_gpio_byte(ice, (CS84xx_CHIP_ADDRESS & 0x7F) << 1,
    552         tmp); //For writing the MAP
    553     write_gpio_byte(ice, reg_addr & 0x7F, tmp); //Do not Increment
    554 
    555     //Deselect the chip
    556     if (invert_cs != 0) {
    557         tmp |= invert_cs;
    558     } else {
    559         tmp |= chip_select;
    560     }
    561     write_gpio(ice, tmp);
    562     snooze(GPIO_I2C_DELAY);
    563 
    564     if (invert_cs != 0) {
    565         tmp &= ~invert_cs;
    566         tmp |= chip_select;
    567     } else {
    568         tmp &= ~chip_select;
    569     }
    570     write_gpio(ice, tmp);
    571     snooze(GPIO_I2C_DELAY);
    572 
    573     write_gpio_byte(ice, (CS84xx_CHIP_ADDRESS & 0x7F) << 1 | 1,
    574         tmp); //For writing the MAP
    575     data = read_gpio_byte(ice, tmp); //For reading
    576 
    577     //Deselect the chip
    578     if (invert_cs != 0) {
    579         tmp |= invert_cs;
    580     } else {
    581         tmp |= chip_select;
    582     }
    583     write_gpio(ice, tmp);
    584 
    585     return data;
    586 }
    587 
    588 
    589 uint8
    590 read_gpio(ice1712 *ice)
    591 {//return -1 if error else return an uint8
    592     return read_cci_uint8(ice, CCI_GPIO_DATA);
    593 }
    594 
    595 
    596 void
    597 write_gpio(ice1712 *ice, uint8 value)
    598 {//return -1 if error else return 0
    599     write_cci_uint8(ice, CCI_GPIO_DATA, value);
    600 }
    601 
  • new file src/add-ons/kernel/drivers/audio/ice1712/io.cpp

    diff --git a/src/add-ons/kernel/drivers/audio/ice1712/io.cpp b/src/add-ons/kernel/drivers/audio/ice1712/io.cpp
    new file mode 100644
    index 0000000..371152a
    - +  
     1/*
     2 * Copyright 2004-2015 Haiku, Inc. All rights reserved.
     3 * Distributed under the terms of the MIT License.
     4 *
     5 * Authors:
     6 *      Jérôme Duval, jerome.duval@free.fr
     7 *      Marcus Overhagen, marcus@overhagen.de
     8 *      Jérôme Lévêque, leveque.jerome@gmail.com
     9 */
     10
     11
     12#include "io.h"
     13#include "ice1712_reg.h"
     14#include "debug.h"
     15
     16extern pci_module_info *pci;
     17
     18static void ak45xx_write_gpio(ice1712 *ice, uint8 reg_addr,
     19    uint8 data, uint8 chip_select, uint8 invert_cs);
     20
     21static void cs84xx_write_gpio(ice1712 *ice, uint8 reg_addr,
     22    uint8 data, uint8 chip_select, uint8 invert_cs);
     23
     24static uint8 ak45xx_read_gpio(ice1712 *ice, uint8 reg_addr,
     25    uint8 chip_select, uint8 invert_cs)
     26        {return 0;} //Unimplemented
     27
     28static uint8 cs84xx_read_gpio(ice1712 *ice, uint8 reg_addr,
     29    uint8 chip_select, uint8 invert_cs);
     30
     31static void write_gpio_byte(ice1712 *ice, uint8 data, uint8 gpio_data);
     32static uint8 read_gpio_byte(ice1712 *ice, uint8 gpio_data);
     33
     34
     35//Address are [PCI_10] + xx
     36uint8
     37read_ccs_uint8(ice1712 *ice, int8 regno)
     38{
     39    return pci->read_io_8(ice->Controller + regno);
     40};
     41
     42
     43uint16
     44read_ccs_uint16(ice1712 *ice, int8 regno)
     45{
     46    return pci->read_io_16(ice->Controller + regno);
     47};
     48
     49
     50uint32
     51read_ccs_uint32(ice1712 *ice, int8 regno)
     52{
     53    return pci->read_io_32(ice->Controller + regno);
     54};
     55
     56
     57void
     58write_ccs_uint8(ice1712 *ice, int8 regno, uint8 value)
     59{
     60    pci->write_io_8(ice->Controller + regno, value);
     61};
     62
     63
     64void
     65write_ccs_uint16(ice1712 *ice, int8 regno, uint16 value)
     66{
     67    pci->write_io_16(ice->Controller + regno, value);
     68};
     69
     70
     71void
     72write_ccs_uint32(ice1712 *ice, int8 regno, uint32 value)
     73{
     74    pci->write_io_32(ice->Controller + regno, value);
     75};
     76
     77
     78uint8
     79read_cci_uint8(ice1712 *ice, int8 index)
     80{
     81    write_ccs_uint8(ice, CCS_CCI_INDEX, index);
     82    return read_ccs_uint8(ice, CCS_CCI_DATA);
     83};
     84
     85
     86void
     87write_cci_uint8(ice1712 *ice, int8 index, uint8 value)
     88{
     89    write_ccs_uint8(ice, CCS_CCI_INDEX, index);
     90    write_ccs_uint8(ice, CCS_CCI_DATA, value);
     91};
     92
     93
     94//Address are [PCI_14] + xx
     95uint8
     96read_ddma_uint8(ice1712 *ice, int8 regno)
     97{
     98    return pci->read_io_8(ice->DDMA + regno);
     99};
     100
     101
     102uint16
     103read_ddma_uint16(ice1712 *ice, int8 regno)
     104{
     105    return pci->read_io_16(ice->DDMA + regno);
     106};
     107
     108
     109uint32
     110read_ddma_uint32(ice1712 *ice, int8 regno)
     111{
     112    return pci->read_io_32(ice->DDMA + regno);
     113};
     114
     115
     116void
     117write_ddma_uint8(ice1712 *ice, int8 regno, uint8 value)
     118{
     119    pci->write_io_8(ice->DDMA + regno, value);
     120};
     121
     122
     123void
     124write_ddma_uint16(ice1712 *ice, int8 regno, uint16 value)
     125{
     126    pci->write_io_16(ice->DDMA + regno, value);
     127};
     128
     129
     130void
     131write_ddma_uint32(ice1712 *ice, int8 regno, uint32 value)
     132{
     133    pci->write_io_32(ice->DDMA + regno, value);
     134};
     135
     136
     137//Address are [PCI_18] + x
     138uint8
     139read_ds_uint8(ice1712 *ice, int8 regno)
     140{
     141    return pci->read_io_8(ice->DMA_Path + regno);
     142};
     143
     144
     145uint16
     146read_ds_uint16(ice1712 *ice, int8 regno)
     147{
     148    return pci->read_io_16(ice->DMA_Path + regno);
     149};
     150
     151
     152uint32
     153read_ds_uint32(ice1712 *ice, int8 regno)
     154{
     155    return pci->read_io_32(ice->DMA_Path + regno);
     156};
     157
     158
     159void
     160write_ds_uint8(ice1712 *ice, int8 regno, uint8 value)
     161{
     162    pci->write_io_8(ice->DMA_Path + regno, value);
     163};
     164
     165
     166void
     167write_ds_uint16(ice1712 *ice, int8 regno, uint16 value)
     168{
     169    pci->write_io_16(ice->DMA_Path + regno, value);
     170};
     171
     172
     173void
     174write_ds_uint32(ice1712 *ice, int8 regno, uint32 value)
     175{
     176    pci->write_io_32(ice->DMA_Path + regno, value);
     177};
     178
     179
     180uint32
     181read_ds_channel_data(ice1712 *ice, uint8 channel, ds8_register index)
     182{
     183    uint8 ds8_channel_index = channel << 4 | index;
     184
     185    write_ds_uint8(ice, DS_CHANNEL_INDEX, ds8_channel_index);
     186    return read_ds_uint32(ice, DS_CHANNEL_DATA);
     187}
     188
     189
     190void
     191write_ds_channel_data(ice1712 *ice, uint8 channel, ds8_register index,
     192    uint32 data)
     193{
     194    uint8 ds8_channel_index = channel << 4 | index;
     195
     196    write_ds_uint8(ice, DS_CHANNEL_INDEX, ds8_channel_index);
     197    write_ds_uint32(ice, DS_CHANNEL_DATA, data);
     198}
     199
     200
     201//Address are [PCI_1C] + xx
     202uint8
     203read_mt_uint8(ice1712 *ice, int8 regno)
     204{
     205    return pci->read_io_8(ice->Multi_Track + regno);
     206};
     207
     208
     209uint16
     210read_mt_uint16(ice1712 *ice, int8 regno)
     211{
     212    return pci->read_io_16(ice->Multi_Track + regno);
     213};
     214
     215
     216uint32
     217read_mt_uint32(ice1712 *ice, int8 regno)
     218{
     219    return pci->read_io_32(ice->Multi_Track + regno);
     220};
     221
     222
     223void
     224write_mt_uint8(ice1712 *ice, int8 regno, uint8 value)
     225{
     226    pci->write_io_8(ice->Multi_Track + regno, value);
     227};
     228
     229
     230void
     231write_mt_uint16(ice1712 *ice, int8 regno, uint16 value)
     232{
     233    pci->write_io_16(ice->Multi_Track + regno, value);
     234};
     235
     236
     237void
     238write_mt_uint32(ice1712 *ice, int8 regno, uint32 value)
     239{
     240    pci->write_io_32(ice->Multi_Track + regno, value);
     241};
     242
     243
     244/*
     245 * return -1 if error else return an uint8
     246 */
     247int16
     248read_i2c(ice1712 *ice, uint8 dev_addr, uint8 byte_addr)
     249{
     250    if (read_ccs_uint8(ice, CCS_I2C_CONTROL_STATUS) != 0x80)
     251        return -1;
     252    write_ccs_uint8(ice, CCS_I2C_BYTE_ADDRESS, byte_addr);
     253    write_ccs_uint8(ice, CCS_I2C_DEV_ADDRESS, dev_addr);
     254    snooze(1000);
     255    return read_ccs_uint8(ice, CCS_I2C_DATA);
     256}
     257
     258
     259/*
     260 * return -1 if error else return 0
     261 */
     262int16
     263write_i2c(ice1712 *ice, uint8 dev_addr, uint8 byte_addr, uint8 value)
     264{
     265    if (read_ccs_uint8(ice, CCS_I2C_CONTROL_STATUS) != 0x80)
     266        return -1;
     267
     268    write_ccs_uint8(ice, CCS_I2C_BYTE_ADDRESS, byte_addr);
     269    write_ccs_uint8(ice, CCS_I2C_DEV_ADDRESS, dev_addr);
     270    write_ccs_uint8(ice, CCS_I2C_DATA, value);
     271    return 0;
     272}
     273
     274
     275int16 read_eeprom(ice1712 *ice, uint8 eeprom[32])
     276{
     277    int i;
     278    int16 tmp;
     279
     280    for (i = 0; i < 6; i++) {
     281        tmp = read_i2c(ice, I2C_EEPROM_ADDRESS_READ, i);
     282        if (tmp >= 0)
     283            eeprom[i] = (uint8)tmp;
     284        else
     285            return -1;
     286    }
     287    if (eeprom[4] > 32)
     288        return -1;
     289    for (i = 6; i < eeprom[4]; i++) {
     290        tmp = read_i2c(ice, I2C_EEPROM_ADDRESS_READ, i);
     291        if (tmp >= 0)
     292            eeprom[i] = (uint8)tmp;
     293        else
     294            return -1;
     295    }
     296    return eeprom[4];
     297}
     298
     299
     300void
     301codec_write(ice1712 *ice, uint8 reg_addr, uint8 data)
     302{
     303    switch (ice->config.product) {
     304        case ICE1712_SUBDEVICE_DELTA66:
     305        case ICE1712_SUBDEVICE_DELTA44:
     306            ak45xx_write_gpio(ice, reg_addr, data,
     307                DELTA66_CODEC_CS_0, 0);
     308            ak45xx_write_gpio(ice, reg_addr, data,
     309                DELTA66_CODEC_CS_1, 0);
     310            break;
     311        case ICE1712_SUBDEVICE_DELTA410:
     312        case ICE1712_SUBDEVICE_AUDIOPHILE_2496:
     313        case ICE1712_SUBDEVICE_DELTADIO2496:
     314            ak45xx_write_gpio(ice, reg_addr, data, AP2496_CODEC_CS, 0);
     315            break;
     316        case ICE1712_SUBDEVICE_DELTA1010:
     317        case ICE1712_SUBDEVICE_DELTA1010LT:
     318            ak45xx_write_gpio(ice, reg_addr, data,
     319                DELTA1010LT_CODEC_CS_0, DELTA1010LT_CS_NONE);
     320            ak45xx_write_gpio(ice, reg_addr, data,
     321                DELTA1010LT_CODEC_CS_1, DELTA1010LT_CS_NONE);
     322            ak45xx_write_gpio(ice, reg_addr, data,
     323                DELTA1010LT_CODEC_CS_2, DELTA1010LT_CS_NONE);
     324            ak45xx_write_gpio(ice, reg_addr, data,
     325                DELTA1010LT_CODEC_CS_3, DELTA1010LT_CS_NONE);
     326            break;
     327        case ICE1712_SUBDEVICE_VX442:
     328            ak45xx_write_gpio(ice, reg_addr, data, VX442_CODEC_CS_0, 0);
     329            ak45xx_write_gpio(ice, reg_addr, data, VX442_CODEC_CS_1, 0);
     330            break;
     331    }
     332}
     333
     334
     335void
     336spdif_write(ice1712 *ice, uint8 reg_addr, uint8 data)
     337{
     338    switch (ice->config.product) {
     339        case ICE1712_SUBDEVICE_DELTA1010:
     340            break;
     341        case ICE1712_SUBDEVICE_DELTADIO2496:
     342            break;
     343        case ICE1712_SUBDEVICE_DELTA66:
     344            break;
     345        case ICE1712_SUBDEVICE_DELTA44:
     346            break;
     347        case ICE1712_SUBDEVICE_AUDIOPHILE_2496:
     348            cs84xx_write_gpio(ice, reg_addr, data, AP2496_SPDIF_CS, 0);
     349            break;
     350        case ICE1712_SUBDEVICE_DELTA410:
     351            break;
     352        case ICE1712_SUBDEVICE_DELTA1010LT:
     353            cs84xx_write_gpio(ice, reg_addr, data, DELTA1010LT_SPDIF_CS,
     354                DELTA1010LT_CS_NONE);
     355            break;
     356        case ICE1712_SUBDEVICE_VX442:
     357            cs84xx_write_gpio(ice, reg_addr, data, VX442_SPDIF_CS, 0);
     358            break;
     359    }
     360}
     361
     362
     363uint8
     364codec_read(ice1712 *ice, uint8 reg_addr)
     365{
     366    uint8 val = 0xFF;
     367    switch (ice->config.product) {
     368        case ICE1712_SUBDEVICE_DELTA66:
     369        case ICE1712_SUBDEVICE_DELTA44:
     370            val = ak45xx_read_gpio(ice, reg_addr, DELTA66_CODEC_CS_0, 0);
     371            break;
     372        case ICE1712_SUBDEVICE_DELTA410:
     373        case ICE1712_SUBDEVICE_AUDIOPHILE_2496:
     374        case ICE1712_SUBDEVICE_DELTADIO2496:
     375            val = ak45xx_read_gpio(ice, reg_addr, AP2496_CODEC_CS, 0);
     376            break;
     377        case ICE1712_SUBDEVICE_DELTA1010:
     378        case ICE1712_SUBDEVICE_DELTA1010LT:
     379            val = ak45xx_read_gpio(ice, reg_addr, DELTA1010LT_CODEC_CS_0,
     380                DELTA1010LT_CS_NONE);
     381            break;
     382        case ICE1712_SUBDEVICE_VX442:
     383            val = ak45xx_read_gpio(ice, reg_addr, VX442_CODEC_CS_0, 0);
     384            break;
     385    }
     386
     387    return val;
     388}
     389
     390
     391uint8
     392spdif_read(ice1712 *ice, uint8 reg_addr)
     393{
     394    uint8 val = 0xFF;
     395    switch (ice->config.product) {
     396        case ICE1712_SUBDEVICE_DELTA1010:
     397            break;
     398        case ICE1712_SUBDEVICE_DELTADIO2496:
     399            break;
     400        case ICE1712_SUBDEVICE_DELTA66:
     401            break;
     402        case ICE1712_SUBDEVICE_DELTA44:
     403            break;
     404        case ICE1712_SUBDEVICE_AUDIOPHILE_2496:
     405            val = cs84xx_read_gpio(ice, reg_addr, AP2496_SPDIF_CS, 0);
     406            break;
     407        case ICE1712_SUBDEVICE_DELTA410:
     408            break;
     409        case ICE1712_SUBDEVICE_DELTA1010LT:
     410            val = cs84xx_read_gpio(ice, reg_addr, DELTA1010LT_SPDIF_CS,
     411                DELTA1010LT_CS_NONE);
     412            break;
     413        case ICE1712_SUBDEVICE_VX442:
     414            val = cs84xx_read_gpio(ice, reg_addr, VX442_SPDIF_CS, 0);
     415            break;
     416    }
     417
     418    return val;
     419}
     420
     421
     422void
     423write_gpio_byte(ice1712 *ice, uint8 data, uint8 gpio_data)
     424{
     425    int i;
     426
     427    for (i = 7; i >= 0; i--) {
     428        // drop clock and data bits
     429        gpio_data &= ~(ice->CommLines.clock | ice->CommLines.data_out);
     430
     431        // set data bit if needed
     432        if (data & (1 << i))
     433            gpio_data |= ice->CommLines.data_out;
     434
     435        write_gpio(ice, gpio_data);
     436        snooze(GPIO_I2C_DELAY);
     437
     438        // raise clock
     439        gpio_data |= ice->CommLines.clock;
     440        write_gpio(ice, gpio_data);
     441        snooze(GPIO_I2C_DELAY);
     442    }
     443}
     444
     445
     446uint8
     447read_gpio_byte(ice1712 *ice, uint8 gpio_data)
     448{
     449    int i;
     450    uint8 data = 0;
     451
     452    for (i = 7; i >= 0; i--) {
     453        // drop clock
     454        gpio_data &= ~(ice->CommLines.clock);
     455        write_gpio(ice, gpio_data);
     456        snooze(GPIO_I2C_DELAY);
     457
     458        if (read_gpio(ice) &ice->CommLines.data_in)
     459            data |= 1 << i;
     460
     461        gpio_data |= ice->CommLines.clock;
     462
     463        write_gpio(ice, gpio_data);
     464        snooze(GPIO_I2C_DELAY);
     465    }
     466
     467    return data;
     468}
     469
     470
     471void
     472ak45xx_write_gpio(ice1712 *ice, uint8 reg_addr, uint8 data,
     473    uint8 chip_select, uint8 invert_cs)
     474{
     475    uint8 tmp;
     476
     477    tmp = read_gpio(ice);
     478    tmp |= ice->CommLines.cs_mask;
     479
     480    if (invert_cs != 0) {
     481        tmp &= ~invert_cs;
     482        tmp |= chip_select;
     483    } else {
     484        tmp &= ~chip_select;
     485    }
     486
     487    write_gpio(ice, tmp);
     488    snooze(GPIO_I2C_DELAY);
     489
     490    write_gpio_byte(ice, ((AK45xx_CHIP_ADDRESS & 0x03) << 6) | 0x20
     491        | (reg_addr & 0x1F), tmp);
     492    write_gpio_byte(ice, data, tmp);
     493
     494    if (invert_cs != 0) {
     495        tmp |= invert_cs;
     496    } else {
     497        tmp |= chip_select;
     498    }
     499    write_gpio(ice, tmp);
     500    snooze(GPIO_I2C_DELAY);
     501}
     502
     503
     504void
     505cs84xx_write_gpio(ice1712 *ice, uint8 reg_addr, uint8 data,
     506    uint8 chip_select, uint8 invert_cs)
     507{
     508    uint8 tmp;
     509
     510    tmp = read_gpio(ice);
     511    tmp |= ice->CommLines.cs_mask;
     512
     513    if (invert_cs != 0) {
     514        tmp &= ~invert_cs;
     515        tmp |= chip_select;
     516    } else {
     517        tmp &= ~chip_select;
     518    }
     519
     520    write_gpio(ice, tmp);
     521    snooze(GPIO_I2C_DELAY);
     522
     523    write_gpio_byte(ice, (CS84xx_CHIP_ADDRESS & 0x7F) << 1, tmp);
     524    write_gpio_byte(ice, reg_addr & 0x7F, tmp); //Do not Increment
     525    write_gpio_byte(ice, data, tmp);
     526
     527    if (invert_cs != 0) {
     528        tmp |= invert_cs;
     529    } else {
     530        tmp |= chip_select;
     531    }
     532    write_gpio(ice, tmp);
     533    snooze(GPIO_I2C_DELAY);
     534}
     535
     536
     537uint8
     538cs84xx_read_gpio(ice1712 *ice, uint8 reg_addr, uint8 chip_select,
     539    uint8 invert_cs)
     540{
     541    uint8 tmp, data;
     542
     543    tmp = read_gpio(ice);
     544    tmp |= ice->CommLines.cs_mask;
     545
     546    if (invert_cs != 0) {
     547        tmp &= ~invert_cs;
     548        tmp |= chip_select;
     549    } else {
     550        tmp &= ~chip_select;
     551    }
     552
     553    write_gpio(ice, tmp);
     554    snooze(GPIO_I2C_DELAY);
     555
     556    write_gpio_byte(ice, (CS84xx_CHIP_ADDRESS & 0x7F) << 1,
     557        tmp); //For writing the MAP
     558    write_gpio_byte(ice, reg_addr & 0x7F, tmp); //Do not Increment
     559
     560    //Deselect the chip
     561    if (invert_cs != 0) {
     562        tmp |= invert_cs;
     563    } else {
     564        tmp |= chip_select;
     565    }
     566    write_gpio(ice, tmp);
     567    snooze(GPIO_I2C_DELAY);
     568
     569    if (invert_cs != 0) {
     570        tmp &= ~invert_cs;
     571        tmp |= chip_select;
     572    } else {
     573        tmp &= ~chip_select;
     574    }
     575    write_gpio(ice, tmp);
     576    snooze(GPIO_I2C_DELAY);
     577
     578    write_gpio_byte(ice, (CS84xx_CHIP_ADDRESS & 0x7F) << 1 | 1,
     579        tmp); //For writing the MAP
     580    data = read_gpio_byte(ice, tmp); //For reading
     581
     582    //Deselect the chip
     583    if (invert_cs != 0) {
     584        tmp |= invert_cs;
     585    } else {
     586        tmp |= chip_select;
     587    }
     588    write_gpio(ice, tmp);
     589
     590    return data;
     591}
     592
     593
     594/*
     595 * return -1 if error else return an uint8
     596 */
     597uint8
     598read_gpio(ice1712 *ice)
     599{
     600    return read_cci_uint8(ice, CCI_GPIO_DATA);
     601}
     602
     603
     604/*
     605 * return -1 if error else return 0
     606 */
     607void
     608write_gpio(ice1712 *ice, uint8 value)
     609{
     610    write_cci_uint8(ice, CCI_GPIO_DATA, value);
     611}
  • src/add-ons/kernel/drivers/audio/ice1712/io.h

    diff --git a/src/add-ons/kernel/drivers/audio/ice1712/io.h b/src/add-ons/kernel/drivers/audio/ice1712/io.h
    index 5d45cb7..20faecc 100644
    a b  
    11/*
    2  * ice1712 BeOS/Haiku Driver for VIA - VT1712 Multi Channel Audio Controller
     2 * Copyright 2004-2015 Haiku, Inc. All rights reserved.
     3 * Distributed under the terms of the MIT License.
    34 *
    4  * Copyright (c) 2002, Jerome Duval     (jerome.duval@free.fr)
    5  * Copyright (c) 2003, Marcus Overhagen (marcus@overhagen.de)
    6  * Copyright (c) 2007, Jerome Leveque   (leveque.jerome@neuf.fr)
    7  *
    8  * All rights reserved
    9  * Distributed under the terms of the MIT license.
     5 * Authors:
     6 *      Jérôme Duval, jerome.duval@free.fr
     7 *      Marcus Overhagen, marcus@overhagen.de
     8 *      Jérôme Lévêque, leveque.jerome@gmail.com
    109 */
    1110
     11
    1212#ifndef _IO_H_
    1313#define _IO_H_
    1414
     
    1616
    1717#include <SupportDefs.h>
    1818
    19 //------------------------------------------------------
    20 //------------------------------------------------------
    2119//Address are [PCI_10] + xx
    22 uint8   read_ccs_uint8(ice1712 *ice,    int8 regno);
    23 uint16  read_ccs_uint16(ice1712 *ice,   int8 regno);
    24 uint32  read_ccs_uint32(ice1712 *ice,   int8 regno);
     20uint8 read_ccs_uint8(ice1712 *ice, int8 regno);
     21uint16 read_ccs_uint16(ice1712 *ice, int8 regno);
     22uint32 read_ccs_uint32(ice1712 *ice, int8 regno);
     23void write_ccs_uint8(ice1712 *ice, int8 regno, uint8 value);
     24void write_ccs_uint16(ice1712 *ice, int8 regno, uint16 value);
     25void write_ccs_uint32(ice1712 *ice, int8 regno, uint32 value);
     26
     27uint8 read_cci_uint8(ice1712 *ice, int8 index);
     28void write_cci_uint8(ice1712 *ice, int8 index, uint8 value);
    2529
    26 void    write_ccs_uint8(ice1712 *ice,   int8 regno, uint8 value);
    27 void    write_ccs_uint16(ice1712 *ice,  int8 regno, uint16 value);
    28 void    write_ccs_uint32(ice1712 *ice,  int8 regno, uint32 value);
    29 //------------------------------------------------------
    30 //------------------------------------------------------
    31 uint8   read_cci_uint8(ice1712 *ice,    int8 index);
    32 void    write_cci_uint8(ice1712 *ice,   int8 index, uint8 value);
    33 //------------------------------------------------------
    34 //------------------------------------------------------
    3530//Address are [PCI_14] + xx
    36 uint8   read_ddma_uint8(ice1712 *ice,   int8 regno);
    37 uint16  read_ddma_uint16(ice1712 *ice,  int8 regno);
    38 uint32  read_ddma_uint32(ice1712 *ice,  int8 regno);
     31uint8 read_ddma_uint8(ice1712 *ice, int8 regno);
     32uint16 read_ddma_uint16(ice1712 *ice, int8 regno);
     33uint32 read_ddma_uint32(ice1712 *ice, int8 regno);
     34
     35void write_ddma_uint8(ice1712 *ice, int8 regno, uint8 value);
     36void write_ddma_uint16(ice1712 *ice, int8 regno, uint16 value);
     37void write_ddma_uint32(ice1712 *ice, int8 regno, uint32 value);
    3938
    40 void    write_ddma_uint8(ice1712 *ice,  int8 regno, uint8 value);
    41 void    write_ddma_uint16(ice1712 *ice, int8 regno, uint16 value);
    42 void    write_ddma_uint32(ice1712 *ice, int8 regno, uint32 value);
    43 //------------------------------------------------------
    44 //------------------------------------------------------
    4539//Address are [PCI_18] + x
    46 uint8   read_ds_uint8(ice1712 *ice,     int8 regno);
    47 uint16  read_ds_uint16(ice1712 *ice,    int8 regno);
    48 uint32  read_ds_uint32(ice1712 *ice,    int8 regno);
     40uint8 read_ds_uint8(ice1712 *ice, int8 regno);
     41uint16 read_ds_uint16(ice1712 *ice, int8 regno);
     42uint32 read_ds_uint32(ice1712 *ice, int8 regno);
    4943
    50 void    write_ds_uint8(ice1712 *ice,    int8 regno, uint8 value);
    51 void    write_ds_uint16(ice1712 *ice,   int8 regno, uint16 value);
    52 void    write_ds_uint32(ice1712 *ice,   int8 regno, uint32 value);
     44void write_ds_uint8(ice1712 *ice, int8 regno, uint8 value);
     45void write_ds_uint16(ice1712 *ice, int8 regno, uint16 value);
     46void write_ds_uint32(ice1712 *ice, int8 regno, uint32 value);
    5347
    5448typedef enum {
    5549    DS8_REGISTER_BUFFER_0_BASE_ADDRESS = 0,
    typedef enum {  
    6155    DS8_REGISTER_LEFT_RIGHT_VOLUME,
    6256} ds8_register;
    6357
    64 uint32  read_ds_channel_data(ice1712 *ice, uint8 channel, ds8_register index);
    65 void    write_ds_channel_data(ice1712 *ice, uint8 channel,
    66             ds8_register index, uint32 data);
    67 //------------------------------------------------------
    68 //------------------------------------------------------
     58uint32 read_ds_channel_data(ice1712 *ice, uint8 channel, ds8_register index);
     59void write_ds_channel_data(ice1712 *ice, uint8 channel, ds8_register index,
     60    uint32 data);
     61
    6962//Address are [PCI_1C] + xx
    70 uint8   read_mt_uint8(ice1712 *ice,     int8 regno);
    71 uint16  read_mt_uint16(ice1712 *ice,    int8 regno);
    72 uint32  read_mt_uint32(ice1712 *ice,    int8 regno);
     63uint8 read_mt_uint8(ice1712 *ice, int8 regno);
     64uint16 read_mt_uint16(ice1712 *ice, int8 regno);
     65uint32 read_mt_uint32(ice1712 *ice, int8 regno);
    7366
    74 void    write_mt_uint8(ice1712 *ice,    int8 regno, uint8 value);
    75 void    write_mt_uint16(ice1712 *ice,   int8 regno, uint16 value);
    76 void    write_mt_uint32(ice1712 *ice,   int8 regno, uint32 value);
    77 //------------------------------------------------------
    78 //------------------------------------------------------
     67void write_mt_uint8(ice1712 *ice, int8 regno, uint8 value);
     68void write_mt_uint16(ice1712 *ice, int8 regno, uint16 value);
     69void write_mt_uint32(ice1712 *ice, int8 regno, uint32 value);
    7970
    80 int16   read_i2c(ice1712 *ice, uint8 dev_addr, uint8 byte_addr);
     71int16 read_i2c(ice1712 *ice, uint8 dev_addr, uint8 byte_addr);
    8172//return -1 if error else return an uint8
    8273
    83 int16   write_i2c(ice1712 *ice, uint8 dev_addr, uint8 byte_addr, uint8 value);
     74int16 write_i2c(ice1712 *ice, uint8 dev_addr, uint8 byte_addr, uint8 value);
    8475//return -1 if error else return 0
    8576
    8677//------------------------------------------------------
    uint8 spdif_read_mult(ice1712 *ice, uint8 reg_addr, uint8 datas[], uint8 size);  
    10192
    10293//------------------------------------------------------
    10394
    104 uint8   read_gpio(ice1712 *ice);
     95uint8 read_gpio(ice1712 *ice);
    10596//return -1 if error else return an uint8
    10697
    107 void    write_gpio(ice1712 *ice, uint8 value);
     98void write_gpio(ice1712 *ice, uint8 value);
    10899
    109100#endif
  • deleted file src/add-ons/kernel/drivers/audio/ice1712/midi.c

    diff --git a/src/add-ons/kernel/drivers/audio/ice1712/midi.c b/src/add-ons/kernel/drivers/audio/ice1712/midi.c
    deleted file mode 100644
    index 4581df4..0000000
    + -  
    1 /*
    2  * ice1712 BeOS/Haiku Driver for VIA - VT1712 Multi Channel Audio Controller
    3  *
    4  * Copyright (c) 2002, Jerome Duval     (jerome.duval@free.fr)
    5  * Copyright (c) 2003, Marcus Overhagen (marcus@overhagen.de)
    6  * Copyright (c) 2007, Jerome Leveque   (leveque.jerome@neuf.fr)
    7  *
    8  * All rights reserved
    9  * Distributed under the terms of the MIT license.
    10  */
    11 
    12 #include <midi_driver.h>
    13 #include <string.h>
    14 #include <stdlib.h>
    15 #include <signal.h>
    16 
    17 #include "ice1712.h"
    18 #include "ice1712_reg.h"
    19 #include "io.h"
    20 #include "util.h"
    21 #include "debug.h"
    22 
    23 extern generic_mpu401_module * mpu401;
    24 
    25 
    26 void
    27 ice_1712_midi_interrupt_op(int32 op, void *data)
    28 {
    29     cpu_status status;
    30     uint8 int_status = 0;
    31     midi_dev *midi = (midi_dev *)data;
    32 
    33     if (op == B_MPU_401_ENABLE_CARD_INT) {
    34         status = lock();
    35 
    36         int_status = read_ccs_uint8(midi->card, CCS_INTERRUPT_MASK);
    37         int_status &= ~(midi->int_mask);
    38         write_ccs_uint8(midi->card, CCS_INTERRUPT_MASK, int_status);
    39 
    40         TRACE("B_MPU_401_ENABLE_CARD_INT: %s\n", midi->name);
    41 
    42         unlock(status);
    43     } else if (op == B_MPU_401_DISABLE_CARD_INT) {
    44         status = lock();
    45 
    46         int_status = read_ccs_uint8(midi->card, CCS_INTERRUPT_MASK);
    47         int_status |= midi->int_mask;
    48         write_ccs_uint8(midi->card, CCS_INTERRUPT_MASK, int_status);
    49 
    50         TRACE("B_MPU_401_DISABLE_CARD_INT: %s\n", midi->name);
    51 
    52         unlock(status);
    53     }
    54 
    55     TRACE("New mask status 0x%x\n", int_status);
    56 }
    57 
    58 
    59 status_t
    60 ice_1712_midi_open(const char *name, uint32 flags, void **cookie)
    61 {
    62     int midi, card;
    63     status_t ret = ENODEV;
    64 
    65     TRACE("**midi_open()\n");
    66     *cookie = NULL;
    67 
    68     for (card = 0; card < num_cards; card++) {
    69         for (midi = 0; midi < cards[card].config.nb_MPU401; midi++) {
    70             if (!strcmp(name, cards[card].midi_interf[midi].name)) {
    71                 midi_dev *dev = &(cards[card].midi_interf[midi]);
    72                 ret = (*mpu401->open_hook)(dev->mpu401device, flags, cookie);
    73                 if (ret >= B_OK) {
    74                     *cookie = dev->mpu401device;
    75                 }
    76                 break;
    77             }
    78         }
    79     }
    80 
    81     return ret;
    82 }
    83 
    84 
    85 status_t
    86 ice_1712_midi_close(void* cookie)
    87 {
    88     TRACE("**midi_close()\n");
    89     return (*mpu401->close_hook)(cookie);
    90 }
    91 
    92 
    93 status_t
    94 ice_1712_midi_free(void* cookie)
    95 {
    96     int midi, card;
    97     status_t ret;
    98 
    99     TRACE("**midi_free()\n");
    100 
    101     ret = (*mpu401->free_hook)(cookie);
    102 
    103     for (card = 0; card < num_cards; card++) {
    104         for (midi = 0; midi < cards[card].config.nb_MPU401; midi++) {
    105             if (cookie == cards[card].midi_interf[midi].mpu401device) {
    106                 cards[card].midi_interf[midi].mpu401device = NULL;
    107                 TRACE("Cleared %p card %d, midi %d\n", cookie, card, midi);
    108                 break;
    109             }
    110         }
    111     }
    112 
    113     return ret;
    114 }
    115 
    116 
    117 status_t
    118 ice_1712_midi_control(void* cookie,
    119     uint32 iop, void* data, size_t len)
    120 {
    121     TRACE("**midi_control()\n");
    122     return (*mpu401->control_hook)(cookie, iop, data, len);
    123 }
    124 
    125 
    126 status_t
    127 ice_1712_midi_read(void * cookie, off_t pos, void * ptr, size_t * nread)
    128 {
    129     status_t ret = B_ERROR;
    130 
    131     ret = (*mpu401->read_hook)(cookie, pos, ptr, nread);
    132     //TRACE("**midi_read(%ld)\n", ret);
    133 
    134     return ret;
    135 }
    136 
    137 
    138 status_t
    139 ice_1712_midi_write(void * cookie, off_t pos, const void * ptr,
    140         size_t * nwritten)
    141 {
    142     status_t ret = B_ERROR;
    143 
    144     ret = (*mpu401->write_hook)(cookie, pos, ptr, nwritten);
    145     //TRACE("**midi_write(%ld)\n", ret);
    146 
    147     return ret;
    148 }
  • new file src/add-ons/kernel/drivers/audio/ice1712/midi.cpp

    diff --git a/src/add-ons/kernel/drivers/audio/ice1712/midi.cpp b/src/add-ons/kernel/drivers/audio/ice1712/midi.cpp
    new file mode 100644
    index 0000000..fdd06c1
    - +  
     1/*
     2 * Copyright 2004-2015 Haiku, Inc. All rights reserved.
     3 * Distributed under the terms of the MIT License.
     4 *
     5 * Authors:
     6 *      Jérôme Duval, jerome.duval@free.fr
     7 *      Marcus Overhagen, marcus@overhagen.de
     8 *      Jérôme Lévêque, leveque.jerome@gmail.com
     9 */
     10
     11
     12#include <midi_driver.h>
     13#include <string.h>
     14#include <stdlib.h>
     15#include <signal.h>
     16
     17#include "ice1712.h"
     18#include "ice1712_reg.h"
     19#include "io.h"
     20#include "util.h"
     21#include "debug.h"
     22
     23extern generic_mpu401_module * mpu401;
     24extern int32 num_cards;
     25extern ice1712 cards[NUM_CARDS];
     26
     27void ice1712Midi_interrupt(int32 op, void *data);
     28
     29
     30void
     31ice1712Midi_interrupt(int32 op, void *data)
     32{
     33    cpu_status status;
     34    uint8 int_status = 0;
     35    ice1712Midi *midi = (ice1712Midi*)data;
     36
     37    if (op == B_MPU_401_ENABLE_CARD_INT) {
     38        status = lock();
     39
     40        int_status = read_ccs_uint8(midi->card, CCS_INTERRUPT_MASK);
     41        int_status &= ~(midi->int_mask);
     42        write_ccs_uint8(midi->card, CCS_INTERRUPT_MASK, int_status);
     43
     44        ITRACE("B_MPU_401_ENABLE_CARD_INT: %s\n", midi->name);
     45
     46        unlock(status);
     47    } else if (op == B_MPU_401_DISABLE_CARD_INT) {
     48        status = lock();
     49
     50        int_status = read_ccs_uint8(midi->card, CCS_INTERRUPT_MASK);
     51        int_status |= midi->int_mask;
     52        write_ccs_uint8(midi->card, CCS_INTERRUPT_MASK, int_status);
     53
     54        ITRACE("B_MPU_401_DISABLE_CARD_INT: %s\n", midi->name);
     55
     56        unlock(status);
     57    }
     58
     59    ITRACE("New mask status 0x%x\n", int_status);
     60}
     61
     62
     63static status_t
     64ice1712Midi_open(const char *name, uint32 flags, void **cookie)
     65{
     66    int midi, card;
     67    status_t ret = ENODEV;
     68
     69    ITRACE("**midi_open()\n");
     70    *cookie = NULL;
     71
     72    for (card = 0; card < num_cards; card++) {
     73        for (midi = 0; midi < cards[card].config.nb_MPU401; midi++) {
     74            if (!strcmp(name, cards[card].midiItf[midi].name)) {
     75                ice1712Midi *dev = &(cards[card].midiItf[midi]);
     76                ret = (*mpu401->open_hook)(dev->mpu401device, flags, cookie);
     77                if (ret >= B_OK) {
     78                    *cookie = dev->mpu401device;
     79                }
     80                break;
     81            }
     82        }
     83    }
     84
     85    return ret;
     86}
     87
     88
     89static status_t
     90ice1712Midi_close(void* cookie)
     91{
     92    ITRACE("**midi_close()\n");
     93    return (*mpu401->close_hook)(cookie);
     94}
     95
     96
     97static status_t
     98ice1712Midi_free(void* cookie)
     99{
     100    int midi, card;
     101    status_t ret;
     102
     103    ITRACE("**midi_free()\n");
     104
     105    ret = (*mpu401->free_hook)(cookie);
     106
     107    for (card = 0; card < num_cards; card++) {
     108        for (midi = 0; midi < cards[card].config.nb_MPU401; midi++) {
     109            if (cookie == cards[card].midiItf[midi].mpu401device) {
     110                cards[card].midiItf[midi].mpu401device = NULL;
     111                ITRACE("Cleared %p card %d, midi %d\n", cookie, card, midi);
     112                break;
     113            }
     114        }
     115    }
     116
     117    return ret;
     118}
     119
     120
     121static status_t
     122ice1712Midi_control(void* cookie,
     123    uint32 iop, void* data, size_t len)
     124{
     125    ITRACE("**midi_control()\n");
     126    return (*mpu401->control_hook)(cookie, iop, data, len);
     127}
     128
     129
     130static status_t
     131ice1712Midi_read(void * cookie, off_t pos, void * ptr, size_t * nread)
     132{
     133    status_t ret = B_ERROR;
     134
     135    ret = (*mpu401->read_hook)(cookie, pos, ptr, nread);
     136    ITRACE_VV("**midi_read: %" B_PRIi32 "\n", ret);
     137
     138    return ret;
     139}
     140
     141
     142static status_t
     143ice1712Midi_write(void * cookie, off_t pos, const void * ptr,
     144        size_t * nwritten)
     145{
     146    status_t ret = B_ERROR;
     147
     148    ret = (*mpu401->write_hook)(cookie, pos, ptr, nwritten);
     149    ITRACE_VV("**midi_write: %" B_PRIi32 "\n", ret);
     150
     151    return ret;
     152}
     153
     154
     155device_hooks ice1712Midi_hooks =
     156{
     157    ice1712Midi_open,
     158    ice1712Midi_close,
     159    ice1712Midi_free,
     160    ice1712Midi_control,
     161    ice1712Midi_read,
     162    ice1712Midi_write,
     163    NULL,
     164    NULL,
     165    NULL,
     166    NULL
     167};
  • deleted file src/add-ons/kernel/drivers/audio/ice1712/multi.c

    diff --git a/src/add-ons/kernel/drivers/audio/ice1712/multi.c b/src/add-ons/kernel/drivers/audio/ice1712/multi.c
    deleted file mode 100644
    index 745315f..0000000
    + -  
    1 /*
    2  * ice1712 BeOS/Haiku Driver for VIA - VT1712 Multi Channel Audio Controller
    3  *
    4  * Copyright (c) 2002, Jerome Duval     (jerome.duval@free.fr)
    5  * Copyright (c) 2003, Marcus Overhagen (marcus@overhagen.de)
    6  * Copyright (c) 2007, Jerome Leveque   (leveque.jerome@neuf.fr)
    7  *
    8  * All rights reserved
    9  * Distributed under the terms of the MIT license.
    10  */
    11 
    12 
    13 #include "ice1712_reg.h"
    14 #include "io.h"
    15 #include "multi.h"
    16 #include "util.h"
    17 
    18 #include <string.h>
    19 #include "debug.h"
    20 
    21 
    22 #define AUTHORIZED_RATE (B_SR_SAME_AS_INPUT | B_SR_96000 \
    23     | B_SR_88200 | B_SR_48000 | B_SR_44100)
    24 #define AUTHORIZED_SAMPLE_SIZE (B_FMT_24BIT)
    25 
    26 #define MAX_CONTROL 32
    27 
    28 
    29 static void
    30 start_DMA(ice1712 *card)
    31 {
    32     uint16 size = card->buffer_size * MAX_DAC;
    33 
    34     write_mt_uint8(card, MT_PROF_PB_CONTROL, 0);
    35 
    36     write_mt_uint32(card, MT_PROF_PB_DMA_BASE_ADDRESS,
    37                  (uint32)card->phys_addr_pb);
    38     write_mt_uint16(card, MT_PROF_PB_DMA_COUNT_ADDRESS,
    39                  (size * SWAPPING_BUFFERS) - 1);
    40     //We want interrupt only from playback
    41     write_mt_uint16(card, MT_PROF_PB_DMA_TERM_COUNT, size - 1);
    42     TRACE("SIZE DMA PLAYBACK %#x\n", size);
    43 
    44     size = card->buffer_size * MAX_ADC;
    45 
    46     write_mt_uint32(card, MT_PROF_REC_DMA_BASE_ADDRESS,
    47                  (uint32)card->phys_addr_rec);
    48     write_mt_uint16(card, MT_PROF_REC_DMA_COUNT_ADDRESS,
    49                  (size * SWAPPING_BUFFERS) - 1);
    50     //We do not want any interrupt from the record
    51     write_mt_uint16(card, MT_PROF_REC_DMA_TERM_COUNT, 0);
    52     TRACE("SIZE DMA RECORD %#x\n", size);
    53 
    54     //Enable output AND Input from Analog CODEC
    55     switch (card->product) {
    56     //TODO: find correct value for all card
    57         case ICE1712_SUBDEVICE_DELTA66:
    58         case ICE1712_SUBDEVICE_DELTA44:
    59         case ICE1712_SUBDEVICE_AUDIOPHILE_2496:
    60         case ICE1712_SUBDEVICE_DELTADIO2496:
    61         case ICE1712_SUBDEVICE_DELTA410:
    62         case ICE1712_SUBDEVICE_DELTA1010LT:
    63         case ICE1712_SUBDEVICE_DELTA1010:
    64             codec_write(card, AK45xx_CLOCK_FORMAT_REGISTER, 0x69);
    65             codec_write(card, AK45xx_RESET_REGISTER, 0x03);
    66             break;
    67         case ICE1712_SUBDEVICE_VX442:
    68 //          ak45xx_write_gpio(ice, reg_addr, data, VX442_CODEC_CS_0);
    69 //          ak45xx_write_gpio(ice, reg_addr, data, VX442_CODEC_CS_1);
    70             break;
    71     }
    72 
    73     //Set Data Format for SPDif codec
    74     switch (card->product) {
    75     //TODO: find correct value for all card
    76         case ICE1712_SUBDEVICE_DELTA1010:
    77             break;
    78         case ICE1712_SUBDEVICE_DELTADIO2496:
    79             break;
    80         case ICE1712_SUBDEVICE_DELTA66:
    81         case ICE1712_SUBDEVICE_DELTA44:
    82 //          ak45xx_write_gpio(ice, reg_addr, data, DELTA66_CODEC_CS_0);
    83 //          ak45xx_write_gpio(ice, reg_addr, data, DELTA66_CODEC_CS_1);
    84             break;
    85         case ICE1712_SUBDEVICE_AUDIOPHILE_2496:
    86             spdif_write(card, CS84xx_SERIAL_INPUT_FORMAT_REG, 0x85);
    87             spdif_write(card, CS84xx_SERIAL_OUTPUT_FORMAT_REG, 0x85);
    88 //          spdif_write(card, CS84xx_SERIAL_OUTPUT_FORMAT_REG, 0x41);
    89             break;
    90         case ICE1712_SUBDEVICE_DELTA410:
    91             break;
    92         case ICE1712_SUBDEVICE_DELTA1010LT:
    93 //          ak45xx_write_gpio(ice, reg_addr, data, DELTA1010LT_CODEC_CS_0);
    94 //          ak45xx_write_gpio(ice, reg_addr, data, DELTA1010LT_CODEC_CS_1);
    95 //          ak45xx_write_gpio(ice, reg_addr, data, DELTA1010LT_CODEC_CS_2);
    96 //          ak45xx_write_gpio(ice, reg_addr, data, DELTA1010LT_CODEC_CS_3);
    97             break;
    98         case ICE1712_SUBDEVICE_VX442:
    99 //          ak45xx_write_gpio(ice, reg_addr, data, VX442_CODEC_CS_0);
    100 //          ak45xx_write_gpio(ice, reg_addr, data, VX442_CODEC_CS_1);
    101             break;
    102     }
    103 
    104     card->buffer = 1;
    105     write_mt_uint8(card, MT_PROF_PB_CONTROL, 5);
    106 }
    107 
    108 
    109 status_t
    110 ice1712_get_description(ice1712 *card, multi_description *data)
    111 {
    112     int chan = 0, i, size;
    113 
    114     data->interface_version = B_CURRENT_INTERFACE_VERSION;
    115     data->interface_minimum = B_CURRENT_INTERFACE_VERSION;
    116 
    117     switch (card->product) {
    118         case ICE1712_SUBDEVICE_DELTA1010:
    119             strncpy(data->friendly_name, "Delta 1010", 32);
    120             break;
    121         case ICE1712_SUBDEVICE_DELTADIO2496:
    122             strncpy(data->friendly_name, "Delta DIO 2496", 32);
    123             break;
    124         case ICE1712_SUBDEVICE_DELTA66:
    125             strncpy(data->friendly_name, "Delta 66", 32);
    126             break;
    127         case ICE1712_SUBDEVICE_DELTA44:
    128             strncpy(data->friendly_name, "Delta 44", 32);
    129             break;
    130         case ICE1712_SUBDEVICE_AUDIOPHILE_2496:
    131             strncpy(data->friendly_name, "Audiophile 2496", 32);
    132             break;
    133         case ICE1712_SUBDEVICE_DELTA410:
    134             strncpy(data->friendly_name, "Delta 410", 32);
    135             break;
    136         case ICE1712_SUBDEVICE_DELTA1010LT:
    137             strncpy(data->friendly_name, "Delta 1010 LT", 32);
    138             break;
    139         case ICE1712_SUBDEVICE_VX442:
    140             strncpy(data->friendly_name, "VX 442", 32);
    141             break;
    142 
    143         default:
    144             strncpy(data->friendly_name, "Unknow device", 32);
    145             break;
    146     }
    147 
    148     strncpy(data->vendor_info, "Haiku", 32);
    149 
    150     data->output_channel_count = card->total_output_channels;
    151     data->input_channel_count = card->total_input_channels;
    152     data->output_bus_channel_count = 0;
    153     data->input_bus_channel_count = 0;
    154     data->aux_bus_channel_count = 0;
    155 
    156     size =  data->output_channel_count + data->input_channel_count
    157         + data->output_bus_channel_count + data->input_bus_channel_count
    158         + data->aux_bus_channel_count;
    159 
    160     TRACE_VV("request_channel_count = %ld\n", data->request_channel_count);
    161 
    162     if (size <= data->request_channel_count) {
    163         for (i = 0; i < card->config.nb_DAC; i++) {
    164         //Analog STEREO output
    165             data->channels[chan].channel_id = chan;
    166             data->channels[chan].kind = B_MULTI_OUTPUT_CHANNEL;
    167             data->channels[chan].designations = B_CHANNEL_STEREO_BUS
    168                 | (((i & 1) == 0) ? B_CHANNEL_LEFT : B_CHANNEL_RIGHT);
    169             data->channels[chan].connectors = 0;
    170             chan++;
    171         }
    172 
    173         if (card->config.spdif & SPDIF_OUT_PRESENT) {
    174         //SPDIF STEREO output
    175             data->channels[chan].channel_id = chan;
    176             data->channels[chan].kind = B_MULTI_OUTPUT_CHANNEL;
    177             data->channels[chan].designations = B_CHANNEL_STEREO_BUS
    178                 | B_CHANNEL_LEFT;
    179             data->channels[chan].connectors = 0;
    180             chan++;
    181             data->channels[chan].channel_id = chan;
    182             data->channels[chan].kind = B_MULTI_OUTPUT_CHANNEL;
    183             data->channels[chan].designations = B_CHANNEL_STEREO_BUS
    184                 | B_CHANNEL_RIGHT;
    185             data->channels[chan].connectors = 0;
    186             chan++;
    187         }
    188 
    189         for (i = 0; i < card->config.nb_ADC; i++) {
    190         //Analog STEREO input
    191             data->channels[chan].channel_id = chan;
    192             data->channels[chan].kind = B_MULTI_INPUT_CHANNEL;
    193             data->channels[chan].designations = B_CHANNEL_STEREO_BUS
    194                 | (((i & 1) == 0) ? B_CHANNEL_LEFT : B_CHANNEL_RIGHT);
    195             data->channels[chan].connectors = 0;
    196             chan++;
    197         }
    198 
    199         if (card->config.spdif & SPDIF_IN_PRESENT) {
    200         //SPDIF STEREO input
    201             data->channels[chan].channel_id = chan;
    202             data->channels[chan].kind = B_MULTI_INPUT_CHANNEL;
    203             data->channels[chan].designations = B_CHANNEL_STEREO_BUS
    204                 | B_CHANNEL_LEFT;
    205             data->channels[chan].connectors = 0;
    206             chan++;
    207             data->channels[chan].channel_id = chan;
    208             data->channels[chan].kind = B_MULTI_INPUT_CHANNEL;
    209             data->channels[chan].designations = B_CHANNEL_STEREO_BUS
    210                 | B_CHANNEL_RIGHT;
    211             data->channels[chan].connectors = 0;
    212             chan++;
    213         }
    214 
    215         //The digital mixer output (it's an Input for Haiku)
    216         data->channels[chan].channel_id = chan;
    217         data->channels[chan].kind = B_MULTI_INPUT_CHANNEL;
    218         data->channels[chan].designations = B_CHANNEL_STEREO_BUS
    219             | B_CHANNEL_LEFT;
    220         data->channels[chan].connectors = 0;
    221         chan++;
    222         data->channels[chan].channel_id = chan;
    223         data->channels[chan].kind = B_MULTI_INPUT_CHANNEL;
    224         data->channels[chan].designations = B_CHANNEL_STEREO_BUS
    225             | B_CHANNEL_RIGHT;
    226         data->channels[chan].connectors = 0;
    227         chan++;
    228     }
    229 
    230     TRACE("output_channel_count = %ld\n", data->output_channel_count);
    231     TRACE("input_channel_count = %ld\n", data->input_channel_count);
    232     TRACE("output_bus_channel_count = %ld\n", data->output_bus_channel_count);
    233     TRACE("input_bus_channel_count = %ld\n", data->input_bus_channel_count);
    234 
    235     data->output_rates = data->input_rates = AUTHORIZED_RATE;
    236     data->min_cvsr_rate = 44100;
    237     data->max_cvsr_rate = 96000;
    238 
    239     data->output_formats = data->input_formats = AUTHORIZED_SAMPLE_SIZE;
    240     data->lock_sources = B_MULTI_LOCK_INTERNAL | B_MULTI_LOCK_SPDIF;
    241     data->timecode_sources = 0;
    242     data->interface_flags = B_MULTI_INTERFACE_PLAYBACK
    243         | B_MULTI_INTERFACE_RECORD;
    244     data->start_latency = 0;
    245 
    246     strcpy(data->control_panel,"");
    247 
    248     return B_OK;
    249 }
    250 
    251 
    252 status_t
    253 ice1712_get_enabled_channels(ice1712 *card, multi_channel_enable *data)
    254 {
    255     int i, total_channel;
    256     uint8 reg;
    257 
    258     total_channel = card->total_output_channels + card->total_input_channels;
    259     for (i = 0; i < total_channel; i++)
    260         B_SET_CHANNEL(data->enable_bits, i, true);
    261 
    262     reg = read_mt_uint8(card, MT_SAMPLING_RATE_SELECT);
    263 
    264     if (reg == 0x10)
    265         data->lock_source = B_MULTI_LOCK_SPDIF;
    266     else
    267         data->lock_source = B_MULTI_LOCK_INTERNAL;
    268 
    269     return B_OK;
    270 }
    271 
    272 
    273 status_t
    274 ice1712_set_enabled_channels(ice1712 *card, multi_channel_enable *data)
    275 {
    276     int i;
    277     int total_channel;
    278 
    279     total_channel = card->total_output_channels + card->total_input_channels;
    280     for (i = 0; i < total_channel; i++)
    281         TRACE("set_enabled_channels %d : %s\n", i,
    282             B_TEST_CHANNEL(data->enable_bits, i) ? "enabled": "disabled");
    283 
    284     TRACE("lock_source %#08X\n", (int)data->lock_source);
    285     TRACE("lock_data %#08X\n", (int)data->lock_data);
    286 
    287     if (data->lock_source == B_MULTI_LOCK_SPDIF)
    288         write_mt_uint8(card, MT_SAMPLING_RATE_SELECT, 0x10);
    289     else
    290         write_mt_uint8(card, MT_SAMPLING_RATE_SELECT, card->sampling_rate);
    291 
    292     card->lock_source = data->lock_source;
    293 
    294     return B_OK;
    295 }
    296 
    297 
    298 status_t
    299 ice1712_get_global_format(ice1712 *card, multi_format_info *data)
    300 {
    301     uint8 sr = read_mt_uint8(card, MT_SAMPLING_RATE_SELECT);
    302 
    303     switch (sr) {
    304         case ICE1712_SAMPLERATE_48K:
    305             data->input.rate = data->output.rate = B_SR_48000;
    306             data->input.cvsr = data->output.cvsr = 48000.0f;
    307             break;
    308         case ICE1712_SAMPLERATE_96K:
    309             data->input.rate = data->output.rate = B_SR_96000;
    310             data->input.cvsr = data->output.cvsr = 96000.0f;
    311             break;
    312         case ICE1712_SAMPLERATE_44K1:
    313             data->input.rate = data->output.rate = B_SR_44100;
    314             data->input.cvsr = data->output.cvsr = 44100.0f;
    315             break;
    316         case ICE1712_SAMPLERATE_88K2:
    317             data->input.rate = data->output.rate = B_SR_88200;
    318             data->input.cvsr = data->output.cvsr = 88200.0f;
    319             break;
    320     }
    321 
    322     data->timecode_kind = 0;
    323     data->output_latency = data->input_latency = 0;
    324     data->output.format = data->input.format = AUTHORIZED_SAMPLE_SIZE;
    325 
    326     TRACE("Sampling Rate = %f\n", data->input.cvsr);
    327 
    328     return B_OK;
    329 }
    330 
    331 
    332 status_t
    333 ice1712_set_global_format(ice1712 *card, multi_format_info *data)
    334 {
    335     TRACE("Input Sampling Rate = %d\n", data->input.rate);
    336     TRACE("Output Sampling Rate = %d\n", data->output.rate);
    337 
    338     //We can't have a different rate for input and output
    339     //so just wait to change our sample rate when
    340     //media server will do what we need
    341     //Lie to it and say we are living in wonderland
    342     if (data->input.rate != data->output.rate)
    343         return B_OK;
    344 
    345     if (card->lock_source == B_MULTI_LOCK_INTERNAL) {
    346         switch (data->output.rate) {
    347             case B_SR_96000:
    348                 card->sampling_rate = 0x07;
    349                 break;
    350             case B_SR_88200:
    351                 card->sampling_rate = 0x0B;
    352                 break;
    353             case B_SR_48000:
    354                 card->sampling_rate = 0x00;
    355                 break;
    356             case B_SR_44100:
    357                 card->sampling_rate = 0x08;
    358                 break;
    359         }
    360         write_mt_uint8(card, MT_SAMPLING_RATE_SELECT, card->sampling_rate);
    361     }
    362     TRACE("New rate = %#x\n", read_mt_uint8(card, MT_SAMPLING_RATE_SELECT));
    363 
    364     return B_OK;
    365 }
    366 
    367 
    368 static uint32
    369 get_combo_cb(ice1712 *card, uint32 index)
    370 {
    371     uint32 value = 0;
    372 
    373     TRACE_VV("   get_combo_cb: %ld, %ld\n", index, value);
    374 
    375     switch (index) {
    376         case 0:
    377             value = card->settings.clock;
    378             break;
    379 
    380         case 1:
    381             value = card->settings.outFormat;
    382             break;
    383 
    384         case 2:
    385             value = card->settings.emphasis;
    386             break;
    387 
    388         case 3:
    389             value = card->settings.copyMode;
    390             break;
    391     }
    392 
    393     return value;
    394 }
    395 
    396 
    397 static void
    398 set_combo_cb(ice1712 *card, uint32 index, uint32 value)
    399 {
    400     TRACE_VV("   set_combo_cb: %ld, %ld\n", index, value);
    401 
    402     switch (index) {
    403         case 0:
    404             if (value < 2)
    405                 card->settings.clock = value;
    406             break;
    407 
    408         case 1:
    409             if (value < 2)
    410                 card->settings.outFormat = value;
    411             break;
    412 
    413         case 2:
    414             if (value < 3)
    415                 card->settings.emphasis = value;
    416             break;
    417 
    418         case 3:
    419             if (value < 3)
    420                 card->settings.copyMode = value;
    421             break;
    422     }
    423 }
    424 
    425 
    426 static uint32
    427 get_output_cb(ice1712 *card, uint32 index)
    428 {
    429     uint32 value = 0;
    430 
    431     if (index < 5)
    432         value = card->settings.output[index];
    433 
    434     TRACE_VV("   get_output_cb: %ld, %ld\n", index, value);
    435 
    436     return value;
    437 }
    438 
    439 
    440 static void
    441 set_output_cb(ice1712 *card, uint32 index, uint32 value)
    442 {
    443     if (index < 5)
    444         card->settings.output[index] = value;
    445 
    446     TRACE_VV("   set_output_cb: %ld, %ld\n", index, value);
    447 }
    448 
    449 
    450 static void
    451 get_volume_cb(ice1712 *card, multi_mix_value *mmv)
    452 {
    453     channel_volume *vol;
    454     uint32 chan = ICE1712_MULTI_GET_CHANNEL(mmv->id);
    455 
    456     TRACE_VV("   get_volume_cb\n");
    457 
    458     if (chan < ICE1712_HARDWARE_VOLUME) {
    459         vol = card->settings.playback;
    460     }
    461     else {
    462         vol = card->settings.record;
    463         chan -= ICE1712_HARDWARE_VOLUME;
    464     }
    465 
    466     //chan is normaly <= ICE1712_HARDWARE_VOLUME
    467     switch (ICE1712_MULTI_GET_INDEX(mmv->id)) {
    468         case 0: //Mute
    469             mmv->u.enable = vol[chan].mute | vol[chan + 1].mute;
    470             TRACE_VV("\tGet mute %d for channel %d or %d\n",
    471                 mmv->u.enable, (int)chan, (int)chan + 1);
    472             break;
    473 
    474         case 2: //Right channel
    475             chan++;
    476             //No break
    477         case 1: //Left channel
    478             mmv->u.gain = vol[chan].volume;
    479             TRACE_VV("\tGet Volume %f for channel %d\n",
    480                 mmv->u.gain, (int)chan);
    481             break;
    482     }
    483 }
    484 
    485 
    486 static void
    487 set_volume_cb(ice1712 *card, multi_mix_value *mmv)
    488 {
    489     channel_volume *vol;
    490     uint32 chan = ICE1712_MULTI_GET_CHANNEL(mmv->id);
    491 
    492     TRACE_VV("   set_volume_cb\n");
    493 
    494     if (chan < ICE1712_HARDWARE_VOLUME) {
    495         vol = card->settings.playback;
    496     }
    497     else {
    498         vol = card->settings.record;
    499         chan -= ICE1712_HARDWARE_VOLUME;
    500     }
    501 
    502     //chan is normaly <= ICE1712_HARDWARE_VOLUME
    503     switch (ICE1712_MULTI_GET_INDEX(mmv->id)) {
    504         case 0: //Mute
    505             vol[chan].mute = mmv->u.enable;
    506             vol[chan + 1].mute = mmv->u.enable;
    507             TRACE_VV("\tChange mute to %d for channel %d and %d\n",
    508                 mmv->u.enable, (int)chan, (int)chan + 1);
    509             break;
    510 
    511         case 2: //Right channel
    512             chan++;
    513             //No break
    514         case 1: //Left channel
    515             vol[chan].volume = mmv->u.gain;
    516             TRACE_VV("\tChange Volume to %f for channel %d\n",
    517                 mmv->u.gain, (int)chan);
    518             break;
    519     }
    520 }
    521 
    522 
    523 status_t
    524 ice1712_get_mix(ice1712 *card, multi_mix_value_info *data)
    525 {
    526     int i;
    527     TRACE_VV("  Asking to get %ld control(s)\n", data->item_count);
    528 
    529     for (i = 0; i < data->item_count; i++) {
    530         multi_mix_value *mmv = &(data->values[i]);
    531         TRACE_VV("   Id %#x\n", (unsigned int)mmv->id);
    532         switch (mmv->id & ICE1712_MULTI_CONTROL_TYPE_MASK) {
    533             case ICE1712_MULTI_CONTROL_TYPE_COMBO:
    534                 mmv->u.mux = get_combo_cb(card,
    535                                 ICE1712_MULTI_GET_CHANNEL(mmv->id));
    536                 break;
    537 
    538             case ICE1712_MULTI_CONTROL_TYPE_VOLUME:
    539                 get_volume_cb(card, mmv);
    540                 break;
    541 
    542             case ICE1712_MULTI_CONTROL_TYPE_OUTPUT:
    543                 mmv->u.mux = get_output_cb(card,
    544                                 ICE1712_MULTI_GET_CHANNEL(mmv->id));
    545                 break;
    546 
    547             default:
    548                 TRACE_VV("    default 0x%x\n", (unsigned int)mmv->id);
    549                 break;
    550         }
    551     }
    552 
    553     return B_OK;
    554 }
    555 
    556 
    557 status_t
    558 ice1712_set_mix(ice1712 *card, multi_mix_value_info *data)
    559 {
    560     int i;
    561 
    562     TRACE_VV("  Asking to set %ld control(s)\n", data->item_count);
    563 
    564     for (i = 0; i < data->item_count; i++) {
    565         multi_mix_value *mmv = &(data->values[i]);
    566         TRACE_VV("   Id %#x\n", (unsigned int)mmv->id);
    567         switch (mmv->id & ICE1712_MULTI_CONTROL_TYPE_MASK) {
    568             case ICE1712_MULTI_CONTROL_TYPE_COMBO:
    569                 set_combo_cb(card, ICE1712_MULTI_GET_CHANNEL(mmv->id),
    570                     mmv->u.mux);
    571                 break;
    572 
    573             case ICE1712_MULTI_CONTROL_TYPE_VOLUME:
    574                 set_volume_cb(card, mmv);
    575                 break;
    576 
    577             case ICE1712_MULTI_CONTROL_TYPE_OUTPUT:
    578                 set_output_cb(card, ICE1712_MULTI_GET_CHANNEL(mmv->id),
    579                     mmv->u.mux);
    580                 break;
    581 
    582             default:
    583                 TRACE_VV("    default 0x%x\n", (unsigned int)mmv->id);
    584                 break;
    585         }
    586     }
    587 
    588     return apply_settings(card);
    589 }
    590 
    591 
    592 status_t
    593 ice1712_list_mix_channels(ice1712 *card, multi_mix_channel_info *data)
    594 {
    595     //Not Implemented
    596     return B_OK;
    597 }
    598 
    599 static const char *Clock[] = {
    600     "Internal",
    601     "Digital",
    602     NULL,
    603 };
    604 
    605 static const char *DigitalFormat[] = {
    606     "Consumer",
    607     "Professional",
    608     NULL,
    609 };
    610 
    611 static const char *DigitalEmphasis[] = {
    612     "None",
    613     "CCITT",
    614     "15/50usec",
    615     NULL,
    616 };
    617 
    618 static const char *DigitalCopyMode[] = {
    619     "Original",
    620     "1st Generation",
    621     "No SCMS",
    622     NULL,
    623 };
    624 
    625 static const char **SettingsGeneral[] = {
    626     Clock,
    627     NULL,
    628 };
    629 
    630 static const char **SettingsDigital[] = {
    631     DigitalFormat,
    632     DigitalEmphasis,
    633     DigitalCopyMode,
    634     NULL,
    635 };
    636 
    637 static const char *string_list[] = {
    638     "Setup",
    639     "General",
    640     "Digital",
    641     "Output Selection",
    642 
    643     "Internal Mixer",
    644 
    645     //General settings
    646     "Master clock",
    647     "reserved_0",
    648     "reserved_1",
    649 
    650     //Digital settings
    651     "Output format",
    652     "Emphasis",
    653     "Copy mode",
    654 
    655     //Output Selection
    656     "Output 1", //11
    657     "Output 2",
    658     "Output 3",
    659     "Output 4",
    660     "Digital Output", //15
    661 
    662     "Haiku output", //16
    663 
    664     "Input 1", //17
    665     "Input 2",
    666     "Input 3",
    667     "Input 4",
    668     "Digital Input", //21
    669     "Internal mixer", //22
    670 };
    671 
    672 static int32 nb_control_created;
    673 
    674 
    675 //This will create a Tab
    676 static int32
    677 create_group_control(multi_mix_control **p_mmc, int32 index, int32 parent,
    678     enum strind_id string, const char* name)
    679 {
    680     multi_mix_control *mmc = *p_mmc;
    681     int32 group;
    682 
    683     TRACE_VV("Create ID create_group_control\n");
    684 
    685     mmc->id = ICE1712_MULTI_CONTROL_FIRSTID + ICE1712_MULTI_SET_INDEX(index);
    686     mmc->parent = parent;
    687     mmc->flags = B_MULTI_MIX_GROUP;
    688     mmc->master = CONTROL_IS_MASTER;
    689     mmc->string = string;
    690 
    691     group = mmc->id;
    692 
    693     if (name != NULL)
    694         strcpy(mmc->name, name);
    695 
    696     TRACE_VV("Create ID %#x\n", (unsigned int)mmc->id);
    697 
    698     nb_control_created++; mmc++;
    699     (*p_mmc) = mmc;
    700 
    701     return group;
    702 }
    703 
    704 
    705 //This will create a Slider with a "Mute" CheckBox
    706 static void
    707 create_channel_control(multi_mix_control **p_mmc, int32 channel, int32 parent,
    708     const char* name)
    709 {
    710     int32 id = ICE1712_MULTI_CONTROL_FIRSTID
    711         + ICE1712_MULTI_CONTROL_TYPE_VOLUME
    712         + ICE1712_MULTI_SET_CHANNEL(channel);
    713     multi_mix_control *mmc = *p_mmc;
    714     multi_mix_control control;
    715 
    716     TRACE_VV("Create ID create_channel_control\n");
    717 
    718     control.master = CONTROL_IS_MASTER;
    719     control.parent = parent;
    720     control.u.gain.max_gain = 0.0;
    721     control.u.gain.min_gain = -144.0;
    722     control.u.gain.granularity = 1.5;
    723 
    724     //The Mute Checkbox
    725     control.id = id++;
    726     control.flags = B_MULTI_MIX_ENABLE;
    727     control.string = S_MUTE;
    728     *mmc = control;
    729     mmc++;
    730 
    731     TRACE_VV("Create ID %#x\n", (unsigned int)control.id);
    732 
    733     //The Left Slider
    734     control.string = S_null;
    735     control.id = id++;
    736     control.flags = B_MULTI_MIX_GAIN;
    737     if (name != NULL)
    738         strcpy(control.name, name);
    739     *mmc = control;
    740     mmc++;
    741 
    742     TRACE_VV("Create ID %#x\n", (unsigned int)control.id);
    743 
    744     //The Right Slider
    745     control.master = control.id; //The Id of the Left Slider
    746     control.id = id++;
    747     *mmc = control;
    748     mmc++;
    749 
    750     TRACE_VV("Create ID %#x\n", (unsigned int)control.id);
    751 
    752     nb_control_created += 3;
    753     (*p_mmc) = mmc;
    754 }
    755 
    756 
    757 static void
    758 create_combo_control(multi_mix_control **p_mmc, const char *values[],
    759     int32 parent, int32 nb_combo, const char *name)
    760 {
    761     int32 id = ICE1712_MULTI_CONTROL_FIRSTID
    762         + ICE1712_MULTI_CONTROL_TYPE_COMBO
    763         + ICE1712_MULTI_SET_CHANNEL(nb_combo);
    764     multi_mix_control *mmc = *p_mmc;
    765     int32 parentControl, i;
    766 
    767     TRACE_VV("Create ID create_combo_control\n");
    768 
    769     //The label
    770     parentControl = mmc->id = id++;
    771     mmc->flags = B_MULTI_MIX_MUX;
    772     mmc->parent = parent;
    773     strcpy(mmc->name, name);
    774 
    775     TRACE_VV("Create ID %#x\n", (unsigned int)parentControl);
    776 
    777     nb_control_created++; mmc++;
    778 
    779     //The values
    780     for (i = 0; values[i] != NULL; i++) {
    781         mmc->id = id++;
    782         mmc->flags = B_MULTI_MIX_MUX_VALUE;
    783         mmc->parent = parentControl;
    784         strcpy(mmc->name, values[i]);
    785 
    786         TRACE_VV("Create ID %#x\n", (unsigned int)mmc->id);
    787 
    788         nb_control_created++; mmc++;
    789     }
    790 
    791     (*p_mmc) = mmc;
    792 }
    793 
    794 
    795 //This will create all possible value for the output
    796 //output 0 -> 3 (physical stereo output) 4 is the Digital
    797 static void
    798 create_output_choice(ice1712 *card, multi_mix_control **p_mmc,
    799     int32 output, int32 parent)
    800 {
    801     int32 id = ICE1712_MULTI_CONTROL_FIRSTID
    802         + ICE1712_MULTI_CONTROL_TYPE_OUTPUT
    803         + ICE1712_MULTI_SET_CHANNEL(output);
    804     multi_mix_control *mmc = *p_mmc;
    805     int32 parentControl, i;
    806 
    807     TRACE_VV("Create ID create_output_choice\n");
    808 
    809     //The label
    810     parentControl = mmc->id = id++;
    811     mmc->flags = B_MULTI_MIX_MUX;
    812     mmc->parent = parent;
    813     strcpy(mmc->name, string_list[11 + output]);
    814     nb_control_created++; mmc++;
    815 
    816     TRACE_VV("Create ID %#x\n", (unsigned int)parentControl);
    817 
    818     //Haiku output
    819     mmc->id = id++;
    820     mmc->flags = B_MULTI_MIX_MUX_VALUE;
    821     mmc->parent = parentControl;
    822     strcpy(mmc->name, string_list[16]);
    823 
    824     TRACE_VV("Create ID %#x\n", (unsigned int)mmc->id);
    825 
    826     nb_control_created++; mmc++;
    827 
    828     //Physical Input
    829     for (i = 0; i < card->config.nb_DAC; i += 2) {
    830         mmc->id = id++;
    831         mmc->flags = B_MULTI_MIX_MUX_VALUE;
    832         mmc->parent = parentControl;
    833         strcpy(mmc->name, string_list[17 + (i / 2)]);
    834 
    835         TRACE_VV("Create ID %#x\n", (unsigned int)mmc->id);
    836 
    837         nb_control_created++; mmc++;
    838     }
    839 
    840     //Physical Digital Input
    841     if (card->config.spdif & SPDIF_IN_PRESENT) {
    842         mmc->id = id++;
    843         mmc->flags = B_MULTI_MIX_MUX_VALUE;
    844         mmc->parent = parentControl;
    845         strcpy(mmc->name, string_list[21]);
    846 
    847         TRACE_VV("Create ID %#x\n", (unsigned int)mmc->id);
    848 
    849         nb_control_created++; mmc++;
    850     }
    851 
    852     //Internal mixer only for Output 1 and Digital Output
    853     if ((output == 0) || (output == 4)) {
    854         mmc->id = id++;
    855         mmc->flags = B_MULTI_MIX_MUX_VALUE;
    856         mmc->parent = parentControl;
    857         strcpy(mmc->name, string_list[22]);
    858 
    859         TRACE_VV("Create ID %#x\n", (unsigned int)mmc->id);
    860 
    861         nb_control_created++; mmc++;
    862     }
    863 
    864     (*p_mmc) = mmc;
    865 }
    866 
    867 
    868 status_t
    869 ice1712_list_mix_controls(ice1712 *card, multi_mix_control_info *mmci)
    870 {
    871     uint32 i, parentTab, parentTabColumn;
    872     multi_mix_control *mmc = mmci->controls;
    873     uint32 group = 0, combo = 0, channel = 0;
    874 
    875     nb_control_created = 0;
    876 
    877     TRACE_VV("count = %ld\n", mmci->control_count);
    878 
    879     //Cleaning
    880     memset(mmc, 0, mmci->control_count * sizeof(multi_mix_control));
    881 
    882     //Setup tab
    883     parentTab = create_group_control(&mmc, group++,
    884         CONTROL_IS_MASTER, S_SETUP, NULL);
    885 
    886     //General Settings
    887     parentTabColumn = create_group_control(&mmc, group++, parentTab,
    888         S_null, string_list[1]);
    889     for (i = 0; SettingsGeneral[i] != NULL; i++) {
    890         create_combo_control(&mmc, SettingsGeneral[i], parentTabColumn,
    891             combo++, string_list[5 + i]);
    892     }
    893 
    894     //Digital Settings
    895     parentTabColumn = create_group_control(&mmc, group++, parentTab,
    896         S_null, string_list[2]);
    897     for (i = 0; SettingsDigital[i] != NULL; i++) {
    898         create_combo_control(&mmc, SettingsDigital[i], parentTabColumn,
    899             combo++, string_list[8 + i]);
    900     }
    901 
    902     //Output Selection Settings
    903     parentTabColumn = create_group_control(&mmc, group++, parentTab,
    904         S_null, string_list[3]);
    905     for (i = 0; i < card->config.nb_DAC; i += 2) {
    906         create_output_choice(card, &mmc, i / 2, parentTabColumn);
    907     }
    908 
    909     if (card->config.spdif & SPDIF_OUT_PRESENT) {
    910         create_output_choice(card, &mmc, 4, parentTabColumn);
    911     }
    912 
    913     //Internal Mixer Tab
    914     //Output
    915     parentTab = create_group_control(&mmc, group++, CONTROL_IS_MASTER,
    916         S_null, string_list[4]);
    917 
    918     for (i = 0; i < card->config.nb_DAC; i += 2) {
    919         parentTabColumn = create_group_control(&mmc, group++, parentTab,
    920             S_null, string_list[(i / 2) + 11]);
    921         create_channel_control(&mmc, channel++, parentTabColumn, NULL);
    922     }
    923 
    924     if (card->config.spdif & SPDIF_OUT_PRESENT) {
    925         parentTabColumn = create_group_control(&mmc, group++, parentTab,
    926             S_null, string_list[15]);
    927         create_channel_control(&mmc, ICE1712_HARDWARE_VOLUME - 2,
    928             parentTabColumn, NULL);
    929     }
    930 
    931     //Input
    932     channel = ICE1712_HARDWARE_VOLUME;
    933     for (i = 0; i < card->config.nb_ADC; i += 2) {
    934         parentTabColumn = create_group_control(&mmc, group++, parentTab,
    935              S_null, string_list[(i / 2) + 17]);
    936         create_channel_control(&mmc, channel++, parentTabColumn, NULL);
    937     }
    938 
    939     if (card->config.spdif & SPDIF_IN_PRESENT) {
    940         parentTabColumn = create_group_control(&mmc, group++, parentTab,
    941             S_null, string_list[21]);
    942         create_channel_control(&mmc, 2 * ICE1712_HARDWARE_VOLUME - 2,
    943             parentTabColumn, NULL);
    944     }
    945 
    946     TRACE_VV("Return %ld control(s)\n", nb_control_created);
    947     mmci->control_count = nb_control_created;
    948 
    949     return B_OK;
    950 }
    951 
    952 
    953 status_t
    954 ice1712_list_mix_connections(ice1712 *card, multi_mix_connection_info *data)
    955 {//Not Implemented
    956     data->actual_count = 0;
    957     return B_OK;
    958 }
    959 
    960 
    961 status_t
    962 ice1712_get_buffers(ice1712 *card, multi_buffer_list *data)
    963 {
    964     int buff, chan_i = 0, chan_o = 0;
    965 
    966     TRACE_VV("flags = %#lx\n", data->flags);
    967     TRACE_VV("request_playback_buffers = %ld\n",
    968           data->request_playback_buffers);
    969     TRACE_VV("request_playback_channels = %ld\n",
    970           data->request_playback_channels);
    971     TRACE_VV("request_playback_buffer_size = %lx\n",
    972           data->request_playback_buffer_size);
    973     TRACE_VV("request_record_buffers = %ld\n",
    974           data->request_record_buffers);
    975     TRACE_VV("request_record_channels = %ld\n",
    976           data->request_record_channels);
    977     TRACE_VV("request_record_buffer_size = %lx\n",
    978           data->request_record_buffer_size);
    979 
    980     for (buff = 0; buff < SWAPPING_BUFFERS; buff++) {
    981         uint32 stride_o = MAX_DAC * SAMPLE_SIZE;
    982         uint32 stride_i = MAX_ADC * SAMPLE_SIZE;
    983         uint32 buf_o = stride_o * card->buffer_size;
    984         uint32 buf_i = stride_i * card->buffer_size;
    985 
    986         if (data->request_playback_channels == card->total_output_channels) {
    987             for (chan_o = 0; chan_o < card->config.nb_DAC; chan_o++) {
    988             //Analog STEREO output
    989                 data->playback_buffers[buff][chan_o].base = card->log_addr_pb
    990                     + buf_o * buff + SAMPLE_SIZE * chan_o;
    991                 data->playback_buffers[buff][chan_o].stride = stride_o;
    992                 TRACE_VV("pb_buffer[%ld][%ld] = %p\n", buff, chan_o,
    993                     data->playback_buffers[buff][chan_o].base);
    994             }
    995 
    996             if (card->config.spdif & SPDIF_OUT_PRESENT) {
    997             //SPDIF STEREO output
    998                 data->playback_buffers[buff][chan_o].base = card->log_addr_pb
    999                     + buf_o * buff + SAMPLE_SIZE * SPDIF_LEFT;
    1000                 data->playback_buffers[buff][chan_o].stride = stride_o;
    1001                 TRACE_VV("pb_buffer[%ld][%ld] = %p\n", buff, chan_o,
    1002                     data->playback_buffers[buff][chan_o].base);
    1003 
    1004                 chan_o++;
    1005                 data->playback_buffers[buff][chan_o].base = card->log_addr_pb
    1006                     + buf_o * buff + SAMPLE_SIZE * SPDIF_RIGHT;
    1007                 data->playback_buffers[buff][chan_o].stride = stride_o;
    1008                 TRACE_VV("pb_buffer[%ld][%ld] = %p\n", buff, chan_o,
    1009                     data->playback_buffers[buff][chan_o].base);
    1010                 chan_o++;
    1011             }
    1012         }
    1013 
    1014         if (data->request_record_channels == card->total_input_channels) {
    1015             for (chan_i = 0; chan_i < card->config.nb_ADC; chan_i++) {
    1016             //Analog STEREO input
    1017                 data->record_buffers[buff][chan_i].base = card->log_addr_rec
    1018                     + buf_i * buff + SAMPLE_SIZE * chan_i;
    1019                 data->record_buffers[buff][chan_i].stride = stride_i;
    1020                 TRACE_VV("rec_buffer[%ld][%ld] = %p\n", buff, chan_i,
    1021                     data->record_buffers[buff][chan_i].base);
    1022             }
    1023 
    1024             if (card->config.spdif & SPDIF_IN_PRESENT) {
    1025             //SPDIF STEREO input
    1026                 data->record_buffers[buff][chan_i].base = card->log_addr_rec
    1027                     + buf_i * buff + SAMPLE_SIZE * SPDIF_LEFT;
    1028                 data->record_buffers[buff][chan_i].stride = stride_i;
    1029                 TRACE_VV("rec_buffer[%ld][%ld] = %p\n", buff, chan_i,
    1030                     data->record_buffers[buff][chan_i].base);
    1031 
    1032                 chan_i++;
    1033                 data->record_buffers[buff][chan_i].base = card->log_addr_rec
    1034                     + buf_i * buff + SAMPLE_SIZE * SPDIF_RIGHT;
    1035                 data->record_buffers[buff][chan_i].stride = stride_i;
    1036                 TRACE_VV("rec_buffer[%ld][%ld] = %p\n", buff, chan_i,
    1037                     data->record_buffers[buff][chan_i].base);
    1038                 chan_i++;
    1039             }
    1040 
    1041             //The digital mixer output
    1042             data->record_buffers[buff][chan_i].base = card->log_addr_rec
    1043                 + buf_i * buff + SAMPLE_SIZE * MIXER_OUT_LEFT;
    1044             data->record_buffers[buff][chan_i].stride = stride_i;
    1045             TRACE_VV("rec_buffer[%ld][%ld] = %p\n", buff, chan_i,
    1046                     data->record_buffers[buff][chan_i].base);
    1047 
    1048             chan_i++;
    1049             data->record_buffers[buff][chan_i].base = card->log_addr_rec
    1050                 + buf_i * buff + SAMPLE_SIZE * MIXER_OUT_RIGHT;
    1051             data->record_buffers[buff][chan_i].stride = stride_i;
    1052             TRACE_VV("rec_buffer[%ld][%ld] = %p\n", buff, chan_i,
    1053                     data->record_buffers[buff][chan_i].base);
    1054             chan_i++;
    1055         }
    1056     }
    1057 
    1058     data->return_playback_buffers = SWAPPING_BUFFERS;
    1059     data->return_playback_channels = card->total_output_channels;
    1060     data->return_playback_buffer_size = card->buffer_size;
    1061 
    1062     TRACE("return_playback_buffers = %ld\n", data->return_playback_buffers);
    1063     TRACE("return_playback_channels = %ld\n", data->return_playback_channels);
    1064     TRACE("return_playback_buffer_size = %ld\n",
    1065         data->return_playback_buffer_size);
    1066 
    1067     data->return_record_buffers = SWAPPING_BUFFERS;
    1068     data->return_record_channels = card->total_input_channels;
    1069     data->return_record_channels = chan_i;
    1070     data->return_record_buffer_size = card->buffer_size;
    1071 
    1072     TRACE("return_record_buffers = %ld\n", data->return_record_buffers);
    1073     TRACE("return_record_channels = %ld\n", data->return_record_channels);
    1074     TRACE("return_record_buffer_size = %ld\n",
    1075         data->return_record_buffer_size);
    1076 
    1077     start_DMA(card);
    1078 
    1079     return B_OK;
    1080 }
    1081 
    1082 
    1083 status_t
    1084 ice1712_buffer_exchange(ice1712 *card, multi_buffer_info *data)
    1085 {
    1086     int cpu_status;
    1087 
    1088     multi_buffer_info buffer_info;
    1089 
    1090 #ifdef __HAIKU__
    1091     if (user_memcpy(&buffer_info, data, sizeof(buffer_info)) < B_OK)
    1092         return B_BAD_ADDRESS;
    1093 #else
    1094     memcpy(&buffer_info, data, sizeof(buffer_info));
    1095 #endif
    1096 
    1097     buffer_info.flags = B_MULTI_BUFFER_PLAYBACK | B_MULTI_BUFFER_RECORD;
    1098 
    1099     if (acquire_sem_etc(card->buffer_ready_sem, 1, B_RELATIVE_TIMEOUT
    1100         | B_CAN_INTERRUPT, 50000) == B_TIMED_OUT) {
    1101         TRACE("buffer_exchange timeout\n");
    1102     };
    1103 
    1104     cpu_status = lock();
    1105 
    1106     // Playback buffers info
    1107     buffer_info.played_real_time = card->played_time;
    1108     buffer_info.played_frames_count = card->frames_count;
    1109     buffer_info.playback_buffer_cycle = (card->buffer - 1)
    1110         % SWAPPING_BUFFERS; //Buffer played
    1111 
    1112     // Record buffers info
    1113     buffer_info.recorded_real_time = card->played_time;
    1114     buffer_info.recorded_frames_count = card->frames_count;
    1115     buffer_info.record_buffer_cycle = (card->buffer - 1)
    1116         % SWAPPING_BUFFERS; //Buffer filled
    1117 
    1118     unlock(cpu_status);
    1119 
    1120 /*  if ((card->buffer % 1500) == 0) {
    1121         uint8 reg8, reg8_dir;
    1122         reg8 = read_gpio(card);
    1123         reg8_dir = read_cci_uint8(card, CCI_GPIO_DIRECTION_CONTROL);
    1124         TRACE("DEBUG === GPIO = %d (dir %d)\n", reg8, reg8_dir);
    1125 
    1126         reg8 = spdif_read(card, CS84xx_VERSION_AND_CHIP_ID);
    1127         TRACE("DEBUG === S/PDif Version : 0x%x\n", reg8);
    1128     }*/
    1129 
    1130 #ifdef __HAIKU__
    1131     if (user_memcpy(data, &buffer_info, sizeof(buffer_info)) < B_OK)
    1132         return B_BAD_ADDRESS;
    1133 #else
    1134     memcpy(data, &buffer_info, sizeof(buffer_info));
    1135 #endif
    1136 
    1137     return B_OK;
    1138 }
    1139 
    1140 status_t ice1712_buffer_force_stop(ice1712 *card)
    1141 {
    1142 //  int cpu_status;
    1143 
    1144     write_mt_uint8(card, MT_PROF_PB_CONTROL, 0);
    1145 
    1146 //  cpu_status = lock();
    1147 
    1148     card->played_time = 0;
    1149     card->frames_count = 0;
    1150     card->buffer = 0;
    1151 
    1152 //  unlock(cpu_status);
    1153 
    1154     return B_OK;
    1155 }
    1156 
  • new file src/add-ons/kernel/drivers/audio/ice1712/multi.cpp

    diff --git a/src/add-ons/kernel/drivers/audio/ice1712/multi.cpp b/src/add-ons/kernel/drivers/audio/ice1712/multi.cpp
    new file mode 100644
    index 0000000..b4292f7
    - +  
     1/*
     2 * Copyright 2004-2015 Haiku, Inc. All rights reserved.
     3 * Distributed under the terms of the MIT License.
     4 *
     5 * Authors:
     6 *      Jérôme Duval, jerome.duval@free.fr
     7 *      Marcus Overhagen, marcus@overhagen.de
     8 *      Jérôme Lévêque, leveque.jerome@gmail.com
     9 */
     10
     11
     12#include "ice1712_reg.h"
     13#include "io.h"
     14#include "multi.h"
     15#include "util.h"
     16
     17#include <string.h>
     18#include "debug.h"
     19
     20status_t ice1712Settings_apply(ice1712 *card);
     21
     22static void ice1712Buffer_Start(ice1712 *card);
     23static uint32 ice1712UI_GetCombo(ice1712 *card, uint32 index);
     24static void ice1712UI_SetCombo(ice1712 *card, uint32 index, uint32 value);
     25static uint32 ice1712UI_GetOutput(ice1712 *card, uint32 index);
     26static void ice1712UI_SetOutput(ice1712 *card, uint32 index, uint32 value);
     27static void ice1712UI_GetVolume(ice1712 *card, multi_mix_value *mmv);
     28static void ice1712UI_SetVolume(ice1712 *card, multi_mix_value *mmv);
     29static void ice1712UI_CreateOutput(ice1712 *card, multi_mix_control **p_mmc,
     30    int32 output, int32 parent);
     31static void ice1712UI_CreateCombo(multi_mix_control **p_mmc,
     32    const char *values[], int32 parent, int32 nb_combo, const char *name);
     33static void ice1712UI_CreateChannel(multi_mix_control **p_mmc,
     34    int32 channel, int32 parent, const char* name);
     35static int32 ice1712UI_CreateGroup(multi_mix_control **p_mmc,
     36    int32 index, int32 parent, enum strind_id string, const char* name);
     37static int32 nb_control_created;
     38
     39#define AUTHORIZED_RATE (B_SR_SAME_AS_INPUT | B_SR_96000 \
     40    | B_SR_88200 | B_SR_48000 | B_SR_44100)
     41#define AUTHORIZED_SAMPLE_SIZE (B_FMT_24BIT)
     42
     43#define MAX_CONTROL 32
     44
     45//ICE1712 Multi - Buffer
     46//----------------------
     47
     48void
     49ice1712Buffer_Start(ice1712 *card)
     50{
     51    uint16 size = card->buffer_size * MAX_DAC;
     52
     53    write_mt_uint8(card, MT_PROF_PB_CONTROL, 0);
     54
     55    write_mt_uint32(card, MT_PROF_PB_DMA_BASE_ADDRESS,
     56        (uint32)(card->phys_pb.address));
     57    write_mt_uint16(card, MT_PROF_PB_DMA_COUNT_ADDRESS,
     58        (size * SWAPPING_BUFFERS) - 1);
     59    //We want interrupt only from playback
     60    write_mt_uint16(card, MT_PROF_PB_DMA_TERM_COUNT, size - 1);
     61    ITRACE("SIZE DMA PLAYBACK %#x\n", size);
     62
     63    size = card->buffer_size * MAX_ADC;
     64
     65    write_mt_uint32(card, MT_PROF_REC_DMA_BASE_ADDRESS,
     66        (uint32)(card->phys_rec.address));
     67    write_mt_uint16(card, MT_PROF_REC_DMA_COUNT_ADDRESS,
     68        (size * SWAPPING_BUFFERS) - 1);
     69    //We do not want any interrupt from the record
     70    write_mt_uint16(card, MT_PROF_REC_DMA_TERM_COUNT, 0);
     71    ITRACE("SIZE DMA RECORD %#x\n", size);
     72
     73    //Enable output AND Input from Analog CODEC
     74    switch (card->config.product) {
     75    //TODO: find correct value for all card
     76        case ICE1712_SUBDEVICE_DELTA66:
     77        case ICE1712_SUBDEVICE_DELTA44:
     78        case ICE1712_SUBDEVICE_AUDIOPHILE_2496:
     79        case ICE1712_SUBDEVICE_DELTADIO2496:
     80        case ICE1712_SUBDEVICE_DELTA410:
     81        case ICE1712_SUBDEVICE_DELTA1010LT:
     82        case ICE1712_SUBDEVICE_DELTA1010:
     83            codec_write(card, AK45xx_CLOCK_FORMAT_REGISTER, 0x69);
     84            codec_write(card, AK45xx_RESET_REGISTER, 0x03);
     85            break;
     86        case ICE1712_SUBDEVICE_VX442:
     87//          ak45xx_write_gpio(ice, reg_addr, data, VX442_CODEC_CS_0);
     88//          ak45xx_write_gpio(ice, reg_addr, data, VX442_CODEC_CS_1);
     89            break;
     90    }
     91
     92    //Set Data Format for SPDif codec
     93    switch (card->config.product) {
     94    //TODO: find correct value for all card
     95        case ICE1712_SUBDEVICE_DELTA1010:
     96            break;
     97        case ICE1712_SUBDEVICE_DELTADIO2496:
     98            break;
     99        case ICE1712_SUBDEVICE_DELTA66:
     100        case ICE1712_SUBDEVICE_DELTA44:
     101//          ak45xx_write_gpio(ice, reg_addr, data, DELTA66_CODEC_CS_0);
     102//          ak45xx_write_gpio(ice, reg_addr, data, DELTA66_CODEC_CS_1);
     103            break;
     104        case ICE1712_SUBDEVICE_AUDIOPHILE_2496:
     105            spdif_write(card, CS84xx_SERIAL_INPUT_FORMAT_REG, 0x85);
     106            spdif_write(card, CS84xx_SERIAL_OUTPUT_FORMAT_REG, 0x85);
     107//          spdif_write(card, CS84xx_SERIAL_OUTPUT_FORMAT_REG, 0x41);
     108            break;
     109        case ICE1712_SUBDEVICE_DELTA410:
     110            break;
     111        case ICE1712_SUBDEVICE_DELTA1010LT:
     112//          ak45xx_write_gpio(ice, reg_addr, data,
     113//              DELTA1010LT_CODEC_CS_0);
     114//          ak45xx_write_gpio(ice, reg_addr, data,
     115//              DELTA1010LT_CODEC_CS_1);
     116//          ak45xx_write_gpio(ice, reg_addr, data,
     117//              DELTA1010LT_CODEC_CS_2);
     118//          ak45xx_write_gpio(ice, reg_addr, data,
     119//              DELTA1010LT_CODEC_CS_3);
     120            break;
     121        case ICE1712_SUBDEVICE_VX442:
     122//          ak45xx_write_gpio(ice, reg_addr, data, VX442_CODEC_CS_0);
     123//          ak45xx_write_gpio(ice, reg_addr, data, VX442_CODEC_CS_1);
     124            break;
     125    }
     126
     127    card->buffer = 1;
     128    write_mt_uint8(card, MT_PROF_PB_CONTROL, 5);
     129}
     130
     131
     132status_t
     133ice1712Buffer_Exchange(ice1712 *card, multi_buffer_info *data)
     134{
     135    multi_buffer_info buffer_info;
     136
     137#ifdef __HAIKU__
     138    if (user_memcpy(&buffer_info, data, sizeof(buffer_info)) < B_OK)
     139        return B_BAD_ADDRESS;
     140#else
     141    memcpy(&buffer_info, data, sizeof(buffer_info));
     142#endif
     143
     144    buffer_info.flags = B_MULTI_BUFFER_PLAYBACK | B_MULTI_BUFFER_RECORD;
     145
     146    if (acquire_sem_etc(card->buffer_ready_sem, 1, B_RELATIVE_TIMEOUT
     147        | B_CAN_INTERRUPT, 50000) == B_TIMED_OUT) {
     148        ITRACE("buffer_exchange timeout\n");
     149    };
     150
     151    // Playback buffers info
     152    buffer_info.played_real_time = card->played_time;
     153    buffer_info.played_frames_count = card->frames_count;
     154    buffer_info.playback_buffer_cycle = (card->buffer - 1)
     155        % SWAPPING_BUFFERS; //Buffer played
     156
     157    // Record buffers info
     158    buffer_info.recorded_real_time = card->played_time;
     159    buffer_info.recorded_frames_count = card->frames_count;
     160    buffer_info.record_buffer_cycle = (card->buffer - 1)
     161        % SWAPPING_BUFFERS; //Buffer filled
     162
     163#ifdef __HAIKU__
     164    if (user_memcpy(data, &buffer_info, sizeof(buffer_info)) < B_OK)
     165        return B_BAD_ADDRESS;
     166#else
     167    memcpy(data, &buffer_info, sizeof(buffer_info));
     168#endif
     169
     170    return B_OK;
     171}
     172
     173
     174status_t
     175ice1712Buffer_Stop(ice1712 *card)
     176{
     177    write_mt_uint8(card, MT_PROF_PB_CONTROL, 0);
     178
     179    card->played_time = 0;
     180    card->frames_count = 0;
     181    card->buffer = 0;
     182
     183    return B_OK;
     184}
     185
     186//ICE1712 Multi - Description
     187//---------------------------
     188
     189status_t
     190ice1712Get_Description(ice1712 *card, multi_description *data)
     191{
     192    int chan = 0, i, size;
     193
     194    data->interface_version = B_CURRENT_INTERFACE_VERSION;
     195    data->interface_minimum = B_CURRENT_INTERFACE_VERSION;
     196
     197    switch (card->config.product) {
     198        case ICE1712_SUBDEVICE_DELTA1010:
     199            strncpy(data->friendly_name, "Delta 1010", 32);
     200            break;
     201        case ICE1712_SUBDEVICE_DELTADIO2496:
     202            strncpy(data->friendly_name, "Delta DIO 2496", 32);
     203            break;
     204        case ICE1712_SUBDEVICE_DELTA66:
     205            strncpy(data->friendly_name, "Delta 66", 32);
     206            break;
     207        case ICE1712_SUBDEVICE_DELTA44:
     208            strncpy(data->friendly_name, "Delta 44", 32);
     209            break;
     210        case ICE1712_SUBDEVICE_AUDIOPHILE_2496:
     211            strncpy(data->friendly_name, "Audiophile 2496", 32);
     212            break;
     213        case ICE1712_SUBDEVICE_DELTA410:
     214            strncpy(data->friendly_name, "Delta 410", 32);
     215            break;
     216        case ICE1712_SUBDEVICE_DELTA1010LT:
     217            strncpy(data->friendly_name, "Delta 1010 LT", 32);
     218            break;
     219        case ICE1712_SUBDEVICE_VX442:
     220            strncpy(data->friendly_name, "VX 442", 32);
     221            break;
     222
     223        default:
     224            strncpy(data->friendly_name, "Unknow device", 32);
     225            break;
     226    }
     227
     228    strncpy(data->vendor_info, "Haiku", 32);
     229
     230    data->output_channel_count = card->total_output_channels;
     231    data->input_channel_count = card->total_input_channels;
     232    data->output_bus_channel_count = 0;
     233    data->input_bus_channel_count = 0;
     234    data->aux_bus_channel_count = 0;
     235
     236    size =  data->output_channel_count + data->input_channel_count
     237        + data->output_bus_channel_count + data->input_bus_channel_count
     238        + data->aux_bus_channel_count;
     239
     240    ITRACE_VV("request_channel_count = %" B_PRIi32 "\n",
     241        data->request_channel_count);
     242
     243    if (size <= data->request_channel_count) {
     244        for (i = 0; i < card->config.nb_DAC; i++) {
     245        //Analog STEREO output
     246            data->channels[chan].channel_id = chan;
     247            data->channels[chan].kind = B_MULTI_OUTPUT_CHANNEL;
     248            data->channels[chan].designations = B_CHANNEL_STEREO_BUS
     249                | (((i & 1) == 0) ? B_CHANNEL_LEFT : B_CHANNEL_RIGHT);
     250            data->channels[chan].connectors = 0;
     251            chan++;
     252        }
     253
     254        if (card->config.spdif & SPDIF_OUT_PRESENT) {
     255        //SPDIF STEREO output
     256            data->channels[chan].channel_id = chan;
     257            data->channels[chan].kind = B_MULTI_OUTPUT_CHANNEL;
     258            data->channels[chan].designations = B_CHANNEL_STEREO_BUS
     259                | B_CHANNEL_LEFT;
     260            data->channels[chan].connectors = 0;
     261            chan++;
     262            data->channels[chan].channel_id = chan;
     263            data->channels[chan].kind = B_MULTI_OUTPUT_CHANNEL;
     264            data->channels[chan].designations = B_CHANNEL_STEREO_BUS
     265                | B_CHANNEL_RIGHT;
     266            data->channels[chan].connectors = 0;
     267            chan++;
     268        }
     269
     270        for (i = 0; i < card->config.nb_ADC; i++) {
     271        //Analog STEREO input
     272            data->channels[chan].channel_id = chan;
     273            data->channels[chan].kind = B_MULTI_INPUT_CHANNEL;
     274            data->channels[chan].designations = B_CHANNEL_STEREO_BUS
     275                | (((i & 1) == 0) ? B_CHANNEL_LEFT : B_CHANNEL_RIGHT);
     276            data->channels[chan].connectors = 0;
     277            chan++;
     278        }
     279
     280        if (card->config.spdif & SPDIF_IN_PRESENT) {
     281        //SPDIF STEREO input
     282            data->channels[chan].channel_id = chan;
     283            data->channels[chan].kind = B_MULTI_INPUT_CHANNEL;
     284            data->channels[chan].designations = B_CHANNEL_STEREO_BUS
     285                | B_CHANNEL_LEFT;
     286            data->channels[chan].connectors = 0;
     287            chan++;
     288            data->channels[chan].channel_id = chan;
     289            data->channels[chan].kind = B_MULTI_INPUT_CHANNEL;
     290            data->channels[chan].designations = B_CHANNEL_STEREO_BUS
     291                | B_CHANNEL_RIGHT;
     292            data->channels[chan].connectors = 0;
     293            chan++;
     294        }
     295
     296        //The digital mixer output (it's an Input for Haiku)
     297        data->channels[chan].channel_id = chan;
     298        data->channels[chan].kind = B_MULTI_INPUT_CHANNEL;
     299        data->channels[chan].designations = B_CHANNEL_STEREO_BUS
     300            | B_CHANNEL_LEFT;
     301        data->channels[chan].connectors = 0;
     302        chan++;
     303        data->channels[chan].channel_id = chan;
     304        data->channels[chan].kind = B_MULTI_INPUT_CHANNEL;
     305        data->channels[chan].designations = B_CHANNEL_STEREO_BUS
     306            | B_CHANNEL_RIGHT;
     307        data->channels[chan].connectors = 0;
     308        chan++;
     309    }
     310
     311    ITRACE("output_channel_count = %" B_PRIi32 "\n",
     312        data->output_channel_count);
     313    ITRACE("input_channel_count = %" B_PRIi32 "\n",
     314        data->input_channel_count);
     315    ITRACE("output_bus_channel_count = %" B_PRIi32 "\n",
     316        data->output_bus_channel_count);
     317    ITRACE("input_bus_channel_count = %" B_PRIi32 "\n",
     318        data->input_bus_channel_count);
     319
     320    data->output_rates = data->input_rates = AUTHORIZED_RATE;
     321    data->min_cvsr_rate = 44100;
     322    data->max_cvsr_rate = 96000;
     323
     324    data->output_formats = data->input_formats = AUTHORIZED_SAMPLE_SIZE;
     325    data->lock_sources = B_MULTI_LOCK_INTERNAL | B_MULTI_LOCK_SPDIF;
     326    data->timecode_sources = 0;
     327    data->interface_flags = B_MULTI_INTERFACE_PLAYBACK
     328        | B_MULTI_INTERFACE_RECORD;
     329    data->start_latency = 0;
     330
     331    strcpy(data->control_panel,"");
     332
     333    return B_OK;
     334}
     335
     336
     337status_t
     338ice1712Get_Channel(ice1712 *card, multi_channel_enable *data)
     339{
     340    int i, total_channel;
     341    uint8 reg;
     342
     343    total_channel = card->total_output_channels + card->total_input_channels;
     344    for (i = 0; i < total_channel; i++)
     345        B_SET_CHANNEL(data->enable_bits, i, true);
     346
     347    reg = read_mt_uint8(card, MT_SAMPLING_RATE_SELECT);
     348
     349    if (reg == 0x10)
     350        data->lock_source = B_MULTI_LOCK_SPDIF;
     351    else
     352        data->lock_source = B_MULTI_LOCK_INTERNAL;
     353
     354    return B_OK;
     355}
     356
     357
     358status_t
     359ice1712Set_Channel(ice1712 *card, multi_channel_enable *data)
     360{
     361    int i;
     362    int total_channel;
     363
     364    total_channel = card->total_output_channels + card->total_input_channels;
     365    for (i = 0; i < total_channel; i++)
     366        ITRACE_VV("set_enabled_channels %d : %s\n", i,
     367            B_TEST_CHANNEL(data->enable_bits, i) ? "enabled": "disabled");
     368
     369    ITRACE_VV("lock_source %" B_PRIx32 "\n", data->lock_source);
     370    ITRACE_VV("lock_data %" B_PRIx32 "\n", data->lock_data);
     371
     372    if (data->lock_source == B_MULTI_LOCK_SPDIF)
     373        write_mt_uint8(card, MT_SAMPLING_RATE_SELECT, 0x10);
     374    else
     375        write_mt_uint8(card, MT_SAMPLING_RATE_SELECT,
     376            card->config.samplingRate);
     377
     378    card->config.lockSource = data->lock_source;
     379
     380    return B_OK;
     381}
     382
     383
     384status_t
     385ice1712Get_Format(ice1712 *card, multi_format_info *data)
     386{
     387    uint8 sr = read_mt_uint8(card, MT_SAMPLING_RATE_SELECT);
     388
     389    switch (sr) {
     390        case ICE1712_SAMPLERATE_48K:
     391            data->input.rate = data->output.rate = B_SR_48000;
     392            data->input.cvsr = data->output.cvsr = 48000.0f;
     393            break;
     394        case ICE1712_SAMPLERATE_96K:
     395            data->input.rate = data->output.rate = B_SR_96000;
     396            data->input.cvsr = data->output.cvsr = 96000.0f;
     397            break;
     398        case ICE1712_SAMPLERATE_44K1:
     399            data->input.rate = data->output.rate = B_SR_44100;
     400            data->input.cvsr = data->output.cvsr = 44100.0f;
     401            break;
     402        case ICE1712_SAMPLERATE_88K2:
     403            data->input.rate = data->output.rate = B_SR_88200;
     404            data->input.cvsr = data->output.cvsr = 88200.0f;
     405            break;
     406    }
     407
     408    data->timecode_kind = 0;
     409    data->output_latency = data->input_latency = 0;
     410    data->output.format = data->input.format = AUTHORIZED_SAMPLE_SIZE;
     411
     412    ITRACE("Sampling Rate = %f\n", data->input.cvsr);
     413
     414    return B_OK;
     415}
     416
     417
     418status_t
     419ice1712Set_Format(ice1712 *card, multi_format_info *data)
     420{
     421    ITRACE("Input Sampling Rate = %" B_PRIu32 "\n",
     422        data->input.rate);
     423    ITRACE("Output Sampling Rate = %" B_PRIu32 "\n",
     424        data->output.rate);
     425
     426    //We can't have a different rate for input and output
     427    //so just wait to change our sample rate when
     428    //media server will do what we need
     429    //Lie to it and say we are living in wonderland
     430    if (data->input.rate != data->output.rate)
     431        return B_OK;
     432
     433    if (card->config.lockSource == B_MULTI_LOCK_INTERNAL) {
     434        switch (data->output.rate) {
     435            case B_SR_96000:
     436                card->config.samplingRate = 0x07;
     437                break;
     438            case B_SR_88200:
     439                card->config.samplingRate = 0x0B;
     440                break;
     441            case B_SR_48000:
     442                card->config.samplingRate = 0x00;
     443                break;
     444            case B_SR_44100:
     445                card->config.samplingRate = 0x08;
     446                break;
     447        }
     448        write_mt_uint8(card, MT_SAMPLING_RATE_SELECT,
     449            card->config.samplingRate);
     450    }
     451    ITRACE("New rate = %#x\n", read_mt_uint8(card, MT_SAMPLING_RATE_SELECT));
     452
     453    return B_OK;
     454}
     455
     456//ICE1712 Multi - UI
     457//------------------
     458
     459static const char *Clock[] = {
     460    "Internal",
     461    "Digital",
     462    NULL,
     463};
     464
     465static const char *DigitalFormat[] = {
     466    "Consumer",
     467    "Professional",
     468    NULL,
     469};
     470
     471static const char *DigitalEmphasis[] = {
     472    "None",
     473    "CCITT",
     474    "15/50usec",
     475    NULL,
     476};
     477
     478static const char *DigitalCopyMode[] = {
     479    "Original",
     480    "1st Generation",
     481    "No SCMS",
     482    NULL,
     483};
     484
     485static const char **SettingsGeneral[] = {
     486    Clock,
     487    NULL,
     488};
     489
     490static const char **SettingsDigital[] = {
     491    DigitalFormat,
     492    DigitalEmphasis,
     493    DigitalCopyMode,
     494    NULL,
     495};
     496
     497static const char *string_list[] = {
     498    "Setup",
     499    "General",
     500    "Digital",
     501    "Output Selection",
     502
     503    "Internal Mixer",
     504
     505    //General settings
     506    "Master clock",
     507    "reserved_0",
     508    "reserved_1",
     509
     510    //Digital settings
     511    "Output format",
     512    "Emphasis",
     513    "Copy mode",
     514
     515    //Output Selection
     516    "Output 1", //11
     517    "Output 2",
     518    "Output 3",
     519    "Output 4",
     520    "Digital Output", //15
     521
     522    "Haiku output", //16
     523
     524    "Input 1", //17
     525    "Input 2",
     526    "Input 3",
     527    "Input 4",
     528    "Digital Input", //21
     529    "Internal mixer", //22
     530};
     531
     532
     533/*
     534 * This will create a Tab
     535 */
     536int32
     537ice1712UI_CreateGroup(multi_mix_control **p_mmc, int32 index,
     538    int32 parent, enum strind_id string, const char* name)
     539{
     540    multi_mix_control *mmc = *p_mmc;
     541    int32 group;
     542
     543    mmc->id = ICE1712_MULTI_CONTROL_FIRSTID + ICE1712_MULTI_SET_INDEX(index);
     544    mmc->parent = parent;
     545    mmc->flags = B_MULTI_MIX_GROUP;
     546    mmc->master = CONTROL_IS_MASTER;
     547    mmc->string = string;
     548
     549    group = mmc->id;
     550
     551    if (name != NULL)
     552        strcpy(mmc->name, name);
     553
     554    ITRACE_VV("Create Group: ID %#" B_PRIx32 "\n", mmc->id);
     555
     556    nb_control_created++; mmc++;
     557    (*p_mmc) = mmc;
     558
     559    return group;
     560}
     561
     562
     563/*
     564 * This will create a Slider with a "Mute" CheckBox
     565 */
     566void
     567ice1712UI_CreateChannel(multi_mix_control **p_mmc, int32 channel,
     568    int32 parent, const char* name)
     569{
     570    int32 id = ICE1712_MULTI_CONTROL_FIRSTID
     571        + ICE1712_MULTI_CONTROL_TYPE_VOLUME
     572        + ICE1712_MULTI_SET_CHANNEL(channel);
     573    multi_mix_control *mmc = *p_mmc;
     574    multi_mix_control control;
     575
     576    control.master = CONTROL_IS_MASTER;
     577    control.parent = parent;
     578    control.gain.max_gain = 0.0;
     579    control.gain.min_gain = -144.0;
     580    control.gain.granularity = 1.5;
     581
     582    //The Mute Checkbox
     583    control.id = id++;
     584    control.flags = B_MULTI_MIX_ENABLE;
     585    control.string = S_MUTE;
     586    *mmc = control;
     587    mmc++;
     588
     589    ITRACE_VV("Create Channel (Mute): ID %#" B_PRIx32 "\n", control.id);
     590
     591    //The Left Slider
     592    control.string = S_null;
     593    control.id = id++;
     594    control.flags = B_MULTI_MIX_GAIN;
     595    if (name != NULL)
     596        strcpy(control.name, name);
     597    *mmc = control;
     598    mmc++;
     599
     600    ITRACE_VV("Create Channel (Left): ID %#" B_PRIx32 "\n", control.id);
     601
     602    //The Right Slider
     603    control.master = control.id; //The Id of the Left Slider
     604    control.id = id++;
     605    *mmc = control;
     606    mmc++;
     607
     608    ITRACE_VV("Create Channel (Right): ID %#" B_PRIx32 "\n", control.id);
     609
     610    nb_control_created += 3;
     611    (*p_mmc) = mmc;
     612}
     613
     614
     615void
     616ice1712UI_CreateCombo(multi_mix_control **p_mmc, const char *values[],
     617    int32 parent, int32 nb_combo, const char *name)
     618{
     619    int32 id = ICE1712_MULTI_CONTROL_FIRSTID
     620        + ICE1712_MULTI_CONTROL_TYPE_COMBO
     621        + ICE1712_MULTI_SET_CHANNEL(nb_combo);
     622    multi_mix_control *mmc = *p_mmc;
     623    int32 parentControl, i;
     624
     625    //The label
     626    parentControl = mmc->id = id++;
     627    mmc->flags = B_MULTI_MIX_MUX;
     628    mmc->parent = parent;
     629    strcpy(mmc->name, name);
     630
     631    ITRACE_VV("Create Combo (label): ID %#" B_PRIx32 "\n", parentControl);
     632
     633    nb_control_created++; mmc++;
     634
     635    //The values
     636    for (i = 0; values[i] != NULL; i++) {
     637        mmc->id = id++;
     638        mmc->flags = B_MULTI_MIX_MUX_VALUE;
     639        mmc->parent = parentControl;
     640        strcpy(mmc->name, values[i]);
     641
     642        ITRACE_VV("Create Combo (value): ID %#" B_PRIx32 "\n", mmc->id);
     643
     644        nb_control_created++; mmc++;
     645    }
     646
     647    (*p_mmc) = mmc;
     648}
     649
     650
     651/*
     652 * This will create all possible value for the output
     653 * output 0 -> 3 (physical stereo output) 4 is the Digital
     654 */
     655void
     656ice1712UI_CreateOutput(ice1712 *card, multi_mix_control **p_mmc,
     657    int32 output, int32 parent)
     658{
     659    int32 id = ICE1712_MULTI_CONTROL_FIRSTID
     660        + ICE1712_MULTI_CONTROL_TYPE_OUTPUT
     661        + ICE1712_MULTI_SET_CHANNEL(output);
     662    multi_mix_control *mmc = *p_mmc;
     663    int32 parentControl, i;
     664
     665    //The label
     666    parentControl = mmc->id = id++;
     667    mmc->flags = B_MULTI_MIX_MUX;
     668    mmc->parent = parent;
     669    strcpy(mmc->name, string_list[11 + output]);
     670    nb_control_created++; mmc++;
     671
     672    ITRACE_VV("Create Output (label): ID %#" B_PRIx32 "\n", parentControl);
     673
     674    //Haiku output
     675    mmc->id = id++;
     676    mmc->flags = B_MULTI_MIX_MUX_VALUE;
     677    mmc->parent = parentControl;
     678    strcpy(mmc->name, string_list[16]);
     679
     680    ITRACE_VV("Create Output (Haiku): ID %#" B_PRIx32 "\n", mmc->id);
     681
     682    nb_control_created++; mmc++;
     683
     684    //Physical Input
     685    for (i = 0; i < card->config.nb_DAC; i += 2) {
     686        mmc->id = id++;
     687        mmc->flags = B_MULTI_MIX_MUX_VALUE;
     688        mmc->parent = parentControl;
     689        strcpy(mmc->name, string_list[17 + (i / 2)]);
     690
     691        ITRACE_VV("Create Output (Physical In): ID %#" B_PRIx32 "\n", mmc->id);
     692
     693        nb_control_created++; mmc++;
     694    }
     695
     696    //Physical Digital Input
     697    if (card->config.spdif & SPDIF_IN_PRESENT) {
     698        mmc->id = id++;
     699        mmc->flags = B_MULTI_MIX_MUX_VALUE;
     700        mmc->parent = parentControl;
     701        strcpy(mmc->name, string_list[21]);
     702
     703        ITRACE_VV("Create Output (Digital In) ID %#" B_PRIx32 "\n", mmc->id);
     704
     705        nb_control_created++; mmc++;
     706    }
     707
     708    //Internal mixer only for Output 1 and Digital Output
     709    if ((output == 0) || (output == 4)) {
     710        mmc->id = id++;
     711        mmc->flags = B_MULTI_MIX_MUX_VALUE;
     712        mmc->parent = parentControl;
     713        strcpy(mmc->name, string_list[22]);
     714
     715        ITRACE_VV("Create Output (Mix); ID %#" B_PRIx32 "\n", mmc->id);
     716
     717        nb_control_created++; mmc++;
     718    }
     719
     720    (*p_mmc) = mmc;
     721}
     722
     723
     724uint32
     725ice1712UI_GetCombo(ice1712 *card, uint32 index)
     726{
     727    uint32 value = 0;
     728
     729    switch (index) {
     730        case 0:
     731            value = card->settings.clock;
     732            break;
     733
     734        case 1:
     735            value = card->settings.outFormat;
     736            break;
     737
     738        case 2:
     739            value = card->settings.emphasis;
     740            break;
     741
     742        case 3:
     743            value = card->settings.copyMode;
     744            break;
     745    }
     746
     747    ITRACE_VV("Get combo: %" B_PRIu32 ", %" B_PRIu32 "\n",
     748        index, value);
     749
     750    return value;
     751}
     752
     753
     754void
     755ice1712UI_SetCombo(ice1712 *card, uint32 index, uint32 value)
     756{
     757    ITRACE_VV("Set combo: %" B_PRIu32 ", %" B_PRIu32 "\n", index, value);
     758
     759    switch (index) {
     760        case 0:
     761            if (value < 2)
     762                card->settings.clock = value;
     763            break;
     764
     765        case 1:
     766            if (value < 2)
     767                card->settings.outFormat = value;
     768            break;
     769
     770        case 2:
     771            if (value < 3)
     772                card->settings.emphasis = value;
     773            break;
     774
     775        case 3:
     776            if (value < 3)
     777                card->settings.copyMode = value;
     778            break;
     779    }
     780}
     781
     782
     783uint32
     784ice1712UI_GetOutput(ice1712 *card, uint32 index)
     785{
     786    uint32 value = 0;
     787
     788    if (index < 5)
     789        value = card->settings.output[index];
     790
     791    ITRACE_VV("Get output: %" B_PRIu32 ", %" B_PRIu32 "\n", index, value);
     792
     793    return value;
     794}
     795
     796
     797void
     798ice1712UI_SetOutput(ice1712 *card, uint32 index, uint32 value)
     799{
     800    if (index < 5)
     801        card->settings.output[index] = value;
     802
     803    ITRACE_VV("Set output: %" B_PRIu32 ", %" B_PRIu32 "\n", index, value);
     804}
     805
     806
     807void
     808ice1712UI_GetVolume(ice1712 *card, multi_mix_value *mmv)
     809{
     810    ice1712Volume *vol;
     811    uint32 chan = ICE1712_MULTI_GET_CHANNEL(mmv->id);
     812
     813    ITRACE_VV("Get volume\n");
     814
     815    if (chan < ICE1712_HARDWARE_VOLUME) {
     816        vol = card->settings.playback;
     817    } else {
     818        vol = card->settings.record;
     819        chan -= ICE1712_HARDWARE_VOLUME;
     820    }
     821
     822    //chan is normaly <= ICE1712_HARDWARE_VOLUME
     823    switch (ICE1712_MULTI_GET_INDEX(mmv->id)) {
     824        case 0: //Mute
     825            mmv->enable = vol[chan].mute | vol[chan + 1].mute;
     826            ITRACE_VV(" Get mute %d for channel %d or %d\n",
     827                mmv->enable, (int)chan, (int)chan + 1);
     828            break;
     829
     830        case 2: //Right channel
     831            chan++;
     832            //No break
     833        case 1: //Left channel
     834            mmv->gain = vol[chan].volume;
     835            ITRACE_VV(" Get Volume %f for channel %d\n",
     836                mmv->gain, (int)chan);
     837            break;
     838    }
     839}
     840
     841
     842void
     843ice1712UI_SetVolume(ice1712 *card, multi_mix_value *mmv)
     844{
     845    ice1712Volume *vol;
     846    uint32 chan = ICE1712_MULTI_GET_CHANNEL(mmv->id);
     847
     848    ITRACE_VV("Set volume\n");
     849
     850    if (chan < ICE1712_HARDWARE_VOLUME) {
     851        vol = card->settings.playback;
     852    } else {
     853        vol = card->settings.record;
     854        chan -= ICE1712_HARDWARE_VOLUME;
     855    }
     856
     857    //chan is normaly <= ICE1712_HARDWARE_VOLUME
     858    switch (ICE1712_MULTI_GET_INDEX(mmv->id)) {
     859        case 0: //Mute
     860            vol[chan].mute = mmv->enable;
     861            vol[chan + 1].mute = mmv->enable;
     862            ITRACE_VV(" Change mute to %d for channel %d and %d\n",
     863                mmv->enable, (int)chan, (int)chan + 1);
     864            break;
     865
     866        case 2: //Right channel
     867            chan++;
     868            //No break
     869        case 1: //Left channel
     870            vol[chan].volume = mmv->gain;
     871            ITRACE_VV(" Change Volume to %f for channel %d\n",
     872                mmv->gain, (int)chan);
     873            break;
     874    }
     875}
     876
     877//ICE1712 Multi - MIX
     878//-------------------
     879
     880status_t
     881ice1712Get_MixValue(ice1712 *card, multi_mix_value_info *data)
     882{
     883    int i;
     884
     885    for (i = 0; i < data->item_count; i++) {
     886        multi_mix_value *mmv = &(data->values[i]);
     887        ITRACE_VV("Get Mix: Id %" B_PRIu32 "\n", mmv->id);
     888        switch (mmv->id & ICE1712_MULTI_CONTROL_TYPE_MASK) {
     889            case ICE1712_MULTI_CONTROL_TYPE_COMBO:
     890                mmv->mux = ice1712UI_GetCombo(card,
     891                    ICE1712_MULTI_GET_CHANNEL(mmv->id));
     892                break;
     893
     894            case ICE1712_MULTI_CONTROL_TYPE_VOLUME:
     895                ice1712UI_GetVolume(card, mmv);
     896                break;
     897
     898            case ICE1712_MULTI_CONTROL_TYPE_OUTPUT:
     899                mmv->mux = ice1712UI_GetOutput(card,
     900                    ICE1712_MULTI_GET_CHANNEL(mmv->id));
     901                break;
     902
     903            default:
     904                ITRACE_VV("Get Mix: unknow %" B_PRIu32 "\n", mmv->id);
     905                break;
     906        }
     907    }
     908
     909    return B_OK;
     910}
     911
     912
     913status_t
     914ice1712Set_MixValue(ice1712 *card, multi_mix_value_info *data)
     915{
     916    int i;
     917
     918    for (i = 0; i < data->item_count; i++) {
     919        multi_mix_value *mmv = &(data->values[i]);
     920        ITRACE_VV("Set Mix: Id %" B_PRIu32 "\n", mmv->id);
     921        switch (mmv->id & ICE1712_MULTI_CONTROL_TYPE_MASK) {
     922            case ICE1712_MULTI_CONTROL_TYPE_COMBO:
     923                ice1712UI_SetCombo(card,
     924                    ICE1712_MULTI_GET_CHANNEL(mmv->id), mmv->mux);
     925                break;
     926
     927            case ICE1712_MULTI_CONTROL_TYPE_VOLUME:
     928                ice1712UI_SetVolume(card, mmv);
     929                break;
     930
     931            case ICE1712_MULTI_CONTROL_TYPE_OUTPUT:
     932                ice1712UI_SetOutput(card,
     933                    ICE1712_MULTI_GET_CHANNEL(mmv->id), mmv->mux);
     934                break;
     935
     936            default:
     937                ITRACE_VV("Set Mix: unknow %" B_PRIu32 "\n", mmv->id);
     938                break;
     939        }
     940    }
     941
     942    return ice1712Settings_apply(card);
     943}
     944
     945
     946/*
     947 * Not implemented
     948 */
     949status_t
     950ice1712Get_MixValueChannel(ice1712 *card, multi_mix_channel_info *data)
     951{
     952    return B_OK;
     953}
     954
     955
     956status_t
     957ice1712Get_MixValueControls(ice1712 *card, multi_mix_control_info *mmci)
     958{
     959    int32 i;
     960    uint32 parentTab, parentTabColumn;
     961    multi_mix_control *mmc = mmci->controls;
     962    uint32 group = 0, combo = 0, channel = 0;
     963
     964    nb_control_created = 0;
     965
     966    ITRACE_VV("Get MixValue Channels: Max %" B_PRIi32 "\n", mmci->control_count);
     967
     968    //Cleaning
     969    memset(mmc, 0, mmci->control_count * sizeof(multi_mix_control));
     970
     971    //Setup tab
     972    parentTab = ice1712UI_CreateGroup(&mmc, group++,
     973        CONTROL_IS_MASTER, S_SETUP, NULL);
     974
     975    //General Settings
     976    parentTabColumn = ice1712UI_CreateGroup(&mmc, group++, parentTab,
     977        S_null, string_list[1]);
     978    for (i = 0; SettingsGeneral[i] != NULL; i++) {
     979        ice1712UI_CreateCombo(&mmc, SettingsGeneral[i], parentTabColumn,
     980            combo++, string_list[5 + i]);
     981    }
     982
     983    //Digital Settings
     984    parentTabColumn = ice1712UI_CreateGroup(&mmc, group++, parentTab,
     985        S_null, string_list[2]);
     986    for (i = 0; SettingsDigital[i] != NULL; i++) {
     987        ice1712UI_CreateCombo(&mmc, SettingsDigital[i], parentTabColumn,
     988            combo++, string_list[8 + i]);
     989    }
     990
     991    //Output Selection Settings
     992    parentTabColumn = ice1712UI_CreateGroup(&mmc, group++, parentTab,
     993        S_null, string_list[3]);
     994    for (i = 0; i < card->config.nb_DAC; i += 2) {
     995        ice1712UI_CreateOutput(card, &mmc, i / 2, parentTabColumn);
     996    }
     997
     998    if (card->config.spdif & SPDIF_OUT_PRESENT) {
     999        ice1712UI_CreateOutput(card, &mmc, 4, parentTabColumn);
     1000    }
     1001
     1002    //Internal Mixer Tab
     1003    //Output
     1004    parentTab = ice1712UI_CreateGroup(&mmc, group++, CONTROL_IS_MASTER,
     1005        S_null, string_list[4]);
     1006
     1007    for (i = 0; i < card->config.nb_DAC; i += 2) {
     1008        parentTabColumn = ice1712UI_CreateGroup(&mmc, group++,
     1009            parentTab, S_null, string_list[(i / 2) + 11]);
     1010        ice1712UI_CreateChannel(&mmc, channel++, parentTabColumn, NULL);
     1011    }
     1012
     1013    if (card->config.spdif & SPDIF_OUT_PRESENT) {
     1014        parentTabColumn = ice1712UI_CreateGroup(&mmc, group++,
     1015            parentTab, S_null, string_list[15]);
     1016        ice1712UI_CreateChannel(&mmc, ICE1712_HARDWARE_VOLUME - 2,
     1017            parentTabColumn, NULL);
     1018    }
     1019
     1020    //Input
     1021    channel = ICE1712_HARDWARE_VOLUME;
     1022    for (i = 0; i < card->config.nb_ADC; i += 2) {
     1023        parentTabColumn = ice1712UI_CreateGroup(&mmc, group++,
     1024            parentTab, S_null, string_list[(i / 2) + 17]);
     1025        ice1712UI_CreateChannel(&mmc, channel++, parentTabColumn, NULL);
     1026    }
     1027
     1028    if (card->config.spdif & SPDIF_IN_PRESENT) {
     1029        parentTabColumn = ice1712UI_CreateGroup(&mmc, group++,
     1030            parentTab, S_null, string_list[21]);
     1031        ice1712UI_CreateChannel(&mmc, 2 * ICE1712_HARDWARE_VOLUME - 2,
     1032            parentTabColumn, NULL);
     1033    }
     1034
     1035    mmci->control_count = nb_control_created;
     1036    ITRACE_VV("Get MixValue Channels: Returned %" B_PRIi32 "\n",
     1037        mmci->control_count);
     1038
     1039    return B_OK;
     1040}
     1041
     1042
     1043/*
     1044 * Not implemented
     1045 */
     1046status_t
     1047ice1712Get_MixValueConnections(ice1712 *card,
     1048    multi_mix_connection_info *data)
     1049{
     1050    data->actual_count = 0;
     1051    return B_OK;
     1052}
     1053
     1054
     1055status_t
     1056ice1712Buffer_Get(ice1712 *card, multi_buffer_list *data)
     1057{
     1058    const size_t stride_o = MAX_DAC * SAMPLE_SIZE;
     1059    const size_t stride_i = MAX_ADC * SAMPLE_SIZE;
     1060    const uint32 buf_o = stride_o * card->buffer_size;
     1061    const uint32 buf_i = stride_i * card->buffer_size;
     1062    int buff, chan_i = 0, chan_o = 0;
     1063
     1064    ITRACE_VV("flags = %#" B_PRIx32 "\n", data->flags);
     1065    ITRACE_VV("request_playback_buffers = %" B_PRIu32 "\n",
     1066            data->request_playback_buffers);
     1067    ITRACE_VV("request_playback_channels = %" B_PRIu32 "\n",
     1068            data->request_playback_channels);
     1069    ITRACE_VV("request_playback_buffer_size = %" B_PRIx32 "\n",
     1070            data->request_playback_buffer_size);
     1071    ITRACE_VV("request_record_buffers = %" B_PRIu32 "\n",
     1072            data->request_record_buffers);
     1073    ITRACE_VV("request_record_channels = %" B_PRIu32 "\n",
     1074            data->request_record_channels);
     1075    ITRACE_VV("request_record_buffer_size = %" B_PRIx32 "\n",
     1076            data->request_record_buffer_size);
     1077
     1078    for (buff = 0; buff < SWAPPING_BUFFERS; buff++) {
     1079        if (data->request_playback_channels == card->total_output_channels) {
     1080            for (chan_o = 0; chan_o < card->config.nb_DAC; chan_o++) {
     1081            //Analog STEREO output
     1082                data->playback_buffers[buff][chan_o].base =
     1083                    (char*)(card->log_addr_pb + buf_o * buff
     1084                        + SAMPLE_SIZE * chan_o);
     1085                data->playback_buffers[buff][chan_o].stride = stride_o;
     1086                ITRACE_VV("pb_buffer[%d][%d] = %p\n", buff, chan_o,
     1087                    data->playback_buffers[buff][chan_o].base);
     1088            }
     1089
     1090            if (card->config.spdif & SPDIF_OUT_PRESENT) {
     1091            //SPDIF STEREO output
     1092                data->playback_buffers[buff][chan_o].base =
     1093                    (char*)(card->log_addr_pb + buf_o * buff
     1094                        + SAMPLE_SIZE * SPDIF_LEFT);
     1095                data->playback_buffers[buff][chan_o].stride = stride_o;
     1096                ITRACE_VV("pb_buffer[%d][%d] = %p\n", buff, chan_o,
     1097                    data->playback_buffers[buff][chan_o].base);
     1098
     1099                chan_o++;
     1100                data->playback_buffers[buff][chan_o].base =
     1101                    (char*)(card->log_addr_pb + buf_o * buff
     1102                        + SAMPLE_SIZE * SPDIF_RIGHT);
     1103                data->playback_buffers[buff][chan_o].stride = stride_o;
     1104                ITRACE_VV("pb_buffer[%d][%d] = %p\n", buff, chan_o,
     1105                    data->playback_buffers[buff][chan_o].base);
     1106                chan_o++;
     1107            }
     1108        }
     1109
     1110        if (data->request_record_channels ==
     1111            card->total_input_channels) {
     1112            for (chan_i = 0; chan_i < card->config.nb_ADC; chan_i++) {
     1113            //Analog STEREO input
     1114                data->record_buffers[buff][chan_i].base =
     1115                    (char*)(card->log_addr_rec + buf_i * buff
     1116                        + SAMPLE_SIZE * chan_i);
     1117                data->record_buffers[buff][chan_i].stride = stride_i;
     1118                ITRACE_VV("rec_buffer[%d][%d] = %p\n", buff, chan_i,
     1119                    data->record_buffers[buff][chan_i].base);
     1120            }
     1121
     1122            if (card->config.spdif & SPDIF_IN_PRESENT) {
     1123            //SPDIF STEREO input
     1124                data->record_buffers[buff][chan_i].base =
     1125                    (char*)(card->log_addr_rec + buf_i * buff
     1126                        + SAMPLE_SIZE * SPDIF_LEFT);
     1127                data->record_buffers[buff][chan_i].stride = stride_i;
     1128                ITRACE_VV("rec_buffer[%d][%d] = %p\n", buff, chan_i,
     1129                    data->record_buffers[buff][chan_i].base);
     1130
     1131                chan_i++;
     1132                data->record_buffers[buff][chan_i].base =
     1133                    (char*)(card->log_addr_rec + buf_i * buff
     1134                        + SAMPLE_SIZE * SPDIF_RIGHT);
     1135                data->record_buffers[buff][chan_i].stride = stride_i;
     1136                ITRACE_VV("rec_buffer[%d][%d] = %p\n", buff, chan_i,
     1137                    data->record_buffers[buff][chan_i].base);
     1138                chan_i++;
     1139            }
     1140
     1141            //The digital mixer output
     1142            data->record_buffers[buff][chan_i].base =
     1143                (char*)(card->log_addr_rec + buf_i * buff
     1144                    + SAMPLE_SIZE * MIXER_OUT_LEFT);
     1145            data->record_buffers[buff][chan_i].stride = stride_i;
     1146            ITRACE_VV("rec_buffer[%d][%d] = %p\n", buff, chan_i,
     1147                    data->record_buffers[buff][chan_i].base);
     1148
     1149            chan_i++;
     1150            data->record_buffers[buff][chan_i].base =
     1151                (char*)(card->log_addr_rec + buf_i * buff
     1152                    + SAMPLE_SIZE * MIXER_OUT_RIGHT);
     1153            data->record_buffers[buff][chan_i].stride = stride_i;
     1154            ITRACE_VV("rec_buffer[%d][%d] = %p\n", buff, chan_i,
     1155                    data->record_buffers[buff][chan_i].base);
     1156            chan_i++;
     1157        }
     1158    }
     1159
     1160    data->return_playback_buffers = SWAPPING_BUFFERS;
     1161    data->return_playback_channels = card->total_output_channels;
     1162    data->return_playback_buffer_size = card->buffer_size;
     1163
     1164    ITRACE("return_playback_buffers = %" B_PRIi32 "\n",
     1165        data->return_playback_buffers);
     1166    ITRACE("return_playback_channels = %" B_PRIi32 "\n",
     1167        data->return_playback_channels);
     1168    ITRACE("return_playback_buffer_size = %" B_PRIu32 "\n",
     1169        data->return_playback_buffer_size);
     1170
     1171    data->return_record_buffers = SWAPPING_BUFFERS;
     1172    data->return_record_channels = card->total_input_channels;
     1173    data->return_record_channels = chan_i;
     1174    data->return_record_buffer_size = card->buffer_size;
     1175
     1176    ITRACE("return_record_buffers = %" B_PRIi32 "\n",
     1177        data->return_record_buffers);
     1178    ITRACE("return_record_channels = %" B_PRIi32 "\n",
     1179        data->return_record_channels);
     1180    ITRACE("return_record_buffer_size = %" B_PRIu32 "\n",
     1181        data->return_record_buffer_size);
     1182
     1183    ice1712Buffer_Start(card);
     1184
     1185    return B_OK;
     1186}
  • src/add-ons/kernel/drivers/audio/ice1712/multi.h

    diff --git a/src/add-ons/kernel/drivers/audio/ice1712/multi.h b/src/add-ons/kernel/drivers/audio/ice1712/multi.h
    index df20361..89ba947 100644
    a b  
    11/*
    2  * ice1712 BeOS/Haiku Driver for VIA - VT1712 Multi Channel Audio Controller
     2 * Copyright 2004-2015 Haiku, Inc. All rights reserved.
     3 * Distributed under the terms of the MIT License.
    34 *
    4  * Copyright (c) 2002, Jerome Duval     (jerome.duval@free.fr)
    5  * Copyright (c) 2003, Marcus Overhagen (marcus@overhagen.de)
    6  * Copyright (c) 2007, Jerome Leveque   (leveque.jerome@neuf.fr)
    7  *
    8  * All rights reserved
    9  * Distributed under the terms of the MIT license.
     5 * Authors:
     6 *      Jérôme Duval, jerome.duval@free.fr
     7 *      Marcus Overhagen, marcus@overhagen.de
     8 *      Jérôme Lévêque, leveque.jerome@gmail.com
    109 */
    1110
     11
    1212#ifndef _ICE1712_MULTI_H_
    1313#define _ICE1712_MULTI_H_
    1414
     
    3030#define ICE1712_MULTI_CONTROL_CHANNEL_MASK  (0x0FF00000)
    3131#define ICE1712_MULTI_CONTROL_INDEX_MASK    (0x00000FFF)
    3232
    33 #define ICE1712_MULTI_SET_CHANNEL(_c_)      ((_c_ << 20) & \
     33#define ICE1712_MULTI_SET_CHANNEL(_c_)      ((_c_ << 20) & \
    3434    ICE1712_MULTI_CONTROL_CHANNEL_MASK)
    35 #define ICE1712_MULTI_GET_CHANNEL(_c_)      ((_c_ & \
     35#define ICE1712_MULTI_GET_CHANNEL(_c_)      ((_c_ & \
    3636    ICE1712_MULTI_CONTROL_CHANNEL_MASK) >> 20)
    3737
    38 #define ICE1712_MULTI_SET_INDEX(_i_)        (_i_ & \
     38#define ICE1712_MULTI_SET_INDEX(_i_)        (_i_ & \
    3939    ICE1712_MULTI_CONTROL_INDEX_MASK)
    40 #define ICE1712_MULTI_GET_INDEX(_i_)        (_i_ & \
     40#define ICE1712_MULTI_GET_INDEX(_i_)        (_i_ & \
    4141    ICE1712_MULTI_CONTROL_INDEX_MASK)
    4242
    4343/*
     
    5151
    5252#define CONTROL_IS_MASTER (0)
    5353
    54 status_t ice1712_get_description(ice1712 *card, multi_description *data);
    55 status_t ice1712_get_enabled_channels(ice1712 *card,
    56             multi_channel_enable *data);
    57 status_t ice1712_set_enabled_channels(ice1712 *card,
    58             multi_channel_enable *data);
    59 status_t ice1712_get_global_format(ice1712 *card, multi_format_info *data);
    60 status_t ice1712_set_global_format(ice1712 *card, multi_format_info *data);
    61 status_t ice1712_get_mix(ice1712 *card, multi_mix_value_info *data);
    62 status_t ice1712_set_mix(ice1712 *card, multi_mix_value_info *data);
    63 status_t ice1712_list_mix_channels(ice1712 *card,
    64             multi_mix_channel_info *data);
    65 status_t ice1712_list_mix_controls(ice1712 *card,
    66             multi_mix_control_info *data);
    67 status_t ice1712_list_mix_connections(ice1712 *card,
    68             multi_mix_connection_info *data);
    69 status_t ice1712_get_buffers(ice1712 *card, multi_buffer_list *data);
    70 status_t ice1712_buffer_exchange(ice1712 *card, multi_buffer_info *data);
    71 status_t ice1712_buffer_force_stop(ice1712 *card);
    72 
     54status_t ice1712Get_Description(ice1712 *card, multi_description *data);
     55status_t ice1712Get_Channel(ice1712 *card, multi_channel_enable *data);
     56status_t ice1712Set_Channel(ice1712 *card, multi_channel_enable *data);
     57status_t ice1712Get_Format(ice1712 *card, multi_format_info *data);
     58status_t ice1712Set_Format(ice1712 *card, multi_format_info *data);
     59status_t ice1712Get_MixValue(ice1712 *card, multi_mix_value_info *data);
     60status_t ice1712Set_MixValue(ice1712 *card, multi_mix_value_info *data);
     61status_t ice1712Get_MixValueChannel(ice1712 *card,
     62    multi_mix_channel_info *data);
     63status_t ice1712Get_MixValueControls(ice1712 *card,
     64    multi_mix_control_info *data);
     65status_t ice1712Get_MixValueConnections(ice1712 *card,
     66    multi_mix_connection_info *data);
     67status_t ice1712Buffer_Get(ice1712 *card, multi_buffer_list *data);
     68status_t ice1712Buffer_Exchange(ice1712 *card, multi_buffer_info *data);
     69status_t ice1712Buffer_Stop(ice1712 *card);
    7370
    7471#endif //_ICE1712_MULTI_H_
    7572
  • deleted file src/add-ons/kernel/drivers/audio/ice1712/util.c

    diff --git a/src/add-ons/kernel/drivers/audio/ice1712/util.c b/src/add-ons/kernel/drivers/audio/ice1712/util.c
    deleted file mode 100644
    index 2feea67..0000000
    + -  
    1 /*
    2  * ice1712 BeOS/Haiku Driver for VIA - VT1712 Multi Channel Audio Controller
    3  *
    4  * Copyright (c) 2002, Jerome Duval     (jerome.duval@free.fr)
    5  * Copyright (c) 2003, Marcus Overhagen (marcus@overhagen.de)
    6  * Copyright (c) 2007, Jerome Leveque   (leveque.jerome@neuf.fr)
    7  *
    8  * All rights reserved
    9  * Distributed under the terms of the MIT license.
    10  */
    11 
    12 #include <Errors.h>
    13 #include <OS.h>
    14 #include <string.h>
    15 
    16 #include "debug.h"
    17 #include "util.h"
    18 
    19 spinlock slock = B_SPINLOCK_INITIALIZER;
    20 
    21 uint32 round_to_pagesize(uint32 size);
    22 
    23 
    24 cpu_status
    25 lock(void)
    26 {
    27     cpu_status status = disable_interrupts();
    28     acquire_spinlock(&slock);
    29     return status;
    30 }
    31 
    32 
    33 void
    34 unlock(cpu_status status)
    35 {
    36     release_spinlock(&slock);
    37     restore_interrupts(status);
    38 }
    39 
    40 
    41 uint32
    42 round_to_pagesize(uint32 size)
    43 {
    44     return (size + B_PAGE_SIZE - 1) & ~(B_PAGE_SIZE - 1);
    45 }
    46 
    47 
    48 area_id
    49 alloc_mem(void **phy, void **log, size_t size, const char *name)
    50 {
    51 // TODO: phy should be phys_addr_t*!
    52     physical_entry pe;
    53     void * logadr;
    54     area_id areaid;
    55     status_t rv;
    56 
    57     TRACE("allocating %#08X bytes for %s\n", (int)size, name);
    58 
    59     size = round_to_pagesize(size);
    60     areaid = create_area(name, &logadr, B_ANY_KERNEL_ADDRESS, size,
    61         B_32_BIT_CONTIGUOUS, B_READ_AREA | B_WRITE_AREA);
    62         // TODO: The rest of the code doesn't deal correctly with physical
    63         // addresses > 4 GB, so we have to force 32 bit addresses here.
    64     if (areaid < B_OK) {
    65         TRACE("couldn't allocate area %s\n",name);
    66         return B_ERROR;
    67     }
    68     rv = get_memory_map(logadr,size,&pe,1);
    69     if (rv < B_OK) {
    70         delete_area(areaid);
    71         TRACE("couldn't map %s\n",name);
    72         return B_ERROR;
    73     }
    74     memset(logadr,0,size);
    75     if (log)
    76         *log = logadr;
    77     if (phy)
    78         *phy = (void*)(addr_t)pe.address;
    79     TRACE("area = %d, size = %#08X, log = %#08X, phy = %#08X\n",
    80         (int)areaid, (int)size, (int)logadr, (int)pe.address);
    81     return areaid;
    82 }
    83 
  • new file src/add-ons/kernel/drivers/audio/ice1712/util.cpp

    diff --git a/src/add-ons/kernel/drivers/audio/ice1712/util.cpp b/src/add-ons/kernel/drivers/audio/ice1712/util.cpp
    new file mode 100644
    index 0000000..01a172e
    - +  
     1/*
     2 * Copyright 2004-2015 Haiku, Inc. All rights reserved.
     3 * Distributed under the terms of the MIT License.
     4 *
     5 * Authors:
     6 *      Jérôme Duval, jerome.duval@free.fr
     7 *      Marcus Overhagen, marcus@overhagen.de
     8 *      Jérôme Lévêque, leveque.jerome@gmail.com
     9 */
     10
     11#include <Errors.h>
     12#include <OS.h>
     13#include <string.h>
     14
     15#include "debug.h"
     16#include "util.h"
     17
     18static spinlock slock = B_SPINLOCK_INITIALIZER;
     19static uint32 round_to_pagesize(uint32 size);
     20
     21cpu_status
     22lock(void)
     23{
     24    cpu_status status = disable_interrupts();
     25    acquire_spinlock(&slock);
     26    return status;
     27}
     28
     29
     30void
     31unlock(cpu_status status)
     32{
     33    release_spinlock(&slock);
     34    restore_interrupts(status);
     35}
     36
     37
     38uint32
     39round_to_pagesize(uint32 size)
     40{
     41    return (size + B_PAGE_SIZE - 1) & ~(B_PAGE_SIZE - 1);
     42}
     43
     44
     45area_id
     46alloc_mem(physical_entry *phy, addr_t *log, size_t size, const char *name)
     47{
     48    void * logadr;
     49    area_id areaid;
     50    status_t rv;
     51
     52    ITRACE("Allocating %s: ", name);
     53
     54    size = round_to_pagesize(size);
     55    areaid = create_area(name, &logadr, B_ANY_KERNEL_ADDRESS, size,
     56        B_32_BIT_CONTIGUOUS, B_READ_AREA | B_WRITE_AREA);
     57        // TODO: The rest of the code doesn't deal correctly with physical
     58        // addresses > 4 GB, so we have to force 32 bit addresses here.
     59    if (areaid < B_OK) {
     60        ITRACE("couldn't allocate\n");
     61        return B_ERROR;
     62    }
     63    rv = get_memory_map(logadr, size, phy, 1);
     64    if (rv < B_OK) {
     65        delete_area(areaid);
     66        ITRACE("couldn't map\n");
     67        return B_ERROR;
     68    }
     69
     70    if (log)
     71        *log = (addr_t)logadr;
     72
     73    ITRACE("area = %" B_PRId32 ", size = %" B_PRIuSIZE ", log = 0x%" \
     74        B_PRIXADDR ", phy = 0x%" B_PRIXPHYSADDR "\n", areaid, size,
     75        *log, phy->address);
     76
     77    return areaid;
     78}
     79
  • src/add-ons/kernel/drivers/audio/ice1712/util.h

    diff --git a/src/add-ons/kernel/drivers/audio/ice1712/util.h b/src/add-ons/kernel/drivers/audio/ice1712/util.h
    index b25997e..ef69e7f 100644
    a b  
    11/*
    2  * ice1712 BeOS/Haiku Driver for VIA - VT1712 Multi Channel Audio Controller
     2 * Copyright 2004-2015 Haiku, Inc. All rights reserved.
     3 * Distributed under the terms of the MIT License.
    34 *
    4  * Copyright (c) 2002, Jerome Duval     (jerome.duval@free.fr)
    5  * Copyright (c) 2003, Marcus Overhagen (marcus@overhagen.de)
    6  * Copyright (c) 2007, Jerome Leveque   (leveque.jerome@neuf.fr)
    7  *
    8  * All rights reserved
    9  * Distributed under the terms of the MIT license.
     5 * Authors:
     6 *      Jérôme Duval, jerome.duval@free.fr
     7 *      Marcus Overhagen, marcus@overhagen.de
     8 *      Jérôme Lévêque, leveque.jerome@gmail.com
    109 */
    1110
     11
    1212#ifndef _UTIL_H_
    1313#define _UTIL_H_
    1414
    15 #include <KernelExport.h>
    16 
    17 area_id alloc_mem(void **phy, void **log, size_t size, const char *name);
    18 
     15area_id alloc_mem(physical_entry *phy, addr_t *log, size_t size,
     16    const char *name);
    1917cpu_status lock(void);
    2018void unlock(cpu_status status);
    2119