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 .hw_params = snd_harmony_hw_params, 582 .prepare = snd_harmony_playback_prepare, 583 .trigger = snd_harmony_playback_trigger, 584 .pointer = snd_harmony_playback_pointer, 585 }; 586 587 static const struct snd_pcm_ops snd_harmony_capture_ops = { 588 .open = snd_harmony_capture_open, 589 .close = snd_harmony_capture_close, 590 .hw_params = snd_harmony_hw_params, 591 .prepare = snd_harmony_capture_prepare, 592 .trigger = snd_harmony_capture_trigger, 593 .pointer = snd_harmony_capture_pointer, 594 }; 595 596 static int 597 snd_harmony_pcm_init(struct snd_harmony *h) 598 { 599 struct snd_pcm *pcm; 600 int err; 601 602 if (snd_BUG_ON(!h)) 603 return -EINVAL; 604 605 harmony_disable_interrupts(h); 606 607 err = snd_pcm_new(h->card, "harmony", 0, 1, 1, &pcm); 608 if (err < 0) 609 return err; 610 611 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, 612 &snd_harmony_playback_ops); 613 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, 614 &snd_harmony_capture_ops); 615 616 pcm->private_data = h; 617 pcm->info_flags = 0; 618 strcpy(pcm->name, "harmony"); 619 h->pcm = pcm; 620 621 h->psubs = NULL; 622 h->csubs = NULL; 623 624 /* initialize graveyard buffer */ 625 h->dma.type = SNDRV_DMA_TYPE_DEV; 626 h->dma.dev = &h->dev->dev; 627 err = snd_dma_alloc_pages(h->dma.type, 628 h->dma.dev, 629 BUF_SIZE*GRAVEYARD_BUFS, 630 &h->gdma); 631 if (err < 0) { 632 printk(KERN_ERR PFX "cannot allocate graveyard buffer!\n"); 633 return err; 634 } 635 636 /* initialize silence buffers */ 637 err = snd_dma_alloc_pages(h->dma.type, 638 h->dma.dev, 639 BUF_SIZE*SILENCE_BUFS, 640 &h->sdma); 641 if (err < 0) { 642 printk(KERN_ERR PFX "cannot allocate silence buffer!\n"); 643 return err; 644 } 645 646 /* pre-allocate space for DMA */ 647 snd_pcm_set_managed_buffer_all(pcm, h->dma.type, h->dma.dev, 648 MAX_BUF_SIZE, MAX_BUF_SIZE); 649 650 h->st.format = snd_harmony_set_data_format(h, 651 SNDRV_PCM_FORMAT_S16_BE, 1); 652 653 return 0; 654 } 655 656 static void 657 snd_harmony_set_new_gain(struct snd_harmony *h) 658 { 659 harmony_wait_for_control(h); 660 harmony_write(h, HARMONY_GAINCTL, h->st.gain); 661 } 662 663 static int 664 snd_harmony_mixercontrol_info(struct snd_kcontrol *kc, 665 struct snd_ctl_elem_info *uinfo) 666 { 667 int mask = (kc->private_value >> 16) & 0xff; 668 int left_shift = (kc->private_value) & 0xff; 669 int right_shift = (kc->private_value >> 8) & 0xff; 670 671 uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : 672 SNDRV_CTL_ELEM_TYPE_INTEGER; 673 uinfo->count = left_shift == right_shift ? 1 : 2; 674 uinfo->value.integer.min = 0; 675 uinfo->value.integer.max = mask; 676 677 return 0; 678 } 679 680 static int 681 snd_harmony_volume_get(struct snd_kcontrol *kc, 682 struct snd_ctl_elem_value *ucontrol) 683 { 684 struct snd_harmony *h = snd_kcontrol_chip(kc); 685 int shift_left = (kc->private_value) & 0xff; 686 int shift_right = (kc->private_value >> 8) & 0xff; 687 int mask = (kc->private_value >> 16) & 0xff; 688 int invert = (kc->private_value >> 24) & 0xff; 689 int left, right; 690 691 spin_lock_irq(&h->mixer_lock); 692 693 left = (h->st.gain >> shift_left) & mask; 694 right = (h->st.gain >> shift_right) & mask; 695 if (invert) { 696 left = mask - left; 697 right = mask - right; 698 } 699 700 ucontrol->value.integer.value[0] = left; 701 if (shift_left != shift_right) 702 ucontrol->value.integer.value[1] = right; 703 704 spin_unlock_irq(&h->mixer_lock); 705 706 return 0; 707 } 708 709 static int 710 snd_harmony_volume_put(struct snd_kcontrol *kc, 711 struct snd_ctl_elem_value *ucontrol) 712 { 713 struct snd_harmony *h = snd_kcontrol_chip(kc); 714 int shift_left = (kc->private_value) & 0xff; 715 int shift_right = (kc->private_value >> 8) & 0xff; 716 int mask = (kc->private_value >> 16) & 0xff; 717 int invert = (kc->private_value >> 24) & 0xff; 718 int left, right; 719 int old_gain = h->st.gain; 720 721 spin_lock_irq(&h->mixer_lock); 722 723 left = ucontrol->value.integer.value[0] & mask; 724 if (invert) 725 left = mask - left; 726 h->st.gain &= ~( (mask << shift_left ) ); 727 h->st.gain |= (left << shift_left); 728 729 if (shift_left != shift_right) { 730 right = ucontrol->value.integer.value[1] & mask; 731 if (invert) 732 right = mask - right; 733 h->st.gain &= ~( (mask << shift_right) ); 734 h->st.gain |= (right << shift_right); 735 } 736 737 snd_harmony_set_new_gain(h); 738 739 spin_unlock_irq(&h->mixer_lock); 740 741 return h->st.gain != old_gain; 742 } 743 744 static int 745 snd_harmony_captureroute_info(struct snd_kcontrol *kc, 746 struct snd_ctl_elem_info *uinfo) 747 { 748 static const char * const texts[2] = { "Line", "Mic" }; 749 750 return snd_ctl_enum_info(uinfo, 1, 2, texts); 751 } 752 753 static int 754 snd_harmony_captureroute_get(struct snd_kcontrol *kc, 755 struct snd_ctl_elem_value *ucontrol) 756 { 757 struct snd_harmony *h = snd_kcontrol_chip(kc); 758 int value; 759 760 spin_lock_irq(&h->mixer_lock); 761 762 value = (h->st.gain >> HARMONY_GAIN_IS_SHIFT) & 1; 763 ucontrol->value.enumerated.item[0] = value; 764 765 spin_unlock_irq(&h->mixer_lock); 766 767 return 0; 768 } 769 770 static int 771 snd_harmony_captureroute_put(struct snd_kcontrol *kc, 772 struct snd_ctl_elem_value *ucontrol) 773 { 774 struct snd_harmony *h = snd_kcontrol_chip(kc); 775 int value; 776 int old_gain = h->st.gain; 777 778 spin_lock_irq(&h->mixer_lock); 779 780 value = ucontrol->value.enumerated.item[0] & 1; 781 h->st.gain &= ~HARMONY_GAIN_IS_MASK; 782 h->st.gain |= value << HARMONY_GAIN_IS_SHIFT; 783 784 snd_harmony_set_new_gain(h); 785 786 spin_unlock_irq(&h->mixer_lock); 787 788 return h->st.gain != old_gain; 789 } 790 791 #define HARMONY_CONTROLS ARRAY_SIZE(snd_harmony_controls) 792 793 #define HARMONY_VOLUME(xname, left_shift, right_shift, mask, invert) \ 794 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ 795 .info = snd_harmony_mixercontrol_info, \ 796 .get = snd_harmony_volume_get, .put = snd_harmony_volume_put, \ 797 .private_value = ((left_shift) | ((right_shift) << 8) | \ 798 ((mask) << 16) | ((invert) << 24)) } 799 800 static const struct snd_kcontrol_new snd_harmony_controls[] = { 801 HARMONY_VOLUME("Master Playback Volume", HARMONY_GAIN_LO_SHIFT, 802 HARMONY_GAIN_RO_SHIFT, HARMONY_GAIN_OUT, 1), 803 HARMONY_VOLUME("Capture Volume", HARMONY_GAIN_LI_SHIFT, 804 HARMONY_GAIN_RI_SHIFT, HARMONY_GAIN_IN, 0), 805 HARMONY_VOLUME("Monitor Volume", HARMONY_GAIN_MA_SHIFT, 806 HARMONY_GAIN_MA_SHIFT, HARMONY_GAIN_MA, 1), 807 { 808 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 809 .name = "Input Route", 810 .info = snd_harmony_captureroute_info, 811 .get = snd_harmony_captureroute_get, 812 .put = snd_harmony_captureroute_put 813 }, 814 HARMONY_VOLUME("Internal Speaker Switch", HARMONY_GAIN_SE_SHIFT, 815 HARMONY_GAIN_SE_SHIFT, 1, 0), 816 HARMONY_VOLUME("Line-Out Switch", HARMONY_GAIN_LE_SHIFT, 817 HARMONY_GAIN_LE_SHIFT, 1, 0), 818 HARMONY_VOLUME("Headphones Switch", HARMONY_GAIN_HE_SHIFT, 819 HARMONY_GAIN_HE_SHIFT, 1, 0), 820 }; 821 822 static void 823 snd_harmony_mixer_reset(struct snd_harmony *h) 824 { 825 harmony_mute(h); 826 harmony_reset(h); 827 h->st.gain = HARMONY_GAIN_DEFAULT; 828 harmony_unmute(h); 829 } 830 831 static int 832 snd_harmony_mixer_init(struct snd_harmony *h) 833 { 834 struct snd_card *card; 835 int idx, err; 836 837 if (snd_BUG_ON(!h)) 838 return -EINVAL; 839 card = h->card; 840 strcpy(card->mixername, "Harmony Gain control interface"); 841 842 for (idx = 0; idx < HARMONY_CONTROLS; idx++) { 843 err = snd_ctl_add(card, 844 snd_ctl_new1(&snd_harmony_controls[idx], h)); 845 if (err < 0) 846 return err; 847 } 848 849 snd_harmony_mixer_reset(h); 850 851 return 0; 852 } 853 854 static int 855 snd_harmony_free(struct snd_harmony *h) 856 { 857 if (h->gdma.addr) 858 snd_dma_free_pages(&h->gdma); 859 if (h->sdma.addr) 860 snd_dma_free_pages(&h->sdma); 861 862 if (h->irq >= 0) 863 free_irq(h->irq, h); 864 865 iounmap(h->iobase); 866 kfree(h); 867 return 0; 868 } 869 870 static int 871 snd_harmony_dev_free(struct snd_device *dev) 872 { 873 struct snd_harmony *h = dev->device_data; 874 return snd_harmony_free(h); 875 } 876 877 static int 878 snd_harmony_create(struct snd_card *card, 879 struct parisc_device *padev, 880 struct snd_harmony **rchip) 881 { 882 int err; 883 struct snd_harmony *h; 884 static const struct snd_device_ops ops = { 885 .dev_free = snd_harmony_dev_free, 886 }; 887 888 *rchip = NULL; 889 890 h = kzalloc(sizeof(*h), GFP_KERNEL); 891 if (h == NULL) 892 return -ENOMEM; 893 894 h->hpa = padev->hpa.start; 895 h->card = card; 896 h->dev = padev; 897 h->irq = -1; 898 h->iobase = ioremap(padev->hpa.start, HARMONY_SIZE); 899 if (h->iobase == NULL) { 900 printk(KERN_ERR PFX "unable to remap hpa 0x%lx\n", 901 (unsigned long)padev->hpa.start); 902 err = -EBUSY; 903 goto free_and_ret; 904 } 905 906 err = request_irq(padev->irq, snd_harmony_interrupt, 0, 907 "harmony", h); 908 if (err) { 909 printk(KERN_ERR PFX "could not obtain interrupt %d", 910 padev->irq); 911 goto free_and_ret; 912 } 913 h->irq = padev->irq; 914 915 spin_lock_init(&h->mixer_lock); 916 spin_lock_init(&h->lock); 917 918 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, 919 h, &ops)) < 0) { 920 goto free_and_ret; 921 } 922 923 *rchip = h; 924 925 return 0; 926 927 free_and_ret: 928 snd_harmony_free(h); 929 return err; 930 } 931 932 static int __init 933 snd_harmony_probe(struct parisc_device *padev) 934 { 935 int err; 936 struct snd_card *card; 937 struct snd_harmony *h; 938 939 err = snd_card_new(&padev->dev, index, id, THIS_MODULE, 0, &card); 940 if (err < 0) 941 return err; 942 943 err = snd_harmony_create(card, padev, &h); 944 if (err < 0) 945 goto free_and_ret; 946 947 err = snd_harmony_pcm_init(h); 948 if (err < 0) 949 goto free_and_ret; 950 951 err = snd_harmony_mixer_init(h); 952 if (err < 0) 953 goto free_and_ret; 954 955 strcpy(card->driver, "harmony"); 956 strcpy(card->shortname, "Harmony"); 957 sprintf(card->longname, "%s at 0x%lx, irq %i", 958 card->shortname, h->hpa, h->irq); 959 960 err = snd_card_register(card); 961 if (err < 0) 962 goto free_and_ret; 963 964 parisc_set_drvdata(padev, card); 965 return 0; 966 967 free_and_ret: 968 snd_card_free(card); 969 return err; 970 } 971 972 static int __exit 973 snd_harmony_remove(struct parisc_device *padev) 974 { 975 snd_card_free(parisc_get_drvdata(padev)); 976 return 0; 977 } 978 979 static struct parisc_driver snd_harmony_driver __refdata = { 980 .name = "harmony", 981 .id_table = snd_harmony_devtable, 982 .probe = snd_harmony_probe, 983 .remove = __exit_p(snd_harmony_remove), 984 }; 985 986 static int __init 987 alsa_harmony_init(void) 988 { 989 return register_parisc_driver(&snd_harmony_driver); 990 } 991 992 static void __exit 993 alsa_harmony_fini(void) 994 { 995 unregister_parisc_driver(&snd_harmony_driver); 996 } 997 998 MODULE_LICENSE("GPL"); 999 MODULE_AUTHOR("Kyle McMartin <kyle@parisc-linux.org>"); 1000 MODULE_DESCRIPTION("Harmony sound driver"); 1001 1002 module_init(alsa_harmony_init); 1003 module_exit(alsa_harmony_fini); 1004