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"); 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 %ld %ld\n", ((stream->blksize * stream->bufcount) >> 2) - 1, (stream->blksize / frame_size) - 1)); 165 } 166 167 return B_OK; 168 } 169 170 status_t 171 es1370_stream_get_nth_buffer(es1370_stream *stream, uint8 chan, uint8 buf, 172 char** buffer, size_t *stride) 173 { 174 uint8 sample_size, frame_size; 175 LOG(("es1370_stream_get_nth_buffer\n")); 176 177 sample_size = stream->b16 + 1; 178 frame_size = sample_size * stream->channels; 179 180 *buffer = stream->buffer->log_base + (buf * stream->bufframes * frame_size) 181 + chan * sample_size; 182 *stride = frame_size; 183 184 return B_OK; 185 } 186 187 static uint32 188 es1370_stream_curaddr(es1370_stream *stream) 189 { 190 es1370_dev *card = stream->card; 191 uint32 reg = 0, cnt = 0; 192 if (stream->use & ES1370_USE_RECORD) { 193 reg = ES1370_REG_ADC_FRAMECNT; 194 } else { 195 reg = ES1370_REG_DAC2_FRAMECNT; 196 } 197 es1370_reg_write_32(&card->config, ES1370_REG_MEMPAGE, reg >> 8); 198 cnt = es1370_reg_read_32(&card->config, reg & 0xff) >> 16; 199 //TRACE(("stream_curaddr %lx\n", (cnt << 2) / stream->blksize)); 200 return (cnt << 2) / stream->blksize; 201 } 202 203 void 204 es1370_stream_start(es1370_stream *stream, void (*inth) (void *), void *inthparam) 205 { 206 uint32 sctrl = 0, ctrl = 0; 207 es1370_dev *card = stream->card; 208 LOG(("es1370_stream_start\n")); 209 210 stream->inth = inth; 211 stream->inthparam = inthparam; 212 213 stream->state |= ES1370_STATE_STARTED; 214 215 sctrl = es1370_reg_read_32(&card->config, ES1370_REG_SERIAL_CONTROL); 216 ctrl = es1370_reg_read_32(&card->config, ES1370_REG_CONTROL); 217 218 if (stream->use & ES1370_USE_RECORD) { 219 sctrl &= ~(SCTRL_R1SEB | SCTRL_R1SMB); 220 if (stream->b16) 221 sctrl |= SCTRL_R1SEB; 222 if (stream->channels == 2) 223 sctrl |= SCTRL_R1SMB; 224 es1370_reg_write_32(&card->config, ES1370_REG_SERIAL_CONTROL, sctrl & ~SCTRL_R1INTEN); 225 es1370_reg_write_32(&card->config, ES1370_REG_SERIAL_CONTROL, sctrl | SCTRL_R1INTEN); 226 227 ctrl |= CTRL_ADC_EN; 228 } else { 229 sctrl &= ~(SCTRL_P2SEB | SCTRL_P2SMB | 0x003f0000); 230 if (stream->b16) 231 sctrl |= SCTRL_P2SEB; 232 if (stream->channels == 2) 233 sctrl |= SCTRL_P2SMB; 234 sctrl |= (stream->b16 + 1) << SCTRL_SH_P2ENDINC; 235 es1370_reg_write_32(&card->config, ES1370_REG_SERIAL_CONTROL, sctrl & ~SCTRL_P2INTEN); 236 es1370_reg_write_32(&card->config, ES1370_REG_SERIAL_CONTROL, sctrl | SCTRL_P2INTEN); 237 238 ctrl |= CTRL_DAC2_EN; 239 } 240 241 es1370_reg_write_32(&card->config, ES1370_REG_SERIAL_CONTROL, sctrl); 242 es1370_reg_write_32(&card->config, ES1370_REG_CONTROL, ctrl); 243 244 #ifdef DEBUG 245 //dump_hardware_regs(&stream->card->config); 246 #endif 247 } 248 249 void 250 es1370_stream_halt(es1370_stream *stream) 251 { 252 uint32 ctrl; 253 es1370_dev *card = stream->card; 254 LOG(("es1370_stream_halt\n")); 255 256 stream->state &= ~ES1370_STATE_STARTED; 257 258 ctrl = es1370_reg_read_32(&card->config, ES1370_REG_CONTROL); 259 if (stream->use & ES1370_USE_RECORD) 260 ctrl &= ~CTRL_ADC_EN; 261 else 262 ctrl &= ~CTRL_DAC2_EN; 263 es1370_reg_write_32(&card->config, ES1370_REG_CONTROL, ctrl); 264 } 265 266 es1370_stream * 267 es1370_stream_new(es1370_dev *card, uint8 use, uint32 bufframes, uint8 bufcount) 268 { 269 es1370_stream *stream; 270 cpu_status status; 271 LOG(("es1370_stream_new\n")); 272 273 stream = malloc(sizeof(es1370_stream)); 274 if (stream == NULL) 275 return (NULL); 276 stream->card = card; 277 stream->use = use; 278 stream->state = !ES1370_STATE_STARTED; 279 stream->b16 = 0; 280 stream->sample_rate = 0; 281 stream->channels = 0; 282 stream->bufframes = bufframes; 283 stream->bufcount = bufcount; 284 stream->inth = NULL; 285 stream->inthparam = NULL; 286 stream->buffer = NULL; 287 stream->blksize = 0; 288 stream->trigblk = 0; 289 stream->blkmod = 0; 290 291 stream->buffer_cycle = 0; 292 stream->frames_count = 0; 293 stream->real_time = 0; 294 stream->update_needed = false; 295 296 status = lock(); 297 LIST_INSERT_HEAD((&card->streams), stream, next); 298 unlock(status); 299 300 return stream; 301 } 302 303 void 304 es1370_stream_delete(es1370_stream *stream) 305 { 306 cpu_status status; 307 int32 i; 308 LOG(("es1370_stream_delete\n")); 309 310 es1370_stream_halt(stream); 311 312 if(stream->buffer) 313 es1370_mem_free(stream->card, stream->buffer->log_base); 314 315 status = lock(); 316 LIST_REMOVE(stream, next); 317 unlock(status); 318 319 free(stream); 320 } 321 322 /* es1370 interrupt */ 323 324 static int32 325 es1370_int(void *arg) 326 { 327 es1370_dev *card = arg; 328 bool gotone = false; 329 uint32 curblk; 330 es1370_stream *stream = NULL; 331 uint32 sta, sctrl; 332 333 // TRACE(("es1370_int(%p)\n", card)); 334 335 sta = es1370_reg_read_32(&card->config, ES1370_REG_STATUS); 336 if (sta & card->interrupt_mask) { 337 338 //TRACE(("interrupt !! %x\n", sta)); 339 sctrl = es1370_reg_read_32(&card->config, ES1370_REG_SERIAL_CONTROL); 340 341 LIST_FOREACH(stream, &card->streams, next) { 342 if (stream->use & ES1370_USE_RECORD) { 343 if ((sta & STAT_ADC) == 0) 344 continue; 345 es1370_reg_write_32(&card->config, ES1370_REG_SERIAL_CONTROL, sctrl & ~SCTRL_R1INTEN); 346 es1370_reg_write_32(&card->config, ES1370_REG_SERIAL_CONTROL, sctrl | SCTRL_R1INTEN); 347 } else { 348 if ((sta & STAT_DAC2) == 0) 349 continue; 350 es1370_reg_write_32(&card->config, ES1370_REG_SERIAL_CONTROL, sctrl & ~SCTRL_P2INTEN); 351 es1370_reg_write_32(&card->config, ES1370_REG_SERIAL_CONTROL, sctrl | SCTRL_P2INTEN); 352 } 353 354 curblk = es1370_stream_curaddr(stream); 355 // TRACE(("INTR at trigblk %lu, stream->trigblk %lu\n", curblk, stream->trigblk)); 356 if (curblk == stream->trigblk) { 357 stream->trigblk++; 358 stream->trigblk = stream->trigblk % stream->blkmod; 359 if (stream->inth) 360 stream->inth(stream->inthparam); 361 } 362 gotone = true; 363 } 364 } else { 365 //TRACE(("interrupt masked %x, ", card->interrupt_mask)); 366 //TRACE(("sta %x\n", sta)); 367 } 368 369 if (gotone) 370 return B_INVOKE_SCHEDULER; 371 372 //TRACE(("Got unhandled interrupt\n")); 373 return B_UNHANDLED_INTERRUPT; 374 } 375 376 377 /* es1370 driver functions */ 378 379 380 /* detect presence of our hardware */ 381 status_t 382 init_hardware(void) 383 { 384 int ix=0; 385 pci_info info; 386 status_t err = ENODEV; 387 388 LOG_CREATE(); 389 390 PRINT(("init_hardware()\n")); 391 392 if (get_module(pci_name, (module_info **)&pci)) 393 return ENOSYS; 394 395 while ((*pci->get_nth_pci_info)(ix, &info) == B_OK) { 396 if (info.vendor_id == 0x1274 397 && (info.device_id == 0x5000 398 /*|| info.device_id == 0x1371 399 || info.device_id == 0x5880*/) 400 ) 401 { 402 err = B_OK; 403 } 404 ix++; 405 } 406 407 put_module(pci_name); 408 409 return err; 410 } 411 412 static void 413 make_device_names( 414 es1370_dev * card) 415 { 416 sprintf(card->name, "audio/hmulti/es1370/%ld", card-cards+1); 417 names[num_names++] = card->name; 418 419 names[num_names] = NULL; 420 } 421 422 423 status_t 424 es1370_init(es1370_dev * card) 425 { 426 card->interrupt_mask = STAT_DAC2 | STAT_ADC; 427 428 /* Init streams list */ 429 LIST_INIT(&(card->streams)); 430 431 /* Init mems list */ 432 LIST_INIT(&(card->mems)); 433 434 return B_OK; 435 } 436 437 static status_t 438 es1370_setup(es1370_dev * card) 439 { 440 status_t err = B_OK; 441 status_t rv; 442 unsigned char cmd; 443 444 PRINT(("es1370_setup(%p)\n", card)); 445 446 make_device_names(card); 447 448 card->config.base = card->info.u.h0.base_registers[0]; 449 card->config.irq = card->info.u.h0.interrupt_line; 450 card->config.type = 0; 451 452 PRINT(("%s deviceid = %#04x chiprev = %x model = %x enhanced at %lx\n", card->name, card->info.device_id, 453 card->info.revision, card->info.u.h0.subsystem_id, card->config.base)); 454 455 cmd = (*pci->read_pci_config)(card->info.bus, card->info.device, card->info.function, PCI_command, 2); 456 PRINT(("PCI command before: %x\n", cmd)); 457 (*pci->write_pci_config)(card->info.bus, card->info.device, card->info.function, PCI_command, 2, cmd | PCI_command_io); 458 cmd = (*pci->read_pci_config)(card->info.bus, card->info.device, card->info.function, PCI_command, 2); 459 PRINT(("PCI command after: %x\n", cmd)); 460 461 es1370_reg_write_32(&card->config, ES1370_REG_SERIAL_CONTROL, SCTRL_P2INTEN | SCTRL_R1INTEN); 462 es1370_reg_write_32(&card->config, ES1370_REG_CONTROL, CTRL_CDC_EN); 463 464 /* reset the codec */ 465 PRINT(("codec reset\n")); 466 es1370_codec_write(&card->config, CODEC_RESET_PWRDWN, 0x2); 467 snooze (20); 468 es1370_codec_write(&card->config, CODEC_RESET_PWRDWN, 0x3); 469 snooze (20); 470 es1370_codec_write(&card->config, CODEC_CLOCK_SEL, 0x0); 471 472 /* set max volume on master and mixer outputs */ 473 es1370_codec_write(&card->config, CODEC_MASTER_VOL_L, 0x0); 474 es1370_codec_write(&card->config, CODEC_MASTER_VOL_R, 0x0); 475 es1370_codec_write(&card->config, CODEC_VOICE_VOL_L, 0x0); 476 es1370_codec_write(&card->config, CODEC_VOICE_VOL_R, 0x0); 477 478 /* unmute CD playback */ 479 es1370_codec_write(&card->config, CODEC_OUTPUT_MIX1, ES1370_OUTPUT_MIX1_CDL | ES1370_OUTPUT_MIX1_CDR); 480 /* unmute mixer output */ 481 es1370_codec_write(&card->config, CODEC_OUTPUT_MIX2, ES1370_OUTPUT_MIX2_VOICEL | ES1370_OUTPUT_MIX2_VOICER); 482 483 snooze(50000); // 50 ms 484 485 PRINT(("installing interrupt : %lx\n", card->config.irq)); 486 err = install_io_interrupt_handler(card->config.irq, es1370_int, card, 0); 487 if (err != B_OK) { 488 PRINT(("failed to install interrupt\n")); 489 return err; 490 } 491 492 if ((err = es1370_init(card))) 493 return (err); 494 495 PRINT(("init_driver done\n")); 496 497 return err; 498 } 499 500 501 status_t 502 init_driver(void) 503 { 504 void *settings_handle; 505 pci_info info; 506 int ix = 0; 507 status_t err; 508 num_cards = 0; 509 510 PRINT(("init_driver()\n")); 511 512 // get driver settings 513 settings_handle = load_driver_settings ("es1370.settings"); 514 if (settings_handle != NULL) { 515 const char *item; 516 char *end; 517 uint32 value; 518 519 item = get_driver_parameter (settings_handle, "sample_rate", "44100", "44100"); 520 value = strtoul (item, &end, 0); 521 if (*end == '\0') current_settings.sample_rate = value; 522 523 item = get_driver_parameter (settings_handle, "buffer_frames", "512", "512"); 524 value = strtoul (item, &end, 0); 525 if (*end == '\0') current_settings.buffer_frames = value; 526 527 item = get_driver_parameter (settings_handle, "buffer_count", "2", "2"); 528 value = strtoul (item, &end, 0); 529 if (*end == '\0') current_settings.buffer_count = value; 530 531 unload_driver_settings (settings_handle); 532 } 533 534 if (get_module(pci_name, (module_info **) &pci)) 535 return ENOSYS; 536 537 while ((*pci->get_nth_pci_info)(ix++, &info) == B_OK) { 538 if (info.vendor_id == 0x1274 539 && (info.device_id == 0x5000 540 /*|| info.device_id == 0x1371 541 || info.device_id == 0x5880*/) 542 ) { 543 if (num_cards == NUM_CARDS) { 544 PRINT(("Too many es1370 cards installed!\n")); 545 break; 546 } 547 memset(&cards[num_cards], 0, sizeof(es1370_dev)); 548 cards[num_cards].info = info; 549 #ifdef __HAIKU__ 550 if ((err = (*pci->reserve_device)(info.bus, info.device, info.function, 551 DRIVER_NAME, &cards[num_cards])) < B_OK) { 552 dprintf("%s: failed to reserve_device(%d, %d, %d,): %s\n", 553 DRIVER_NAME, info.bus, info.device, info.function, 554 strerror(err)); 555 continue; 556 } 557 #endif 558 if (es1370_setup(&cards[num_cards])) { 559 PRINT(("Setup of es1370 %ld failed\n", num_cards+1)); 560 #ifdef __HAIKU__ 561 (*pci->unreserve_device)(info.bus, info.device, info.function, 562 DRIVER_NAME, &cards[num_cards]); 563 #endif 564 } 565 else { 566 num_cards++; 567 } 568 } 569 } 570 if (!num_cards) { 571 PRINT(("no cards\n")); 572 put_module(pci_name); 573 PRINT(("no suitable cards found\n")); 574 return ENODEV; 575 } 576 577 return B_OK; 578 } 579 580 581 static void 582 es1370_shutdown(es1370_dev *card) 583 { 584 PRINT(("shutdown(%p)\n", card)); 585 //ac97_amp_enable(&card->config, false); 586 card->interrupt_mask = 0; 587 588 remove_io_interrupt_handler(card->config.irq, es1370_int, card); 589 } 590 591 592 void 593 uninit_driver(void) 594 { 595 int ix, cnt = num_cards; 596 num_cards = 0; 597 598 PRINT(("uninit_driver()\n")); 599 for (ix=0; ix<cnt; ix++) { 600 es1370_shutdown(&cards[ix]); 601 #ifdef __HAIKU__ 602 (*pci->unreserve_device)(cards[ix].info.bus, 603 cards[ix].info.device, cards[ix].info.function, 604 DRIVER_NAME, &cards[ix]); 605 #endif 606 } 607 memset(&cards, 0, sizeof(cards)); 608 put_module(pci_name); 609 } 610 611 612 const char ** 613 publish_devices(void) 614 { 615 int ix = 0; 616 PRINT(("publish_devices()\n")); 617 618 for (ix=0; names[ix]; ix++) { 619 PRINT(("publish %s\n", names[ix])); 620 } 621 return (const char **)names; 622 } 623 624 625 device_hooks * 626 find_device(const char * name) 627 { 628 int ix; 629 630 PRINT(("find_device(%s)\n", name)); 631 632 for (ix=0; ix<num_cards; ix++) { 633 if (!strcmp(cards[ix].name, name)) { 634 return &multi_hooks; 635 } 636 } 637 PRINT(("find_device(%s) failed\n", name)); 638 return NULL; 639 } 640 641 int32 api_version = B_CUR_DRIVER_API_VERSION; 642 643