root/sound/parisc/harmony.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. harmony_read
  2. harmony_write
  3. harmony_wait_for_control
  4. harmony_reset
  5. harmony_disable_interrupts
  6. harmony_enable_interrupts
  7. harmony_mute
  8. harmony_unmute
  9. harmony_set_control
  10. snd_harmony_interrupt
  11. snd_harmony_rate_bits
  12. snd_harmony_playback_trigger
  13. snd_harmony_capture_trigger
  14. snd_harmony_set_data_format
  15. snd_harmony_playback_prepare
  16. snd_harmony_capture_prepare
  17. snd_harmony_playback_pointer
  18. snd_harmony_capture_pointer
  19. snd_harmony_playback_open
  20. snd_harmony_capture_open
  21. snd_harmony_playback_close
  22. snd_harmony_capture_close
  23. snd_harmony_hw_params
  24. snd_harmony_hw_free
  25. snd_harmony_pcm_init
  26. snd_harmony_set_new_gain
  27. snd_harmony_mixercontrol_info
  28. snd_harmony_volume_get
  29. snd_harmony_volume_put
  30. snd_harmony_captureroute_info
  31. snd_harmony_captureroute_get
  32. snd_harmony_captureroute_put
  33. snd_harmony_mixer_reset
  34. snd_harmony_mixer_init
  35. snd_harmony_free
  36. snd_harmony_dev_free
  37. snd_harmony_create
  38. snd_harmony_probe
  39. snd_harmony_remove
  40. alsa_harmony_init
  41. alsa_harmony_fini

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

/* [<][>][^][v][top][bottom][index][help] */