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 LOG(("es1370_stream_delete\n")); 308 309 es1370_stream_halt(stream); 310 311 if(stream->buffer) 312 es1370_mem_free(stream->card, stream->buffer->log_base); 313 314 status = lock(); 315 LIST_REMOVE(stream, next); 316 unlock(status); 317 318 free(stream); 319 } 320 321 /* es1370 interrupt */ 322 323 static int32 324 es1370_int(void *arg) 325 { 326 es1370_dev *card = arg; 327 bool gotone = false; 328 uint32 curblk; 329 es1370_stream *stream = NULL; 330 uint32 sta, sctrl; 331 332 // TRACE(("es1370_int(%p)\n", card)); 333 334 sta = es1370_reg_read_32(&card->config, ES1370_REG_STATUS); 335 if (sta & card->interrupt_mask) { 336 337 //TRACE(("interrupt !! %x\n", sta)); 338 sctrl = es1370_reg_read_32(&card->config, ES1370_REG_SERIAL_CONTROL); 339 340 LIST_FOREACH(stream, &card->streams, next) { 341 if (stream->use & ES1370_USE_RECORD) { 342 if ((sta & STAT_ADC) == 0) 343 continue; 344 es1370_reg_write_32(&card->config, ES1370_REG_SERIAL_CONTROL, sctrl & ~SCTRL_R1INTEN); 345 es1370_reg_write_32(&card->config, ES1370_REG_SERIAL_CONTROL, sctrl | SCTRL_R1INTEN); 346 } else { 347 if ((sta & STAT_DAC2) == 0) 348 continue; 349 es1370_reg_write_32(&card->config, ES1370_REG_SERIAL_CONTROL, sctrl & ~SCTRL_P2INTEN); 350 es1370_reg_write_32(&card->config, ES1370_REG_SERIAL_CONTROL, sctrl | SCTRL_P2INTEN); 351 } 352 353 curblk = es1370_stream_curaddr(stream); 354 // TRACE(("INTR at trigblk %lu, stream->trigblk %lu\n", curblk, stream->trigblk)); 355 if (curblk == stream->trigblk) { 356 stream->trigblk++; 357 stream->trigblk = stream->trigblk % stream->blkmod; 358 if (stream->inth) 359 stream->inth(stream->inthparam); 360 } 361 gotone = true; 362 } 363 } else { 364 //TRACE(("interrupt masked %x, ", card->interrupt_mask)); 365 //TRACE(("sta %x\n", sta)); 366 } 367 368 if (gotone) 369 return B_INVOKE_SCHEDULER; 370 371 //TRACE(("Got unhandled interrupt\n")); 372 return B_UNHANDLED_INTERRUPT; 373 } 374 375 376 /* es1370 driver functions */ 377 378 379 /* detect presence of our hardware */ 380 status_t 381 init_hardware(void) 382 { 383 int ix=0; 384 pci_info info; 385 status_t err = ENODEV; 386 387 LOG_CREATE(); 388 389 PRINT(("init_hardware()\n")); 390 391 if (get_module(pci_name, (module_info **)&pci)) 392 return ENOSYS; 393 394 while ((*pci->get_nth_pci_info)(ix, &info) == B_OK) { 395 if (info.vendor_id == 0x1274 396 && (info.device_id == 0x5000 397 /*|| info.device_id == 0x1371 398 || info.device_id == 0x5880*/) 399 ) 400 { 401 err = B_OK; 402 } 403 ix++; 404 } 405 406 put_module(pci_name); 407 408 return err; 409 } 410 411 static void 412 make_device_names( 413 es1370_dev * card) 414 { 415 sprintf(card->name, "audio/hmulti/es1370/%ld", card-cards+1); 416 names[num_names++] = card->name; 417 418 names[num_names] = NULL; 419 } 420 421 422 status_t 423 es1370_init(es1370_dev * card) 424 { 425 card->interrupt_mask = STAT_DAC2 | STAT_ADC; 426 427 /* Init streams list */ 428 LIST_INIT(&(card->streams)); 429 430 /* Init mems list */ 431 LIST_INIT(&(card->mems)); 432 433 return B_OK; 434 } 435 436 static status_t 437 es1370_setup(es1370_dev * card) 438 { 439 status_t err = B_OK; 440 unsigned char cmd; 441 442 PRINT(("es1370_setup(%p)\n", card)); 443 444 make_device_names(card); 445 446 card->config.base = card->info.u.h0.base_registers[0]; 447 card->config.irq = card->info.u.h0.interrupt_line; 448 card->config.type = 0; 449 450 PRINT(("%s deviceid = %#04x chiprev = %x model = %x enhanced at %lx\n", card->name, card->info.device_id, 451 card->info.revision, card->info.u.h0.subsystem_id, card->config.base)); 452 453 cmd = (*pci->read_pci_config)(card->info.bus, card->info.device, card->info.function, PCI_command, 2); 454 PRINT(("PCI command before: %x\n", cmd)); 455 (*pci->write_pci_config)(card->info.bus, card->info.device, card->info.function, PCI_command, 2, cmd | PCI_command_io); 456 cmd = (*pci->read_pci_config)(card->info.bus, card->info.device, card->info.function, PCI_command, 2); 457 PRINT(("PCI command after: %x\n", cmd)); 458 459 es1370_reg_write_32(&card->config, ES1370_REG_SERIAL_CONTROL, SCTRL_P2INTEN | SCTRL_R1INTEN); 460 es1370_reg_write_32(&card->config, ES1370_REG_CONTROL, CTRL_CDC_EN); 461 462 /* reset the codec */ 463 PRINT(("codec reset\n")); 464 es1370_codec_write(&card->config, CODEC_RESET_PWRDWN, 0x2); 465 snooze (20); 466 es1370_codec_write(&card->config, CODEC_RESET_PWRDWN, 0x3); 467 snooze (20); 468 es1370_codec_write(&card->config, CODEC_CLOCK_SEL, 0x0); 469 470 /* set max volume on master and mixer outputs */ 471 es1370_codec_write(&card->config, CODEC_MASTER_VOL_L, 0x0); 472 es1370_codec_write(&card->config, CODEC_MASTER_VOL_R, 0x0); 473 es1370_codec_write(&card->config, CODEC_VOICE_VOL_L, 0x0); 474 es1370_codec_write(&card->config, CODEC_VOICE_VOL_R, 0x0); 475 476 /* unmute CD playback */ 477 es1370_codec_write(&card->config, CODEC_OUTPUT_MIX1, ES1370_OUTPUT_MIX1_CDL | ES1370_OUTPUT_MIX1_CDR); 478 /* unmute mixer output */ 479 es1370_codec_write(&card->config, CODEC_OUTPUT_MIX2, ES1370_OUTPUT_MIX2_VOICEL | ES1370_OUTPUT_MIX2_VOICER); 480 481 snooze(50000); // 50 ms 482 483 PRINT(("installing interrupt : %lx\n", card->config.irq)); 484 err = install_io_interrupt_handler(card->config.irq, es1370_int, card, 0); 485 if (err != B_OK) { 486 PRINT(("failed to install interrupt\n")); 487 return err; 488 } 489 490 if ((err = es1370_init(card))) 491 return (err); 492 493 PRINT(("init_driver done\n")); 494 495 return err; 496 } 497 498 499 status_t 500 init_driver(void) 501 { 502 void *settings_handle; 503 pci_info info; 504 int ix = 0; 505 status_t err; 506 num_cards = 0; 507 508 PRINT(("init_driver()\n")); 509 510 // get driver settings 511 settings_handle = load_driver_settings ("es1370.settings"); 512 if (settings_handle != NULL) { 513 const char *item; 514 char *end; 515 uint32 value; 516 517 item = get_driver_parameter (settings_handle, "sample_rate", "44100", "44100"); 518 value = strtoul (item, &end, 0); 519 if (*end == '\0') current_settings.sample_rate = value; 520 521 item = get_driver_parameter (settings_handle, "buffer_frames", "512", "512"); 522 value = strtoul (item, &end, 0); 523 if (*end == '\0') current_settings.buffer_frames = value; 524 525 item = get_driver_parameter (settings_handle, "buffer_count", "2", "2"); 526 value = strtoul (item, &end, 0); 527 if (*end == '\0') current_settings.buffer_count = value; 528 529 unload_driver_settings (settings_handle); 530 } 531 532 if (get_module(pci_name, (module_info **) &pci)) 533 return ENOSYS; 534 535 while ((*pci->get_nth_pci_info)(ix++, &info) == B_OK) { 536 if (info.vendor_id == 0x1274 537 && (info.device_id == 0x5000 538 /*|| info.device_id == 0x1371 539 || info.device_id == 0x5880*/) 540 ) { 541 if (num_cards == NUM_CARDS) { 542 PRINT(("Too many es1370 cards installed!\n")); 543 break; 544 } 545 memset(&cards[num_cards], 0, sizeof(es1370_dev)); 546 cards[num_cards].info = info; 547 #ifdef __HAIKU__ 548 if ((err = (*pci->reserve_device)(info.bus, info.device, info.function, 549 DRIVER_NAME, &cards[num_cards])) < B_OK) { 550 dprintf("%s: failed to reserve_device(%d, %d, %d,): %s\n", 551 DRIVER_NAME, info.bus, info.device, info.function, 552 strerror(err)); 553 continue; 554 } 555 #endif 556 if (es1370_setup(&cards[num_cards])) { 557 PRINT(("Setup of es1370 %ld failed\n", num_cards+1)); 558 #ifdef __HAIKU__ 559 (*pci->unreserve_device)(info.bus, info.device, info.function, 560 DRIVER_NAME, &cards[num_cards]); 561 #endif 562 } 563 else { 564 num_cards++; 565 } 566 } 567 } 568 if (!num_cards) { 569 PRINT(("no cards\n")); 570 put_module(pci_name); 571 PRINT(("no suitable cards found\n")); 572 return ENODEV; 573 } 574 575 return B_OK; 576 } 577 578 579 static void 580 es1370_shutdown(es1370_dev *card) 581 { 582 PRINT(("shutdown(%p)\n", card)); 583 //ac97_amp_enable(&card->config, false); 584 card->interrupt_mask = 0; 585 586 remove_io_interrupt_handler(card->config.irq, es1370_int, card); 587 } 588 589 590 void 591 uninit_driver(void) 592 { 593 int ix, cnt = num_cards; 594 num_cards = 0; 595 596 PRINT(("uninit_driver()\n")); 597 for (ix=0; ix<cnt; ix++) { 598 es1370_shutdown(&cards[ix]); 599 #ifdef __HAIKU__ 600 (*pci->unreserve_device)(cards[ix].info.bus, 601 cards[ix].info.device, cards[ix].info.function, 602 DRIVER_NAME, &cards[ix]); 603 #endif 604 } 605 memset(&cards, 0, sizeof(cards)); 606 put_module(pci_name); 607 } 608 609 610 const char ** 611 publish_devices(void) 612 { 613 int ix = 0; 614 PRINT(("publish_devices()\n")); 615 616 for (ix=0; names[ix]; ix++) { 617 PRINT(("publish %s\n", names[ix])); 618 } 619 return (const char **)names; 620 } 621 622 623 device_hooks * 624 find_device(const char * name) 625 { 626 int ix; 627 628 PRINT(("find_device(%s)\n", name)); 629 630 for (ix=0; ix<num_cards; ix++) { 631 if (!strcmp(cards[ix].name, name)) { 632 return &multi_hooks; 633 } 634 } 635 PRINT(("find_device(%s) failed\n", name)); 636 return NULL; 637 } 638 639 int32 api_version = B_CUR_DRIVER_API_VERSION; 640 641