1 // SPDX-License-Identifier: GPL-2.0-only
2 /* Hewlett-Packard Harmony audio driver
4 * This is a driver for the Harmony audio chipset found
5 * on the LASI ASIC of various early HP PA-RISC workstations.
7 * Copyright (C) 2004, Kyle McMartin <kyle@{debian.org,parisc-linux.org}>
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
18 * - graveyard and silence buffers last for lifetime of
19 * the driver. playback and capture buffers are allocated
20 * per _open()/_close().
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>
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>
43 #include <asm/hardware.h>
44 #include <asm/parisc-device.h>
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.");
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 },
60 { HPHW_FIO
, HVERSION_REV_ANY_ID
, HVERSION_ANY_ID
, 0x0007B },
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 },
68 MODULE_DEVICE_TABLE(parisc
, snd_harmony_devtable
);
70 #define NAME "harmony"
73 static const unsigned int snd_harmony_rates
[] = {
74 5512, 6615, 8000, 9600,
75 11025, 16000, 18900, 22050,
76 27428, 32000, 33075, 37800,
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
88 static const struct snd_pcm_hw_constraint_list hw_constraint_rates
= {
89 .count
= ARRAY_SIZE(snd_harmony_rates
),
90 .list
= snd_harmony_rates
,
94 static inline unsigned long
95 harmony_read(struct snd_harmony
*h
, unsigned r
)
97 return __raw_readl(h
->iobase
+ r
);
101 harmony_write(struct snd_harmony
*h
, unsigned r
, unsigned long v
)
103 __raw_writel(v
, h
->iobase
+ r
);
107 harmony_wait_for_control(struct snd_harmony
*h
)
109 while (harmony_read(h
, HARMONY_CNTL
) & HARMONY_CNTL_C
) ;
113 harmony_reset(struct snd_harmony
*h
)
115 harmony_write(h
, HARMONY_RESET
, 1);
117 harmony_write(h
, HARMONY_RESET
, 0);
121 harmony_disable_interrupts(struct snd_harmony
*h
)
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
);
131 harmony_enable_interrupts(struct snd_harmony
*h
)
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
);
141 harmony_mute(struct snd_harmony
*h
)
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
);
152 harmony_unmute(struct snd_harmony
*h
)
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
);
163 harmony_set_control(struct snd_harmony
*h
)
168 spin_lock_irqsave(&h
->lock
, flags
);
170 ctrl
= (HARMONY_CNTL_C
|
171 (h
->st
.format
<< 6) |
172 (h
->st
.stereo
<< 5) |
175 harmony_wait_for_control(h
);
176 harmony_write(h
, HARMONY_CNTL
, ctrl
);
178 spin_unlock_irqrestore(&h
->lock
, flags
);
182 snd_harmony_interrupt(int irq
, void *dev
)
185 struct snd_harmony
*h
= dev
;
188 harmony_disable_interrupts(h
);
189 harmony_wait_for_control(h
);
190 dstatus
= harmony_read(h
, HARMONY_DSTATUS
);
191 spin_unlock(&h
->lock
);
193 if (dstatus
& HARMONY_DSTATUS_PN
) {
194 if (h
->psubs
&& h
->st
.playing
) {
196 h
->pbuf
.buf
+= h
->pbuf
.count
; /* PAGE_SIZE */
197 h
->pbuf
.buf
%= h
->pbuf
.size
; /* MAX_BUFS*PAGE_SIZE */
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
);
206 harmony_write(h
, HARMONY_PNXTADD
, h
->sdma
.addr
);
207 h
->stats
.silence_intr
++;
208 spin_unlock(&h
->lock
);
212 if (dstatus
& HARMONY_DSTATUS_RN
) {
213 if (h
->csubs
&& h
->st
.capturing
) {
215 h
->cbuf
.buf
+= h
->cbuf
.count
;
216 h
->cbuf
.buf
%= h
->cbuf
.size
;
218 harmony_write(h
, HARMONY_RNXTADD
,
219 h
->cbuf
.addr
+ h
->cbuf
.buf
);
221 spin_unlock(&h
->lock
);
222 snd_pcm_period_elapsed(h
->csubs
);
225 harmony_write(h
, HARMONY_RNXTADD
, h
->gdma
.addr
);
226 h
->stats
.graveyard_intr
++;
227 spin_unlock(&h
->lock
);
232 harmony_enable_interrupts(h
);
233 spin_unlock(&h
->lock
);
239 snd_harmony_rate_bits(int rate
)
243 for (i
= 0; i
< ARRAY_SIZE(snd_harmony_rates
); i
++)
244 if (snd_harmony_rates
[i
] == rate
)
247 return HARMONY_SR_44KHZ
;
250 static const struct snd_pcm_hardware snd_harmony_playback
=
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
),
263 .buffer_bytes_max
= MAX_BUF_SIZE
,
264 .period_bytes_min
= BUF_SIZE
,
265 .period_bytes_max
= BUF_SIZE
,
267 .periods_max
= MAX_BUFS
,
271 static const struct snd_pcm_hardware snd_harmony_capture
=
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
),
284 .buffer_bytes_max
= MAX_BUF_SIZE
,
285 .period_bytes_min
= BUF_SIZE
,
286 .period_bytes_max
= BUF_SIZE
,
288 .periods_max
= MAX_BUFS
,
293 snd_harmony_playback_trigger(struct snd_pcm_substream
*ss
, int cmd
)
295 struct snd_harmony
*h
= snd_pcm_substream_chip(ss
);
302 case SNDRV_PCM_TRIGGER_START
:
304 harmony_write(h
, HARMONY_PNXTADD
, h
->pbuf
.addr
);
305 harmony_write(h
, HARMONY_RNXTADD
, h
->gdma
.addr
);
307 harmony_enable_interrupts(h
);
309 case SNDRV_PCM_TRIGGER_STOP
:
312 harmony_write(h
, HARMONY_PNXTADD
, h
->sdma
.addr
);
313 harmony_disable_interrupts(h
);
315 case SNDRV_PCM_TRIGGER_PAUSE_PUSH
:
316 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE
:
317 case SNDRV_PCM_TRIGGER_SUSPEND
:
319 spin_unlock(&h
->lock
);
323 spin_unlock(&h
->lock
);
329 snd_harmony_capture_trigger(struct snd_pcm_substream
*ss
, int cmd
)
331 struct snd_harmony
*h
= snd_pcm_substream_chip(ss
);
338 case SNDRV_PCM_TRIGGER_START
:
340 harmony_write(h
, HARMONY_PNXTADD
, h
->sdma
.addr
);
341 harmony_write(h
, HARMONY_RNXTADD
, h
->cbuf
.addr
);
343 harmony_enable_interrupts(h
);
345 case SNDRV_PCM_TRIGGER_STOP
:
348 harmony_write(h
, HARMONY_RNXTADD
, h
->gdma
.addr
);
349 harmony_disable_interrupts(h
);
351 case SNDRV_PCM_TRIGGER_PAUSE_PUSH
:
352 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE
:
353 case SNDRV_PCM_TRIGGER_SUSPEND
:
355 spin_unlock(&h
->lock
);
359 spin_unlock(&h
->lock
);
365 snd_harmony_set_data_format(struct snd_harmony
*h
, int fmt
, int force
)
367 int o
= h
->st
.format
;
371 case SNDRV_PCM_FORMAT_S16_BE
:
372 n
= HARMONY_DF_16BIT_LINEAR
;
374 case SNDRV_PCM_FORMAT_A_LAW
:
375 n
= HARMONY_DF_8BIT_ALAW
;
377 case SNDRV_PCM_FORMAT_MU_LAW
:
378 n
= HARMONY_DF_8BIT_ULAW
;
381 n
= HARMONY_DF_16BIT_LINEAR
;
385 if (force
|| o
!= n
) {
386 snd_pcm_format_set_silence(fmt
, h
->sdma
.area
, SILENCE_BUFSZ
/
387 (snd_pcm_format_physical_width(fmt
)
395 snd_harmony_playback_prepare(struct snd_pcm_substream
*ss
)
397 struct snd_harmony
*h
= snd_pcm_substream_chip(ss
);
398 struct snd_pcm_runtime
*rt
= ss
->runtime
;
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
)
409 h
->st
.rate
= snd_harmony_rate_bits(rt
->rate
);
410 h
->st
.format
= snd_harmony_set_data_format(h
, rt
->format
, 0);
412 if (rt
->channels
== 2)
413 h
->st
.stereo
= HARMONY_SS_STEREO
;
415 h
->st
.stereo
= HARMONY_SS_MONO
;
417 harmony_set_control(h
);
419 h
->pbuf
.addr
= rt
->dma_addr
;
425 snd_harmony_capture_prepare(struct snd_pcm_substream
*ss
)
427 struct snd_harmony
*h
= snd_pcm_substream_chip(ss
);
428 struct snd_pcm_runtime
*rt
= ss
->runtime
;
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
)
439 h
->st
.rate
= snd_harmony_rate_bits(rt
->rate
);
440 h
->st
.format
= snd_harmony_set_data_format(h
, rt
->format
, 0);
442 if (rt
->channels
== 2)
443 h
->st
.stereo
= HARMONY_SS_STEREO
;
445 h
->st
.stereo
= HARMONY_SS_MONO
;
447 harmony_set_control(h
);
449 h
->cbuf
.addr
= rt
->dma_addr
;
454 static snd_pcm_uframes_t
455 snd_harmony_playback_pointer(struct snd_pcm_substream
*ss
)
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
;
462 if (!(h
->st
.playing
) || (h
->psubs
== NULL
))
465 if ((h
->pbuf
.addr
== 0) || (h
->pbuf
.size
== 0))
468 pcuradd
= harmony_read(h
, HARMONY_PCURADD
);
469 played
= pcuradd
- h
->pbuf
.addr
;
472 printk(KERN_DEBUG PFX
"playback_pointer is 0x%lx-0x%lx = %d bytes\n",
473 pcuradd
, h
->pbuf
.addr
, played
);
476 if (pcuradd
> h
->pbuf
.addr
+ h
->pbuf
.size
) {
480 return bytes_to_frames(rt
, played
);
483 static snd_pcm_uframes_t
484 snd_harmony_capture_pointer(struct snd_pcm_substream
*ss
)
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
;
491 if (!(h
->st
.capturing
) || (h
->csubs
== NULL
))
494 if ((h
->cbuf
.addr
== 0) || (h
->cbuf
.size
== 0))
497 rcuradd
= harmony_read(h
, HARMONY_RCURADD
);
498 caught
= rcuradd
- h
->cbuf
.addr
;
501 printk(KERN_DEBUG PFX
"capture_pointer is 0x%lx-0x%lx = %d bytes\n",
502 rcuradd
, h
->cbuf
.addr
, caught
);
505 if (rcuradd
> h
->cbuf
.addr
+ h
->cbuf
.size
) {
509 return bytes_to_frames(rt
, caught
);
513 snd_harmony_playback_open(struct snd_pcm_substream
*ss
)
515 struct snd_harmony
*h
= snd_pcm_substream_chip(ss
);
516 struct snd_pcm_runtime
*rt
= ss
->runtime
;
520 rt
->hw
= snd_harmony_playback
;
521 snd_pcm_hw_constraint_list(rt
, 0, SNDRV_PCM_HW_PARAM_RATE
,
522 &hw_constraint_rates
);
524 err
= snd_pcm_hw_constraint_integer(rt
, SNDRV_PCM_HW_PARAM_PERIODS
);
532 snd_harmony_capture_open(struct snd_pcm_substream
*ss
)
534 struct snd_harmony
*h
= snd_pcm_substream_chip(ss
);
535 struct snd_pcm_runtime
*rt
= ss
->runtime
;
539 rt
->hw
= snd_harmony_capture
;
540 snd_pcm_hw_constraint_list(rt
, 0, SNDRV_PCM_HW_PARAM_RATE
,
541 &hw_constraint_rates
);
543 err
= snd_pcm_hw_constraint_integer(rt
, SNDRV_PCM_HW_PARAM_PERIODS
);
551 snd_harmony_playback_close(struct snd_pcm_substream
*ss
)
553 struct snd_harmony
*h
= snd_pcm_substream_chip(ss
);
559 snd_harmony_capture_close(struct snd_pcm_substream
*ss
)
561 struct snd_harmony
*h
= snd_pcm_substream_chip(ss
);
567 snd_harmony_hw_params(struct snd_pcm_substream
*ss
,
568 struct snd_pcm_hw_params
*hw
)
571 struct snd_harmony
*h
= snd_pcm_substream_chip(ss
);
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
);
581 snd_harmony_hw_free(struct snd_pcm_substream
*ss
)
583 return snd_pcm_lib_free_pages(ss
);
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
,
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
,
609 snd_harmony_pcm_init(struct snd_harmony
*h
)
617 harmony_disable_interrupts(h
);
619 err
= snd_pcm_new(h
->card
, "harmony", 0, 1, 1, &pcm
);
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
);
628 pcm
->private_data
= h
;
630 strcpy(pcm
->name
, "harmony");
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
,
641 BUF_SIZE
*GRAVEYARD_BUFS
,
644 printk(KERN_ERR PFX
"cannot allocate graveyard buffer!\n");
648 /* initialize silence buffers */
649 err
= snd_dma_alloc_pages(h
->dma
.type
,
651 BUF_SIZE
*SILENCE_BUFS
,
654 printk(KERN_ERR PFX
"cannot allocate silence buffer!\n");
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
);
662 h
->st
.format
= snd_harmony_set_data_format(h
,
663 SNDRV_PCM_FORMAT_S16_BE
, 1);
669 snd_harmony_set_new_gain(struct snd_harmony
*h
)
671 harmony_wait_for_control(h
);
672 harmony_write(h
, HARMONY_GAINCTL
, h
->st
.gain
);
676 snd_harmony_mixercontrol_info(struct snd_kcontrol
*kc
,
677 struct snd_ctl_elem_info
*uinfo
)
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;
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
;
693 snd_harmony_volume_get(struct snd_kcontrol
*kc
,
694 struct snd_ctl_elem_value
*ucontrol
)
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;
703 spin_lock_irq(&h
->mixer_lock
);
705 left
= (h
->st
.gain
>> shift_left
) & mask
;
706 right
= (h
->st
.gain
>> shift_right
) & mask
;
709 right
= mask
- right
;
712 ucontrol
->value
.integer
.value
[0] = left
;
713 if (shift_left
!= shift_right
)
714 ucontrol
->value
.integer
.value
[1] = right
;
716 spin_unlock_irq(&h
->mixer_lock
);
722 snd_harmony_volume_put(struct snd_kcontrol
*kc
,
723 struct snd_ctl_elem_value
*ucontrol
)
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;
731 int old_gain
= h
->st
.gain
;
733 spin_lock_irq(&h
->mixer_lock
);
735 left
= ucontrol
->value
.integer
.value
[0] & mask
;
738 h
->st
.gain
&= ~( (mask
<< shift_left
) );
739 h
->st
.gain
|= (left
<< shift_left
);
741 if (shift_left
!= shift_right
) {
742 right
= ucontrol
->value
.integer
.value
[1] & mask
;
744 right
= mask
- right
;
745 h
->st
.gain
&= ~( (mask
<< shift_right
) );
746 h
->st
.gain
|= (right
<< shift_right
);
749 snd_harmony_set_new_gain(h
);
751 spin_unlock_irq(&h
->mixer_lock
);
753 return h
->st
.gain
!= old_gain
;
757 snd_harmony_captureroute_info(struct snd_kcontrol
*kc
,
758 struct snd_ctl_elem_info
*uinfo
)
760 static const char * const texts
[2] = { "Line", "Mic" };
762 return snd_ctl_enum_info(uinfo
, 1, 2, texts
);
766 snd_harmony_captureroute_get(struct snd_kcontrol
*kc
,
767 struct snd_ctl_elem_value
*ucontrol
)
769 struct snd_harmony
*h
= snd_kcontrol_chip(kc
);
772 spin_lock_irq(&h
->mixer_lock
);
774 value
= (h
->st
.gain
>> HARMONY_GAIN_IS_SHIFT
) & 1;
775 ucontrol
->value
.enumerated
.item
[0] = value
;
777 spin_unlock_irq(&h
->mixer_lock
);
783 snd_harmony_captureroute_put(struct snd_kcontrol
*kc
,
784 struct snd_ctl_elem_value
*ucontrol
)
786 struct snd_harmony
*h
= snd_kcontrol_chip(kc
);
788 int old_gain
= h
->st
.gain
;
790 spin_lock_irq(&h
->mixer_lock
);
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
;
796 snd_harmony_set_new_gain(h
);
798 spin_unlock_irq(&h
->mixer_lock
);
800 return h
->st
.gain
!= old_gain
;
803 #define HARMONY_CONTROLS ARRAY_SIZE(snd_harmony_controls)
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)) }
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),
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
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),
835 snd_harmony_mixer_reset(struct snd_harmony
*h
)
839 h
->st
.gain
= HARMONY_GAIN_DEFAULT
;
844 snd_harmony_mixer_init(struct snd_harmony
*h
)
846 struct snd_card
*card
;
852 strcpy(card
->mixername
, "Harmony Gain control interface");
854 for (idx
= 0; idx
< HARMONY_CONTROLS
; idx
++) {
855 err
= snd_ctl_add(card
,
856 snd_ctl_new1(&snd_harmony_controls
[idx
], h
));
861 snd_harmony_mixer_reset(h
);
867 snd_harmony_free(struct snd_harmony
*h
)
870 snd_dma_free_pages(&h
->gdma
);
872 snd_dma_free_pages(&h
->sdma
);
883 snd_harmony_dev_free(struct snd_device
*dev
)
885 struct snd_harmony
*h
= dev
->device_data
;
886 return snd_harmony_free(h
);
890 snd_harmony_create(struct snd_card
*card
,
891 struct parisc_device
*padev
,
892 struct snd_harmony
**rchip
)
895 struct snd_harmony
*h
;
896 static struct snd_device_ops ops
= {
897 .dev_free
= snd_harmony_dev_free
,
902 h
= kzalloc(sizeof(*h
), GFP_KERNEL
);
906 h
->hpa
= padev
->hpa
.start
;
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
);
918 err
= request_irq(padev
->irq
, snd_harmony_interrupt
, 0,
921 printk(KERN_ERR PFX
"could not obtain interrupt %d",
927 spin_lock_init(&h
->mixer_lock
);
928 spin_lock_init(&h
->lock
);
930 if ((err
= snd_device_new(card
, SNDRV_DEV_LOWLEVEL
,
945 snd_harmony_probe(struct parisc_device
*padev
)
948 struct snd_card
*card
;
949 struct snd_harmony
*h
;
951 err
= snd_card_new(&padev
->dev
, index
, id
, THIS_MODULE
, 0, &card
);
955 err
= snd_harmony_create(card
, padev
, &h
);
959 err
= snd_harmony_pcm_init(h
);
963 err
= snd_harmony_mixer_init(h
);
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
);
972 err
= snd_card_register(card
);
976 parisc_set_drvdata(padev
, card
);
985 snd_harmony_remove(struct parisc_device
*padev
)
987 snd_card_free(parisc_get_drvdata(padev
));
991 static struct parisc_driver snd_harmony_driver __refdata
= {
993 .id_table
= snd_harmony_devtable
,
994 .probe
= snd_harmony_probe
,
995 .remove
= __exit_p(snd_harmony_remove
),
999 alsa_harmony_init(void)
1001 return register_parisc_driver(&snd_harmony_driver
);
1005 alsa_harmony_fini(void)
1007 unregister_parisc_driver(&snd_harmony_driver
);
1010 MODULE_LICENSE("GPL");
1011 MODULE_AUTHOR("Kyle McMartin <kyle@parisc-linux.org>");
1012 MODULE_DESCRIPTION("Harmony sound driver");
1014 module_init(alsa_harmony_init
);
1015 module_exit(alsa_harmony_fini
);