1 /* 2 * ES1370 Haiku Driver for ES1370 audio 3 * 4 * Copyright 2002-2007, Haiku, Inc. 5 * Distributed under the terms of the MIT License. 6 * 7 * Authors: 8 * Jerome Duval, jerome.duval@free.fr 9 */ 10 11 #include <KernelExport.h> 12 #include <PCI.h> 13 #include <driver_settings.h> 14 #include <stdio.h> 15 #include <stdlib.h> 16 #include <string.h> 17 #include "es1370.h" 18 #include "debug.h" 19 #include "config.h" 20 #include "util.h" 21 #include "io.h" 22 #include <fcntl.h> 23 #include <unistd.h> 24 #include <malloc.h> 25 26 status_t init_hardware(void); 27 status_t init_driver(void); 28 void uninit_driver(void); 29 const char ** publish_devices(void); 30 device_hooks * find_device(const char *); 31 status_t es1370_init(es1370_dev * card); 32 33 static char pci_name[] = B_PCI_MODULE_NAME; 34 pci_module_info *pci; 35 36 int32 num_cards; 37 es1370_dev cards[NUM_CARDS]; 38 int32 num_names; 39 char * names[NUM_CARDS*20+1]; 40 41 extern device_hooks multi_hooks; 42 43 es1370_settings current_settings = { 44 44100, // sample rate 45 512, // buffer frames 46 2, // buffer count 47 }; 48 49 50 /* es1370 Memory management */ 51 52 static es1370_mem * 53 es1370_mem_new(es1370_dev *card, size_t size) 54 { 55 es1370_mem *mem; 56 57 if ((mem = malloc(sizeof(*mem))) == NULL) 58 return (NULL); 59 60 mem->area = alloc_mem(&mem->phy_base, &mem->log_base, size, "es1370 buffer", true); 61 mem->size = size; 62 if (mem->area < B_OK) { 63 free(mem); 64 return NULL; 65 } 66 return mem; 67 } 68 69 static void 70 es1370_mem_delete(es1370_mem *mem) 71 { 72 if(mem->area > B_OK) 73 delete_area(mem->area); 74 free(mem); 75 } 76 77 static void * 78 es1370_mem_alloc(es1370_dev *card, size_t size) 79 { 80 es1370_mem *mem; 81 82 mem = es1370_mem_new(card, size); 83 if (mem == NULL) 84 return (NULL); 85 86 LIST_INSERT_HEAD(&(card->mems), mem, next); 87 88 return mem; 89 } 90 91 static void 92 es1370_mem_free(es1370_dev *card, void *ptr) 93 { 94 es1370_mem *mem; 95 96 LIST_FOREACH(mem, &card->mems, next) { 97 if (mem->log_base != ptr) 98 continue; 99 LIST_REMOVE(mem, next); 100 101 es1370_mem_delete(mem); 102 break; 103 } 104 } 105 106 /* es1370 stream functions */ 107 108 status_t 109 es1370_stream_set_audioparms(es1370_stream *stream, uint8 channels, 110 uint8 b16, uint32 sample_rate) 111 { 112 uint8 sample_size, frame_size; 113 LOG(("es1370_stream_set_audioparms\n")); 114 115 if ((stream->channels == channels) && 116 (stream->b16 == b16) && 117 (stream->sample_rate == sample_rate)) 118 return B_OK; 119 120 if(stream->buffer) 121 es1370_mem_free(stream->card, stream->buffer->log_base); 122 123 stream->b16 = b16; 124 stream->sample_rate = sample_rate; 125 stream->channels = channels; 126 127 sample_size = stream->b16 + 1; 128 frame_size = sample_size * stream->channels; 129 130 stream->buffer = es1370_mem_alloc(stream->card, stream->bufframes * frame_size * stream->bufcount); 131 132 stream->trigblk = 0; /* This shouldn't be needed */ 133 stream->blkmod = stream->bufcount; 134 stream->blksize = stream->bufframes * frame_size; 135 136 return B_OK; 137 } 138 139 status_t 140 es1370_stream_commit_parms(es1370_stream *stream) 141 { 142 uint8 sample_size, frame_size; 143 uint32 ctrl; 144 es1370_dev *card = stream->card; 145 LOG(("es1370_stream_commit_parms\n")); 146 147 ctrl = es1370_reg_read_32(&card->config, ES1370_REG_CONTROL) & ~CTRL_PCLKDIV; 148 ctrl |= DAC2_SRTODIV((uint16)stream->sample_rate) << CTRL_SH_PCLKDIV; 149 es1370_reg_write_32(&card->config, ES1370_REG_CONTROL, ctrl); 150 151 sample_size = stream->b16 + 1; 152 frame_size = sample_size * stream->channels; 153 154 if (stream->use & ES1370_USE_RECORD) { 155 es1370_reg_write_32(&card->config, ES1370_REG_MEMPAGE, 0xd); 156 es1370_reg_write_32(&card->config, ES1370_REG_ADC_FRAMEADR & 0xff, (uint32)stream->buffer->phy_base); 157 es1370_reg_write_32(&card->config, ES1370_REG_ADC_FRAMECNT & 0xff, ((stream->blksize * stream->bufcount) >> 2) - 1); 158 es1370_reg_write_32(&card->config, ES1370_REG_ADC_SCOUNT & 0xff, stream->bufframes - 1); 159 } else { 160 es1370_reg_write_32(&card->config, ES1370_REG_MEMPAGE, 0xc); 161 es1370_reg_write_32(&card->config, ES1370_REG_DAC2_FRAMEADR & 0xff, (uint32)stream->buffer->phy_base); 162 es1370_reg_write_32(&card->config, ES1370_REG_DAC2_FRAMECNT & 0xff, ((stream->blksize * stream->bufcount) >> 2) - 1); 163 es1370_reg_write_32(&card->config, ES1370_REG_DAC2_SCOUNT & 0xff, stream->bufframes - 1); 164 LOG(("es1370_stream_commit_parms %" B_PRId32 " %" B_PRId32 "\n", 165 ((stream->blksize * stream->bufcount) >> 2) - 1, 166 (stream->blksize / frame_size) - 1)); 167 } 168 169 return B_OK; 170 } 171 172 status_t 173 es1370_stream_get_nth_buffer(es1370_stream *stream, uint8 chan, uint8 buf, 174 char** buffer, size_t *stride) 175 { 176 uint8 sample_size, frame_size; 177 LOG(("es1370_stream_get_nth_buffer\n")); 178 179 sample_size = stream->b16 + 1; 180 frame_size = sample_size * stream->channels; 181 182 *buffer = (char *)stream->buffer->log_base 183 + (buf * stream->bufframes * frame_size) + chan * sample_size; 184 *stride = frame_size; 185 186 return B_OK; 187 } 188 189 static uint32 190 es1370_stream_curaddr(es1370_stream *stream) 191 { 192 es1370_dev *card = stream->card; 193 uint32 reg = 0, cnt = 0; 194 if (stream->use & ES1370_USE_RECORD) { 195 reg = ES1370_REG_ADC_FRAMECNT; 196 } else { 197 reg = ES1370_REG_DAC2_FRAMECNT; 198 } 199 es1370_reg_write_32(&card->config, ES1370_REG_MEMPAGE, reg >> 8); 200 cnt = es1370_reg_read_32(&card->config, reg & 0xff) >> 16; 201 //TRACE(("stream_curaddr %lx\n", (cnt << 2) / stream->blksize)); 202 return (cnt << 2) / stream->blksize; 203 } 204 205 void 206 es1370_stream_start(es1370_stream *stream, void (*inth) (void *), void *inthparam) 207 { 208 uint32 sctrl = 0, ctrl = 0; 209 es1370_dev *card = stream->card; 210 LOG(("es1370_stream_start\n")); 211 212 stream->inth = inth; 213 stream->inthparam = inthparam; 214 215 stream->state |= ES1370_STATE_STARTED; 216 217 sctrl = es1370_reg_read_32(&card->config, ES1370_REG_SERIAL_CONTROL); 218 ctrl = es1370_reg_read_32(&card->config, ES1370_REG_CONTROL); 219 220 if (stream->use & ES1370_USE_RECORD) { 221 sctrl &= ~(SCTRL_R1SEB | SCTRL_R1SMB); 222 if (stream->b16) 223 sctrl |= SCTRL_R1SEB; 224 if (stream->channels == 2) 225 sctrl |= SCTRL_R1SMB; 226 es1370_reg_write_32(&card->config, ES1370_REG_SERIAL_CONTROL, sctrl & ~SCTRL_R1INTEN); 227 es1370_reg_write_32(&card->config, ES1370_REG_SERIAL_CONTROL, sctrl | SCTRL_R1INTEN); 228 229 ctrl |= CTRL_ADC_EN; 230 } else { 231 sctrl &= ~(SCTRL_P2SEB | SCTRL_P2SMB | 0x003f0000); 232 if (stream->b16) 233 sctrl |= SCTRL_P2SEB; 234 if (stream->channels == 2) 235 sctrl |= SCTRL_P2SMB; 236 sctrl |= (stream->b16 + 1) << SCTRL_SH_P2ENDINC; 237 es1370_reg_write_32(&card->config, ES1370_REG_SERIAL_CONTROL, sctrl & ~SCTRL_P2INTEN); 238 es1370_reg_write_32(&card->config, ES1370_REG_SERIAL_CONTROL, sctrl | SCTRL_P2INTEN); 239 240 ctrl |= CTRL_DAC2_EN; 241 } 242 243 es1370_reg_write_32(&card->config, ES1370_REG_SERIAL_CONTROL, sctrl); 244 es1370_reg_write_32(&card->config, ES1370_REG_CONTROL, ctrl); 245 246 #ifdef DEBUG 247 //dump_hardware_regs(&stream->card->config); 248 #endif 249 } 250 251 void 252 es1370_stream_halt(es1370_stream *stream) 253 { 254 uint32 ctrl; 255 es1370_dev *card = stream->card; 256 LOG(("es1370_stream_halt\n")); 257 258 stream->state &= ~ES1370_STATE_STARTED; 259 260 ctrl = es1370_reg_read_32(&card->config, ES1370_REG_CONTROL); 261 if (stream->use & ES1370_USE_RECORD) 262 ctrl &= ~CTRL_ADC_EN; 263 else 264 ctrl &= ~CTRL_DAC2_EN; 265 es1370_reg_write_32(&card->config, ES1370_REG_CONTROL, ctrl); 266 } 267 268 es1370_stream * 269 es1370_stream_new(es1370_dev *card, uint8 use, uint32 bufframes, uint8 bufcount) 270 { 271 es1370_stream *stream; 272 cpu_status status; 273 LOG(("es1370_stream_new\n")); 274 275 stream = malloc(sizeof(es1370_stream)); 276 if (stream == NULL) 277 return (NULL); 278 stream->card = card; 279 stream->use = use; 280 stream->state = !ES1370_STATE_STARTED; 281 stream->b16 = 0; 282 stream->sample_rate = 0; 283 stream->channels = 0; 284 stream->bufframes = bufframes; 285 stream->bufcount = bufcount; 286 stream->inth = NULL; 287 stream->inthparam = NULL; 288 stream->buffer = NULL; 289 stream->blksize = 0; 290 stream->trigblk = 0; 291 stream->blkmod = 0; 292 293 stream->buffer_cycle = 0; 294 stream->frames_count = 0; 295 stream->real_time = 0; 296 stream->update_needed = false; 297 298 status = lock(); 299 LIST_INSERT_HEAD((&card->streams), stream, next); 300 unlock(status); 301 302 return stream; 303 } 304 305 void 306 es1370_stream_delete(es1370_stream *stream) 307 { 308 cpu_status status; 309 LOG(("es1370_stream_delete\n")); 310 311 es1370_stream_halt(stream); 312 313 if(stream->buffer) 314 es1370_mem_free(stream->card, stream->buffer->log_base); 315 316 status = lock(); 317 LIST_REMOVE(stream, next); 318 unlock(status); 319 320 free(stream); 321 } 322 323 /* es1370 interrupt */ 324 325 static int32 326 es1370_int(void *arg) 327 { 328 es1370_dev *card = arg; 329 bool gotone = false; 330 uint32 curblk; 331 es1370_stream *stream = NULL; 332 uint32 sta, sctrl; 333 334 // TRACE(("es1370_int(%p)\n", card)); 335 336 sta = es1370_reg_read_32(&card->config, ES1370_REG_STATUS); 337 if (sta & card->interrupt_mask) { 338 339 //TRACE(("interrupt !! %x\n", sta)); 340 sctrl = es1370_reg_read_32(&card->config, ES1370_REG_SERIAL_CONTROL); 341 342 LIST_FOREACH(stream, &card->streams, next) { 343 if (stream->use & ES1370_USE_RECORD) { 344 if ((sta & STAT_ADC) == 0) 345 continue; 346 es1370_reg_write_32(&card->config, ES1370_REG_SERIAL_CONTROL, sctrl & ~SCTRL_R1INTEN); 347 es1370_reg_write_32(&card->config, ES1370_REG_SERIAL_CONTROL, sctrl | SCTRL_R1INTEN); 348 } else { 349 if ((sta & STAT_DAC2) == 0) 350 continue; 351 es1370_reg_write_32(&card->config, ES1370_REG_SERIAL_CONTROL, sctrl & ~SCTRL_P2INTEN); 352 es1370_reg_write_32(&card->config, ES1370_REG_SERIAL_CONTROL, sctrl | SCTRL_P2INTEN); 353 } 354 355 curblk = es1370_stream_curaddr(stream); 356 // TRACE(("INTR at trigblk %lu, stream->trigblk %lu\n", curblk, stream->trigblk)); 357 if (curblk == stream->trigblk) { 358 stream->trigblk++; 359 stream->trigblk = stream->trigblk % stream->blkmod; 360 if (stream->inth) 361 stream->inth(stream->inthparam); 362 } 363 gotone = true; 364 } 365 } else { 366 //TRACE(("interrupt masked %x, ", card->interrupt_mask)); 367 //TRACE(("sta %x\n", sta)); 368 } 369 370 if (gotone) 371 return B_INVOKE_SCHEDULER; 372 373 //TRACE(("Got unhandled interrupt\n")); 374 return B_UNHANDLED_INTERRUPT; 375 } 376 377 378 /* es1370 driver functions */ 379 380 381 /* detect presence of our hardware */ 382 status_t 383 init_hardware(void) 384 { 385 int ix=0; 386 pci_info info; 387 status_t err = ENODEV; 388 389 if (get_module(pci_name, (module_info **)&pci)) 390 return ENOSYS; 391 392 while ((*pci->get_nth_pci_info)(ix, &info) == B_OK) { 393 if (info.vendor_id == 0x1274 && (info.device_id == 0x5000 394 /*|| info.device_id == 0x1371 || info.device_id == 0x5880*/)) 395 { 396 LOG_CREATE(); 397 PRINT(("init_hardware()\n")); 398 399 err = B_OK; 400 } 401 ix++; 402 } 403 404 put_module(pci_name); 405 406 return err; 407 } 408 409 static void 410 make_device_names( 411 es1370_dev * card) 412 { 413 sprintf(card->name, "audio/hmulti/es1370/%ld", card-cards+1); 414 names[num_names++] = card->name; 415 416 names[num_names] = NULL; 417 } 418 419 420 status_t 421 es1370_init(es1370_dev * card) 422 { 423 card->interrupt_mask = STAT_DAC2 | STAT_ADC; 424 425 /* Init streams list */ 426 LIST_INIT(&(card->streams)); 427 428 /* Init mems list */ 429 LIST_INIT(&(card->mems)); 430 431 return B_OK; 432 } 433 434 static status_t 435 es1370_setup(es1370_dev * card) 436 { 437 status_t err = B_OK; 438 unsigned char cmd; 439 440 PRINT(("es1370_setup(%p)\n", card)); 441 442 make_device_names(card); 443 444 card->config.base = card->info.u.h0.base_registers[0]; 445 card->config.irq = card->info.u.h0.interrupt_line; 446 card->config.type = 0; 447 448 PRINT(("%s deviceid = %#04x chiprev = %x model = %x enhanced at %" B_PRIx32 449 "\n", card->name, card->info.device_id, card->info.revision, 450 card->info.u.h0.subsystem_id, card->config.base)); 451 452 cmd = (*pci->read_pci_config)(card->info.bus, card->info.device, card->info.function, PCI_command, 2); 453 PRINT(("PCI command before: %x\n", cmd)); 454 (*pci->write_pci_config)(card->info.bus, card->info.device, 455 card->info.function, PCI_command, 2, 456 cmd | PCI_command_master | PCI_command_io); 457 cmd = (*pci->read_pci_config)(card->info.bus, card->info.device, card->info.function, PCI_command, 2); 458 PRINT(("PCI command after: %x\n", cmd)); 459 460 es1370_reg_write_32(&card->config, ES1370_REG_SERIAL_CONTROL, SCTRL_P2INTEN | SCTRL_R1INTEN); 461 es1370_reg_write_32(&card->config, ES1370_REG_CONTROL, CTRL_CDC_EN); 462 463 /* reset the codec */ 464 PRINT(("codec reset\n")); 465 es1370_codec_write(&card->config, CODEC_RESET_PWRDWN, 0x2); 466 snooze (20); 467 es1370_codec_write(&card->config, CODEC_RESET_PWRDWN, 0x3); 468 snooze (20); 469 es1370_codec_write(&card->config, CODEC_CLOCK_SEL, 0x0); 470 471 /* set max volume on master and mixer outputs */ 472 es1370_codec_write(&card->config, CODEC_MASTER_VOL_L, 0x0); 473 es1370_codec_write(&card->config, CODEC_MASTER_VOL_R, 0x0); 474 es1370_codec_write(&card->config, CODEC_VOICE_VOL_L, 0x0); 475 es1370_codec_write(&card->config, CODEC_VOICE_VOL_R, 0x0); 476 477 /* unmute CD playback */ 478 es1370_codec_write(&card->config, CODEC_OUTPUT_MIX1, ES1370_OUTPUT_MIX1_CDL | ES1370_OUTPUT_MIX1_CDR); 479 /* unmute mixer output */ 480 es1370_codec_write(&card->config, CODEC_OUTPUT_MIX2, ES1370_OUTPUT_MIX2_VOICEL | ES1370_OUTPUT_MIX2_VOICER); 481 482 snooze(50000); // 50 ms 483 484 PRINT(("installing interrupt : %" B_PRIu32 "\n", card->config.irq)); 485 err = install_io_interrupt_handler(card->config.irq, es1370_int, card, 0); 486 if (err != B_OK) { 487 PRINT(("failed to install interrupt\n")); 488 return err; 489 } 490 491 if ((err = es1370_init(card))) 492 return (err); 493 494 PRINT(("init_driver done\n")); 495 496 return err; 497 } 498 499 500 status_t 501 init_driver(void) 502 { 503 void *settings_handle; 504 pci_info info; 505 int ix = 0; 506 status_t err; 507 num_cards = 0; 508 509 PRINT(("init_driver()\n")); 510 511 // get driver settings 512 settings_handle = load_driver_settings ("es1370.settings"); 513 if (settings_handle != NULL) { 514 const char *item; 515 char *end; 516 uint32 value; 517 518 item = get_driver_parameter (settings_handle, "sample_rate", "44100", "44100"); 519 value = strtoul (item, &end, 0); 520 if (*end == '\0') current_settings.sample_rate = value; 521 522 item = get_driver_parameter (settings_handle, "buffer_frames", "512", "512"); 523 value = strtoul (item, &end, 0); 524 if (*end == '\0') current_settings.buffer_frames = value; 525 526 item = get_driver_parameter (settings_handle, "buffer_count", "2", "2"); 527 value = strtoul (item, &end, 0); 528 if (*end == '\0') current_settings.buffer_count = value; 529 530 unload_driver_settings (settings_handle); 531 } 532 533 if (get_module(pci_name, (module_info **) &pci)) 534 return ENOSYS; 535 536 while ((*pci->get_nth_pci_info)(ix++, &info) == B_OK) { 537 if (info.vendor_id == 0x1274 538 && (info.device_id == 0x5000 539 /*|| info.device_id == 0x1371 540 || info.device_id == 0x5880*/) 541 ) { 542 if (num_cards == NUM_CARDS) { 543 PRINT(("Too many es1370 cards installed!\n")); 544 break; 545 } 546 memset(&cards[num_cards], 0, sizeof(es1370_dev)); 547 cards[num_cards].info = info; 548 #ifdef __HAIKU__ 549 if ((err = (*pci->reserve_device)(info.bus, info.device, info.function, 550 DRIVER_NAME, &cards[num_cards])) < B_OK) { 551 dprintf("%s: failed to reserve_device(%d, %d, %d,): %s\n", 552 DRIVER_NAME, info.bus, info.device, info.function, 553 strerror(err)); 554 continue; 555 } 556 #endif 557 if (es1370_setup(&cards[num_cards])) { 558 PRINT(("Setup of es1370 %" B_PRId32 " failed\n", num_cards+1)); 559 #ifdef __HAIKU__ 560 (*pci->unreserve_device)(info.bus, info.device, info.function, 561 DRIVER_NAME, &cards[num_cards]); 562 #endif 563 } 564 else { 565 num_cards++; 566 } 567 } 568 } 569 if (!num_cards) { 570 PRINT(("no cards\n")); 571 put_module(pci_name); 572 PRINT(("no suitable cards found\n")); 573 return ENODEV; 574 } 575 576 return B_OK; 577 } 578 579 580 static void 581 es1370_shutdown(es1370_dev *card) 582 { 583 PRINT(("shutdown(%p)\n", card)); 584 //ac97_amp_enable(&card->config, false); 585 card->interrupt_mask = 0; 586 587 remove_io_interrupt_handler(card->config.irq, es1370_int, card); 588 } 589 590 591 void 592 uninit_driver(void) 593 { 594 int ix, cnt = num_cards; 595 num_cards = 0; 596 597 PRINT(("uninit_driver()\n")); 598 for (ix=0; ix<cnt; ix++) { 599 es1370_shutdown(&cards[ix]); 600 #ifdef __HAIKU__ 601 (*pci->unreserve_device)(cards[ix].info.bus, 602 cards[ix].info.device, cards[ix].info.function, 603 DRIVER_NAME, &cards[ix]); 604 #endif 605 } 606 memset(&cards, 0, sizeof(cards)); 607 put_module(pci_name); 608 } 609 610 611 const char ** 612 publish_devices(void) 613 { 614 int ix = 0; 615 PRINT(("publish_devices()\n")); 616 617 for (ix=0; names[ix]; ix++) { 618 PRINT(("publish %s\n", names[ix])); 619 } 620 return (const char **)names; 621 } 622 623 624 device_hooks * 625 find_device(const char * name) 626 { 627 int ix; 628 629 PRINT(("find_device(%s)\n", name)); 630 631 for (ix=0; ix<num_cards; ix++) { 632 if (!strcmp(cards[ix].name, name)) { 633 return &multi_hooks; 634 } 635 } 636 PRINT(("find_device(%s) failed\n", name)); 637 return NULL; 638 } 639 640 int32 api_version = B_CUR_DRIVER_API_VERSION; 641 642