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