diff options
Diffstat (limited to 'sound/parisc')
-rw-r--r-- | sound/parisc/harmony.c | 103 |
1 files changed, 36 insertions, 67 deletions
diff --git a/sound/parisc/harmony.c b/sound/parisc/harmony.c index d833349ed518..0513137d4ec4 100644 --- a/sound/parisc/harmony.c +++ b/sound/parisc/harmony.c | |||
@@ -59,6 +59,14 @@ | |||
59 | 59 | ||
60 | #include "harmony.h" | 60 | #include "harmony.h" |
61 | 61 | ||
62 | static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */ | ||
63 | static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */ | ||
64 | module_param(index, int, 0444); | ||
65 | MODULE_PARM_DESC(index, "Index value for Harmony driver."); | ||
66 | module_param(id, charp, 0444); | ||
67 | MODULE_PARM_DESC(id, "ID string for Harmony driver."); | ||
68 | |||
69 | |||
62 | static struct parisc_device_id snd_harmony_devtable[] = { | 70 | static struct parisc_device_id snd_harmony_devtable[] = { |
63 | /* bushmaster / flounder */ | 71 | /* bushmaster / flounder */ |
64 | { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0007A }, | 72 | { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0007A }, |
@@ -299,12 +307,11 @@ static int | |||
299 | snd_harmony_playback_trigger(snd_pcm_substream_t *ss, int cmd) | 307 | snd_harmony_playback_trigger(snd_pcm_substream_t *ss, int cmd) |
300 | { | 308 | { |
301 | harmony_t *h = snd_pcm_substream_chip(ss); | 309 | harmony_t *h = snd_pcm_substream_chip(ss); |
302 | unsigned long flags; | ||
303 | 310 | ||
304 | if (h->st.capturing) | 311 | if (h->st.capturing) |
305 | return -EBUSY; | 312 | return -EBUSY; |
306 | 313 | ||
307 | spin_lock_irqsave(&h->lock, flags); | 314 | spin_lock(&h->lock); |
308 | switch (cmd) { | 315 | switch (cmd) { |
309 | case SNDRV_PCM_TRIGGER_START: | 316 | case SNDRV_PCM_TRIGGER_START: |
310 | h->st.playing = 1; | 317 | h->st.playing = 1; |
@@ -323,11 +330,11 @@ snd_harmony_playback_trigger(snd_pcm_substream_t *ss, int cmd) | |||
323 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | 330 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: |
324 | case SNDRV_PCM_TRIGGER_SUSPEND: | 331 | case SNDRV_PCM_TRIGGER_SUSPEND: |
325 | default: | 332 | default: |
326 | spin_unlock_irqrestore(&h->lock, flags); | 333 | spin_unlock(&h->lock); |
327 | snd_BUG(); | 334 | snd_BUG(); |
328 | return -EINVAL; | 335 | return -EINVAL; |
329 | } | 336 | } |
330 | spin_unlock_irqrestore(&h->lock, flags); | 337 | spin_unlock(&h->lock); |
331 | 338 | ||
332 | return 0; | 339 | return 0; |
333 | } | 340 | } |
@@ -336,12 +343,11 @@ static int | |||
336 | snd_harmony_capture_trigger(snd_pcm_substream_t *ss, int cmd) | 343 | snd_harmony_capture_trigger(snd_pcm_substream_t *ss, int cmd) |
337 | { | 344 | { |
338 | harmony_t *h = snd_pcm_substream_chip(ss); | 345 | harmony_t *h = snd_pcm_substream_chip(ss); |
339 | unsigned long flags; | ||
340 | 346 | ||
341 | if (h->st.playing) | 347 | if (h->st.playing) |
342 | return -EBUSY; | 348 | return -EBUSY; |
343 | 349 | ||
344 | spin_lock_irqsave(&h->lock, flags); | 350 | spin_lock(&h->lock); |
345 | switch (cmd) { | 351 | switch (cmd) { |
346 | case SNDRV_PCM_TRIGGER_START: | 352 | case SNDRV_PCM_TRIGGER_START: |
347 | h->st.capturing = 1; | 353 | h->st.capturing = 1; |
@@ -360,11 +366,11 @@ snd_harmony_capture_trigger(snd_pcm_substream_t *ss, int cmd) | |||
360 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | 366 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: |
361 | case SNDRV_PCM_TRIGGER_SUSPEND: | 367 | case SNDRV_PCM_TRIGGER_SUSPEND: |
362 | default: | 368 | default: |
363 | spin_unlock_irqrestore(&h->lock, flags); | 369 | spin_unlock(&h->lock); |
364 | snd_BUG(); | 370 | snd_BUG(); |
365 | return -EINVAL; | 371 | return -EINVAL; |
366 | } | 372 | } |
367 | spin_unlock_irqrestore(&h->lock, flags); | 373 | spin_unlock(&h->lock); |
368 | 374 | ||
369 | return 0; | 375 | return 0; |
370 | } | 376 | } |
@@ -710,9 +716,8 @@ snd_harmony_volume_get(snd_kcontrol_t *kc, | |||
710 | int mask = (kc->private_value >> 16) & 0xff; | 716 | int mask = (kc->private_value >> 16) & 0xff; |
711 | int invert = (kc->private_value >> 24) & 0xff; | 717 | int invert = (kc->private_value >> 24) & 0xff; |
712 | int left, right; | 718 | int left, right; |
713 | unsigned long flags; | ||
714 | 719 | ||
715 | spin_lock_irqsave(&h->mixer_lock, flags); | 720 | spin_lock_irq(&h->mixer_lock); |
716 | 721 | ||
717 | left = (h->st.gain >> shift_left) & mask; | 722 | left = (h->st.gain >> shift_left) & mask; |
718 | right = (h->st.gain >> shift_right) & mask; | 723 | right = (h->st.gain >> shift_right) & mask; |
@@ -725,7 +730,7 @@ snd_harmony_volume_get(snd_kcontrol_t *kc, | |||
725 | if (shift_left != shift_right) | 730 | if (shift_left != shift_right) |
726 | ucontrol->value.integer.value[1] = right; | 731 | ucontrol->value.integer.value[1] = right; |
727 | 732 | ||
728 | spin_unlock_irqrestore(&h->mixer_lock, flags); | 733 | spin_unlock_irq(&h->mixer_lock); |
729 | 734 | ||
730 | return 0; | 735 | return 0; |
731 | } | 736 | } |
@@ -741,9 +746,8 @@ snd_harmony_volume_put(snd_kcontrol_t *kc, | |||
741 | int invert = (kc->private_value >> 24) & 0xff; | 746 | int invert = (kc->private_value >> 24) & 0xff; |
742 | int left, right; | 747 | int left, right; |
743 | int old_gain = h->st.gain; | 748 | int old_gain = h->st.gain; |
744 | unsigned long flags; | ||
745 | 749 | ||
746 | spin_lock_irqsave(&h->mixer_lock, flags); | 750 | spin_lock_irq(&h->mixer_lock); |
747 | 751 | ||
748 | left = ucontrol->value.integer.value[0] & mask; | 752 | left = ucontrol->value.integer.value[0] & mask; |
749 | if (invert) | 753 | if (invert) |
@@ -761,7 +765,7 @@ snd_harmony_volume_put(snd_kcontrol_t *kc, | |||
761 | 765 | ||
762 | snd_harmony_set_new_gain(h); | 766 | snd_harmony_set_new_gain(h); |
763 | 767 | ||
764 | spin_unlock_irqrestore(&h->mixer_lock, flags); | 768 | spin_unlock_irq(&h->mixer_lock); |
765 | 769 | ||
766 | return h->st.gain != old_gain; | 770 | return h->st.gain != old_gain; |
767 | } | 771 | } |
@@ -787,14 +791,13 @@ snd_harmony_captureroute_get(snd_kcontrol_t *kc, | |||
787 | { | 791 | { |
788 | harmony_t *h = snd_kcontrol_chip(kc); | 792 | harmony_t *h = snd_kcontrol_chip(kc); |
789 | int value; | 793 | int value; |
790 | unsigned long flags; | ||
791 | 794 | ||
792 | spin_lock_irqsave(&h->mixer_lock, flags); | 795 | spin_lock_irq(&h->mixer_lock); |
793 | 796 | ||
794 | value = (h->st.gain >> HARMONY_GAIN_IS_SHIFT) & 1; | 797 | value = (h->st.gain >> HARMONY_GAIN_IS_SHIFT) & 1; |
795 | ucontrol->value.enumerated.item[0] = value; | 798 | ucontrol->value.enumerated.item[0] = value; |
796 | 799 | ||
797 | spin_unlock_irqrestore(&h->mixer_lock, flags); | 800 | spin_unlock_irq(&h->mixer_lock); |
798 | 801 | ||
799 | return 0; | 802 | return 0; |
800 | } | 803 | } |
@@ -806,9 +809,8 @@ snd_harmony_captureroute_put(snd_kcontrol_t *kc, | |||
806 | harmony_t *h = snd_kcontrol_chip(kc); | 809 | harmony_t *h = snd_kcontrol_chip(kc); |
807 | int value; | 810 | int value; |
808 | int old_gain = h->st.gain; | 811 | int old_gain = h->st.gain; |
809 | unsigned long flags; | ||
810 | 812 | ||
811 | spin_lock_irqsave(&h->mixer_lock, flags); | 813 | spin_lock_irq(&h->mixer_lock); |
812 | 814 | ||
813 | value = ucontrol->value.enumerated.item[0] & 1; | 815 | value = ucontrol->value.enumerated.item[0] & 1; |
814 | h->st.gain &= ~HARMONY_GAIN_IS_MASK; | 816 | h->st.gain &= ~HARMONY_GAIN_IS_MASK; |
@@ -816,7 +818,7 @@ snd_harmony_captureroute_put(snd_kcontrol_t *kc, | |||
816 | 818 | ||
817 | snd_harmony_set_new_gain(h); | 819 | snd_harmony_set_new_gain(h); |
818 | 820 | ||
819 | spin_unlock_irqrestore(&h->mixer_lock, flags); | 821 | spin_unlock_irq(&h->mixer_lock); |
820 | 822 | ||
821 | return h->st.gain != old_gain; | 823 | return h->st.gain != old_gain; |
822 | } | 824 | } |
@@ -923,19 +925,14 @@ snd_harmony_create(snd_card_t *card, | |||
923 | 925 | ||
924 | *rchip = NULL; | 926 | *rchip = NULL; |
925 | 927 | ||
926 | h = kmalloc(sizeof(*h), GFP_KERNEL); | 928 | h = kzalloc(sizeof(*h), GFP_KERNEL); |
927 | if (h == NULL) | 929 | if (h == NULL) |
928 | return -ENOMEM; | 930 | return -ENOMEM; |
929 | 931 | ||
930 | memset(&h->st, 0, sizeof(h->st)); | ||
931 | memset(&h->stats, 0, sizeof(h->stats)); | ||
932 | memset(&h->pbuf, 0, sizeof(h->pbuf)); | ||
933 | memset(&h->cbuf, 0, sizeof(h->cbuf)); | ||
934 | |||
935 | h->hpa = padev->hpa.start; | 932 | h->hpa = padev->hpa.start; |
936 | h->card = card; | 933 | h->card = card; |
937 | h->dev = padev; | 934 | h->dev = padev; |
938 | h->irq = padev->irq; | 935 | h->irq = -1; |
939 | h->iobase = ioremap_nocache(padev->hpa.start, HARMONY_SIZE); | 936 | h->iobase = ioremap_nocache(padev->hpa.start, HARMONY_SIZE); |
940 | if (h->iobase == NULL) { | 937 | if (h->iobase == NULL) { |
941 | printk(KERN_ERR PFX "unable to remap hpa 0x%lx\n", | 938 | printk(KERN_ERR PFX "unable to remap hpa 0x%lx\n", |
@@ -944,13 +941,14 @@ snd_harmony_create(snd_card_t *card, | |||
944 | goto free_and_ret; | 941 | goto free_and_ret; |
945 | } | 942 | } |
946 | 943 | ||
947 | err = request_irq(h->irq, snd_harmony_interrupt, 0, | 944 | err = request_irq(padev->irq, snd_harmony_interrupt, 0, |
948 | "harmony", h); | 945 | "harmony", h); |
949 | if (err) { | 946 | if (err) { |
950 | printk(KERN_ERR PFX "could not obtain interrupt %d", | 947 | printk(KERN_ERR PFX "could not obtain interrupt %d", |
951 | h->irq); | 948 | padev->irq); |
952 | goto free_and_ret; | 949 | goto free_and_ret; |
953 | } | 950 | } |
951 | h->irq = padev->irq; | ||
954 | 952 | ||
955 | spin_lock_init(&h->mixer_lock); | 953 | spin_lock_init(&h->mixer_lock); |
956 | spin_lock_init(&h->lock); | 954 | spin_lock_init(&h->lock); |
@@ -975,35 +973,24 @@ static int __devinit | |||
975 | snd_harmony_probe(struct parisc_device *padev) | 973 | snd_harmony_probe(struct parisc_device *padev) |
976 | { | 974 | { |
977 | int err; | 975 | int err; |
978 | static int dev; | ||
979 | snd_card_t *card; | 976 | snd_card_t *card; |
980 | harmony_t *h; | 977 | harmony_t *h; |
981 | static int index = SNDRV_DEFAULT_IDX1; | ||
982 | static char *id = SNDRV_DEFAULT_STR1; | ||
983 | |||
984 | h = parisc_get_drvdata(padev); | ||
985 | if (h != NULL) { | ||
986 | return -ENODEV; | ||
987 | } | ||
988 | 978 | ||
989 | card = snd_card_new(index, id, THIS_MODULE, 0); | 979 | card = snd_card_new(index, id, THIS_MODULE, 0); |
990 | if (card == NULL) | 980 | if (card == NULL) |
991 | return -ENOMEM; | 981 | return -ENOMEM; |
992 | 982 | ||
993 | err = snd_harmony_create(card, padev, &h); | 983 | err = snd_harmony_create(card, padev, &h); |
994 | if (err < 0) { | 984 | if (err < 0) |
995 | goto free_and_ret; | 985 | goto free_and_ret; |
996 | } | ||
997 | 986 | ||
998 | err = snd_harmony_pcm_init(h); | 987 | err = snd_harmony_pcm_init(h); |
999 | if (err < 0) { | 988 | if (err < 0) |
1000 | goto free_and_ret; | 989 | goto free_and_ret; |
1001 | } | ||
1002 | 990 | ||
1003 | err = snd_harmony_mixer_init(h); | 991 | err = snd_harmony_mixer_init(h); |
1004 | if (err < 0) { | 992 | if (err < 0) |
1005 | goto free_and_ret; | 993 | goto free_and_ret; |
1006 | } | ||
1007 | 994 | ||
1008 | strcpy(card->driver, "harmony"); | 995 | strcpy(card->driver, "harmony"); |
1009 | strcpy(card->shortname, "Harmony"); | 996 | strcpy(card->shortname, "Harmony"); |
@@ -1011,13 +998,10 @@ snd_harmony_probe(struct parisc_device *padev) | |||
1011 | card->shortname, h->hpa, h->irq); | 998 | card->shortname, h->hpa, h->irq); |
1012 | 999 | ||
1013 | err = snd_card_register(card); | 1000 | err = snd_card_register(card); |
1014 | if (err < 0) { | 1001 | if (err < 0) |
1015 | goto free_and_ret; | 1002 | goto free_and_ret; |
1016 | } | ||
1017 | |||
1018 | dev++; | ||
1019 | parisc_set_drvdata(padev, h); | ||
1020 | 1003 | ||
1004 | parisc_set_drvdata(padev, card); | ||
1021 | return 0; | 1005 | return 0; |
1022 | 1006 | ||
1023 | free_and_ret: | 1007 | free_and_ret: |
@@ -1028,8 +1012,8 @@ free_and_ret: | |||
1028 | static int __devexit | 1012 | static int __devexit |
1029 | snd_harmony_remove(struct parisc_device *padev) | 1013 | snd_harmony_remove(struct parisc_device *padev) |
1030 | { | 1014 | { |
1031 | harmony_t *h = parisc_get_drvdata(padev); | 1015 | snd_card_free(parisc_get_drvdata(padev)); |
1032 | snd_card_free(h->card); | 1016 | parisc_set_drvdata(padev, NULL); |
1033 | return 0; | 1017 | return 0; |
1034 | } | 1018 | } |
1035 | 1019 | ||
@@ -1043,28 +1027,13 @@ static struct parisc_driver snd_harmony_driver = { | |||
1043 | static int __init | 1027 | static int __init |
1044 | alsa_harmony_init(void) | 1028 | alsa_harmony_init(void) |
1045 | { | 1029 | { |
1046 | int err; | 1030 | return register_parisc_driver(&snd_harmony_driver); |
1047 | |||
1048 | err = register_parisc_driver(&snd_harmony_driver); | ||
1049 | if (err < 0) { | ||
1050 | printk(KERN_ERR PFX "device not found\n"); | ||
1051 | return err; | ||
1052 | } | ||
1053 | |||
1054 | return 0; | ||
1055 | } | 1031 | } |
1056 | 1032 | ||
1057 | static void __exit | 1033 | static void __exit |
1058 | alsa_harmony_fini(void) | 1034 | alsa_harmony_fini(void) |
1059 | { | 1035 | { |
1060 | int err; | 1036 | return unregister_parisc_driver(&snd_harmony_driver); |
1061 | |||
1062 | err = unregister_parisc_driver(&snd_harmony_driver); | ||
1063 | if (err < 0) { | ||
1064 | printk(KERN_ERR PFX "failed to unregister\n"); | ||
1065 | } | ||
1066 | |||
1067 | return; | ||
1068 | } | 1037 | } |
1069 | 1038 | ||
1070 | MODULE_LICENSE("GPL"); | 1039 | MODULE_LICENSE("GPL"); |