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 28 static status_t ice1712Settings_load(ice1712 *card); 29 status_t ice1712Settings_apply(ice1712 *card); 30 static int32 ice1712HW_interrupt(void *arg); 31 static status_t ice1712HW_setup(ice1712 *ice); 32 static void ice1712HW_shutdown(ice1712 *ice); 33 34 extern device_hooks ice1712Midi_hooks; 35 extern device_hooks ice1712Audio_hooks; 36 void ice1712Midi_interrupt(int32 op, void *data); 37 38 pci_module_info *pci; 39 generic_mpu401_module *mpu401; 40 41 int32 num_cards = 0; 42 ice1712 cards[NUM_CARDS]; 43 44 //3 interfaces (2 midi + 1 audio) can be defined for each card 45 static char *names[NUM_CARDS*3+1]; 46 static int32 num_names = 0; 47 48 #define HMULTI_AUDIO_DEV_PATH "audio/hmulti/ice1712" 49 50 //Haiku Driver API 51 //---------------- 52 53 int32 api_version = B_CUR_DRIVER_API_VERSION; 54 55 extern "C" status_t 56 init_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 81 extern "C" status_t 82 init_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 145 extern "C" void 146 uninit_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 166 extern "C" const char ** 167 publish_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 179 extern "C" device_hooks * 180 find_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 204 int32 205 ice1712HW_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 262 status_t 263 ice1712HW_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 494 void 495 ice1712HW_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 513 static status_t 514 ice1712Audio_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 538 static status_t 539 ice1712Audio_close(void *cookie) 540 { 541 ITRACE("** close()\n"); 542 return B_OK; 543 } 544 545 546 static status_t 547 ice1712Audio_free(void *cookie) 548 { 549 ITRACE("** free()\n"); 550 return B_OK; 551 } 552 553 554 static status_t 555 ice1712Audio_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 656 static status_t 657 ice1712Audio_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 666 static status_t 667 ice1712Audio_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 676 device_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 695 status_t 696 ice1712Settings_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 726 status_t 727 ice1712Settings_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 } 830