aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pcmcia/pdaudiocf/pdaudiocf.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pcmcia/pdaudiocf/pdaudiocf.c')
-rw-r--r--sound/pcmcia/pdaudiocf/pdaudiocf.c154
1 files changed, 60 insertions, 94 deletions
diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf.c b/sound/pcmcia/pdaudiocf/pdaudiocf.c
index a7cd2d4df757..77caf43a3109 100644
--- a/sound/pcmcia/pdaudiocf/pdaudiocf.c
+++ b/sound/pcmcia/pdaudiocf/pdaudiocf.c
@@ -52,16 +52,13 @@ MODULE_PARM_DESC(enable, "Enable " CARD_NAME " soundcard.");
52/* 52/*
53 */ 53 */
54 54
55static dev_info_t dev_info = "snd-pdaudiocf";
56static struct snd_card *card_list[SNDRV_CARDS]; 55static struct snd_card *card_list[SNDRV_CARDS];
57static dev_link_t *dev_list;
58 56
59/* 57/*
60 * prototypes 58 * prototypes
61 */ 59 */
62static void pdacf_config(dev_link_t *link); 60static void pdacf_config(dev_link_t *link);
63static int pdacf_event(event_t event, int priority, event_callback_args_t *args); 61static void snd_pdacf_detach(struct pcmcia_device *p_dev);
64static void snd_pdacf_detach(dev_link_t *link);
65 62
66static void pdacf_release(dev_link_t *link) 63static void pdacf_release(dev_link_t *link)
67{ 64{
@@ -83,10 +80,6 @@ static int snd_pdacf_free(struct snd_pdacf *pdacf)
83 80
84 pdacf_release(link); 81 pdacf_release(link);
85 82
86 /* Break the link with Card Services */
87 if (link->handle)
88 pcmcia_deregister_client(link->handle);
89
90 card_list[pdacf->index] = NULL; 83 card_list[pdacf->index] = NULL;
91 pdacf->card = NULL; 84 pdacf->card = NULL;
92 85
@@ -103,11 +96,10 @@ static int snd_pdacf_dev_free(struct snd_device *device)
103/* 96/*
104 * snd_pdacf_attach - attach callback for cs 97 * snd_pdacf_attach - attach callback for cs
105 */ 98 */
106static dev_link_t *snd_pdacf_attach(void) 99static int snd_pdacf_attach(struct pcmcia_device *p_dev)
107{ 100{
108 client_reg_t client_reg; /* Register with cardmgr */ 101 int i;
109 dev_link_t *link; /* Info for cardmgr */ 102 dev_link_t *link; /* Info for cardmgr */
110 int i, ret;
111 struct snd_pdacf *pdacf; 103 struct snd_pdacf *pdacf;
112 struct snd_card *card; 104 struct snd_card *card;
113 static struct snd_device_ops ops = { 105 static struct snd_device_ops ops = {
@@ -122,26 +114,26 @@ static dev_link_t *snd_pdacf_attach(void)
122 } 114 }
123 if (i >= SNDRV_CARDS) { 115 if (i >= SNDRV_CARDS) {
124 snd_printk(KERN_ERR "pdacf: too many cards found\n"); 116 snd_printk(KERN_ERR "pdacf: too many cards found\n");
125 return NULL; 117 return -EINVAL;
126 } 118 }
127 if (! enable[i]) 119 if (! enable[i])
128 return NULL; /* disabled explicitly */ 120 return -ENODEV; /* disabled explicitly */
129 121
130 /* ok, create a card instance */ 122 /* ok, create a card instance */
131 card = snd_card_new(index[i], id[i], THIS_MODULE, 0); 123 card = snd_card_new(index[i], id[i], THIS_MODULE, 0);
132 if (card == NULL) { 124 if (card == NULL) {
133 snd_printk(KERN_ERR "pdacf: cannot create a card instance\n"); 125 snd_printk(KERN_ERR "pdacf: cannot create a card instance\n");
134 return NULL; 126 return -ENOMEM;
135 } 127 }
136 128
137 pdacf = snd_pdacf_create(card); 129 pdacf = snd_pdacf_create(card);
138 if (! pdacf) 130 if (! pdacf)
139 return NULL; 131 return -EIO;
140 132
141 if (snd_device_new(card, SNDRV_DEV_LOWLEVEL, pdacf, &ops) < 0) { 133 if (snd_device_new(card, SNDRV_DEV_LOWLEVEL, pdacf, &ops) < 0) {
142 kfree(pdacf); 134 kfree(pdacf);
143 snd_card_free(card); 135 snd_card_free(card);
144 return NULL; 136 return -ENODEV;
145 } 137 }
146 138
147 pdacf->index = i; 139 pdacf->index = i;
@@ -165,22 +157,12 @@ static dev_link_t *snd_pdacf_attach(void)
165 link->conf.Present = PRESENT_OPTION; 157 link->conf.Present = PRESENT_OPTION;
166 158
167 /* Chain drivers */ 159 /* Chain drivers */
168 link->next = dev_list; 160 link->next = NULL;
169 dev_list = link;
170
171 /* Register with Card Services */
172 client_reg.dev_info = &dev_info;
173 client_reg.Version = 0x0210;
174 client_reg.event_callback_args.client_data = link;
175
176 ret = pcmcia_register_client(&link->handle, &client_reg);
177 if (ret != CS_SUCCESS) {
178 cs_error(link->handle, RegisterClient, ret);
179 snd_pdacf_detach(link);
180 return NULL;
181 }
182 161
183 return link; 162 link->handle = p_dev;
163 pdacf_config(link);
164
165 return 0;
184} 166}
185 167
186 168
@@ -227,21 +209,13 @@ static int snd_pdacf_assign_resources(struct snd_pdacf *pdacf, int port, int irq
227/* 209/*
228 * snd_pdacf_detach - detach callback for cs 210 * snd_pdacf_detach - detach callback for cs
229 */ 211 */
230static void snd_pdacf_detach(dev_link_t *link) 212static void snd_pdacf_detach(struct pcmcia_device *p_dev)
231{ 213{
214 dev_link_t *link = dev_to_instance(p_dev);
232 struct snd_pdacf *chip = link->priv; 215 struct snd_pdacf *chip = link->priv;
233 216
234 snd_printdd(KERN_DEBUG "pdacf_detach called\n"); 217 snd_printdd(KERN_DEBUG "pdacf_detach called\n");
235 /* Remove the interface data from the linked list */ 218
236 {
237 dev_link_t **linkp;
238 /* Locate device structure */
239 for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
240 if (*linkp == link)
241 break;
242 if (*linkp)
243 *linkp = link->next;
244 }
245 if (chip->chip_status & PDAUDIOCF_STAT_IS_CONFIGURED) 219 if (chip->chip_status & PDAUDIOCF_STAT_IS_CONFIGURED)
246 snd_pdacf_powerdown(chip); 220 snd_pdacf_powerdown(chip);
247 chip->chip_status |= PDAUDIOCF_STAT_IS_STALE; /* to be sure */ 221 chip->chip_status |= PDAUDIOCF_STAT_IS_STALE; /* to be sure */
@@ -310,62 +284,51 @@ failed:
310 pcmcia_release_irq(link->handle, &link->irq); 284 pcmcia_release_irq(link->handle, &link->irq);
311} 285}
312 286
313/* 287#ifdef CONFIG_PM
314 * event callback 288
315 */ 289static int pdacf_suspend(struct pcmcia_device *dev)
316static int pdacf_event(event_t event, int priority, event_callback_args_t *args)
317{ 290{
318 dev_link_t *link = args->client_data; 291 dev_link_t *link = dev_to_instance(dev);
319 struct snd_pdacf *chip = link->priv; 292 struct snd_pdacf *chip = link->priv;
320 293
321 switch (event) { 294 snd_printdd(KERN_DEBUG "SUSPEND\n");
322 case CS_EVENT_CARD_REMOVAL: 295 link->state |= DEV_SUSPEND;
323 snd_printdd(KERN_DEBUG "CARD_REMOVAL..\n"); 296 if (chip) {
324 link->state &= ~DEV_PRESENT; 297 snd_printdd(KERN_DEBUG "snd_pdacf_suspend calling\n");
325 if (link->state & DEV_CONFIG) { 298 snd_pdacf_suspend(chip, PMSG_SUSPEND);
326 chip->chip_status |= PDAUDIOCF_STAT_IS_STALE; 299 }
327 } 300
328 break; 301 snd_printdd(KERN_DEBUG "RESET_PHYSICAL\n");
329 case CS_EVENT_CARD_INSERTION: 302 if (link->state & DEV_CONFIG)
330 snd_printdd(KERN_DEBUG "CARD_INSERTION..\n"); 303 pcmcia_release_configuration(link->handle);
331 link->state |= DEV_PRESENT; 304
332 pdacf_config(link); 305 return 0;
333 break; 306}
334#ifdef CONFIG_PM 307
335 case CS_EVENT_PM_SUSPEND: 308static int pdacf_resume(struct pcmcia_device *dev)
336 snd_printdd(KERN_DEBUG "SUSPEND\n"); 309{
337 link->state |= DEV_SUSPEND; 310 dev_link_t *link = dev_to_instance(dev);
311 struct snd_pdacf *chip = link->priv;
312
313 snd_printdd(KERN_DEBUG "RESUME\n");
314 link->state &= ~DEV_SUSPEND;
315
316 snd_printdd(KERN_DEBUG "CARD_RESET\n");
317 if (DEV_OK(link)) {
318 snd_printdd(KERN_DEBUG "requestconfig...\n");
319 pcmcia_request_configuration(link->handle, &link->conf);
338 if (chip) { 320 if (chip) {
339 snd_printdd(KERN_DEBUG "snd_pdacf_suspend calling\n"); 321 snd_printdd(KERN_DEBUG "calling snd_pdacf_resume\n");
340 snd_pdacf_suspend(chip, PMSG_SUSPEND); 322 snd_pdacf_resume(chip);
341 }
342 /* Fall through... */
343 case CS_EVENT_RESET_PHYSICAL:
344 snd_printdd(KERN_DEBUG "RESET_PHYSICAL\n");
345 if (link->state & DEV_CONFIG)
346 pcmcia_release_configuration(link->handle);
347 break;
348 case CS_EVENT_PM_RESUME:
349 snd_printdd(KERN_DEBUG "RESUME\n");
350 link->state &= ~DEV_SUSPEND;
351 /* Fall through... */
352 case CS_EVENT_CARD_RESET:
353 snd_printdd(KERN_DEBUG "CARD_RESET\n");
354 if (DEV_OK(link)) {
355 snd_printdd(KERN_DEBUG "requestconfig...\n");
356 pcmcia_request_configuration(link->handle, &link->conf);
357 if (chip) {
358 snd_printdd(KERN_DEBUG "calling snd_pdacf_resume\n");
359 snd_pdacf_resume(chip);
360 }
361 } 323 }
362 snd_printdd(KERN_DEBUG "resume done!\n");
363 break;
364#endif
365 } 324 }
325 snd_printdd(KERN_DEBUG "resume done!\n");
326
366 return 0; 327 return 0;
367} 328}
368 329
330#endif
331
369/* 332/*
370 * Module entry points 333 * Module entry points
371 */ 334 */
@@ -380,10 +343,14 @@ static struct pcmcia_driver pdacf_cs_driver = {
380 .drv = { 343 .drv = {
381 .name = "snd-pdaudiocf", 344 .name = "snd-pdaudiocf",
382 }, 345 },
383 .attach = snd_pdacf_attach, 346 .probe = snd_pdacf_attach,
384 .event = pdacf_event, 347 .remove = snd_pdacf_detach,
385 .detach = snd_pdacf_detach,
386 .id_table = snd_pdacf_ids, 348 .id_table = snd_pdacf_ids,
349#ifdef CONFIG_PM
350 .suspend = pdacf_suspend,
351 .resume = pdacf_resume,
352#endif
353
387}; 354};
388 355
389static int __init init_pdacf(void) 356static int __init init_pdacf(void)
@@ -394,7 +361,6 @@ static int __init init_pdacf(void)
394static void __exit exit_pdacf(void) 361static void __exit exit_pdacf(void)
395{ 362{
396 pcmcia_unregister_driver(&pdacf_cs_driver); 363 pcmcia_unregister_driver(&pdacf_cs_driver);
397 BUG_ON(dev_list != NULL);
398} 364}
399 365
400module_init(init_pdacf); 366module_init(init_pdacf);