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 error
= snd_card_create(index
[dev
], id
[dev
], THIS_MODULE
,
112 sizeof(struct snd_card_es968
), &card
);
115 acard
= card
->private_data
;
116 if ((error
= snd_card_es968_pnp(dev
, acard
, pcard
, pid
))) {
120 snd_card_set_dev(card
, &pcard
->card
->dev
);
122 if ((error
= snd_sbdsp_create(card
, port
[dev
],
124 snd_card_es968_interrupt
,
127 SB_HW_AUTO
, &chip
)) < 0) {
133 if ((error
= snd_sb8dsp_pcm(chip
, 0, NULL
)) < 0) {
138 if ((error
= snd_sbmixer_new(chip
)) < 0) {
143 if ((error
= snd_sb8dsp_midi(chip
, 0, NULL
)) < 0) {
148 strcpy(card
->driver
, "ES968");
149 strcpy(card
->shortname
, "ESS ES968");
150 sprintf(card
->longname
, "%s soundcard, %s at 0x%lx, irq %d, dma %d",
151 card
->shortname
, chip
->name
, chip
->port
, irq
[dev
], dma8
[dev
]);
153 if ((error
= snd_card_register(card
)) < 0) {
157 pnp_set_card_drvdata(pcard
, card
);
161 static unsigned int __devinitdata es968_devices
;
163 static int __devinit
snd_es968_pnp_detect(struct pnp_card_link
*card
,
164 const struct pnp_card_device_id
*id
)
169 for ( ; dev
< SNDRV_CARDS
; dev
++) {
172 res
= snd_card_es968_probe(dev
, card
, id
);
182 static void __devexit
snd_es968_pnp_remove(struct pnp_card_link
* pcard
)
184 snd_card_free(pnp_get_card_drvdata(pcard
));
185 pnp_set_card_drvdata(pcard
, NULL
);
189 static int snd_es968_pnp_suspend(struct pnp_card_link
*pcard
, pm_message_t state
)
191 struct snd_card
*card
= pnp_get_card_drvdata(pcard
);
192 struct snd_card_es968
*acard
= card
->private_data
;
193 struct snd_sb
*chip
= acard
->chip
;
195 snd_power_change_state(card
, SNDRV_CTL_POWER_D3hot
);
196 snd_pcm_suspend_all(chip
->pcm
);
197 snd_sbmixer_suspend(chip
);
201 static int snd_es968_pnp_resume(struct pnp_card_link
*pcard
)
203 struct snd_card
*card
= pnp_get_card_drvdata(pcard
);
204 struct snd_card_es968
*acard
= card
->private_data
;
205 struct snd_sb
*chip
= acard
->chip
;
207 snd_sbdsp_reset(chip
);
208 snd_sbmixer_resume(chip
);
209 snd_power_change_state(card
, SNDRV_CTL_POWER_D0
);
214 static struct pnp_card_driver es968_pnpc_driver
= {
215 .flags
= PNP_DRIVER_RES_DISABLE
,
217 .id_table
= snd_es968_pnpids
,
218 .probe
= snd_es968_pnp_detect
,
219 .remove
= __devexit_p(snd_es968_pnp_remove
),
221 .suspend
= snd_es968_pnp_suspend
,
222 .resume
= snd_es968_pnp_resume
,
226 static int __init
alsa_card_es968_init(void)
228 int err
= pnp_register_card_driver(&es968_pnpc_driver
);
232 if (!es968_devices
) {
233 pnp_unregister_card_driver(&es968_pnpc_driver
);
235 snd_printk(KERN_ERR
"no ES968 based soundcards found\n");
242 static void __exit
alsa_card_es968_exit(void)
244 pnp_unregister_card_driver(&es968_pnpc_driver
);
247 module_init(alsa_card_es968_init
)
248 module_exit(alsa_card_es968_exit
)