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.c104
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
50static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ 51static 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
789static int snd_amd7930_info_volume(struct snd_kcontrol *kctl, struct snd_ctl_elem_info *uinfo) 789static 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
921static int snd_amd7930_free(struct snd_amd7930 *amd) 907static 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
947static int __devinit snd_amd7930_create(struct snd_card *card, 936static 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
1015static int __devinit amd7930_attach_common(struct resource *rp, int irq) 1004static 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
1067static int __devinit amd7930_obio_attach(struct device_node *dp) 1058static 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
1096static 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
1103static 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
1116static int __init amd7930_init(void) 1071static 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
1134static void __exit amd7930_exit(void) 1076static void __exit amd7930_exit(void)