aboutsummaryrefslogtreecommitdiffstats
path: root/sound/sparc/amd7930.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/sparc/amd7930.c')
-rw-r--r--sound/sparc/amd7930.c138
1 files changed, 77 insertions, 61 deletions
diff --git a/sound/sparc/amd7930.c b/sound/sparc/amd7930.c
index dfe9bac7fa32..ba1b2a3443d3 100644
--- a/sound/sparc/amd7930.c
+++ b/sound/sparc/amd7930.c
@@ -46,6 +46,7 @@
46#include <asm/io.h> 46#include <asm/io.h>
47#include <asm/irq.h> 47#include <asm/irq.h>
48#include <asm/sbus.h> 48#include <asm/sbus.h>
49#include <asm/prom.h>
49 50
50static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ 51static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
51static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ 52static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
@@ -335,7 +336,6 @@ struct snd_amd7930 {
335 int pgain; 336 int pgain;
336 int mgain; 337 int mgain;
337 338
338 struct sbus_dev *sdev;
339 unsigned int irq; 339 unsigned int irq;
340 unsigned int regs_size; 340 unsigned int regs_size;
341 struct snd_amd7930 *next; 341 struct snd_amd7930 *next;
@@ -946,11 +946,9 @@ static struct snd_device_ops snd_amd7930_dev_ops = {
946}; 946};
947 947
948static int __init snd_amd7930_create(struct snd_card *card, 948static int __init snd_amd7930_create(struct snd_card *card,
949 struct sbus_dev *sdev,
950 struct resource *rp, 949 struct resource *rp,
951 unsigned int reg_size, 950 unsigned int reg_size,
952 struct linux_prom_irqs *irq_prop, 951 int irq, int dev,
953 int dev,
954 struct snd_amd7930 **ramd) 952 struct snd_amd7930 **ramd)
955{ 953{
956 unsigned long flags; 954 unsigned long flags;
@@ -964,7 +962,6 @@ static int __init snd_amd7930_create(struct snd_card *card,
964 962
965 spin_lock_init(&amd->lock); 963 spin_lock_init(&amd->lock);
966 amd->card = card; 964 amd->card = card;
967 amd->sdev = sdev;
968 amd->regs_size = reg_size; 965 amd->regs_size = reg_size;
969 966
970 amd->regs = sbus_ioremap(rp, 0, amd->regs_size, "amd7930"); 967 amd->regs = sbus_ioremap(rp, 0, amd->regs_size, "amd7930");
@@ -975,15 +972,14 @@ static int __init snd_amd7930_create(struct snd_card *card,
975 972
976 amd7930_idle(amd); 973 amd7930_idle(amd);
977 974
978 if (request_irq(irq_prop->pri, snd_amd7930_interrupt, 975 if (request_irq(irq, snd_amd7930_interrupt,
979 SA_INTERRUPT | SA_SHIRQ, "amd7930", amd)) { 976 SA_INTERRUPT | SA_SHIRQ, "amd7930", amd)) {
980 snd_printk("amd7930-%d: Unable to grab IRQ %d\n", 977 snd_printk("amd7930-%d: Unable to grab IRQ %d\n",
981 dev, 978 dev, irq);
982 irq_prop->pri);
983 snd_amd7930_free(amd); 979 snd_amd7930_free(amd);
984 return -EBUSY; 980 return -EBUSY;
985 } 981 }
986 amd->irq = irq_prop->pri; 982 amd->irq = irq;
987 983
988 amd7930_enable_ints(amd); 984 amd7930_enable_ints(amd);
989 985
@@ -1017,47 +1013,21 @@ static int __init snd_amd7930_create(struct snd_card *card,
1017 return 0; 1013 return 0;
1018} 1014}
1019 1015
1020static int __init amd7930_attach(int prom_node, struct sbus_dev *sdev) 1016static int __init amd7930_attach_common(struct resource *rp, int irq)
1021{ 1017{
1022 static int dev; 1018 static int dev_num;
1023 struct linux_prom_registers reg_prop;
1024 struct linux_prom_irqs irq_prop;
1025 struct resource res, *rp;
1026 struct snd_card *card; 1019 struct snd_card *card;
1027 struct snd_amd7930 *amd; 1020 struct snd_amd7930 *amd;
1028 int err; 1021 int err;
1029 1022
1030 if (dev >= SNDRV_CARDS) 1023 if (dev_num >= SNDRV_CARDS)
1031 return -ENODEV; 1024 return -ENODEV;
1032 if (!enable[dev]) { 1025 if (!enable[dev_num]) {
1033 dev++; 1026 dev_num++;
1034 return -ENOENT; 1027 return -ENOENT;
1035 } 1028 }
1036 1029
1037 err = prom_getproperty(prom_node, "intr", 1030 card = snd_card_new(index[dev_num], id[dev_num], THIS_MODULE, 0);
1038 (char *) &irq_prop, sizeof(irq_prop));
1039 if (err < 0) {
1040 snd_printk("amd7930-%d: Firmware node lacks IRQ property.\n", dev);
1041 return -ENODEV;
1042 }
1043
1044 err = prom_getproperty(prom_node, "reg",
1045 (char *) &reg_prop, sizeof(reg_prop));
1046 if (err < 0) {
1047 snd_printk("amd7930-%d: Firmware node lacks register property.\n", dev);
1048 return -ENODEV;
1049 }
1050
1051 if (sdev) {
1052 rp = &sdev->resource[0];
1053 } else {
1054 rp = &res;
1055 rp->start = reg_prop.phys_addr;
1056 rp->end = rp->start + reg_prop.reg_size - 1;
1057 rp->flags = IORESOURCE_IO | (reg_prop.which_io & 0xff);
1058 }
1059
1060 card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
1061 if (card == NULL) 1031 if (card == NULL)
1062 return -ENOMEM; 1032 return -ENOMEM;
1063 1033
@@ -1067,10 +1037,11 @@ static int __init amd7930_attach(int prom_node, struct sbus_dev *sdev)
1067 card->shortname, 1037 card->shortname,
1068 rp->flags & 0xffL, 1038 rp->flags & 0xffL,
1069 rp->start, 1039 rp->start,
1070 irq_prop.pri); 1040 irq);
1071 1041
1072 if ((err = snd_amd7930_create(card, sdev, rp, reg_prop.reg_size, 1042 if ((err = snd_amd7930_create(card, rp,
1073 &irq_prop, dev, &amd)) < 0) 1043 (rp->end - rp->start) + 1,
1044 irq, dev_num, &amd)) < 0)
1074 goto out_err; 1045 goto out_err;
1075 1046
1076 if ((err = snd_amd7930_pcm(amd)) < 0) 1047 if ((err = snd_amd7930_pcm(amd)) < 0)
@@ -1085,7 +1056,8 @@ static int __init amd7930_attach(int prom_node, struct sbus_dev *sdev)
1085 amd->next = amd7930_list; 1056 amd->next = amd7930_list;
1086 amd7930_list = amd; 1057 amd7930_list = amd;
1087 1058
1088 dev++; 1059 dev_num++;
1060
1089 return 0; 1061 return 0;
1090 1062
1091out_err: 1063out_err:
@@ -1093,29 +1065,71 @@ out_err:
1093 return err; 1065 return err;
1094} 1066}
1095 1067
1096static int __init amd7930_init(void) 1068static int __init amd7930_obio_attach(struct device_node *dp)
1069{
1070 struct linux_prom_registers *regs;
1071 struct linux_prom_irqs *irqp;
1072 struct resource res, *rp;
1073 int len;
1074
1075 irqp = of_get_property(dp, "intr", &len);
1076 if (!irqp) {
1077 snd_printk("%s: Firmware node lacks IRQ property.\n",
1078 dp->full_name);
1079 return -ENODEV;
1080 }
1081
1082 regs = of_get_property(dp, "reg", &len);
1083 if (!regs) {
1084 snd_printk("%s: Firmware node lacks register property.\n",
1085 dp->full_name);
1086 return -ENODEV;
1087 }
1088
1089 rp = &res;
1090 rp->start = regs->phys_addr;
1091 rp->end = rp->start + regs->reg_size - 1;
1092 rp->flags = IORESOURCE_IO | (regs->which_io & 0xff);
1093
1094 return amd7930_attach_common(rp, irqp->pri);
1095}
1096
1097static int __devinit amd7930_sbus_probe(struct of_device *dev, const struct of_device_id *match)
1097{ 1098{
1098 struct sbus_bus *sbus; 1099 struct sbus_dev *sdev = to_sbus_device(&dev->dev);
1099 struct sbus_dev *sdev;
1100 int node, found;
1101 1100
1102 found = 0; 1101 return amd7930_attach_common(&sdev->resource[0], sdev->irqs[0]);
1102}
1103
1104static struct of_device_id amd7930_match[] = {
1105 {
1106 .name = "audio",
1107 },
1108 {},
1109};
1110
1111static struct of_platform_driver amd7930_sbus_driver = {
1112 .name = "audio",
1113 .match_table = amd7930_match,
1114 .probe = amd7930_sbus_probe,
1115};
1116
1117static int __init amd7930_init(void)
1118{
1119 struct device_node *dp;
1103 1120
1104 /* Try to find the sun4c "audio" node first. */ 1121 /* Try to find the sun4c "audio" node first. */
1105 node = prom_getchild(prom_root_node); 1122 dp = of_find_node_by_path("/");
1106 node = prom_searchsiblings(node, "audio"); 1123 dp = dp->child;
1107 if (node && amd7930_attach(node, NULL) == 0) 1124 while (dp) {
1108 found++; 1125 if (!strcmp(dp->name, "audio"))
1126 amd7930_obio_attach(dp);
1109 1127
1110 /* Probe each SBUS for amd7930 chips. */ 1128 dp = dp->sibling;
1111 for_all_sbusdev(sdev, sbus) {
1112 if (!strcmp(sdev->prom_name, "audio")) {
1113 if (amd7930_attach(sdev->prom_node, sdev) == 0)
1114 found++;
1115 }
1116 } 1129 }
1117 1130
1118 return (found > 0) ? 0 : -EIO; 1131 /* Probe each SBUS for amd7930 chips. */
1132 return of_register_driver(&amd7930_sbus_driver, &sbus_bus_type);
1119} 1133}
1120 1134
1121static void __exit amd7930_exit(void) 1135static void __exit amd7930_exit(void)
@@ -1131,6 +1145,8 @@ static void __exit amd7930_exit(void)
1131 } 1145 }
1132 1146
1133 amd7930_list = NULL; 1147 amd7930_list = NULL;
1148
1149 of_unregister_driver(&amd7930_sbus_driver);
1134} 1150}
1135 1151
1136module_init(amd7930_init); 1152module_init(amd7930_init);