diff options
Diffstat (limited to 'sound/sparc')
-rw-r--r-- | sound/sparc/amd7930.c | 83 |
1 files changed, 20 insertions, 63 deletions
diff --git a/sound/sparc/amd7930.c b/sound/sparc/amd7930.c index 0c63e0585b15..0f82c3f6cfdb 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 | ||
@@ -920,13 +921,16 @@ static int __devinit snd_amd7930_mixer(struct snd_amd7930 *amd) | |||
920 | 921 | ||
921 | static int snd_amd7930_free(struct snd_amd7930 *amd) | 922 | static int snd_amd7930_free(struct snd_amd7930 *amd) |
922 | { | 923 | { |
924 | struct of_device *op = amd->op; | ||
925 | |||
923 | amd7930_idle(amd); | 926 | amd7930_idle(amd); |
924 | 927 | ||
925 | if (amd->irq) | 928 | if (amd->irq) |
926 | free_irq(amd->irq, amd); | 929 | free_irq(amd->irq, amd); |
927 | 930 | ||
928 | if (amd->regs) | 931 | if (amd->regs) |
929 | sbus_iounmap(amd->regs, amd->regs_size); | 932 | of_iounmap(&op->resource[0], amd->regs, |
933 | resource_size(&op->resource[0])); | ||
930 | 934 | ||
931 | kfree(amd); | 935 | kfree(amd); |
932 | 936 | ||
@@ -945,13 +949,12 @@ static struct snd_device_ops snd_amd7930_dev_ops = { | |||
945 | }; | 949 | }; |
946 | 950 | ||
947 | static int __devinit snd_amd7930_create(struct snd_card *card, | 951 | static int __devinit snd_amd7930_create(struct snd_card *card, |
948 | struct resource *rp, | 952 | struct of_device *op, |
949 | unsigned int reg_size, | ||
950 | int irq, int dev, | 953 | int irq, int dev, |
951 | struct snd_amd7930 **ramd) | 954 | struct snd_amd7930 **ramd) |
952 | { | 955 | { |
953 | unsigned long flags; | ||
954 | struct snd_amd7930 *amd; | 956 | struct snd_amd7930 *amd; |
957 | unsigned long flags; | ||
955 | int err; | 958 | int err; |
956 | 959 | ||
957 | *ramd = NULL; | 960 | *ramd = NULL; |
@@ -961,9 +964,10 @@ static int __devinit snd_amd7930_create(struct snd_card *card, | |||
961 | 964 | ||
962 | spin_lock_init(&amd->lock); | 965 | spin_lock_init(&amd->lock); |
963 | amd->card = card; | 966 | amd->card = card; |
964 | amd->regs_size = reg_size; | 967 | amd->op = op; |
965 | 968 | ||
966 | amd->regs = sbus_ioremap(rp, 0, amd->regs_size, "amd7930"); | 969 | amd->regs = of_ioremap(&op->resource[0], 0, |
970 | resource_size(&op->resource[0]), "amd7930"); | ||
967 | if (!amd->regs) { | 971 | if (!amd->regs) { |
968 | snd_printk("amd7930-%d: Unable to map chip registers.\n", dev); | 972 | snd_printk("amd7930-%d: Unable to map chip registers.\n", dev); |
969 | return -EIO; | 973 | return -EIO; |
@@ -1012,12 +1016,15 @@ static int __devinit snd_amd7930_create(struct snd_card *card, | |||
1012 | return 0; | 1016 | return 0; |
1013 | } | 1017 | } |
1014 | 1018 | ||
1015 | static int __devinit amd7930_attach_common(struct resource *rp, int irq) | 1019 | static int __devinit amd7930_sbus_probe(struct of_device *op, const struct of_device_id *match) |
1016 | { | 1020 | { |
1021 | struct resource *rp = &op->resource[0]; | ||
1017 | static int dev_num; | 1022 | static int dev_num; |
1018 | struct snd_card *card; | 1023 | struct snd_card *card; |
1019 | struct snd_amd7930 *amd; | 1024 | struct snd_amd7930 *amd; |
1020 | int err; | 1025 | int err, irq; |
1026 | |||
1027 | irq = op->irqs[0]; | ||
1021 | 1028 | ||
1022 | if (dev_num >= SNDRV_CARDS) | 1029 | if (dev_num >= SNDRV_CARDS) |
1023 | return -ENODEV; | 1030 | return -ENODEV; |
@@ -1038,8 +1045,7 @@ static int __devinit amd7930_attach_common(struct resource *rp, int irq) | |||
1038 | (unsigned long long)rp->start, | 1045 | (unsigned long long)rp->start, |
1039 | irq); | 1046 | irq); |
1040 | 1047 | ||
1041 | if ((err = snd_amd7930_create(card, rp, | 1048 | if ((err = snd_amd7930_create(card, op, |
1042 | (rp->end - rp->start) + 1, | ||
1043 | irq, dev_num, &amd)) < 0) | 1049 | irq, dev_num, &amd)) < 0) |
1044 | goto out_err; | 1050 | goto out_err; |
1045 | 1051 | ||
@@ -1064,42 +1070,6 @@ out_err: | |||
1064 | return err; | 1070 | return err; |
1065 | } | 1071 | } |
1066 | 1072 | ||
1067 | static int __devinit amd7930_obio_attach(struct device_node *dp) | ||
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[] = { | 1073 | static struct of_device_id amd7930_match[] = { |
1104 | { | 1074 | { |
1105 | .name = "audio", | 1075 | .name = "audio", |
@@ -1115,20 +1085,7 @@ static struct of_platform_driver amd7930_sbus_driver = { | |||
1115 | 1085 | ||
1116 | static int __init amd7930_init(void) | 1086 | static int __init amd7930_init(void) |
1117 | { | 1087 | { |
1118 | struct device_node *dp; | 1088 | 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 | } | 1089 | } |
1133 | 1090 | ||
1134 | static void __exit amd7930_exit(void) | 1091 | static void __exit amd7930_exit(void) |