3 card-es968.c - driver for ESS AudioDrive ES968 based soundcards.
4 Copyright (C) 1999 by Massimo Piccioni <dafastidio@libero.it>
6 Thanks to Pierfrancesco 'qM2' Passerini.
8 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
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #include <linux/init.h>
24 #include <linux/time.h>
25 #include <linux/pnp.h>
26 #include <linux/moduleparam.h>
27 #include <sound/core.h>
28 #include <sound/initval.h>
33 MODULE_AUTHOR("Massimo Piccioni <dafastidio@libero.it>");
34 MODULE_DESCRIPTION("ESS AudioDrive ES968");
35 MODULE_LICENSE("GPL");
36 MODULE_SUPPORTED_DEVICE("{{ESS,AudioDrive ES968}}");
38 static int index
[SNDRV_CARDS
] = SNDRV_DEFAULT_IDX
; /* Index 0-MAX */
39 static char *id
[SNDRV_CARDS
] = SNDRV_DEFAULT_STR
; /* ID for this card */
40 static int enable
[SNDRV_CARDS
] = SNDRV_DEFAULT_ENABLE_ISAPNP
; /* Enable this card */
41 static long port
[SNDRV_CARDS
] = SNDRV_DEFAULT_PORT
; /* PnP setup */
42 static int irq
[SNDRV_CARDS
] = SNDRV_DEFAULT_IRQ
; /* Pnp setup */
43 static int dma8
[SNDRV_CARDS
] = SNDRV_DEFAULT_DMA
; /* PnP setup */
45 module_param_array(index
, int, NULL
, 0444);
46 MODULE_PARM_DESC(index
, "Index value for es968 based soundcard.");
47 module_param_array(id
, charp
, NULL
, 0444);
48 MODULE_PARM_DESC(id
, "ID string for es968 based soundcard.");
49 module_param_array(enable
, bool, NULL
, 0444);
50 MODULE_PARM_DESC(enable
, "Enable es968 based soundcard.");
52 struct snd_card_es968
{
57 static struct pnp_card_device_id snd_es968_pnpids
[] = {
58 { .id
= "ESS0968", .devs
= { { "@@@0968" }, } },
59 { .id
= "", } /* end */
62 MODULE_DEVICE_TABLE(pnp_card
, snd_es968_pnpids
);
64 #define DRIVER_NAME "snd-card-es968"
66 static irqreturn_t
snd_card_es968_interrupt(int irq
, void *dev_id
)
68 struct snd_sb
*chip
= dev_id
;
70 if (chip
->open
& SB_OPEN_PCM
) {
71 return snd_sb8dsp_interrupt(chip
);
73 return snd_sb8dsp_midi_interrupt(chip
);
77 static int __devinit
snd_card_es968_pnp(int dev
, struct snd_card_es968
*acard
,
78 struct pnp_card_link
*card
,
79 const struct pnp_card_device_id
*id
)
84 acard
->dev
= pnp_request_card_device(card
, id
->devs
[0].id
, NULL
);
85 if (acard
->dev
== NULL
)
90 err
= pnp_activate_dev(pdev
);
92 snd_printk(KERN_ERR PFX
"AUDIO pnp configure failure\n");
95 port
[dev
] = pnp_port_start(pdev
, 0);
96 dma8
[dev
] = pnp_dma(pdev
, 1);
97 irq
[dev
] = pnp_irq(pdev
, 0);
102 static int __devinit
snd_card_es968_probe(int dev
,
103 struct pnp_card_link
*pcard
,
104 const struct pnp_card_device_id
*pid
)
108 struct snd_card
*card
;
109 struct snd_card_es968
*acard
;
111 if ((card
= snd_card_new(index
[dev
], id
[dev
], THIS_MODULE
,
112 sizeof(struct snd_card_es968
))) == NULL
)
114 acard
= card
->private_data
;
115 if ((error
= snd_card_es968_pnp(dev
, acard
, pcard
, pid
))) {
119 snd_card_set_dev(card
, &pcard
->card
->dev
);
121 if ((error
= snd_sbdsp_create(card
, port
[dev
],
123 snd_card_es968_interrupt
,
126 SB_HW_AUTO
, &chip
)) < 0) {
132 if ((error
= snd_sb8dsp_pcm(chip
, 0, NULL
)) < 0) {
137 if ((error
= snd_sbmixer_new(chip
)) < 0) {
142 if ((error
= snd_sb8dsp_midi(chip
, 0, NULL
)) < 0) {
147 strcpy(card
->driver
, "ES968");
148 strcpy(card
->shortname
, "ESS ES968");
149 sprintf(card
->longname
, "%s soundcard, %s at 0x%lx, irq %d, dma %d",
150 card
->shortname
, chip
->name
, chip
->port
, irq
[dev
], dma8
[dev
]);
152 if ((error
= snd_card_register(card
)) < 0) {
156 pnp_set_card_drvdata(pcard
, card
);
160 static unsigned int __devinitdata es968_devices
;
162 static int __devinit
snd_es968_pnp_detect(struct pnp_card_link
*card
,
163 const struct pnp_card_device_id
*id
)
168 for ( ; dev
< SNDRV_CARDS
; dev
++) {
171 res
= snd_card_es968_probe(dev
, card
, id
);
181 static void __devexit
snd_es968_pnp_remove(struct pnp_card_link
* pcard
)
183 snd_card_free(pnp_get_card_drvdata(pcard
));
184 pnp_set_card_drvdata(pcard
, NULL
);
188 static int snd_es968_pnp_suspend(struct pnp_card_link
*pcard
, pm_message_t state
)
190 struct snd_card
*card
= pnp_get_card_drvdata(pcard
);
191 struct snd_card_es968
*acard
= card
->private_data
;
192 struct snd_sb
*chip
= acard
->chip
;
194 snd_power_change_state(card
, SNDRV_CTL_POWER_D3hot
);
195 snd_pcm_suspend_all(chip
->pcm
);
196 snd_sbmixer_suspend(chip
);
200 static int snd_es968_pnp_resume(struct pnp_card_link
*pcard
)
202 struct snd_card
*card
= pnp_get_card_drvdata(pcard
);
203 struct snd_card_es968
*acard
= card
->private_data
;
204 struct snd_sb
*chip
= acard
->chip
;
206 snd_sbdsp_reset(chip
);
207 snd_sbmixer_resume(chip
);
208 snd_power_change_state(card
, SNDRV_CTL_POWER_D0
);
213 static struct pnp_card_driver es968_pnpc_driver
= {
214 .flags
= PNP_DRIVER_RES_DISABLE
,
216 .id_table
= snd_es968_pnpids
,
217 .probe
= snd_es968_pnp_detect
,
218 .remove
= __devexit_p(snd_es968_pnp_remove
),
220 .suspend
= snd_es968_pnp_suspend
,
221 .resume
= snd_es968_pnp_resume
,
225 static int __init
alsa_card_es968_init(void)
227 int err
= pnp_register_card_driver(&es968_pnpc_driver
);
231 if (!es968_devices
) {
232 pnp_unregister_card_driver(&es968_pnpc_driver
);
234 snd_printk(KERN_ERR
"no ES968 based soundcards found\n");
241 static void __exit
alsa_card_es968_exit(void)
243 pnp_unregister_card_driver(&es968_pnpc_driver
);
246 module_init(alsa_card_es968_init
)
247 module_exit(alsa_card_es968_exit
)