]> pilppa.org Git - linux-2.6-omap-h63xx.git/blob - sound/parisc/harmony.c
Merge /spare/repo/linux-2.6/
[linux-2.6-omap-h63xx.git] / sound / parisc / harmony.c
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) {
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) {
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_disable_interrupts(h);
320                 break;
321         case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
322         case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
323         case SNDRV_PCM_TRIGGER_SUSPEND:
324         default:
325                 spin_unlock_irqrestore(&h->lock, flags);
326                 snd_BUG();
327                 return -EINVAL;
328         }
329         spin_unlock_irqrestore(&h->lock, flags);
330         
331         return 0;
332 }
333
334 static int
335 snd_harmony_capture_trigger(snd_pcm_substream_t *ss, int cmd)
336 {
337         harmony_t *h = snd_pcm_substream_chip(ss);
338         unsigned long flags;
339
340         if (h->st.playing)
341                 return -EBUSY;
342
343         spin_lock_irqsave(&h->lock, flags);
344         switch (cmd) {
345         case SNDRV_PCM_TRIGGER_START:
346                 h->st.capturing = 1;
347                 harmony_write(h, HARMONY_PNXTADD, h->sdma.addr);
348                 harmony_write(h, HARMONY_RNXTADD, h->cbuf.addr);
349                 harmony_unmute(h);
350                 harmony_enable_interrupts(h);
351                 break;
352         case SNDRV_PCM_TRIGGER_STOP:
353                 h->st.capturing = 0;
354                 harmony_mute(h);
355                 harmony_disable_interrupts(h);
356                 break;
357         case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
358         case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
359         case SNDRV_PCM_TRIGGER_SUSPEND:
360         default:
361                 spin_unlock_irqrestore(&h->lock, flags);
362                 snd_BUG();
363                 return -EINVAL;
364         }
365         spin_unlock_irqrestore(&h->lock, flags);
366                 
367         return 0;
368 }
369
370 static int
371 snd_harmony_set_data_format(harmony_t *h, int fmt, int force)
372 {
373         int o = h->st.format;
374         int n;
375
376         switch(fmt) {
377         case SNDRV_PCM_FORMAT_S16_BE:
378                 n = HARMONY_DF_16BIT_LINEAR;
379                 break;
380         case SNDRV_PCM_FORMAT_A_LAW:
381                 n = HARMONY_DF_8BIT_ALAW;
382                 break;
383         case SNDRV_PCM_FORMAT_MU_LAW:
384                 n = HARMONY_DF_8BIT_ULAW;
385                 break;
386         default:
387                 n = HARMONY_DF_16BIT_LINEAR;
388                 break;
389         }
390
391         if (force || o != n) {
392                 snd_pcm_format_set_silence(fmt, h->sdma.area, SILENCE_BUFSZ / 
393                                            (snd_pcm_format_physical_width(fmt)
394                                             / 8));
395         }
396
397         return n;
398 }
399
400 static int
401 snd_harmony_playback_prepare(snd_pcm_substream_t *ss)
402 {
403         harmony_t *h = snd_pcm_substream_chip(ss);
404         snd_pcm_runtime_t *rt = ss->runtime;
405         
406         if (h->st.capturing)
407                 return -EBUSY;
408         
409         h->pbuf.size = snd_pcm_lib_buffer_bytes(ss);
410         h->pbuf.count = snd_pcm_lib_period_bytes(ss);
411         h->pbuf.buf = 0;
412         h->st.playing = 0;
413
414         h->st.rate = snd_harmony_rate_bits(rt->rate);
415         h->st.format = snd_harmony_set_data_format(h, rt->format, 0);
416         
417         if (rt->channels == 2)
418                 h->st.stereo = HARMONY_SS_STEREO;
419         else
420                 h->st.stereo = HARMONY_SS_MONO;
421
422         harmony_set_control(h);
423
424         h->pbuf.addr = rt->dma_addr;
425
426         return 0;
427 }
428
429 static int
430 snd_harmony_capture_prepare(snd_pcm_substream_t *ss)
431 {
432         harmony_t *h = snd_pcm_substream_chip(ss);
433         snd_pcm_runtime_t *rt = ss->runtime;
434
435         if (h->st.playing)
436                 return -EBUSY;
437
438         h->cbuf.size = snd_pcm_lib_buffer_bytes(ss);
439         h->cbuf.count = snd_pcm_lib_period_bytes(ss);
440         h->cbuf.buf = 0;
441         h->st.capturing = 0;
442
443         h->st.rate = snd_harmony_rate_bits(rt->rate);
444         h->st.format = snd_harmony_set_data_format(h, rt->format, 0);
445
446         if (rt->channels == 2)
447                 h->st.stereo = HARMONY_SS_STEREO;
448         else
449                 h->st.stereo = HARMONY_SS_MONO;
450
451         harmony_set_control(h);
452
453         h->cbuf.addr = rt->dma_addr;
454
455         return 0;
456 }
457
458 static snd_pcm_uframes_t 
459 snd_harmony_playback_pointer(snd_pcm_substream_t *ss)
460 {
461         snd_pcm_runtime_t *rt = ss->runtime;
462         harmony_t *h = snd_pcm_substream_chip(ss);
463         unsigned long pcuradd;
464         unsigned long played;
465
466         if (!(h->st.playing) || (h->psubs == NULL)) 
467                 return 0;
468
469         if ((h->pbuf.addr == 0) || (h->pbuf.size == 0))
470                 return 0;
471         
472         pcuradd = harmony_read(h, HARMONY_PCURADD);
473         played = pcuradd - h->pbuf.addr;
474
475 #ifdef HARMONY_DEBUG
476         printk(KERN_DEBUG PFX "playback_pointer is 0x%lx-0x%lx = %d bytes\n", 
477                pcuradd, h->pbuf.addr, played);  
478 #endif
479
480         if (pcuradd > h->pbuf.addr + h->pbuf.size) {
481                 return 0;
482         }
483
484         return bytes_to_frames(rt, played);
485 }
486
487 static snd_pcm_uframes_t
488 snd_harmony_capture_pointer(snd_pcm_substream_t *ss)
489 {
490         snd_pcm_runtime_t *rt = ss->runtime;
491         harmony_t *h = snd_pcm_substream_chip(ss);
492         unsigned long rcuradd;
493         unsigned long caught;
494
495         if (!(h->st.capturing) || (h->csubs == NULL))
496                 return 0;
497
498         if ((h->cbuf.addr == 0) || (h->cbuf.size == 0))
499                 return 0;
500
501         rcuradd = harmony_read(h, HARMONY_RCURADD);
502         caught = rcuradd - h->cbuf.addr;
503
504 #ifdef HARMONY_DEBUG
505         printk(KERN_DEBUG PFX "capture_pointer is 0x%lx-0x%lx = %d bytes\n",
506                rcuradd, h->cbuf.addr, caught);
507 #endif
508
509         if (rcuradd > h->cbuf.addr + h->cbuf.size) {
510                 return 0;
511         }
512
513         return bytes_to_frames(rt, caught);
514 }
515
516 static int 
517 snd_harmony_playback_open(snd_pcm_substream_t *ss)
518 {
519         harmony_t *h = snd_pcm_substream_chip(ss);
520         snd_pcm_runtime_t *rt = ss->runtime;
521         int err;
522         
523         h->psubs = ss;
524         rt->hw = snd_harmony_playback;
525         snd_pcm_hw_constraint_list(rt, 0, SNDRV_PCM_HW_PARAM_RATE, 
526                                    &hw_constraint_rates);
527         
528         err = snd_pcm_hw_constraint_integer(rt, SNDRV_PCM_HW_PARAM_PERIODS);
529         if (err < 0)
530                 return err;
531         
532         return 0;
533 }
534
535 static int
536 snd_harmony_capture_open(snd_pcm_substream_t *ss)
537 {
538         harmony_t *h = snd_pcm_substream_chip(ss);
539         snd_pcm_runtime_t *rt = ss->runtime;
540         int err;
541
542         h->csubs = ss;
543         rt->hw = snd_harmony_capture;
544         snd_pcm_hw_constraint_list(rt, 0, SNDRV_PCM_HW_PARAM_RATE,
545                                    &hw_constraint_rates);
546
547         err = snd_pcm_hw_constraint_integer(rt, SNDRV_PCM_HW_PARAM_PERIODS);
548         if (err < 0)
549                 return err;
550
551         return 0;
552 }
553
554 static int 
555 snd_harmony_playback_close(snd_pcm_substream_t *ss)
556 {
557         harmony_t *h = snd_pcm_substream_chip(ss);
558         h->psubs = NULL;
559         return 0;
560 }
561
562 static int
563 snd_harmony_capture_close(snd_pcm_substream_t *ss)
564 {
565         harmony_t *h = snd_pcm_substream_chip(ss);
566         h->csubs = NULL;
567         return 0;
568 }
569
570 static int 
571 snd_harmony_hw_params(snd_pcm_substream_t *ss,
572                       snd_pcm_hw_params_t *hw)
573 {
574         int err;
575         harmony_t *h = snd_pcm_substream_chip(ss);
576         
577         err = snd_pcm_lib_malloc_pages(ss, params_buffer_bytes(hw));
578         if (err > 0 && h->dma.type == SNDRV_DMA_TYPE_CONTINUOUS)
579                 ss->runtime->dma_addr = __pa(ss->runtime->dma_area);
580         
581         return err;
582 }
583
584 static int 
585 snd_harmony_hw_free(snd_pcm_substream_t *ss) 
586 {
587         return snd_pcm_lib_free_pages(ss);
588 }
589
590 static snd_pcm_ops_t snd_harmony_playback_ops = {
591         .open = snd_harmony_playback_open,
592         .close = snd_harmony_playback_close,
593         .ioctl = snd_pcm_lib_ioctl,
594         .hw_params = snd_harmony_hw_params,
595         .hw_free = snd_harmony_hw_free,
596         .prepare = snd_harmony_playback_prepare,
597         .trigger = snd_harmony_playback_trigger,
598         .pointer = snd_harmony_playback_pointer,
599 };
600
601 static snd_pcm_ops_t snd_harmony_capture_ops = {
602         .open = snd_harmony_capture_open,
603         .close = snd_harmony_capture_close,
604         .ioctl = snd_pcm_lib_ioctl,
605         .hw_params = snd_harmony_hw_params,
606         .hw_free = snd_harmony_hw_free,
607         .prepare = snd_harmony_capture_prepare,
608         .trigger = snd_harmony_capture_trigger,
609         .pointer = snd_harmony_capture_pointer,
610 };
611
612 static int 
613 snd_harmony_pcm_init(harmony_t *h)
614 {
615         snd_pcm_t *pcm;
616         int err;
617
618         harmony_disable_interrupts(h);
619         
620         err = snd_pcm_new(h->card, "harmony", 0, 1, 1, &pcm);
621         if (err < 0)
622                 return err;
623         
624         snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, 
625                         &snd_harmony_playback_ops);
626         snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
627                         &snd_harmony_capture_ops);
628
629         pcm->private_data = h;
630         pcm->info_flags = 0;
631         strcpy(pcm->name, "harmony");
632         h->pcm = pcm;
633
634         h->psubs = NULL;
635         h->csubs = NULL;
636         
637         /* initialize graveyard buffer */
638         h->dma.type = SNDRV_DMA_TYPE_DEV;
639         h->dma.dev = &h->dev->dev;
640         err = snd_dma_alloc_pages(h->dma.type,
641                                   h->dma.dev,
642                                   BUF_SIZE*GRAVEYARD_BUFS,
643                                   &h->gdma);
644         if (err < 0) {
645                 printk(KERN_ERR PFX "cannot allocate graveyard buffer!\n");
646                 return err;
647         }
648         
649         /* initialize silence buffers */
650         err = snd_dma_alloc_pages(h->dma.type,
651                                   h->dma.dev,
652                                   BUF_SIZE*SILENCE_BUFS,
653                                   &h->sdma);
654         if (err < 0) {
655                 printk(KERN_ERR PFX "cannot allocate silence buffer!\n");
656                 return err;
657         }
658
659         /* pre-allocate space for DMA */
660         err = snd_pcm_lib_preallocate_pages_for_all(pcm, h->dma.type,
661                                                     h->dma.dev,
662                                                     MAX_BUF_SIZE, 
663                                                     MAX_BUF_SIZE);
664         if (err < 0) {
665                 printk(KERN_ERR PFX "buffer allocation error: %d\n", err);
666                 return err;
667         }
668
669         h->st.format = snd_harmony_set_data_format(h,
670                 SNDRV_PCM_FORMAT_S16_BE, 1);
671
672         return 0;
673 }
674
675 static void 
676 snd_harmony_set_new_gain(harmony_t *h)
677 {
678         harmony_wait_for_control(h);
679         harmony_write(h, HARMONY_GAINCTL, h->st.gain);
680 }
681
682 static int 
683 snd_harmony_mixercontrol_info(snd_kcontrol_t *kc, 
684                               snd_ctl_elem_info_t *uinfo)
685 {
686         int mask = (kc->private_value >> 16) & 0xff;
687         int left_shift = (kc->private_value) & 0xff;
688         int right_shift = (kc->private_value >> 8) & 0xff;
689         
690         uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : 
691                        SNDRV_CTL_ELEM_TYPE_INTEGER;
692         uinfo->count = left_shift == right_shift ? 1 : 2;
693         uinfo->value.integer.min = 0;
694         uinfo->value.integer.max = mask;
695
696         return 0;
697 }
698
699 static int 
700 snd_harmony_volume_get(snd_kcontrol_t *kc, 
701                        snd_ctl_elem_value_t *ucontrol)
702 {
703         harmony_t *h = snd_kcontrol_chip(kc);
704         int shift_left = (kc->private_value) & 0xff;
705         int shift_right = (kc->private_value >> 8) & 0xff;
706         int mask = (kc->private_value >> 16) & 0xff;
707         int invert = (kc->private_value >> 24) & 0xff;
708         int left, right;
709         unsigned long flags;
710         
711         spin_lock_irqsave(&h->mixer_lock, flags);
712
713         left = (h->st.gain >> shift_left) & mask;
714         right = (h->st.gain >> shift_right) & mask;
715
716         if (invert) {
717                 left = mask - left;
718                 right = mask - right;
719         }
720         ucontrol->value.integer.value[0] = left;
721         ucontrol->value.integer.value[1] = right;
722
723         spin_unlock_irqrestore(&h->mixer_lock, flags);
724
725         return 0;
726 }  
727
728 static int 
729 snd_harmony_volume_put(snd_kcontrol_t *kc, 
730                        snd_ctl_elem_value_t *ucontrol)
731 {
732         harmony_t *h = snd_kcontrol_chip(kc);
733         int shift_left = (kc->private_value) & 0xff;
734         int shift_right = (kc->private_value >> 8) & 0xff;
735         int mask = (kc->private_value >> 16) & 0xff;
736         int invert = (kc->private_value >> 24) & 0xff;
737         int left, right;
738         int old_gain = h->st.gain;
739         unsigned long flags;
740         
741         left = ucontrol->value.integer.value[0] & mask;
742         right = ucontrol->value.integer.value[1] & mask;
743         if (invert) {
744                 left = mask - left;
745                 right = mask - right;
746         }
747         
748         spin_lock_irqsave(&h->mixer_lock, flags);
749
750         h->st.gain &= ~( (mask << shift_right) | (mask << shift_left) );
751         h->st.gain |=  ( (left << shift_left) | (right << shift_right) );
752         snd_harmony_set_new_gain(h);
753
754         spin_unlock_irqrestore(&h->mixer_lock, flags);
755         
756         return (old_gain - h->st.gain);
757 }
758
759 #define HARMONY_CONTROLS (sizeof(snd_harmony_controls)/ \
760                           sizeof(snd_kcontrol_new_t))
761
762 #define HARMONY_VOLUME(xname, left_shift, right_shift, mask, invert) \
763 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname,                \
764   .info = snd_harmony_mixercontrol_info,                             \
765   .get = snd_harmony_volume_get, .put = snd_harmony_volume_put,      \
766   .private_value = ((left_shift) | ((right_shift) << 8) |            \
767                    ((mask) << 16) | ((invert) << 24)) }
768
769 static snd_kcontrol_new_t snd_harmony_controls[] = {
770         HARMONY_VOLUME("Playback Volume", HARMONY_GAIN_LO_SHIFT, 
771                        HARMONY_GAIN_RO_SHIFT, HARMONY_GAIN_OUT, 1),
772         HARMONY_VOLUME("Capture Volume", HARMONY_GAIN_LI_SHIFT,
773                        HARMONY_GAIN_RI_SHIFT, HARMONY_GAIN_IN, 0),
774 };
775
776 static void __init 
777 snd_harmony_mixer_reset(harmony_t *h)
778 {
779         harmony_mute(h);
780         harmony_reset(h);
781         h->st.gain = HARMONY_GAIN_DEFAULT;
782         harmony_unmute(h);
783 }
784
785 static int __init 
786 snd_harmony_mixer_init(harmony_t *h)
787 {
788         snd_card_t *card = h->card;
789         int idx, err;
790
791         snd_assert(h != NULL, return -EINVAL);
792         strcpy(card->mixername, "Harmony Gain control interface");
793
794         for (idx = 0; idx < HARMONY_CONTROLS; idx++) {
795                 err = snd_ctl_add(card, 
796                                   snd_ctl_new1(&snd_harmony_controls[idx], h));
797                 if (err < 0)
798                         return err;
799         }
800         
801         snd_harmony_mixer_reset(h);
802
803         return 0;
804 }
805
806 static int
807 snd_harmony_free(harmony_t *h)
808 {
809         if (h->gdma.addr)
810                 snd_dma_free_pages(&h->gdma);
811         if (h->sdma.addr)
812                 snd_dma_free_pages(&h->sdma);
813
814         if (h->irq >= 0)
815                 free_irq(h->irq, h);
816
817         if (h->iobase)
818                 iounmap(h->iobase);
819
820         parisc_set_drvdata(h->dev, NULL);
821
822         kfree(h);
823         return 0;
824 }
825
826 static int
827 snd_harmony_dev_free(snd_device_t *dev)
828 {
829         harmony_t *h = dev->device_data;
830         return snd_harmony_free(h);
831 }
832
833 static int __devinit
834 snd_harmony_create(snd_card_t *card, 
835                    struct parisc_device *padev, 
836                    harmony_t **rchip)
837 {
838         int err;
839         harmony_t *h;
840         static snd_device_ops_t ops = {
841                 .dev_free = snd_harmony_dev_free,
842         };
843
844         *rchip = NULL;
845
846         h = kmalloc(sizeof(*h), GFP_KERNEL);
847         if (h == NULL)
848                 return -ENOMEM;
849
850         memset(&h->st, 0, sizeof(h->st));
851         memset(&h->stats, 0, sizeof(h->stats));
852         memset(&h->pbuf, 0, sizeof(h->pbuf));
853         memset(&h->cbuf, 0, sizeof(h->cbuf));
854
855         h->hpa = padev->hpa;
856         h->card = card;
857         h->dev = padev;
858         h->irq = padev->irq;
859         h->iobase = ioremap_nocache(padev->hpa, HARMONY_SIZE);
860         if (h->iobase == NULL) {
861                 printk(KERN_ERR PFX "unable to remap hpa 0x%lx\n",
862                        padev->hpa);
863                 err = -EBUSY;
864                 goto free_and_ret;
865         }
866                 
867         err = request_irq(h->irq, snd_harmony_interrupt, 0,
868                           "harmony", h);
869         if (err) {
870                 printk(KERN_ERR PFX "could not obtain interrupt %d",
871                        h->irq);
872                 goto free_and_ret;
873         }
874
875         spin_lock_init(&h->mixer_lock);
876         spin_lock_init(&h->lock);
877
878         if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL,
879                                   h, &ops)) < 0) {
880                 goto free_and_ret;
881         }
882
883         snd_card_set_dev(card, &padev->dev);
884
885         *rchip = h;
886
887         return 0;
888
889 free_and_ret:
890         snd_harmony_free(h);
891         return err;
892 }
893
894 static int __devinit
895 snd_harmony_probe(struct parisc_device *padev)
896 {
897         int err;
898         static int dev;
899         snd_card_t *card;
900         harmony_t *h;
901         static int index = SNDRV_DEFAULT_IDX1;
902         static char *id = SNDRV_DEFAULT_STR1;
903
904         h = parisc_get_drvdata(padev);
905         if (h != NULL) {
906                 return -ENODEV;
907         }
908
909         card = snd_card_new(index, id, THIS_MODULE, 0);
910         if (card == NULL)
911                 return -ENOMEM;
912
913         err = snd_harmony_create(card, padev, &h);
914         if (err < 0) {
915                 goto free_and_ret;
916         }
917
918         err = snd_harmony_pcm_init(h);
919         if (err < 0) {
920                 goto free_and_ret;
921         }
922
923         err = snd_harmony_mixer_init(h);
924         if (err < 0) {
925                 goto free_and_ret;
926         }
927
928         strcpy(card->driver, "harmony");
929         strcpy(card->shortname, "Harmony");
930         sprintf(card->longname, "%s at 0x%lx, irq %i",
931                 card->shortname, h->hpa, h->irq);
932
933         err = snd_card_register(card);
934         if (err < 0) {
935                 goto free_and_ret;
936         }
937
938         dev++;
939         parisc_set_drvdata(padev, h);
940
941         return 0;
942
943 free_and_ret:
944         snd_card_free(card);
945         return err;
946 }
947
948 static int __devexit
949 snd_harmony_remove(struct parisc_device *padev)
950 {
951         harmony_t *h = parisc_get_drvdata(padev);
952         snd_card_free(h->card);
953         return 0;
954 }
955
956 static struct parisc_driver snd_harmony_driver = {
957         .name = "harmony",
958         .id_table = snd_harmony_devtable,
959         .probe = snd_harmony_probe,
960         .remove = snd_harmony_remove,
961 };
962
963 static int __init 
964 alsa_harmony_init(void)
965 {
966         int err;
967
968         err = register_parisc_driver(&snd_harmony_driver);
969         if (err < 0) {
970                 printk(KERN_ERR PFX "device not found\n");
971                 return err;
972         }
973
974         return 0;
975 }
976
977 static void __exit
978 alsa_harmony_fini(void)
979 {
980         int err;
981
982         err = unregister_parisc_driver(&snd_harmony_driver);
983         if (err < 0) {
984                 printk(KERN_ERR PFX "failed to unregister\n");
985         }
986         
987         return;
988 }
989
990 MODULE_LICENSE("GPL");
991 MODULE_AUTHOR("Kyle McMartin <kyle@parisc-linux.org>");
992 MODULE_DESCRIPTION("Harmony sound driver");
993
994 module_init(alsa_harmony_init);
995 module_exit(alsa_harmony_fini);