aboutsummaryrefslogtreecommitdiffstats
path: root/sound/isa/es1688/es1688.c
diff options
context:
space:
mode:
authorKrzysztof Helt <krzysztof.h1@wp.pl>2010-05-10 03:47:32 -0400
committerTakashi Iwai <tiwai@suse.de>2010-05-10 03:49:30 -0400
commita20971b201ac1fcd236400942c98b0106c42c70a (patch)
treef71d82b13c1b0d8a94187a68c0b694605664bbf3 /sound/isa/es1688/es1688.c
parent396fa8272601c3d488cb8391c3962a7ee552afd0 (diff)
ALSA: Merge es1688 and es968 drivers
The ESS ES968 chip is nothing more then a PnP companion for a non-PnP audio chip. It was paired with non-PnP ESS' chips: ES688 and ES1688. The ESS' audio chips are handled by the es1688 driver in native mode. The PnP cards are handled by the ES968 driver in SB compatible mode. Move the ES968 chip handling to the es1688 driver so the driver can handle both PnP and non-PnP cards. The es968 is removed. Also, a new PnP id is added for the card I acquired (the change was tested on this card). Signed-off-by: Krzysztof Helt <krzysztof.h1@wp.pl> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/isa/es1688/es1688.c')
-rw-r--r--sound/isa/es1688/es1688.c205
1 files changed, 177 insertions, 28 deletions
diff --git a/sound/isa/es1688/es1688.c b/sound/isa/es1688/es1688.c
index 281679493fb4..fdcce311f80a 100644
--- a/sound/isa/es1688/es1688.c
+++ b/sound/isa/es1688/es1688.c
@@ -22,6 +22,7 @@
22#include <linux/init.h> 22#include <linux/init.h>
23#include <linux/err.h> 23#include <linux/err.h>
24#include <linux/isa.h> 24#include <linux/isa.h>
25#include <linux/isapnp.h>
25#include <linux/time.h> 26#include <linux/time.h>
26#include <linux/wait.h> 27#include <linux/wait.h>
27#include <linux/moduleparam.h> 28#include <linux/moduleparam.h>
@@ -45,8 +46,13 @@ MODULE_SUPPORTED_DEVICE("{{ESS,ES688 PnP AudioDrive,pnp:ESS0100},"
45 "{ESS,ES688 AudioDrive,pnp:ESS6881}," 46 "{ESS,ES688 AudioDrive,pnp:ESS6881},"
46 "{ESS,ES1688 AudioDrive,pnp:ESS1681}}"); 47 "{ESS,ES1688 AudioDrive,pnp:ESS1681}}");
47 48
49MODULE_ALIAS("snd_es968");
50
48static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ 51static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
49static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ 52static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
53#ifdef CONFIG_PNP
54static int isapnp[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP;
55#endif
50static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */ 56static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */
51static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x220,0x240,0x260 */ 57static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x220,0x240,0x260 */
52static long fm_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* Usually 0x388 */ 58static long fm_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* Usually 0x388 */
@@ -60,6 +66,10 @@ MODULE_PARM_DESC(index, "Index value for " CRD_NAME " soundcard.");
60module_param_array(id, charp, NULL, 0444); 66module_param_array(id, charp, NULL, 0444);
61MODULE_PARM_DESC(id, "ID string for " CRD_NAME " soundcard."); 67MODULE_PARM_DESC(id, "ID string for " CRD_NAME " soundcard.");
62module_param_array(enable, bool, NULL, 0444); 68module_param_array(enable, bool, NULL, 0444);
69#ifdef CONFIG_PNP
70module_param_array(isapnp, bool, NULL, 0444);
71MODULE_PARM_DESC(isapnp, "PnP detection for specified soundcard.");
72#endif
63MODULE_PARM_DESC(enable, "Enable " CRD_NAME " soundcard."); 73MODULE_PARM_DESC(enable, "Enable " CRD_NAME " soundcard.");
64module_param_array(port, long, NULL, 0444); 74module_param_array(port, long, NULL, 0444);
65MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver."); 75MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver.");
@@ -74,14 +84,21 @@ MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for " CRD_NAME " driver.");
74module_param_array(dma8, int, NULL, 0444); 84module_param_array(dma8, int, NULL, 0444);
75MODULE_PARM_DESC(dma8, "8-bit DMA # for " CRD_NAME " driver."); 85MODULE_PARM_DESC(dma8, "8-bit DMA # for " CRD_NAME " driver.");
76 86
87#ifdef CONFIG_PNP
88#define is_isapnp_selected(dev) isapnp[dev]
89#else
90#define is_isapnp_selected(dev) 0
91#endif
92
77static int __devinit snd_es1688_match(struct device *dev, unsigned int n) 93static int __devinit snd_es1688_match(struct device *dev, unsigned int n)
78{ 94{
79 return enable[n]; 95 return enable[n] && !is_isapnp_selected(n);
80} 96}
81 97
82static int __devinit snd_es1688_legacy_create(struct snd_card *card, 98static int __devinit snd_es1688_legacy_create(struct snd_card *card,
83 struct snd_es1688 *chip, struct device *dev, unsigned int n) 99 struct device *dev, unsigned int n)
84{ 100{
101 struct snd_es1688 *chip = card->private_data;
85 static long possible_ports[] = {0x220, 0x240, 0x260}; 102 static long possible_ports[] = {0x220, 0x240, 0x260};
86 static int possible_irqs[] = {5, 9, 10, 7, -1}; 103 static int possible_irqs[] = {5, 9, 10, 7, -1};
87 static int possible_dmas[] = {1, 3, 0, -1}; 104 static int possible_dmas[] = {1, 3, 0, -1};
@@ -117,32 +134,20 @@ static int __devinit snd_es1688_legacy_create(struct snd_card *card,
117 return error; 134 return error;
118} 135}
119 136
120static int __devinit snd_es1688_probe(struct device *dev, unsigned int n) 137static int __devinit snd_es1688_probe(struct snd_card *card, unsigned int n)
121{ 138{
122 struct snd_card *card; 139 struct snd_es1688 *chip = card->private_data;
123 struct snd_es1688 *chip;
124 struct snd_opl3 *opl3; 140 struct snd_opl3 *opl3;
125 struct snd_pcm *pcm; 141 struct snd_pcm *pcm;
126 int error; 142 int error;
127 143
128 error = snd_card_create(index[n], id[n], THIS_MODULE,
129 sizeof(struct snd_es1688), &card);
130 if (error < 0)
131 return error;
132
133 chip = card->private_data;
134
135 error = snd_es1688_legacy_create(card, chip, dev, n);
136 if (error < 0)
137 goto out;
138
139 error = snd_es1688_pcm(card, chip, 0, &pcm); 144 error = snd_es1688_pcm(card, chip, 0, &pcm);
140 if (error < 0) 145 if (error < 0)
141 goto out; 146 return error;
142 147
143 error = snd_es1688_mixer(card, chip); 148 error = snd_es1688_mixer(card, chip);
144 if (error < 0) 149 if (error < 0)
145 goto out; 150 return error;
146 151
147 strcpy(card->driver, "ES1688"); 152 strcpy(card->driver, "ES1688");
148 strcpy(card->shortname, pcm->name); 153 strcpy(card->shortname, pcm->name);
@@ -155,12 +160,12 @@ static int __devinit snd_es1688_probe(struct device *dev, unsigned int n)
155 if (fm_port[n] > 0) { 160 if (fm_port[n] > 0) {
156 if (snd_opl3_create(card, fm_port[n], fm_port[n] + 2, 161 if (snd_opl3_create(card, fm_port[n], fm_port[n] + 2,
157 OPL3_HW_OPL3, 0, &opl3) < 0) 162 OPL3_HW_OPL3, 0, &opl3) < 0)
158 dev_warn(dev, 163 dev_warn(card->dev,
159 "opl3 not detected at 0x%lx\n", fm_port[n]); 164 "opl3 not detected at 0x%lx\n", fm_port[n]);
160 else { 165 else {
161 error = snd_opl3_hwdep_new(opl3, 0, 1, NULL); 166 error = snd_opl3_hwdep_new(opl3, 0, 1, NULL);
162 if (error < 0) 167 if (error < 0)
163 goto out; 168 return error;
164 } 169 }
165 } 170 }
166 171
@@ -170,23 +175,41 @@ static int __devinit snd_es1688_probe(struct device *dev, unsigned int n)
170 chip->mpu_port, 0, 175 chip->mpu_port, 0,
171 mpu_irq[n], IRQF_DISABLED, NULL); 176 mpu_irq[n], IRQF_DISABLED, NULL);
172 if (error < 0) 177 if (error < 0)
173 goto out; 178 return error;
174 } 179 }
175 180
181 return snd_card_register(card);
182}
183
184static int __devinit snd_es1688_isa_probe(struct device *dev, unsigned int n)
185{
186 struct snd_card *card;
187 int error;
188
189 error = snd_card_create(index[n], id[n], THIS_MODULE,
190 sizeof(struct snd_es1688), &card);
191 if (error < 0)
192 return error;
193
194 error = snd_es1688_legacy_create(card, dev, n);
195 if (error < 0)
196 goto out;
197
176 snd_card_set_dev(card, dev); 198 snd_card_set_dev(card, dev);
177 199
178 error = snd_card_register(card); 200 error = snd_es1688_probe(card, n);
179 if (error < 0) 201 if (error < 0)
180 goto out; 202 goto out;
181 203
182 dev_set_drvdata(dev, card); 204 dev_set_drvdata(dev, card);
183 return 0;
184 205
185out: snd_card_free(card); 206 return 0;
207out:
208 snd_card_free(card);
186 return error; 209 return error;
187} 210}
188 211
189static int __devexit snd_es1688_remove(struct device *dev, unsigned int n) 212static int __devexit snd_es1688_isa_remove(struct device *dev, unsigned int n)
190{ 213{
191 snd_card_free(dev_get_drvdata(dev)); 214 snd_card_free(dev_get_drvdata(dev));
192 dev_set_drvdata(dev, NULL); 215 dev_set_drvdata(dev, NULL);
@@ -195,8 +218,8 @@ static int __devexit snd_es1688_remove(struct device *dev, unsigned int n)
195 218
196static struct isa_driver snd_es1688_driver = { 219static struct isa_driver snd_es1688_driver = {
197 .match = snd_es1688_match, 220 .match = snd_es1688_match,
198 .probe = snd_es1688_probe, 221 .probe = snd_es1688_isa_probe,
199 .remove = __devexit_p(snd_es1688_remove), 222 .remove = __devexit_p(snd_es1688_isa_remove),
200#if 0 /* FIXME */ 223#if 0 /* FIXME */
201 .suspend = snd_es1688_suspend, 224 .suspend = snd_es1688_suspend,
202 .resume = snd_es1688_resume, 225 .resume = snd_es1688_resume,
@@ -206,14 +229,140 @@ static struct isa_driver snd_es1688_driver = {
206 } 229 }
207}; 230};
208 231
232static int snd_es968_pnp_is_probed;
233
234#ifdef CONFIG_PNP
235static int __devinit snd_card_es968_pnp(struct snd_card *card, unsigned int n,
236 struct pnp_card_link *pcard,
237 const struct pnp_card_device_id *pid)
238{
239 struct snd_es1688 *chip = card->private_data;
240 struct pnp_dev *pdev;
241 int error;
242
243 pdev = pnp_request_card_device(pcard, pid->devs[0].id, NULL);
244 if (pdev == NULL)
245 return -ENODEV;
246
247 error = pnp_activate_dev(pdev);
248 if (error < 0) {
249 snd_printk(KERN_ERR "ES968 pnp configure failure\n");
250 return error;
251 }
252 port[n] = pnp_port_start(pdev, 0);
253 dma8[n] = pnp_dma(pdev, 0);
254 irq[n] = pnp_irq(pdev, 0);
255
256 return snd_es1688_create(card, chip, port[n], mpu_port[n], irq[n],
257 mpu_irq[n], dma8[n], ES1688_HW_AUTO);
258}
259
260static int __devinit snd_es968_pnp_detect(struct pnp_card_link *pcard,
261 const struct pnp_card_device_id *pid)
262{
263 struct snd_card *card;
264 static unsigned int dev;
265 int error;
266 struct snd_es1688 *chip;
267
268 if (snd_es968_pnp_is_probed)
269 return -EBUSY;
270 for ( ; dev < SNDRV_CARDS; dev++) {
271 if (enable[dev] && isapnp[dev])
272 break;
273 }
274
275 error = snd_card_create(index[dev], id[dev], THIS_MODULE,
276 sizeof(struct snd_es1688), &card);
277 if (error < 0)
278 return error;
279 chip = card->private_data;
280
281 error = snd_card_es968_pnp(card, dev, pcard, pid);
282 if (error < 0) {
283 snd_card_free(card);
284 return error;
285 }
286 snd_card_set_dev(card, &pcard->card->dev);
287 error = snd_es1688_probe(card, dev);
288 if (error < 0)
289 return error;
290 pnp_set_card_drvdata(pcard, card);
291 snd_es968_pnp_is_probed = 1;
292 return 0;
293}
294
295static void __devexit snd_es968_pnp_remove(struct pnp_card_link * pcard)
296{
297 snd_card_free(pnp_get_card_drvdata(pcard));
298 pnp_set_card_drvdata(pcard, NULL);
299 snd_es968_pnp_is_probed = 0;
300}
301
302#ifdef CONFIG_PM
303static int snd_es968_pnp_suspend(struct pnp_card_link *pcard,
304 pm_message_t state)
305{
306 struct snd_card *card = pnp_get_card_drvdata(pcard);
307 struct snd_es1688 *chip = card->private_data;
308
309 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
310 snd_pcm_suspend_all(chip->pcm);
311 return 0;
312}
313
314static int snd_es968_pnp_resume(struct pnp_card_link *pcard)
315{
316 struct snd_card *card = pnp_get_card_drvdata(pcard);
317 struct snd_es1688 *chip = card->private_data;
318
319 snd_es1688_reset(chip);
320 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
321 return 0;
322}
323#endif
324
325static struct pnp_card_device_id snd_es968_pnpids[] = {
326 { .id = "ESS0968", .devs = { { "@@@0968" }, } },
327 { .id = "ESS0968", .devs = { { "ESS0968" }, } },
328 { .id = "", } /* end */
329};
330
331MODULE_DEVICE_TABLE(pnp_card, snd_es968_pnpids);
332
333static struct pnp_card_driver es968_pnpc_driver = {
334 .flags = PNP_DRIVER_RES_DISABLE,
335 .name = DEV_NAME " PnP",
336 .id_table = snd_es968_pnpids,
337 .probe = snd_es968_pnp_detect,
338 .remove = __devexit_p(snd_es968_pnp_remove),
339#ifdef CONFIG_PM
340 .suspend = snd_es968_pnp_suspend,
341 .resume = snd_es968_pnp_resume,
342#endif
343};
344#endif
345
209static int __init alsa_card_es1688_init(void) 346static int __init alsa_card_es1688_init(void)
210{ 347{
348#ifdef CONFIG_PNP
349 pnp_register_card_driver(&es968_pnpc_driver);
350 if (snd_es968_pnp_is_probed)
351 return 0;
352 pnp_unregister_card_driver(&es968_pnpc_driver);
353#endif
211 return isa_register_driver(&snd_es1688_driver, SNDRV_CARDS); 354 return isa_register_driver(&snd_es1688_driver, SNDRV_CARDS);
212} 355}
213 356
214static void __exit alsa_card_es1688_exit(void) 357static void __exit alsa_card_es1688_exit(void)
215{ 358{
216 isa_unregister_driver(&snd_es1688_driver); 359 if (!snd_es968_pnp_is_probed) {
360 isa_unregister_driver(&snd_es1688_driver);
361 return;
362 }
363#ifdef CONFIG_PNP
364 pnp_unregister_card_driver(&es968_pnpc_driver);
365#endif
217} 366}
218 367
219module_init(alsa_card_es1688_init); 368module_init(alsa_card_es1688_init);