diff options
Diffstat (limited to 'sound/sparc/amd7930.c')
-rw-r--r-- | sound/sparc/amd7930.c | 104 |
1 files changed, 23 insertions, 81 deletions
diff --git a/sound/sparc/amd7930.c b/sound/sparc/amd7930.c index 0c63e0585b15..f87933e48812 100644 --- a/sound/sparc/amd7930.c +++ b/sound/sparc/amd7930.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Driver for AMD7930 sound chips found on Sparcs. | 2 | * Driver for AMD7930 sound chips found on Sparcs. |
3 | * Copyright (C) 2002 David S. Miller <davem@redhat.com> | 3 | * Copyright (C) 2002, 2008 David S. Miller <davem@davemloft.net> |
4 | * | 4 | * |
5 | * Based entirely upon drivers/sbus/audio/amd7930.c which is: | 5 | * Based entirely upon drivers/sbus/audio/amd7930.c which is: |
6 | * Copyright (C) 1996,1997 Thomas K. Dyas (tdyas@eden.rutgers.edu) | 6 | * Copyright (C) 1996,1997 Thomas K. Dyas (tdyas@eden.rutgers.edu) |
@@ -35,6 +35,8 @@ | |||
35 | #include <linux/init.h> | 35 | #include <linux/init.h> |
36 | #include <linux/interrupt.h> | 36 | #include <linux/interrupt.h> |
37 | #include <linux/moduleparam.h> | 37 | #include <linux/moduleparam.h> |
38 | #include <linux/of.h> | ||
39 | #include <linux/of_device.h> | ||
38 | 40 | ||
39 | #include <sound/core.h> | 41 | #include <sound/core.h> |
40 | #include <sound/pcm.h> | 42 | #include <sound/pcm.h> |
@@ -44,7 +46,6 @@ | |||
44 | 46 | ||
45 | #include <asm/io.h> | 47 | #include <asm/io.h> |
46 | #include <asm/irq.h> | 48 | #include <asm/irq.h> |
47 | #include <asm/sbus.h> | ||
48 | #include <asm/prom.h> | 49 | #include <asm/prom.h> |
49 | 50 | ||
50 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ | 51 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ |
@@ -335,8 +336,8 @@ struct snd_amd7930 { | |||
335 | int pgain; | 336 | int pgain; |
336 | int mgain; | 337 | int mgain; |
337 | 338 | ||
339 | struct of_device *op; | ||
338 | unsigned int irq; | 340 | unsigned int irq; |
339 | unsigned int regs_size; | ||
340 | struct snd_amd7930 *next; | 341 | struct snd_amd7930 *next; |
341 | }; | 342 | }; |
342 | 343 | ||
@@ -765,7 +766,6 @@ static int __devinit snd_amd7930_pcm(struct snd_amd7930 *amd) | |||
765 | /* playback count */ 1, | 766 | /* playback count */ 1, |
766 | /* capture count */ 1, &pcm)) < 0) | 767 | /* capture count */ 1, &pcm)) < 0) |
767 | return err; | 768 | return err; |
768 | snd_assert(pcm != NULL, return -EINVAL); | ||
769 | 769 | ||
770 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_amd7930_playback_ops); | 770 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_amd7930_playback_ops); |
771 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_amd7930_capture_ops); | 771 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_amd7930_capture_ops); |
@@ -788,13 +788,6 @@ static int __devinit snd_amd7930_pcm(struct snd_amd7930 *amd) | |||
788 | 788 | ||
789 | static int snd_amd7930_info_volume(struct snd_kcontrol *kctl, struct snd_ctl_elem_info *uinfo) | 789 | static int snd_amd7930_info_volume(struct snd_kcontrol *kctl, struct snd_ctl_elem_info *uinfo) |
790 | { | 790 | { |
791 | int type = kctl->private_value; | ||
792 | |||
793 | snd_assert(type == VOLUME_MONITOR || | ||
794 | type == VOLUME_CAPTURE || | ||
795 | type == VOLUME_PLAYBACK, return -EINVAL); | ||
796 | (void) type; | ||
797 | |||
798 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | 791 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; |
799 | uinfo->count = 1; | 792 | uinfo->count = 1; |
800 | uinfo->value.integer.min = 0; | 793 | uinfo->value.integer.min = 0; |
@@ -809,10 +802,6 @@ static int snd_amd7930_get_volume(struct snd_kcontrol *kctl, struct snd_ctl_elem | |||
809 | int type = kctl->private_value; | 802 | int type = kctl->private_value; |
810 | int *swval; | 803 | int *swval; |
811 | 804 | ||
812 | snd_assert(type == VOLUME_MONITOR || | ||
813 | type == VOLUME_CAPTURE || | ||
814 | type == VOLUME_PLAYBACK, return -EINVAL); | ||
815 | |||
816 | switch (type) { | 805 | switch (type) { |
817 | case VOLUME_MONITOR: | 806 | case VOLUME_MONITOR: |
818 | swval = &amd->mgain; | 807 | swval = &amd->mgain; |
@@ -838,10 +827,6 @@ static int snd_amd7930_put_volume(struct snd_kcontrol *kctl, struct snd_ctl_elem | |||
838 | int type = kctl->private_value; | 827 | int type = kctl->private_value; |
839 | int *swval, change; | 828 | int *swval, change; |
840 | 829 | ||
841 | snd_assert(type == VOLUME_MONITOR || | ||
842 | type == VOLUME_CAPTURE || | ||
843 | type == VOLUME_PLAYBACK, return -EINVAL); | ||
844 | |||
845 | switch (type) { | 830 | switch (type) { |
846 | case VOLUME_MONITOR: | 831 | case VOLUME_MONITOR: |
847 | swval = &amd->mgain; | 832 | swval = &amd->mgain; |
@@ -904,7 +889,8 @@ static int __devinit snd_amd7930_mixer(struct snd_amd7930 *amd) | |||
904 | struct snd_card *card; | 889 | struct snd_card *card; |
905 | int idx, err; | 890 | int idx, err; |
906 | 891 | ||
907 | snd_assert(amd != NULL && amd->card != NULL, return -EINVAL); | 892 | if (snd_BUG_ON(!amd || !amd->card)) |
893 | return -EINVAL; | ||
908 | 894 | ||
909 | card = amd->card; | 895 | card = amd->card; |
910 | strcpy(card->mixername, card->shortname); | 896 | strcpy(card->mixername, card->shortname); |
@@ -920,13 +906,16 @@ static int __devinit snd_amd7930_mixer(struct snd_amd7930 *amd) | |||
920 | 906 | ||
921 | static int snd_amd7930_free(struct snd_amd7930 *amd) | 907 | static int snd_amd7930_free(struct snd_amd7930 *amd) |
922 | { | 908 | { |
909 | struct of_device *op = amd->op; | ||
910 | |||
923 | amd7930_idle(amd); | 911 | amd7930_idle(amd); |
924 | 912 | ||
925 | if (amd->irq) | 913 | if (amd->irq) |
926 | free_irq(amd->irq, amd); | 914 | free_irq(amd->irq, amd); |
927 | 915 | ||
928 | if (amd->regs) | 916 | if (amd->regs) |
929 | sbus_iounmap(amd->regs, amd->regs_size); | 917 | of_iounmap(&op->resource[0], amd->regs, |
918 | resource_size(&op->resource[0])); | ||
930 | 919 | ||
931 | kfree(amd); | 920 | kfree(amd); |
932 | 921 | ||
@@ -945,13 +934,12 @@ static struct snd_device_ops snd_amd7930_dev_ops = { | |||
945 | }; | 934 | }; |
946 | 935 | ||
947 | static int __devinit snd_amd7930_create(struct snd_card *card, | 936 | static int __devinit snd_amd7930_create(struct snd_card *card, |
948 | struct resource *rp, | 937 | struct of_device *op, |
949 | unsigned int reg_size, | ||
950 | int irq, int dev, | 938 | int irq, int dev, |
951 | struct snd_amd7930 **ramd) | 939 | struct snd_amd7930 **ramd) |
952 | { | 940 | { |
953 | unsigned long flags; | ||
954 | struct snd_amd7930 *amd; | 941 | struct snd_amd7930 *amd; |
942 | unsigned long flags; | ||
955 | int err; | 943 | int err; |
956 | 944 | ||
957 | *ramd = NULL; | 945 | *ramd = NULL; |
@@ -961,9 +949,10 @@ static int __devinit snd_amd7930_create(struct snd_card *card, | |||
961 | 949 | ||
962 | spin_lock_init(&amd->lock); | 950 | spin_lock_init(&amd->lock); |
963 | amd->card = card; | 951 | amd->card = card; |
964 | amd->regs_size = reg_size; | 952 | amd->op = op; |
965 | 953 | ||
966 | amd->regs = sbus_ioremap(rp, 0, amd->regs_size, "amd7930"); | 954 | amd->regs = of_ioremap(&op->resource[0], 0, |
955 | resource_size(&op->resource[0]), "amd7930"); | ||
967 | if (!amd->regs) { | 956 | if (!amd->regs) { |
968 | snd_printk("amd7930-%d: Unable to map chip registers.\n", dev); | 957 | snd_printk("amd7930-%d: Unable to map chip registers.\n", dev); |
969 | return -EIO; | 958 | return -EIO; |
@@ -1012,12 +1001,15 @@ static int __devinit snd_amd7930_create(struct snd_card *card, | |||
1012 | return 0; | 1001 | return 0; |
1013 | } | 1002 | } |
1014 | 1003 | ||
1015 | static int __devinit amd7930_attach_common(struct resource *rp, int irq) | 1004 | static int __devinit amd7930_sbus_probe(struct of_device *op, const struct of_device_id *match) |
1016 | { | 1005 | { |
1006 | struct resource *rp = &op->resource[0]; | ||
1017 | static int dev_num; | 1007 | static int dev_num; |
1018 | struct snd_card *card; | 1008 | struct snd_card *card; |
1019 | struct snd_amd7930 *amd; | 1009 | struct snd_amd7930 *amd; |
1020 | int err; | 1010 | int err, irq; |
1011 | |||
1012 | irq = op->irqs[0]; | ||
1021 | 1013 | ||
1022 | if (dev_num >= SNDRV_CARDS) | 1014 | if (dev_num >= SNDRV_CARDS) |
1023 | return -ENODEV; | 1015 | return -ENODEV; |
@@ -1038,8 +1030,7 @@ static int __devinit amd7930_attach_common(struct resource *rp, int irq) | |||
1038 | (unsigned long long)rp->start, | 1030 | (unsigned long long)rp->start, |
1039 | irq); | 1031 | irq); |
1040 | 1032 | ||
1041 | if ((err = snd_amd7930_create(card, rp, | 1033 | if ((err = snd_amd7930_create(card, op, |
1042 | (rp->end - rp->start) + 1, | ||
1043 | irq, dev_num, &amd)) < 0) | 1034 | irq, dev_num, &amd)) < 0) |
1044 | goto out_err; | 1035 | goto out_err; |
1045 | 1036 | ||
@@ -1064,43 +1055,7 @@ out_err: | |||
1064 | return err; | 1055 | return err; |
1065 | } | 1056 | } |
1066 | 1057 | ||
1067 | static int __devinit amd7930_obio_attach(struct device_node *dp) | 1058 | static const struct of_device_id amd7930_match[] = { |
1068 | { | ||
1069 | const struct linux_prom_registers *regs; | ||
1070 | const struct linux_prom_irqs *irqp; | ||
1071 | struct resource res, *rp; | ||
1072 | int len; | ||
1073 | |||
1074 | irqp = of_get_property(dp, "intr", &len); | ||
1075 | if (!irqp) { | ||
1076 | snd_printk("%s: Firmware node lacks IRQ property.\n", | ||
1077 | dp->full_name); | ||
1078 | return -ENODEV; | ||
1079 | } | ||
1080 | |||
1081 | regs = of_get_property(dp, "reg", &len); | ||
1082 | if (!regs) { | ||
1083 | snd_printk("%s: Firmware node lacks register property.\n", | ||
1084 | dp->full_name); | ||
1085 | return -ENODEV; | ||
1086 | } | ||
1087 | |||
1088 | rp = &res; | ||
1089 | rp->start = regs->phys_addr; | ||
1090 | rp->end = rp->start + regs->reg_size - 1; | ||
1091 | rp->flags = IORESOURCE_IO | (regs->which_io & 0xff); | ||
1092 | |||
1093 | return amd7930_attach_common(rp, irqp->pri); | ||
1094 | } | ||
1095 | |||
1096 | static int __devinit amd7930_sbus_probe(struct of_device *dev, const struct of_device_id *match) | ||
1097 | { | ||
1098 | struct sbus_dev *sdev = to_sbus_device(&dev->dev); | ||
1099 | |||
1100 | return amd7930_attach_common(&sdev->resource[0], sdev->irqs[0]); | ||
1101 | } | ||
1102 | |||
1103 | static struct of_device_id amd7930_match[] = { | ||
1104 | { | 1059 | { |
1105 | .name = "audio", | 1060 | .name = "audio", |
1106 | }, | 1061 | }, |
@@ -1115,20 +1070,7 @@ static struct of_platform_driver amd7930_sbus_driver = { | |||
1115 | 1070 | ||
1116 | static int __init amd7930_init(void) | 1071 | static int __init amd7930_init(void) |
1117 | { | 1072 | { |
1118 | struct device_node *dp; | 1073 | return of_register_driver(&amd7930_sbus_driver, &of_bus_type); |
1119 | |||
1120 | /* Try to find the sun4c "audio" node first. */ | ||
1121 | dp = of_find_node_by_path("/"); | ||
1122 | dp = dp->child; | ||
1123 | while (dp) { | ||
1124 | if (!strcmp(dp->name, "audio")) | ||
1125 | amd7930_obio_attach(dp); | ||
1126 | |||
1127 | dp = dp->sibling; | ||
1128 | } | ||
1129 | |||
1130 | /* Probe each SBUS for amd7930 chips. */ | ||
1131 | return of_register_driver(&amd7930_sbus_driver, &sbus_bus_type); | ||
1132 | } | 1074 | } |
1133 | 1075 | ||
1134 | static void __exit amd7930_exit(void) | 1076 | static void __exit amd7930_exit(void) |