diff options
author | Krzysztof Helt <krzysztof.h1@wp.pl> | 2009-12-10 14:39:28 -0500 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2009-12-11 08:43:04 -0500 |
commit | 14ff3e78304e3f7fe18f950c3aa0686e6800b3fb (patch) | |
tree | 967c746fd0247aa74c68d9b3b38a90b167bad39c | |
parent | 3067e02f8f3ae2f3f02ba76400d03b8bcb4942b0 (diff) |
ALSA: dt019x: merge into the als100 driver
The als100 driver is so similar to the dt019x/als007 driver
that one driver's source can be used for both drivers with
only few changes. Merge the dt019x driver into the als100.
Signed-off-by: Krzysztof Helt <krzysztof.h1@wp.pl>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r-- | sound/isa/Kconfig | 21 | ||||
-rw-r--r-- | sound/isa/Makefile | 2 | ||||
-rw-r--r-- | sound/isa/als100.c | 121 | ||||
-rw-r--r-- | sound/isa/dt019x.c | 321 |
4 files changed, 90 insertions, 375 deletions
diff --git a/sound/isa/Kconfig b/sound/isa/Kconfig index 02fe81ca88fd..194af3b01e13 100644 --- a/sound/isa/Kconfig +++ b/sound/isa/Kconfig | |||
@@ -63,15 +63,16 @@ config SND_AD1848 | |||
63 | will be called snd-ad1848. | 63 | will be called snd-ad1848. |
64 | 64 | ||
65 | config SND_ALS100 | 65 | config SND_ALS100 |
66 | tristate "Avance Logic ALS100/ALS120" | 66 | tristate "Diamond Tech. DT-019x and Avance Logic ALSxxx" |
67 | depends on PNP | 67 | depends on PNP |
68 | select ISAPNP | 68 | select ISAPNP |
69 | select SND_OPL3_LIB | 69 | select SND_OPL3_LIB |
70 | select SND_MPU401_UART | 70 | select SND_MPU401_UART |
71 | select SND_SB16_DSP | 71 | select SND_SB16_DSP |
72 | help | 72 | help |
73 | Say Y here to include support for soundcards based on Avance | 73 | Say Y here to include support for soundcards based on the |
74 | Logic ALS100, ALS110, ALS120 and ALS200 chips. | 74 | Diamond Technologies DT-019X or Avance Logic chips: ALS007, |
75 | ALS100, ALS110, ALS120 and ALS200 chips. | ||
75 | 76 | ||
76 | To compile this driver as a module, choose M here: the module | 77 | To compile this driver as a module, choose M here: the module |
77 | will be called snd-als100. | 78 | will be called snd-als100. |
@@ -127,20 +128,6 @@ config SND_CS4236 | |||
127 | To compile this driver as a module, choose M here: the module | 128 | To compile this driver as a module, choose M here: the module |
128 | will be called snd-cs4236. | 129 | will be called snd-cs4236. |
129 | 130 | ||
130 | config SND_DT019X | ||
131 | tristate "Diamond Technologies DT-019X, Avance Logic ALS-007" | ||
132 | depends on PNP | ||
133 | select ISAPNP | ||
134 | select SND_OPL3_LIB | ||
135 | select SND_MPU401_UART | ||
136 | select SND_SB16_DSP | ||
137 | help | ||
138 | Say Y here to include support for soundcards based on the | ||
139 | Diamond Technologies DT-019X or Avance Logic ALS-007 chips. | ||
140 | |||
141 | To compile this driver as a module, choose M here: the module | ||
142 | will be called snd-dt019x. | ||
143 | |||
144 | config SND_ES968 | 131 | config SND_ES968 |
145 | tristate "Generic ESS ES968 driver" | 132 | tristate "Generic ESS ES968 driver" |
146 | depends on PNP | 133 | depends on PNP |
diff --git a/sound/isa/Makefile b/sound/isa/Makefile index b906b9a1a81e..c73d30c4f462 100644 --- a/sound/isa/Makefile +++ b/sound/isa/Makefile | |||
@@ -7,7 +7,6 @@ snd-adlib-objs := adlib.o | |||
7 | snd-als100-objs := als100.o | 7 | snd-als100-objs := als100.o |
8 | snd-azt2320-objs := azt2320.o | 8 | snd-azt2320-objs := azt2320.o |
9 | snd-cmi8330-objs := cmi8330.o | 9 | snd-cmi8330-objs := cmi8330.o |
10 | snd-dt019x-objs := dt019x.o | ||
11 | snd-es18xx-objs := es18xx.o | 10 | snd-es18xx-objs := es18xx.o |
12 | snd-opl3sa2-objs := opl3sa2.o | 11 | snd-opl3sa2-objs := opl3sa2.o |
13 | snd-sc6000-objs := sc6000.o | 12 | snd-sc6000-objs := sc6000.o |
@@ -19,7 +18,6 @@ obj-$(CONFIG_SND_ADLIB) += snd-adlib.o | |||
19 | obj-$(CONFIG_SND_ALS100) += snd-als100.o | 18 | obj-$(CONFIG_SND_ALS100) += snd-als100.o |
20 | obj-$(CONFIG_SND_AZT2320) += snd-azt2320.o | 19 | obj-$(CONFIG_SND_AZT2320) += snd-azt2320.o |
21 | obj-$(CONFIG_SND_CMI8330) += snd-cmi8330.o | 20 | obj-$(CONFIG_SND_CMI8330) += snd-cmi8330.o |
22 | obj-$(CONFIG_SND_DT019X) += snd-dt019x.o | ||
23 | obj-$(CONFIG_SND_ES18XX) += snd-es18xx.o | 21 | obj-$(CONFIG_SND_ES18XX) += snd-es18xx.o |
24 | obj-$(CONFIG_SND_OPL3SA2) += snd-opl3sa2.o | 22 | obj-$(CONFIG_SND_OPL3SA2) += snd-opl3sa2.o |
25 | obj-$(CONFIG_SND_SC6000) += snd-sc6000.o | 23 | obj-$(CONFIG_SND_SC6000) += snd-sc6000.o |
diff --git a/sound/isa/als100.c b/sound/isa/als100.c index 5fd52e4d7079..20becc89f6f6 100644 --- a/sound/isa/als100.c +++ b/sound/isa/als100.c | |||
@@ -2,9 +2,13 @@ | |||
2 | /* | 2 | /* |
3 | card-als100.c - driver for Avance Logic ALS100 based soundcards. | 3 | card-als100.c - driver for Avance Logic ALS100 based soundcards. |
4 | Copyright (C) 1999-2000 by Massimo Piccioni <dafastidio@libero.it> | 4 | Copyright (C) 1999-2000 by Massimo Piccioni <dafastidio@libero.it> |
5 | Copyright (C) 1999-2002 by Massimo Piccioni <dafastidio@libero.it> | ||
5 | 6 | ||
6 | Thanks to Pierfrancesco 'qM2' Passerini. | 7 | Thanks to Pierfrancesco 'qM2' Passerini. |
7 | 8 | ||
9 | Generalised for soundcards based on DT-0196 and ALS-007 chips | ||
10 | by Jonathan Woithe <jwoithe@physics.adelaide.edu.au>: June 2002. | ||
11 | |||
8 | This program is free software; you can redistribute it and/or modify | 12 | This program is free software; you can redistribute it and/or modify |
9 | it under the terms of the GNU General Public License as published by | 13 | it under the terms of the GNU General Public License as published by |
10 | the Free Software Foundation; either version 2 of the License, or | 14 | the Free Software Foundation; either version 2 of the License, or |
@@ -33,10 +37,10 @@ | |||
33 | 37 | ||
34 | #define PFX "als100: " | 38 | #define PFX "als100: " |
35 | 39 | ||
36 | MODULE_AUTHOR("Massimo Piccioni <dafastidio@libero.it>"); | 40 | MODULE_DESCRIPTION("Avance Logic ALS007/ALS1X0"); |
37 | MODULE_DESCRIPTION("Avance Logic ALS1X0"); | 41 | MODULE_SUPPORTED_DEVICE("{{Diamond Technologies DT-019X}," |
38 | MODULE_LICENSE("GPL"); | 42 | "{Avance Logic ALS-007}}" |
39 | MODULE_SUPPORTED_DEVICE("{{Avance Logic,ALS100 - PRO16PNP}," | 43 | "{{Avance Logic,ALS100 - PRO16PNP}," |
40 | "{Avance Logic,ALS110}," | 44 | "{Avance Logic,ALS110}," |
41 | "{Avance Logic,ALS120}," | 45 | "{Avance Logic,ALS120}," |
42 | "{Avance Logic,ALS200}," | 46 | "{Avance Logic,ALS200}," |
@@ -45,9 +49,12 @@ MODULE_SUPPORTED_DEVICE("{{Avance Logic,ALS100 - PRO16PNP}," | |||
45 | "{Avance Logic,ALS120}," | 49 | "{Avance Logic,ALS120}," |
46 | "{RTL,RTL3000}}"); | 50 | "{RTL,RTL3000}}"); |
47 | 51 | ||
52 | MODULE_AUTHOR("Massimo Piccioni <dafastidio@libero.it>"); | ||
53 | MODULE_LICENSE("GPL"); | ||
54 | |||
48 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ | 55 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ |
49 | static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ | 56 | static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ |
50 | static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP; /* Enable this card */ | 57 | static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */ |
51 | static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */ | 58 | static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */ |
52 | static long mpu_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */ | 59 | static long mpu_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */ |
53 | static long fm_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */ | 60 | static long fm_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */ |
@@ -57,14 +64,15 @@ static int dma8[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* PnP setup */ | |||
57 | static int dma16[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* PnP setup */ | 64 | static int dma16[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* PnP setup */ |
58 | 65 | ||
59 | module_param_array(index, int, NULL, 0444); | 66 | module_param_array(index, int, NULL, 0444); |
60 | MODULE_PARM_DESC(index, "Index value for als100 based soundcard."); | 67 | MODULE_PARM_DESC(index, "Index value for Avance Logic based soundcard."); |
61 | module_param_array(id, charp, NULL, 0444); | 68 | module_param_array(id, charp, NULL, 0444); |
62 | MODULE_PARM_DESC(id, "ID string for als100 based soundcard."); | 69 | MODULE_PARM_DESC(id, "ID string for Avance Logic based soundcard."); |
63 | module_param_array(enable, bool, NULL, 0444); | 70 | module_param_array(enable, bool, NULL, 0444); |
64 | MODULE_PARM_DESC(enable, "Enable als100 based soundcard."); | 71 | MODULE_PARM_DESC(enable, "Enable Avance Logic based soundcard."); |
72 | |||
73 | MODULE_ALIAS("snd-dt019x"); | ||
65 | 74 | ||
66 | struct snd_card_als100 { | 75 | struct snd_card_als100 { |
67 | int dev_no; | ||
68 | struct pnp_dev *dev; | 76 | struct pnp_dev *dev; |
69 | struct pnp_dev *devmpu; | 77 | struct pnp_dev *devmpu; |
70 | struct pnp_dev *devopl; | 78 | struct pnp_dev *devopl; |
@@ -72,25 +80,43 @@ struct snd_card_als100 { | |||
72 | }; | 80 | }; |
73 | 81 | ||
74 | static struct pnp_card_device_id snd_als100_pnpids[] = { | 82 | static struct pnp_card_device_id snd_als100_pnpids[] = { |
83 | /* DT197A30 */ | ||
84 | { .id = "RWB1688", | ||
85 | .devs = { { "@@@0001" }, { "@X@0001" }, { "@H@0001" } }, | ||
86 | .driver_data = SB_HW_DT019X }, | ||
87 | /* DT0196 / ALS-007 */ | ||
88 | { .id = "ALS0007", | ||
89 | .devs = { { "@@@0001" }, { "@X@0001" }, { "@H@0001" } }, | ||
90 | .driver_data = SB_HW_DT019X }, | ||
75 | /* ALS100 - PRO16PNP */ | 91 | /* ALS100 - PRO16PNP */ |
76 | { .id = "ALS0001", .devs = { { "@@@0001" }, { "@X@0001" }, { "@H@0001" } } }, | 92 | { .id = "ALS0001", |
93 | .devs = { { "@@@0001" }, { "@X@0001" }, { "@H@0001" } }, | ||
94 | .driver_data = SB_HW_ALS100 }, | ||
77 | /* ALS110 - MF1000 - Digimate 3D Sound */ | 95 | /* ALS110 - MF1000 - Digimate 3D Sound */ |
78 | { .id = "ALS0110", .devs = { { "@@@1001" }, { "@X@1001" }, { "@H@1001" } } }, | 96 | { .id = "ALS0110", |
97 | .devs = { { "@@@1001" }, { "@X@1001" }, { "@H@1001" } }, | ||
98 | .driver_data = SB_HW_ALS100 }, | ||
79 | /* ALS120 */ | 99 | /* ALS120 */ |
80 | { .id = "ALS0120", .devs = { { "@@@2001" }, { "@X@2001" }, { "@H@2001" } } }, | 100 | { .id = "ALS0120", |
101 | .devs = { { "@@@2001" }, { "@X@2001" }, { "@H@2001" } }, | ||
102 | .driver_data = SB_HW_ALS100 }, | ||
81 | /* ALS200 */ | 103 | /* ALS200 */ |
82 | { .id = "ALS0200", .devs = { { "@@@0020" }, { "@X@0020" }, { "@H@0001" } } }, | 104 | { .id = "ALS0200", |
105 | .devs = { { "@@@0020" }, { "@X@0020" }, { "@H@0001" } }, | ||
106 | .driver_data = SB_HW_ALS100 }, | ||
83 | /* ALS200 OEM */ | 107 | /* ALS200 OEM */ |
84 | { .id = "ALS0200", .devs = { { "@@@0020" }, { "@X@0020" }, { "@H@0020" } } }, | 108 | { .id = "ALS0200", |
109 | .devs = { { "@@@0020" }, { "@X@0020" }, { "@H@0020" } }, | ||
110 | .driver_data = SB_HW_ALS100 }, | ||
85 | /* RTL3000 */ | 111 | /* RTL3000 */ |
86 | { .id = "RTL3000", .devs = { { "@@@2001" }, { "@X@2001" }, { "@H@2001" } } }, | 112 | { .id = "RTL3000", |
87 | { .id = "", } /* end */ | 113 | .devs = { { "@@@2001" }, { "@X@2001" }, { "@H@2001" } }, |
114 | .driver_data = SB_HW_ALS100 }, | ||
115 | { .id = "" } /* end */ | ||
88 | }; | 116 | }; |
89 | 117 | ||
90 | MODULE_DEVICE_TABLE(pnp_card, snd_als100_pnpids); | 118 | MODULE_DEVICE_TABLE(pnp_card, snd_als100_pnpids); |
91 | 119 | ||
92 | #define DRIVER_NAME "snd-card-als100" | ||
93 | |||
94 | static int __devinit snd_card_als100_pnp(int dev, struct snd_card_als100 *acard, | 120 | static int __devinit snd_card_als100_pnp(int dev, struct snd_card_als100 *acard, |
95 | struct pnp_card_link *card, | 121 | struct pnp_card_link *card, |
96 | const struct pnp_card_device_id *id) | 122 | const struct pnp_card_device_id *id) |
@@ -113,8 +139,12 @@ static int __devinit snd_card_als100_pnp(int dev, struct snd_card_als100 *acard, | |||
113 | return err; | 139 | return err; |
114 | } | 140 | } |
115 | port[dev] = pnp_port_start(pdev, 0); | 141 | port[dev] = pnp_port_start(pdev, 0); |
116 | dma8[dev] = pnp_dma(pdev, 1); | 142 | if (id->driver_data == SB_HW_DT019X) |
117 | dma16[dev] = pnp_dma(pdev, 0); | 143 | dma8[dev] = pnp_dma(pdev, 0); |
144 | else { | ||
145 | dma8[dev] = pnp_dma(pdev, 1); | ||
146 | dma16[dev] = pnp_dma(pdev, 0); | ||
147 | } | ||
118 | irq[dev] = pnp_irq(pdev, 0); | 148 | irq[dev] = pnp_irq(pdev, 0); |
119 | 149 | ||
120 | pdev = acard->devmpu; | 150 | pdev = acard->devmpu; |
@@ -175,22 +205,33 @@ static int __devinit snd_card_als100_probe(int dev, | |||
175 | } | 205 | } |
176 | snd_card_set_dev(card, &pcard->card->dev); | 206 | snd_card_set_dev(card, &pcard->card->dev); |
177 | 207 | ||
178 | if ((error = snd_sbdsp_create(card, port[dev], | 208 | if (pid->driver_data == SB_HW_DT019X) |
179 | irq[dev], | 209 | dma16[dev] = -1; |
180 | snd_sb16dsp_interrupt, | 210 | |
181 | dma8[dev], | 211 | error = snd_sbdsp_create(card, port[dev], irq[dev], |
182 | dma16[dev], | 212 | snd_sb16dsp_interrupt, |
183 | SB_HW_ALS100, &chip)) < 0) { | 213 | dma8[dev], dma16[dev], |
214 | pid->driver_data, | ||
215 | &chip); | ||
216 | if (error < 0) { | ||
184 | snd_card_free(card); | 217 | snd_card_free(card); |
185 | return error; | 218 | return error; |
186 | } | 219 | } |
187 | acard->chip = chip; | 220 | acard->chip = chip; |
188 | 221 | ||
189 | strcpy(card->driver, "ALS100"); | 222 | if (pid->driver_data == SB_HW_DT019X) { |
190 | strcpy(card->shortname, "Avance Logic ALS100"); | 223 | strcpy(card->driver, "DT-019X"); |
191 | sprintf(card->longname, "%s, %s at 0x%lx, irq %d, dma %d&%d", | 224 | strcpy(card->shortname, "Diamond Tech. DT-019X"); |
192 | card->shortname, chip->name, chip->port, | 225 | sprintf(card->longname, "%s, %s at 0x%lx, irq %d, dma %d", |
193 | irq[dev], dma8[dev], dma16[dev]); | 226 | card->shortname, chip->name, chip->port, |
227 | irq[dev], dma8[dev]); | ||
228 | } else { | ||
229 | strcpy(card->driver, "ALS100"); | ||
230 | strcpy(card->shortname, "Avance Logic ALS100"); | ||
231 | sprintf(card->longname, "%s, %s at 0x%lx, irq %d, dma %d&%d", | ||
232 | card->shortname, chip->name, chip->port, | ||
233 | irq[dev], dma8[dev], dma16[dev]); | ||
234 | } | ||
194 | 235 | ||
195 | if ((error = snd_sb16dsp_pcm(chip, 0, NULL)) < 0) { | 236 | if ((error = snd_sb16dsp_pcm(chip, 0, NULL)) < 0) { |
196 | snd_card_free(card); | 237 | snd_card_free(card); |
@@ -203,9 +244,19 @@ static int __devinit snd_card_als100_probe(int dev, | |||
203 | } | 244 | } |
204 | 245 | ||
205 | if (mpu_port[dev] > 0 && mpu_port[dev] != SNDRV_AUTO_PORT) { | 246 | if (mpu_port[dev] > 0 && mpu_port[dev] != SNDRV_AUTO_PORT) { |
206 | if (snd_mpu401_uart_new(card, 0, MPU401_HW_ALS100, | 247 | int mpu_type = MPU401_HW_ALS100; |
248 | |||
249 | if (mpu_irq[dev] == SNDRV_AUTO_IRQ) | ||
250 | mpu_irq[dev] = -1; | ||
251 | |||
252 | if (pid->driver_data == SB_HW_DT019X) | ||
253 | mpu_type = MPU401_HW_MPU401; | ||
254 | |||
255 | if (snd_mpu401_uart_new(card, 0, | ||
256 | mpu_type, | ||
207 | mpu_port[dev], 0, | 257 | mpu_port[dev], 0, |
208 | mpu_irq[dev], IRQF_DISABLED, | 258 | mpu_irq[dev], |
259 | mpu_irq[dev] >= 0 ? IRQF_DISABLED : 0, | ||
209 | NULL) < 0) | 260 | NULL) < 0) |
210 | snd_printk(KERN_ERR PFX "no MPU-401 device at 0x%lx\n", mpu_port[dev]); | 261 | snd_printk(KERN_ERR PFX "no MPU-401 device at 0x%lx\n", mpu_port[dev]); |
211 | } | 262 | } |
@@ -291,7 +342,7 @@ static int snd_als100_pnp_resume(struct pnp_card_link *pcard) | |||
291 | 342 | ||
292 | static struct pnp_card_driver als100_pnpc_driver = { | 343 | static struct pnp_card_driver als100_pnpc_driver = { |
293 | .flags = PNP_DRIVER_RES_DISABLE, | 344 | .flags = PNP_DRIVER_RES_DISABLE, |
294 | .name = "als100", | 345 | .name = "als100", |
295 | .id_table = snd_als100_pnpids, | 346 | .id_table = snd_als100_pnpids, |
296 | .probe = snd_als100_pnp_detect, | 347 | .probe = snd_als100_pnp_detect, |
297 | .remove = __devexit_p(snd_als100_pnp_remove), | 348 | .remove = __devexit_p(snd_als100_pnp_remove), |
@@ -312,7 +363,7 @@ static int __init alsa_card_als100_init(void) | |||
312 | if (!als100_devices) { | 363 | if (!als100_devices) { |
313 | pnp_unregister_card_driver(&als100_pnpc_driver); | 364 | pnp_unregister_card_driver(&als100_pnpc_driver); |
314 | #ifdef MODULE | 365 | #ifdef MODULE |
315 | snd_printk(KERN_ERR "no ALS100 based soundcards found\n"); | 366 | snd_printk(KERN_ERR "no Avance Logic based soundcards found\n"); |
316 | #endif | 367 | #endif |
317 | return -ENODEV; | 368 | return -ENODEV; |
318 | } | 369 | } |
diff --git a/sound/isa/dt019x.c b/sound/isa/dt019x.c deleted file mode 100644 index 80f5b1af9be8..000000000000 --- a/sound/isa/dt019x.c +++ /dev/null | |||
@@ -1,321 +0,0 @@ | |||
1 | |||
2 | /* | ||
3 | dt019x.c - driver for Diamond Technologies DT-0197H based soundcards. | ||
4 | Copyright (C) 1999, 2002 by Massimo Piccioni <dafastidio@libero.it> | ||
5 | |||
6 | Generalised for soundcards based on DT-0196 and ALS-007 chips | ||
7 | by Jonathan Woithe <jwoithe@physics.adelaide.edu.au>: June 2002. | ||
8 | |||
9 | This program is free software; you can redistribute it and/or modify | ||
10 | it under the terms of the GNU General Public License as published by | ||
11 | the Free Software Foundation; either version 2 of the License, or | ||
12 | (at your option) any later version. | ||
13 | |||
14 | This program is distributed in the hope that it will be useful, | ||
15 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | GNU General Public License for more details. | ||
18 | |||
19 | You should have received a copy of the GNU General Public License | ||
20 | along with this program; if not, write to the Free Software | ||
21 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
22 | */ | ||
23 | |||
24 | #include <linux/init.h> | ||
25 | #include <linux/wait.h> | ||
26 | #include <linux/pnp.h> | ||
27 | #include <linux/moduleparam.h> | ||
28 | #include <sound/core.h> | ||
29 | #include <sound/initval.h> | ||
30 | #include <sound/mpu401.h> | ||
31 | #include <sound/opl3.h> | ||
32 | #include <sound/sb.h> | ||
33 | |||
34 | #define PFX "dt019x: " | ||
35 | |||
36 | MODULE_AUTHOR("Massimo Piccioni <dafastidio@libero.it>"); | ||
37 | MODULE_DESCRIPTION("Diamond Technologies DT-019X / Avance Logic ALS-007"); | ||
38 | MODULE_LICENSE("GPL"); | ||
39 | MODULE_SUPPORTED_DEVICE("{{Diamond Technologies DT-019X}," | ||
40 | "{Avance Logic ALS-007}}"); | ||
41 | |||
42 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ | ||
43 | static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ | ||
44 | static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */ | ||
45 | static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */ | ||
46 | static long mpu_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */ | ||
47 | static long fm_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */ | ||
48 | static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* PnP setup */ | ||
49 | static int mpu_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* PnP setup */ | ||
50 | static int dma8[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* PnP setup */ | ||
51 | |||
52 | module_param_array(index, int, NULL, 0444); | ||
53 | MODULE_PARM_DESC(index, "Index value for DT-019X based soundcard."); | ||
54 | module_param_array(id, charp, NULL, 0444); | ||
55 | MODULE_PARM_DESC(id, "ID string for DT-019X based soundcard."); | ||
56 | module_param_array(enable, bool, NULL, 0444); | ||
57 | MODULE_PARM_DESC(enable, "Enable DT-019X based soundcard."); | ||
58 | |||
59 | struct snd_card_dt019x { | ||
60 | struct pnp_dev *dev; | ||
61 | struct pnp_dev *devmpu; | ||
62 | struct pnp_dev *devopl; | ||
63 | struct snd_sb *chip; | ||
64 | }; | ||
65 | |||
66 | static struct pnp_card_device_id snd_dt019x_pnpids[] = { | ||
67 | /* DT197A30 */ | ||
68 | { .id = "RWB1688", .devs = { { "@@@0001" }, { "@X@0001" }, { "@H@0001" }, } }, | ||
69 | /* DT0196 / ALS-007 */ | ||
70 | { .id = "ALS0007", .devs = { { "@@@0001" }, { "@X@0001" }, { "@H@0001" }, } }, | ||
71 | { .id = "", } | ||
72 | }; | ||
73 | |||
74 | MODULE_DEVICE_TABLE(pnp_card, snd_dt019x_pnpids); | ||
75 | |||
76 | |||
77 | #define DRIVER_NAME "snd-card-dt019x" | ||
78 | |||
79 | |||
80 | static int __devinit snd_card_dt019x_pnp(int dev, struct snd_card_dt019x *acard, | ||
81 | struct pnp_card_link *card, | ||
82 | const struct pnp_card_device_id *pid) | ||
83 | { | ||
84 | struct pnp_dev *pdev; | ||
85 | int err; | ||
86 | |||
87 | acard->dev = pnp_request_card_device(card, pid->devs[0].id, NULL); | ||
88 | if (acard->dev == NULL) | ||
89 | return -ENODEV; | ||
90 | |||
91 | acard->devmpu = pnp_request_card_device(card, pid->devs[1].id, NULL); | ||
92 | acard->devopl = pnp_request_card_device(card, pid->devs[2].id, NULL); | ||
93 | |||
94 | pdev = acard->dev; | ||
95 | |||
96 | err = pnp_activate_dev(pdev); | ||
97 | if (err < 0) { | ||
98 | snd_printk(KERN_ERR PFX "DT-019X AUDIO pnp configure failure\n"); | ||
99 | return err; | ||
100 | } | ||
101 | |||
102 | port[dev] = pnp_port_start(pdev, 0); | ||
103 | dma8[dev] = pnp_dma(pdev, 0); | ||
104 | irq[dev] = pnp_irq(pdev, 0); | ||
105 | snd_printdd("dt019x: found audio interface: port=0x%lx, irq=0x%x, dma=0x%x\n", | ||
106 | port[dev],irq[dev],dma8[dev]); | ||
107 | |||
108 | pdev = acard->devmpu; | ||
109 | if (pdev != NULL) { | ||
110 | err = pnp_activate_dev(pdev); | ||
111 | if (err < 0) { | ||
112 | pnp_release_card_device(pdev); | ||
113 | snd_printk(KERN_ERR PFX "DT-019X MPU401 pnp configure failure, skipping\n"); | ||
114 | goto __mpu_error; | ||
115 | } | ||
116 | mpu_port[dev] = pnp_port_start(pdev, 0); | ||
117 | mpu_irq[dev] = pnp_irq(pdev, 0); | ||
118 | snd_printdd("dt019x: found MPU-401: port=0x%lx, irq=0x%x\n", | ||
119 | mpu_port[dev],mpu_irq[dev]); | ||
120 | } else { | ||
121 | __mpu_error: | ||
122 | acard->devmpu = NULL; | ||
123 | mpu_port[dev] = -1; | ||
124 | } | ||
125 | |||
126 | pdev = acard->devopl; | ||
127 | if (pdev != NULL) { | ||
128 | err = pnp_activate_dev(pdev); | ||
129 | if (err < 0) { | ||
130 | pnp_release_card_device(pdev); | ||
131 | snd_printk(KERN_ERR PFX "DT-019X OPL3 pnp configure failure, skipping\n"); | ||
132 | goto __fm_error; | ||
133 | } | ||
134 | fm_port[dev] = pnp_port_start(pdev, 0); | ||
135 | snd_printdd("dt019x: found OPL3 synth: port=0x%lx\n",fm_port[dev]); | ||
136 | } else { | ||
137 | __fm_error: | ||
138 | acard->devopl = NULL; | ||
139 | fm_port[dev] = -1; | ||
140 | } | ||
141 | |||
142 | return 0; | ||
143 | } | ||
144 | |||
145 | static int __devinit snd_card_dt019x_probe(int dev, struct pnp_card_link *pcard, const struct pnp_card_device_id *pid) | ||
146 | { | ||
147 | int error; | ||
148 | struct snd_sb *chip; | ||
149 | struct snd_card *card; | ||
150 | struct snd_card_dt019x *acard; | ||
151 | struct snd_opl3 *opl3; | ||
152 | |||
153 | error = snd_card_create(index[dev], id[dev], THIS_MODULE, | ||
154 | sizeof(struct snd_card_dt019x), &card); | ||
155 | if (error < 0) | ||
156 | return error; | ||
157 | acard = card->private_data; | ||
158 | |||
159 | snd_card_set_dev(card, &pcard->card->dev); | ||
160 | if ((error = snd_card_dt019x_pnp(dev, acard, pcard, pid))) { | ||
161 | snd_card_free(card); | ||
162 | return error; | ||
163 | } | ||
164 | |||
165 | if ((error = snd_sbdsp_create(card, port[dev], | ||
166 | irq[dev], | ||
167 | snd_sb16dsp_interrupt, | ||
168 | dma8[dev], | ||
169 | -1, | ||
170 | SB_HW_DT019X, | ||
171 | &chip)) < 0) { | ||
172 | snd_card_free(card); | ||
173 | return error; | ||
174 | } | ||
175 | acard->chip = chip; | ||
176 | |||
177 | strcpy(card->driver, "DT-019X"); | ||
178 | strcpy(card->shortname, "Diamond Tech. DT-019X"); | ||
179 | sprintf(card->longname, "%s, %s at 0x%lx, irq %d, dma %d", | ||
180 | card->shortname, chip->name, chip->port, | ||
181 | irq[dev], dma8[dev]); | ||
182 | |||
183 | if ((error = snd_sb16dsp_pcm(chip, 0, NULL)) < 0) { | ||
184 | snd_card_free(card); | ||
185 | return error; | ||
186 | } | ||
187 | if ((error = snd_sbmixer_new(chip)) < 0) { | ||
188 | snd_card_free(card); | ||
189 | return error; | ||
190 | } | ||
191 | |||
192 | if (mpu_port[dev] > 0 && mpu_port[dev] != SNDRV_AUTO_PORT) { | ||
193 | if (mpu_irq[dev] == SNDRV_AUTO_IRQ) | ||
194 | mpu_irq[dev] = -1; | ||
195 | if (snd_mpu401_uart_new(card, 0, | ||
196 | /* MPU401_HW_SB,*/ | ||
197 | MPU401_HW_MPU401, | ||
198 | mpu_port[dev], 0, | ||
199 | mpu_irq[dev], | ||
200 | mpu_irq[dev] >= 0 ? IRQF_DISABLED : 0, | ||
201 | NULL) < 0) | ||
202 | snd_printk(KERN_ERR PFX "no MPU-401 device at 0x%lx ?\n", mpu_port[dev]); | ||
203 | } | ||
204 | |||
205 | if (fm_port[dev] > 0 && fm_port[dev] != SNDRV_AUTO_PORT) { | ||
206 | if (snd_opl3_create(card, | ||
207 | fm_port[dev], | ||
208 | fm_port[dev] + 2, | ||
209 | OPL3_HW_AUTO, 0, &opl3) < 0) { | ||
210 | snd_printk(KERN_ERR PFX "no OPL device at 0x%lx-0x%lx ?\n", | ||
211 | fm_port[dev], fm_port[dev] + 2); | ||
212 | } else { | ||
213 | if ((error = snd_opl3_timer_new(opl3, 0, 1)) < 0) { | ||
214 | snd_card_free(card); | ||
215 | return error; | ||
216 | } | ||
217 | if ((error = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) { | ||
218 | snd_card_free(card); | ||
219 | return error; | ||
220 | } | ||
221 | } | ||
222 | } | ||
223 | |||
224 | if ((error = snd_card_register(card)) < 0) { | ||
225 | snd_card_free(card); | ||
226 | return error; | ||
227 | } | ||
228 | pnp_set_card_drvdata(pcard, card); | ||
229 | return 0; | ||
230 | } | ||
231 | |||
232 | static unsigned int __devinitdata dt019x_devices; | ||
233 | |||
234 | static int __devinit snd_dt019x_pnp_probe(struct pnp_card_link *card, | ||
235 | const struct pnp_card_device_id *pid) | ||
236 | { | ||
237 | static int dev; | ||
238 | int res; | ||
239 | |||
240 | for ( ; dev < SNDRV_CARDS; dev++) { | ||
241 | if (!enable[dev]) | ||
242 | continue; | ||
243 | res = snd_card_dt019x_probe(dev, card, pid); | ||
244 | if (res < 0) | ||
245 | return res; | ||
246 | dev++; | ||
247 | dt019x_devices++; | ||
248 | return 0; | ||
249 | } | ||
250 | return -ENODEV; | ||
251 | } | ||
252 | |||
253 | static void __devexit snd_dt019x_pnp_remove(struct pnp_card_link * pcard) | ||
254 | { | ||
255 | snd_card_free(pnp_get_card_drvdata(pcard)); | ||
256 | pnp_set_card_drvdata(pcard, NULL); | ||
257 | } | ||
258 | |||
259 | #ifdef CONFIG_PM | ||
260 | static int snd_dt019x_pnp_suspend(struct pnp_card_link *pcard, pm_message_t state) | ||
261 | { | ||
262 | struct snd_card *card = pnp_get_card_drvdata(pcard); | ||
263 | struct snd_card_dt019x *acard = card->private_data; | ||
264 | struct snd_sb *chip = acard->chip; | ||
265 | |||
266 | snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); | ||
267 | snd_pcm_suspend_all(chip->pcm); | ||
268 | snd_sbmixer_suspend(chip); | ||
269 | return 0; | ||
270 | } | ||
271 | |||
272 | static int snd_dt019x_pnp_resume(struct pnp_card_link *pcard) | ||
273 | { | ||
274 | struct snd_card *card = pnp_get_card_drvdata(pcard); | ||
275 | struct snd_card_dt019x *acard = card->private_data; | ||
276 | struct snd_sb *chip = acard->chip; | ||
277 | |||
278 | snd_sbdsp_reset(chip); | ||
279 | snd_sbmixer_resume(chip); | ||
280 | snd_power_change_state(card, SNDRV_CTL_POWER_D0); | ||
281 | return 0; | ||
282 | } | ||
283 | #endif | ||
284 | |||
285 | static struct pnp_card_driver dt019x_pnpc_driver = { | ||
286 | .flags = PNP_DRIVER_RES_DISABLE, | ||
287 | .name = "dt019x", | ||
288 | .id_table = snd_dt019x_pnpids, | ||
289 | .probe = snd_dt019x_pnp_probe, | ||
290 | .remove = __devexit_p(snd_dt019x_pnp_remove), | ||
291 | #ifdef CONFIG_PM | ||
292 | .suspend = snd_dt019x_pnp_suspend, | ||
293 | .resume = snd_dt019x_pnp_resume, | ||
294 | #endif | ||
295 | }; | ||
296 | |||
297 | static int __init alsa_card_dt019x_init(void) | ||
298 | { | ||
299 | int err; | ||
300 | |||
301 | err = pnp_register_card_driver(&dt019x_pnpc_driver); | ||
302 | if (err) | ||
303 | return err; | ||
304 | |||
305 | if (!dt019x_devices) { | ||
306 | pnp_unregister_card_driver(&dt019x_pnpc_driver); | ||
307 | #ifdef MODULE | ||
308 | snd_printk(KERN_ERR "no DT-019X / ALS-007 based soundcards found\n"); | ||
309 | #endif | ||
310 | return -ENODEV; | ||
311 | } | ||
312 | return 0; | ||
313 | } | ||
314 | |||
315 | static void __exit alsa_card_dt019x_exit(void) | ||
316 | { | ||
317 | pnp_unregister_card_driver(&dt019x_pnpc_driver); | ||
318 | } | ||
319 | |||
320 | module_init(alsa_card_dt019x_init) | ||
321 | module_exit(alsa_card_dt019x_exit) | ||