1 /* Hewlett-Packard Harmony audio driver 2 * 3 * This is a driver for the Harmony audio chipset found 4 * on the LASI ASIC of various early HP PA-RISC workstations. 5 * 6 * Copyright (C) 2004, Kyle McMartin <kyle@{debian.org,parisc-linux.org}> 7 * 8 * Based on the previous Harmony incarnations by, 9 * Copyright 2000 (c) Linuxcare Canada, Alex deVries 10 * Copyright 2000-2003 (c) Helge Deller 11 * Copyright 2001 (c) Matthieu Delahaye 12 * Copyright 2001 (c) Jean-Christophe Vaugeois 13 * Copyright 2003 (c) Laurent Canet 14 * Copyright 2004 (c) Stuart Brady 15 * 16 * This program is free software; you can redistribute it and/or modify 17 * it under the terms of the GNU General Public License, version 2, as 18 * published by the Free Software Foundation. 19 * 20 * This program is distributed in the hope that it will be useful, 21 * but WITHOUT ANY WARRANTY; without even the implied warranty of 22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 23 * GNU General Public License for more details. 24 * 25 * You should have received a copy of the GNU General Public License 26 * along with this program; if not, write to the Free Software 27 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 28 * 29 * Notes: 30 * - graveyard and silence buffers last for lifetime of 31 * the driver. playback and capture buffers are allocated 32 * per _open()/_close(). 33 * 34 * TODO: 35 * 36 */ 37 38 #include <linux/init.h> 39 #include <linux/slab.h> 40 #include <linux/time.h> 41 #include <linux/wait.h> 42 #include <linux/delay.h> 43 #include <linux/module.h> 44 #include <linux/interrupt.h> 45 #include <linux/spinlock.h> 46 #include <linux/dma-mapping.h> 47 48 #include <sound/driver.h> 49 #include <sound/core.h> 50 #include <sound/pcm.h> 51 #include <sound/control.h> 52 #include <sound/rawmidi.h> 53 #include <sound/initval.h> 54 #include <sound/info.h> 55 56 #include <asm/io.h> 57 #include <asm/hardware.h> 58 #include <asm/parisc-device.h> 59 60 #include "harmony.h" 61 62 static struct parisc_device_id snd_harmony_devtable[] = { 63 /* bushmaster / flounder */ 64 { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0007A }, 65 /* 712 / 715 */ 66 { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0007B }, 67 /* pace */ 68 { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0007E }, 69 /* outfield / coral II */ 70 { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0007F }, 71 { 0, } 72 }; 73 74 MODULE_DEVICE_TABLE(parisc, snd_harmony_devtable); 75 76 #define NAME "harmony" 77 #define PFX NAME ": " 78 79 static unsigned int snd_harmony_rates[] = { 80 5512, 6615, 8000, 9600, 81 11025, 16000, 18900, 22050, 82 27428, 32000, 33075, 37800, 83 44100, 48000 84 }; 85 86 static unsigned int rate_bits[14] = { 87 HARMONY_SR_5KHZ, HARMONY_SR_6KHZ, HARMONY_SR_8KHZ, 88 HARMONY_SR_9KHZ, HARMONY_SR_11KHZ, HARMONY_SR_16KHZ, 89 HARMONY_SR_18KHZ, HARMONY_SR_22KHZ, HARMONY_SR_27KHZ, 90 HARMONY_SR_32KHZ, HARMONY_SR_33KHZ, HARMONY_SR_37KHZ, 91 HARMONY_SR_44KHZ, HARMONY_SR_48KHZ 92 }; 93 94 static snd_pcm_hw_constraint_list_t hw_constraint_rates = { 95 .count = ARRAY_SIZE(snd_harmony_rates), 96 .list = snd_harmony_rates, 97 .mask = 0, 98 }; 99 100 inline unsigned long 101 harmony_read(harmony_t *h, unsigned r) 102 { 103 return __raw_readl(h->iobase + r); 104 } 105 106 inline void 107 harmony_write(harmony_t *h, unsigned r, unsigned long v) 108 { 109 __raw_writel(v, h->iobase + r); 110 } 111 112 static void 113 harmony_wait_for_control(harmony_t *h) 114 { 115 while (harmony_read(h, HARMONY_CNTL) & HARMONY_CNTL_C) ; 116 } 117 118 inline void 119 harmony_reset(harmony_t *h) 120 { 121 harmony_write(h, HARMONY_RESET, 1); 122 mdelay(50); 123 harmony_write(h, HARMONY_RESET, 0); 124 } 125 126 static void 127 harmony_disable_interrupts(harmony_t *h) 128 { 129 u32 dstatus; 130 harmony_wait_for_control(h); 131 dstatus = harmony_read(h, HARMONY_DSTATUS); 132 dstatus &= ~HARMONY_DSTATUS_IE; 133 harmony_write(h, HARMONY_DSTATUS, dstatus); 134 } 135 136 static void 137 harmony_enable_interrupts(harmony_t *h) 138 { 139 u32 dstatus; 140 harmony_wait_for_control(h); 141 dstatus = harmony_read(h, HARMONY_DSTATUS); 142 dstatus |= HARMONY_DSTATUS_IE; 143 harmony_write(h, HARMONY_DSTATUS, dstatus); 144 } 145 146 static void 147 harmony_mute(harmony_t *h) 148 { 149 unsigned long flags; 150 151 spin_lock_irqsave(&h->mixer_lock, flags); 152 harmony_wait_for_control(h); 153 harmony_write(h, HARMONY_GAINCTL, HARMONY_GAIN_SILENCE); 154 spin_unlock_irqrestore(&h->mixer_lock, flags); 155 } 156 157 static void 158 harmony_unmute(harmony_t *h) 159 { 160 unsigned long flags; 161 162 spin_lock_irqsave(&h->mixer_lock, flags); 163 harmony_wait_for_control(h); 164 harmony_write(h, HARMONY_GAINCTL, h->st.gain); 165 spin_unlock_irqrestore(&h->mixer_lock, flags); 166 } 167 168 static void 169 harmony_set_control(harmony_t *h) 170 { 171 u32 ctrl; 172 unsigned long flags; 173 174 spin_lock_irqsave(&h->lock, flags); 175 176 ctrl = (HARMONY_CNTL_C | 177 (h->st.format << 6) | 178 (h->st.stereo << 5) | 179 (h->st.rate)); 180 181 harmony_wait_for_control(h); 182 harmony_write(h, HARMONY_CNTL, ctrl); 183 184 spin_unlock_irqrestore(&h->lock, flags); 185 } 186 187 static irqreturn_t 188 snd_harmony_interrupt(int irq, void *dev, struct pt_regs *regs) 189 { 190 u32 dstatus; 191 harmony_t *h = dev; 192 193 spin_lock(&h->lock); 194 harmony_disable_interrupts(h); 195 harmony_wait_for_control(h); 196 dstatus = harmony_read(h, HARMONY_DSTATUS); 197 spin_unlock(&h->lock); 198 199 if (dstatus & HARMONY_DSTATUS_PN) { 200 if (h->psubs && h->st.playing) { 201 spin_lock(&h->lock); 202 h->pbuf.buf += h->pbuf.count; /* PAGE_SIZE */ 203 h->pbuf.buf %= h->pbuf.size; /* MAX_BUFS*PAGE_SIZE */ 204 205 harmony_write(h, HARMONY_PNXTADD, 206 h->pbuf.addr + h->pbuf.buf); 207 h->stats.play_intr++; 208 spin_unlock(&h->lock); 209 snd_pcm_period_elapsed(h->psubs); 210 } else { 211 spin_lock(&h->lock); 212 harmony_write(h, HARMONY_PNXTADD, h->sdma.addr); 213 h->stats.silence_intr++; 214 spin_unlock(&h->lock); 215 } 216 } 217 218 if (dstatus & HARMONY_DSTATUS_RN) { 219 if (h->csubs && h->st.capturing) { 220 spin_lock(&h->lock); 221 h->cbuf.buf += h->cbuf.count; 222 h->cbuf.buf %= h->cbuf.size; 223 224 harmony_write(h, HARMONY_RNXTADD, 225 h->cbuf.addr + h->cbuf.buf); 226 h->stats.rec_intr++; 227 spin_unlock(&h->lock); 228 snd_pcm_period_elapsed(h->csubs); 229 } else { 230 spin_lock(&h->lock); 231 harmony_write(h, HARMONY_RNXTADD, h->gdma.addr); 232 h->stats.graveyard_intr++; 233 spin_unlock(&h->lock); 234 } 235 } 236 237 spin_lock(&h->lock); 238 harmony_enable_interrupts(h); 239 spin_unlock(&h->lock); 240 241 return IRQ_HANDLED; 242 } 243 244 static unsigned int 245 snd_harmony_rate_bits(int rate) 246 { 247 unsigned int i; 248 249 for (i = 0; i < ARRAY_SIZE(snd_harmony_rates); i++) 250 if (snd_harmony_rates[i] == rate) 251 return rate_bits[i]; 252 253 return HARMONY_SR_44KHZ; 254 } 255 256 static snd_pcm_hardware_t snd_harmony_playback = 257 { 258 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | 259 SNDRV_PCM_INFO_JOINT_DUPLEX | SNDRV_PCM_INFO_MMAP_VALID | 260 SNDRV_PCM_INFO_BLOCK_TRANSFER), 261 .formats = (SNDRV_PCM_FMTBIT_S16_BE | SNDRV_PCM_FMTBIT_MU_LAW | 262 SNDRV_PCM_FMTBIT_A_LAW), 263 .rates = (SNDRV_PCM_RATE_5512 | SNDRV_PCM_RATE_8000_48000 | 264 SNDRV_PCM_RATE_KNOT), 265 .rate_min = 5512, 266 .rate_max = 48000, 267 .channels_min = 1, 268 .channels_max = 2, 269 .buffer_bytes_max = MAX_BUF_SIZE, 270 .period_bytes_min = BUF_SIZE, 271 .period_bytes_max = BUF_SIZE, 272 .periods_min = 1, 273 .periods_max = MAX_BUFS, 274 .fifo_size = 0, 275 }; 276 277 static snd_pcm_hardware_t snd_harmony_capture = 278 { 279 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | 280 SNDRV_PCM_INFO_JOINT_DUPLEX | SNDRV_PCM_INFO_MMAP_VALID | 281 SNDRV_PCM_INFO_BLOCK_TRANSFER), 282 .formats = (SNDRV_PCM_FMTBIT_S16_BE | SNDRV_PCM_FMTBIT_MU_LAW | 283 SNDRV_PCM_FMTBIT_A_LAW), 284 .rates = (SNDRV_PCM_RATE_5512 | SNDRV_PCM_RATE_8000_48000 | 285 SNDRV_PCM_RATE_KNOT), 286 .rate_min = 5512, 287 .rate_max = 48000, 288 .channels_min = 1, 289 .channels_max = 2, 290 .buffer_bytes_max = MAX_BUF_SIZE, 291 .period_bytes_min = BUF_SIZE, 292 .period_bytes_max = BUF_SIZE, 293 .periods_min = 1, 294 .periods_max = MAX_BUFS, 295 .fifo_size = 0, 296 }; 297 298 static int 299 snd_harmony_playback_trigger(snd_pcm_substream_t *ss, int cmd) 300 { 301 harmony_t *h = snd_pcm_substream_chip(ss); 302 unsigned long flags; 303 304 if (h->st.capturing) 305 return -EBUSY; 306 307 spin_lock_irqsave(&h->lock, flags); 308 switch (cmd) { 309 case SNDRV_PCM_TRIGGER_START: 310 h->st.playing = 1; 311 harmony_write(h, HARMONY_PNXTADD, h->pbuf.addr); 312 harmony_write(h, HARMONY_RNXTADD, h->gdma.addr); 313 harmony_unmute(h); 314 harmony_enable_interrupts(h); 315 break; 316 case SNDRV_PCM_TRIGGER_STOP: 317 h->st.playing = 0; 318 harmony_mute(h); 319 harmony_write(h, HARMONY_PNXTADD, h->sdma.addr); 320 harmony_disable_interrupts(h); 321 break; 322 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 323 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 324 case SNDRV_PCM_TRIGGER_SUSPEND: 325 default: 326 spin_unlock_irqrestore(&h->lock, flags); 327 snd_BUG(); 328 return -EINVAL; 329 } 330 spin_unlock_irqrestore(&h->lock, flags); 331 332 return 0; 333 } 334 335 static int 336 snd_harmony_capture_trigger(snd_pcm_substream_t *ss, int cmd) 337 { 338 harmony_t *h = snd_pcm_substream_chip(ss); 339 unsigned long flags; 340 341 if (h->st.playing) 342 return -EBUSY; 343 344 spin_lock_irqsave(&h->lock, flags); 345 switch (cmd) { 346 case SNDRV_PCM_TRIGGER_START: 347 h->st.capturing = 1; 348 harmony_write(h, HARMONY_PNXTADD, h->sdma.addr); 349 harmony_write(h, HARMONY_RNXTADD, h->cbuf.addr); 350 harmony_unmute(h); 351 harmony_enable_interrupts(h); 352 break; 353 case SNDRV_PCM_TRIGGER_STOP: 354 h->st.capturing = 0; 355 harmony_mute(h); 356 harmony_write(h, HARMONY_RNXTADD, h->gdma.addr); 357 harmony_disable_interrupts(h); 358 break; 359 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 360 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 361 case SNDRV_PCM_TRIGGER_SUSPEND: 362 default: 363 spin_unlock_irqrestore(&h->lock, flags); 364 snd_BUG(); 365 return -EINVAL; 366 } 367 spin_unlock_irqrestore(&h->lock, flags); 368 369 return 0; 370 } 371 372 static int 373 snd_harmony_set_data_format(harmony_t *h, int fmt, int force) 374 { 375 int o = h->st.format; 376 int n; 377 378 switch(fmt) { 379 case SNDRV_PCM_FORMAT_S16_BE: 380 n = HARMONY_DF_16BIT_LINEAR; 381 break; 382 case SNDRV_PCM_FORMAT_A_LAW: 383 n = HARMONY_DF_8BIT_ALAW; 384 break; 385 case SNDRV_PCM_FORMAT_MU_LAW: 386 n = HARMONY_DF_8BIT_ULAW; 387 break; 388 default: 389 n = HARMONY_DF_16BIT_LINEAR; 390 break; 391 } 392 393 if (force || o != n) { 394 snd_pcm_format_set_silence(fmt, h->sdma.area, SILENCE_BUFSZ / 395 (snd_pcm_format_physical_width(fmt) 396 / 8)); 397 } 398 399 return n; 400 } 401 402 static int 403 snd_harmony_playback_prepare(snd_pcm_substream_t *ss) 404 { 405 harmony_t *h = snd_pcm_substream_chip(ss); 406 snd_pcm_runtime_t *rt = ss->runtime; 407 408 if (h->st.capturing) 409 return -EBUSY; 410 411 h->pbuf.size = snd_pcm_lib_buffer_bytes(ss); 412 h->pbuf.count = snd_pcm_lib_period_bytes(ss); 413 if (h->pbuf.buf >= h->pbuf.size) 414 h->pbuf.buf = 0; 415 h->st.playing = 0; 416 417 h->st.rate = snd_harmony_rate_bits(rt->rate); 418 h->st.format = snd_harmony_set_data_format(h, rt->format, 0); 419 420 if (rt->channels == 2) 421 h->st.stereo = HARMONY_SS_STEREO; 422 else 423 h->st.stereo = HARMONY_SS_MONO; 424 425 harmony_set_control(h); 426 427 h->pbuf.addr = rt->dma_addr; 428 429 return 0; 430 } 431 432 static int 433 snd_harmony_capture_prepare(snd_pcm_substream_t *ss) 434 { 435 harmony_t *h = snd_pcm_substream_chip(ss); 436 snd_pcm_runtime_t *rt = ss->runtime; 437 438 if (h->st.playing) 439 return -EBUSY; 440 441 h->cbuf.size = snd_pcm_lib_buffer_bytes(ss); 442 h->cbuf.count = snd_pcm_lib_period_bytes(ss); 443 if (h->cbuf.buf >= h->cbuf.size) 444 h->cbuf.buf = 0; 445 h->st.capturing = 0; 446 447 h->st.rate = snd_harmony_rate_bits(rt->rate); 448 h->st.format = snd_harmony_set_data_format(h, rt->format, 0); 449 450 if (rt->channels == 2) 451 h->st.stereo = HARMONY_SS_STEREO; 452 else 453 h->st.stereo = HARMONY_SS_MONO; 454 455 harmony_set_control(h); 456 457 h->cbuf.addr = rt->dma_addr; 458 459 return 0; 460 } 461 462 static snd_pcm_uframes_t 463 snd_harmony_playback_pointer(snd_pcm_substream_t *ss) 464 { 465 snd_pcm_runtime_t *rt = ss->runtime; 466 harmony_t *h = snd_pcm_substream_chip(ss); 467 unsigned long pcuradd; 468 unsigned long played; 469 470 if (!(h->st.playing) || (h->psubs == NULL)) 471 return 0; 472 473 if ((h->pbuf.addr == 0) || (h->pbuf.size == 0)) 474 return 0; 475 476 pcuradd = harmony_read(h, HARMONY_PCURADD); 477 played = pcuradd - h->pbuf.addr; 478 479 #ifdef HARMONY_DEBUG 480 printk(KERN_DEBUG PFX "playback_pointer is 0x%lx-0x%lx = %d bytes\n", 481 pcuradd, h->pbuf.addr, played); 482 #endif 483 484 if (pcuradd > h->pbuf.addr + h->pbuf.size) { 485 return 0; 486 } 487 488 return bytes_to_frames(rt, played); 489 } 490 491 static snd_pcm_uframes_t 492 snd_harmony_capture_pointer(snd_pcm_substream_t *ss) 493 { 494 snd_pcm_runtime_t *rt = ss->runtime; 495 harmony_t *h = snd_pcm_substream_chip(ss); 496 unsigned long rcuradd; 497 unsigned long caught; 498 499 if (!(h->st.capturing) || (h->csubs == NULL)) 500 return 0; 501 502 if ((h->cbuf.addr == 0) || (h->cbuf.size == 0)) 503 return 0; 504 505 rcuradd = harmony_read(h, HARMONY_RCURADD); 506 caught = rcuradd - h->cbuf.addr; 507 508 #ifdef HARMONY_DEBUG 509 printk(KERN_DEBUG PFX "capture_pointer is 0x%lx-0x%lx = %d bytes\n", 510 rcuradd, h->cbuf.addr, caught); 511 #endif 512 513 if (rcuradd > h->cbuf.addr + h->cbuf.size) { 514 return 0; 515 } 516 517 return bytes_to_frames(rt, caught); 518 } 519 520 static int 521 snd_harmony_playback_open(snd_pcm_substream_t *ss) 522 { 523 harmony_t *h = snd_pcm_substream_chip(ss); 524 snd_pcm_runtime_t *rt = ss->runtime; 525 int err; 526 527 h->psubs = ss; 528 rt->hw = snd_harmony_playback; 529 snd_pcm_hw_constraint_list(rt, 0, SNDRV_PCM_HW_PARAM_RATE, 530 &hw_constraint_rates); 531 532 err = snd_pcm_hw_constraint_integer(rt, SNDRV_PCM_HW_PARAM_PERIODS); 533 if (err < 0) 534 return err; 535 536 return 0; 537 } 538 539 static int 540 snd_harmony_capture_open(snd_pcm_substream_t *ss) 541 { 542 harmony_t *h = snd_pcm_substream_chip(ss); 543 snd_pcm_runtime_t *rt = ss->runtime; 544 int err; 545 546 h->csubs = ss; 547 rt->hw = snd_harmony_capture; 548 snd_pcm_hw_constraint_list(rt, 0, SNDRV_PCM_HW_PARAM_RATE, 549 &hw_constraint_rates); 550 551 err = snd_pcm_hw_constraint_integer(rt, SNDRV_PCM_HW_PARAM_PERIODS); 552 if (err < 0) 553 return err; 554 555 return 0; 556 } 557 558 static int 559 snd_harmony_playback_close(snd_pcm_substream_t *ss) 560 { 561 harmony_t *h = snd_pcm_substream_chip(ss); 562 h->psubs = NULL; 563 return 0; 564 } 565 566 static int 567 snd_harmony_capture_close(snd_pcm_substream_t *ss) 568 { 569 harmony_t *h = snd_pcm_substream_chip(ss); 570 h->csubs = NULL; 571 return 0; 572 } 573 574 static int 575 snd_harmony_hw_params(snd_pcm_substream_t *ss, 576 snd_pcm_hw_params_t *hw) 577 { 578 int err; 579 harmony_t *h = snd_pcm_substream_chip(ss); 580 581 err = snd_pcm_lib_malloc_pages(ss, params_buffer_bytes(hw)); 582 if (err > 0 && h->dma.type == SNDRV_DMA_TYPE_CONTINUOUS) 583 ss->runtime->dma_addr = __pa(ss->runtime->dma_area); 584 585 return err; 586 } 587 588 static int 589 snd_harmony_hw_free(snd_pcm_substream_t *ss) 590 { 591 return snd_pcm_lib_free_pages(ss); 592 } 593 594 static snd_pcm_ops_t snd_harmony_playback_ops = { 595 .open = snd_harmony_playback_open, 596 .close = snd_harmony_playback_close, 597 .ioctl = snd_pcm_lib_ioctl, 598 .hw_params = snd_harmony_hw_params, 599 .hw_free = snd_harmony_hw_free, 600 .prepare = snd_harmony_playback_prepare, 601 .trigger = snd_harmony_playback_trigger, 602 .pointer = snd_harmony_playback_pointer, 603 }; 604 605 static snd_pcm_ops_t snd_harmony_capture_ops = { 606 .open = snd_harmony_capture_open, 607 .close = snd_harmony_capture_close, 608 .ioctl = snd_pcm_lib_ioctl, 609 .hw_params = snd_harmony_hw_params, 610 .hw_free = snd_harmony_hw_free, 611 .prepare = snd_harmony_capture_prepare, 612 .trigger = snd_harmony_capture_trigger, 613 .pointer = snd_harmony_capture_pointer, 614 }; 615 616 static int 617 snd_harmony_pcm_init(harmony_t *h) 618 { 619 snd_pcm_t *pcm; 620 int err; 621 622 harmony_disable_interrupts(h); 623 624 err = snd_pcm_new(h->card, "harmony", 0, 1, 1, &pcm); 625 if (err < 0) 626 return err; 627 628 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, 629 &snd_harmony_playback_ops); 630 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, 631 &snd_harmony_capture_ops); 632 633 pcm->private_data = h; 634 pcm->info_flags = 0; 635 strcpy(pcm->name, "harmony"); 636 h->pcm = pcm; 637 638 h->psubs = NULL; 639 h->csubs = NULL; 640 641 /* initialize graveyard buffer */ 642 h->dma.type = SNDRV_DMA_TYPE_DEV; 643 h->dma.dev = &h->dev->dev; 644 err = snd_dma_alloc_pages(h->dma.type, 645 h->dma.dev, 646 BUF_SIZE*GRAVEYARD_BUFS, 647 &h->gdma); 648 if (err < 0) { 649 printk(KERN_ERR PFX "cannot allocate graveyard buffer!\n"); 650 return err; 651 } 652 653 /* initialize silence buffers */ 654 err = snd_dma_alloc_pages(h->dma.type, 655 h->dma.dev, 656 BUF_SIZE*SILENCE_BUFS, 657 &h->sdma); 658 if (err < 0) { 659 printk(KERN_ERR PFX "cannot allocate silence buffer!\n"); 660 return err; 661 } 662 663 /* pre-allocate space for DMA */ 664 err = snd_pcm_lib_preallocate_pages_for_all(pcm, h->dma.type, 665 h->dma.dev, 666 MAX_BUF_SIZE, 667 MAX_BUF_SIZE); 668 if (err < 0) { 669 printk(KERN_ERR PFX "buffer allocation error: %d\n", err); 670 return err; 671 } 672 673 h->st.format = snd_harmony_set_data_format(h, 674 SNDRV_PCM_FORMAT_S16_BE, 1); 675 676 return 0; 677 } 678 679 static void 680 snd_harmony_set_new_gain(harmony_t *h) 681 { 682 harmony_wait_for_control(h); 683 harmony_write(h, HARMONY_GAINCTL, h->st.gain); 684 } 685 686 static int 687 snd_harmony_mixercontrol_info(snd_kcontrol_t *kc, 688 snd_ctl_elem_info_t *uinfo) 689 { 690 int mask = (kc->private_value >> 16) & 0xff; 691 int left_shift = (kc->private_value) & 0xff; 692 int right_shift = (kc->private_value >> 8) & 0xff; 693 694 uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : 695 SNDRV_CTL_ELEM_TYPE_INTEGER; 696 uinfo->count = left_shift == right_shift ? 1 : 2; 697 uinfo->value.integer.min = 0; 698 uinfo->value.integer.max = mask; 699 700 return 0; 701 } 702 703 static int 704 snd_harmony_volume_get(snd_kcontrol_t *kc, 705 snd_ctl_elem_value_t *ucontrol) 706 { 707 harmony_t *h = snd_kcontrol_chip(kc); 708 int shift_left = (kc->private_value) & 0xff; 709 int shift_right = (kc->private_value >> 8) & 0xff; 710 int mask = (kc->private_value >> 16) & 0xff; 711 int invert = (kc->private_value >> 24) & 0xff; 712 int left, right; 713 unsigned long flags; 714 715 spin_lock_irqsave(&h->mixer_lock, flags); 716 717 left = (h->st.gain >> shift_left) & mask; 718 right = (h->st.gain >> shift_right) & mask; 719 if (invert) { 720 left = mask - left; 721 right = mask - right; 722 } 723 724 ucontrol->value.integer.value[0] = left; 725 if (shift_left != shift_right) 726 ucontrol->value.integer.value[1] = right; 727 728 spin_unlock_irqrestore(&h->mixer_lock, flags); 729 730 return 0; 731 } 732 733 static int 734 snd_harmony_volume_put(snd_kcontrol_t *kc, 735 snd_ctl_elem_value_t *ucontrol) 736 { 737 harmony_t *h = snd_kcontrol_chip(kc); 738 int shift_left = (kc->private_value) & 0xff; 739 int shift_right = (kc->private_value >> 8) & 0xff; 740 int mask = (kc->private_value >> 16) & 0xff; 741 int invert = (kc->private_value >> 24) & 0xff; 742 int left, right; 743 int old_gain = h->st.gain; 744 unsigned long flags; 745 746 spin_lock_irqsave(&h->mixer_lock, flags); 747 748 left = ucontrol->value.integer.value[0] & mask; 749 if (invert) 750 left = mask - left; 751 h->st.gain &= ~( (mask << shift_left ) ); 752 h->st.gain |= (left << shift_left); 753 754 if (shift_left != shift_right) { 755 right = ucontrol->value.integer.value[1] & mask; 756 if (invert) 757 right = mask - right; 758 h->st.gain &= ~( (mask << shift_right) ); 759 h->st.gain |= (right << shift_right); 760 } 761 762 snd_harmony_set_new_gain(h); 763 764 spin_unlock_irqrestore(&h->mixer_lock, flags); 765 766 return h->st.gain != old_gain; 767 } 768 769 static int 770 snd_harmony_captureroute_info(snd_kcontrol_t *kc, 771 snd_ctl_elem_info_t *uinfo) 772 { 773 static char *texts[2] = { "Line", "Mic" }; 774 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 775 uinfo->count = 1; 776 uinfo->value.enumerated.items = 2; 777 if (uinfo->value.enumerated.item > 1) 778 uinfo->value.enumerated.item = 1; 779 strcpy(uinfo->value.enumerated.name, 780 texts[uinfo->value.enumerated.item]); 781 return 0; 782 } 783 784 static int 785 snd_harmony_captureroute_get(snd_kcontrol_t *kc, 786 snd_ctl_elem_value_t *ucontrol) 787 { 788 harmony_t *h = snd_kcontrol_chip(kc); 789 int value; 790 unsigned long flags; 791 792 spin_lock_irqsave(&h->mixer_lock, flags); 793 794 value = (h->st.gain >> HARMONY_GAIN_IS_SHIFT) & 1; 795 ucontrol->value.enumerated.item[0] = value; 796 797 spin_unlock_irqrestore(&h->mixer_lock, flags); 798 799 return 0; 800 } 801 802 static int 803 snd_harmony_captureroute_put(snd_kcontrol_t *kc, 804 snd_ctl_elem_value_t *ucontrol) 805 { 806 harmony_t *h = snd_kcontrol_chip(kc); 807 int value; 808 int old_gain = h->st.gain; 809 unsigned long flags; 810 811 spin_lock_irqsave(&h->mixer_lock, flags); 812 813 value = ucontrol->value.enumerated.item[0] & 1; 814 h->st.gain &= ~HARMONY_GAIN_IS_MASK; 815 h->st.gain |= value << HARMONY_GAIN_IS_SHIFT; 816 817 snd_harmony_set_new_gain(h); 818 819 spin_unlock_irqrestore(&h->mixer_lock, flags); 820 821 return h->st.gain != old_gain; 822 } 823 824 #define HARMONY_CONTROLS (sizeof(snd_harmony_controls)/ \ 825 sizeof(snd_kcontrol_new_t)) 826 827 #define HARMONY_VOLUME(xname, left_shift, right_shift, mask, invert) \ 828 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ 829 .info = snd_harmony_mixercontrol_info, \ 830 .get = snd_harmony_volume_get, .put = snd_harmony_volume_put, \ 831 .private_value = ((left_shift) | ((right_shift) << 8) | \ 832 ((mask) << 16) | ((invert) << 24)) } 833 834 static snd_kcontrol_new_t snd_harmony_controls[] = { 835 HARMONY_VOLUME("Master Playback Volume", HARMONY_GAIN_LO_SHIFT, 836 HARMONY_GAIN_RO_SHIFT, HARMONY_GAIN_OUT, 1), 837 HARMONY_VOLUME("Capture Volume", HARMONY_GAIN_LI_SHIFT, 838 HARMONY_GAIN_RI_SHIFT, HARMONY_GAIN_IN, 0), 839 HARMONY_VOLUME("Monitor Volume", HARMONY_GAIN_MA_SHIFT, 840 HARMONY_GAIN_MA_SHIFT, HARMONY_GAIN_MA, 1), 841 { 842 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 843 .name = "Input Route", 844 .info = snd_harmony_captureroute_info, 845 .get = snd_harmony_captureroute_get, 846 .put = snd_harmony_captureroute_put 847 }, 848 HARMONY_VOLUME("Internal Speaker Switch", HARMONY_GAIN_SE_SHIFT, 849 HARMONY_GAIN_SE_SHIFT, 1, 0), 850 HARMONY_VOLUME("Line-Out Switch", HARMONY_GAIN_LE_SHIFT, 851 HARMONY_GAIN_LE_SHIFT, 1, 0), 852 HARMONY_VOLUME("Headphones Switch", HARMONY_GAIN_HE_SHIFT, 853 HARMONY_GAIN_HE_SHIFT, 1, 0), 854 }; 855 856 static void __init 857 snd_harmony_mixer_reset(harmony_t *h) 858 { 859 harmony_mute(h); 860 harmony_reset(h); 861 h->st.gain = HARMONY_GAIN_DEFAULT; 862 harmony_unmute(h); 863 } 864 865 static int __init 866 snd_harmony_mixer_init(harmony_t *h) 867 { 868 snd_card_t *card = h->card; 869 int idx, err; 870 871 snd_assert(h != NULL, return -EINVAL); 872 strcpy(card->mixername, "Harmony Gain control interface"); 873 874 for (idx = 0; idx < HARMONY_CONTROLS; idx++) { 875 err = snd_ctl_add(card, 876 snd_ctl_new1(&snd_harmony_controls[idx], h)); 877 if (err < 0) 878 return err; 879 } 880 881 snd_harmony_mixer_reset(h); 882 883 return 0; 884 } 885 886 static int 887 snd_harmony_free(harmony_t *h) 888 { 889 if (h->gdma.addr) 890 snd_dma_free_pages(&h->gdma); 891 if (h->sdma.addr) 892 snd_dma_free_pages(&h->sdma); 893 894 if (h->irq >= 0) 895 free_irq(h->irq, h); 896 897 if (h->iobase) 898 iounmap(h->iobase); 899 900 parisc_set_drvdata(h->dev, NULL); 901 902 kfree(h); 903 return 0; 904 } 905 906 static int 907 snd_harmony_dev_free(snd_device_t *dev) 908 { 909 harmony_t *h = dev->device_data; 910 return snd_harmony_free(h); 911 } 912 913 static int __devinit 914 snd_harmony_create(snd_card_t *card, 915 struct parisc_device *padev, 916 harmony_t **rchip) 917 { 918 int err; 919 harmony_t *h; 920 static snd_device_ops_t ops = { 921 .dev_free = snd_harmony_dev_free, 922 }; 923 924 *rchip = NULL; 925 926 h = kmalloc(sizeof(*h), GFP_KERNEL); 927 if (h == NULL) 928 return -ENOMEM; 929 930 memset(&h->st, 0, sizeof(h->st)); 931 memset(&h->stats, 0, sizeof(h->stats)); 932 memset(&h->pbuf, 0, sizeof(h->pbuf)); 933 memset(&h->cbuf, 0, sizeof(h->cbuf)); 934 935 h->hpa = padev->hpa.start; 936 h->card = card; 937 h->dev = padev; 938 h->irq = padev->irq; 939 h->iobase = ioremap_nocache(padev->hpa.start, HARMONY_SIZE); 940 if (h->iobase == NULL) { 941 printk(KERN_ERR PFX "unable to remap hpa 0x%lx\n", 942 padev->hpa.start); 943 err = -EBUSY; 944 goto free_and_ret; 945 } 946 947 err = request_irq(h->irq, snd_harmony_interrupt, 0, 948 "harmony", h); 949 if (err) { 950 printk(KERN_ERR PFX "could not obtain interrupt %d", 951 h->irq); 952 goto free_and_ret; 953 } 954 955 spin_lock_init(&h->mixer_lock); 956 spin_lock_init(&h->lock); 957 958 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, 959 h, &ops)) < 0) { 960 goto free_and_ret; 961 } 962 963 snd_card_set_dev(card, &padev->dev); 964 965 *rchip = h; 966 967 return 0; 968 969 free_and_ret: 970 snd_harmony_free(h); 971 return err; 972 } 973 974 static int __devinit 975 snd_harmony_probe(struct parisc_device *padev) 976 { 977 int err; 978 static int dev; 979 snd_card_t *card; 980 harmony_t *h; 981 static int index = SNDRV_DEFAULT_IDX1; 982 static char *id = SNDRV_DEFAULT_STR1; 983 984 h = parisc_get_drvdata(padev); 985 if (h != NULL) { 986 return -ENODEV; 987 } 988 989 card = snd_card_new(index, id, THIS_MODULE, 0); 990 if (card == NULL) 991 return -ENOMEM; 992 993 err = snd_harmony_create(card, padev, &h); 994 if (err < 0) { 995 goto free_and_ret; 996 } 997 998 err = snd_harmony_pcm_init(h); 999 if (err < 0) { 1000 goto free_and_ret; 1001 } 1002 1003 err = snd_harmony_mixer_init(h); 1004 if (err < 0) { 1005 goto free_and_ret; 1006 } 1007 1008 strcpy(card->driver, "harmony"); 1009 strcpy(card->shortname, "Harmony"); 1010 sprintf(card->longname, "%s at 0x%lx, irq %i", 1011 card->shortname, h->hpa, h->irq); 1012 1013 err = snd_card_register(card); 1014 if (err < 0) { 1015 goto free_and_ret; 1016 } 1017 1018 dev++; 1019 parisc_set_drvdata(padev, h); 1020 1021 return 0; 1022 1023 free_and_ret: 1024 snd_card_free(card); 1025 return err; 1026 } 1027 1028 static int __devexit 1029 snd_harmony_remove(struct parisc_device *padev) 1030 { 1031 harmony_t *h = parisc_get_drvdata(padev); 1032 snd_card_free(h->card); 1033 return 0; 1034 } 1035 1036 static struct parisc_driver snd_harmony_driver = { 1037 .name = "harmony", 1038 .id_table = snd_harmony_devtable, 1039 .probe = snd_harmony_probe, 1040 .remove = snd_harmony_remove, 1041 }; 1042 1043 static int __init 1044 alsa_harmony_init(void) 1045 { 1046 int err; 1047 1048 err = register_parisc_driver(&snd_harmony_driver); 1049 if (err < 0) { 1050 printk(KERN_ERR PFX "device not found\n"); 1051 return err; 1052 } 1053 1054 return 0; 1055 } 1056 1057 static void __exit 1058 alsa_harmony_fini(void) 1059 { 1060 int err; 1061 1062 err = unregister_parisc_driver(&snd_harmony_driver); 1063 if (err < 0) { 1064 printk(KERN_ERR PFX "failed to unregister\n"); 1065 } 1066 1067 return; 1068 } 1069 1070 MODULE_LICENSE("GPL"); 1071 MODULE_AUTHOR("Kyle McMartin <kyle@parisc-linux.org>"); 1072 MODULE_DESCRIPTION("Harmony sound driver"); 1073 1074 module_init(alsa_harmony_init); 1075 module_exit(alsa_harmony_fini); 1076