diff options
Diffstat (limited to 'sound/pcmcia/vx/vxpocket.c')
-rw-r--r-- | sound/pcmcia/vx/vxpocket.c | 155 |
1 files changed, 55 insertions, 100 deletions
diff --git a/sound/pcmcia/vx/vxpocket.c b/sound/pcmcia/vx/vxpocket.c index 5bb079d17959..66900d20a42f 100644 --- a/sound/pcmcia/vx/vxpocket.c +++ b/sound/pcmcia/vx/vxpocket.c | |||
@@ -55,11 +55,6 @@ MODULE_PARM_DESC(ibl, "Capture IBL size for VXPocket soundcard."); | |||
55 | */ | 55 | */ |
56 | 56 | ||
57 | static unsigned int card_alloc; | 57 | static unsigned int card_alloc; |
58 | static dev_link_t *dev_list; /* Linked list of devices */ | ||
59 | static dev_info_t dev_info = "snd-vxpocket"; | ||
60 | |||
61 | |||
62 | static int vxpocket_event(event_t event, int priority, event_callback_args_t *args); | ||
63 | 58 | ||
64 | 59 | ||
65 | /* | 60 | /* |
@@ -73,11 +68,6 @@ static void vxpocket_release(dev_link_t *link) | |||
73 | pcmcia_release_irq(link->handle, &link->irq); | 68 | pcmcia_release_irq(link->handle, &link->irq); |
74 | link->state &= ~DEV_CONFIG; | 69 | link->state &= ~DEV_CONFIG; |
75 | } | 70 | } |
76 | if (link->handle) { | ||
77 | /* Break the link with Card Services */ | ||
78 | pcmcia_deregister_client(link->handle); | ||
79 | link->handle = NULL; | ||
80 | } | ||
81 | } | 71 | } |
82 | 72 | ||
83 | /* | 73 | /* |
@@ -144,11 +134,9 @@ static struct snd_vx_hardware vxp440_hw = { | |||
144 | */ | 134 | */ |
145 | static struct snd_vxpocket *snd_vxpocket_new(struct snd_card *card, int ibl) | 135 | static struct snd_vxpocket *snd_vxpocket_new(struct snd_card *card, int ibl) |
146 | { | 136 | { |
147 | client_reg_t client_reg; /* Register with cardmgr */ | ||
148 | dev_link_t *link; /* Info for cardmgr */ | 137 | dev_link_t *link; /* Info for cardmgr */ |
149 | struct vx_core *chip; | 138 | struct vx_core *chip; |
150 | struct snd_vxpocket *vxp; | 139 | struct snd_vxpocket *vxp; |
151 | int ret; | ||
152 | static struct snd_device_ops ops = { | 140 | static struct snd_device_ops ops = { |
153 | .dev_free = snd_vxpocket_dev_free, | 141 | .dev_free = snd_vxpocket_dev_free, |
154 | }; | 142 | }; |
@@ -184,26 +172,6 @@ static struct snd_vxpocket *snd_vxpocket_new(struct snd_card *card, int ibl) | |||
184 | link->conf.ConfigIndex = 1; | 172 | link->conf.ConfigIndex = 1; |
185 | link->conf.Present = PRESENT_OPTION; | 173 | link->conf.Present = PRESENT_OPTION; |
186 | 174 | ||
187 | /* Register with Card Services */ | ||
188 | memset(&client_reg, 0, sizeof(client_reg)); | ||
189 | client_reg.dev_info = &dev_info; | ||
190 | client_reg.EventMask = | ||
191 | CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL | ||
192 | #ifdef CONFIG_PM | ||
193 | | CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET | ||
194 | | CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME | ||
195 | #endif | ||
196 | ; | ||
197 | client_reg.event_handler = &vxpocket_event; | ||
198 | client_reg.Version = 0x0210; | ||
199 | client_reg.event_callback_args.client_data = link; | ||
200 | |||
201 | ret = pcmcia_register_client(&link->handle, &client_reg); | ||
202 | if (ret != CS_SUCCESS) { | ||
203 | cs_error(link->handle, RegisterClient, ret); | ||
204 | return NULL; | ||
205 | } | ||
206 | |||
207 | return vxp; | 175 | return vxp; |
208 | } | 176 | } |
209 | 177 | ||
@@ -317,67 +285,55 @@ failed: | |||
317 | kfree(parse); | 285 | kfree(parse); |
318 | } | 286 | } |
319 | 287 | ||
288 | #ifdef CONFIG_PM | ||
320 | 289 | ||
321 | /* | 290 | static int vxp_suspend(struct pcmcia_device *dev) |
322 | * event callback | ||
323 | */ | ||
324 | static int vxpocket_event(event_t event, int priority, event_callback_args_t *args) | ||
325 | { | 291 | { |
326 | dev_link_t *link = args->client_data; | 292 | dev_link_t *link = dev_to_instance(dev); |
327 | struct vx_core *chip = link->priv; | 293 | struct vx_core *chip = link->priv; |
328 | 294 | ||
329 | switch (event) { | 295 | snd_printdd(KERN_DEBUG "SUSPEND\n"); |
330 | case CS_EVENT_CARD_REMOVAL: | 296 | link->state |= DEV_SUSPEND; |
331 | snd_printdd(KERN_DEBUG "CARD_REMOVAL..\n"); | 297 | if (chip) { |
332 | link->state &= ~DEV_PRESENT; | 298 | snd_printdd(KERN_DEBUG "snd_vx_suspend calling\n"); |
333 | if (link->state & DEV_CONFIG) | 299 | snd_vx_suspend(chip, PMSG_SUSPEND); |
334 | chip->chip_status |= VX_STAT_IS_STALE; | 300 | } |
335 | break; | 301 | snd_printdd(KERN_DEBUG "RESET_PHYSICAL\n"); |
336 | case CS_EVENT_CARD_INSERTION: | 302 | if (link->state & DEV_CONFIG) |
337 | snd_printdd(KERN_DEBUG "CARD_INSERTION..\n"); | 303 | pcmcia_release_configuration(link->handle); |
338 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; | 304 | |
339 | vxpocket_config(link); | 305 | return 0; |
340 | break; | 306 | } |
341 | #ifdef CONFIG_PM | 307 | |
342 | case CS_EVENT_PM_SUSPEND: | 308 | static int vxp_resume(struct pcmcia_device *dev) |
343 | snd_printdd(KERN_DEBUG "SUSPEND\n"); | 309 | { |
344 | link->state |= DEV_SUSPEND; | 310 | dev_link_t *link = dev_to_instance(dev); |
311 | struct vx_core *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 | //struct snd_vxpocket *vxp = (struct snd_vxpocket *)chip; | ||
319 | snd_printdd(KERN_DEBUG "requestconfig...\n"); | ||
320 | pcmcia_request_configuration(link->handle, &link->conf); | ||
345 | if (chip) { | 321 | if (chip) { |
346 | snd_printdd(KERN_DEBUG "snd_vx_suspend calling\n"); | 322 | snd_printdd(KERN_DEBUG "calling snd_vx_resume\n"); |
347 | snd_vx_suspend(chip, PMSG_SUSPEND); | 323 | snd_vx_resume(chip); |
348 | } | 324 | } |
349 | /* Fall through... */ | ||
350 | case CS_EVENT_RESET_PHYSICAL: | ||
351 | snd_printdd(KERN_DEBUG "RESET_PHYSICAL\n"); | ||
352 | if (link->state & DEV_CONFIG) | ||
353 | pcmcia_release_configuration(link->handle); | ||
354 | break; | ||
355 | case CS_EVENT_PM_RESUME: | ||
356 | snd_printdd(KERN_DEBUG "RESUME\n"); | ||
357 | link->state &= ~DEV_SUSPEND; | ||
358 | /* Fall through... */ | ||
359 | case CS_EVENT_CARD_RESET: | ||
360 | snd_printdd(KERN_DEBUG "CARD_RESET\n"); | ||
361 | if (DEV_OK(link)) { | ||
362 | //struct snd_vxpocket *vxp = (struct snd_vxpocket *)chip; | ||
363 | snd_printdd(KERN_DEBUG "requestconfig...\n"); | ||
364 | pcmcia_request_configuration(link->handle, &link->conf); | ||
365 | if (chip) { | ||
366 | snd_printdd(KERN_DEBUG "calling snd_vx_resume\n"); | ||
367 | snd_vx_resume(chip); | ||
368 | } | ||
369 | } | ||
370 | snd_printdd(KERN_DEBUG "resume done!\n"); | ||
371 | break; | ||
372 | #endif | ||
373 | } | 325 | } |
326 | snd_printdd(KERN_DEBUG "resume done!\n"); | ||
327 | |||
374 | return 0; | 328 | return 0; |
375 | } | 329 | } |
376 | 330 | ||
331 | #endif | ||
332 | |||
377 | 333 | ||
378 | /* | 334 | /* |
379 | */ | 335 | */ |
380 | static dev_link_t *vxpocket_attach(void) | 336 | static int vxpocket_attach(struct pcmcia_device *p_dev) |
381 | { | 337 | { |
382 | struct snd_card *card; | 338 | struct snd_card *card; |
383 | struct snd_vxpocket *vxp; | 339 | struct snd_vxpocket *vxp; |
@@ -390,22 +346,22 @@ static dev_link_t *vxpocket_attach(void) | |||
390 | } | 346 | } |
391 | if (i >= SNDRV_CARDS) { | 347 | if (i >= SNDRV_CARDS) { |
392 | snd_printk(KERN_ERR "vxpocket: too many cards found\n"); | 348 | snd_printk(KERN_ERR "vxpocket: too many cards found\n"); |
393 | return NULL; | 349 | return -EINVAL; |
394 | } | 350 | } |
395 | if (! enable[i]) | 351 | if (! enable[i]) |
396 | return NULL; /* disabled explicitly */ | 352 | return -ENODEV; /* disabled explicitly */ |
397 | 353 | ||
398 | /* ok, create a card instance */ | 354 | /* ok, create a card instance */ |
399 | card = snd_card_new(index[i], id[i], THIS_MODULE, 0); | 355 | card = snd_card_new(index[i], id[i], THIS_MODULE, 0); |
400 | if (card == NULL) { | 356 | if (card == NULL) { |
401 | snd_printk(KERN_ERR "vxpocket: cannot create a card instance\n"); | 357 | snd_printk(KERN_ERR "vxpocket: cannot create a card instance\n"); |
402 | return NULL; | 358 | return -ENOMEM; |
403 | } | 359 | } |
404 | 360 | ||
405 | vxp = snd_vxpocket_new(card, ibl[i]); | 361 | vxp = snd_vxpocket_new(card, ibl[i]); |
406 | if (! vxp) { | 362 | if (! vxp) { |
407 | snd_card_free(card); | 363 | snd_card_free(card); |
408 | return NULL; | 364 | return -ENODEV; |
409 | } | 365 | } |
410 | card->private_data = vxp; | 366 | card->private_data = vxp; |
411 | 367 | ||
@@ -413,17 +369,21 @@ static dev_link_t *vxpocket_attach(void) | |||
413 | card_alloc |= 1 << i; | 369 | card_alloc |= 1 << i; |
414 | 370 | ||
415 | /* Chain drivers */ | 371 | /* Chain drivers */ |
416 | vxp->link.next = dev_list; | 372 | vxp->link.next = NULL; |
417 | dev_list = &vxp->link; | 373 | |
374 | vxp->link.handle = p_dev; | ||
375 | vxp->link.state |= DEV_PRESENT | DEV_CONFIG_PENDING; | ||
376 | p_dev->instance = &vxp->link; | ||
377 | vxpocket_config(&vxp->link); | ||
418 | 378 | ||
419 | return &vxp->link; | 379 | return 0; |
420 | } | 380 | } |
421 | 381 | ||
422 | static void vxpocket_detach(dev_link_t *link) | 382 | static void vxpocket_detach(struct pcmcia_device *p_dev) |
423 | { | 383 | { |
384 | dev_link_t *link = dev_to_instance(p_dev); | ||
424 | struct snd_vxpocket *vxp; | 385 | struct snd_vxpocket *vxp; |
425 | struct vx_core *chip; | 386 | struct vx_core *chip; |
426 | dev_link_t **linkp; | ||
427 | 387 | ||
428 | if (! link) | 388 | if (! link) |
429 | return; | 389 | return; |
@@ -432,13 +392,6 @@ static void vxpocket_detach(dev_link_t *link) | |||
432 | chip = (struct vx_core *)vxp; | 392 | chip = (struct vx_core *)vxp; |
433 | card_alloc &= ~(1 << vxp->index); | 393 | card_alloc &= ~(1 << vxp->index); |
434 | 394 | ||
435 | /* Remove the interface data from the linked list */ | ||
436 | for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) | ||
437 | if (*linkp == link) { | ||
438 | *linkp = link->next; | ||
439 | break; | ||
440 | } | ||
441 | |||
442 | chip->chip_status |= VX_STAT_IS_STALE; /* to be sure */ | 395 | chip->chip_status |= VX_STAT_IS_STALE; /* to be sure */ |
443 | snd_card_disconnect(chip->card); | 396 | snd_card_disconnect(chip->card); |
444 | vxpocket_release(link); | 397 | vxpocket_release(link); |
@@ -460,10 +413,13 @@ static struct pcmcia_driver vxp_cs_driver = { | |||
460 | .drv = { | 413 | .drv = { |
461 | .name = "snd-vxpocket", | 414 | .name = "snd-vxpocket", |
462 | }, | 415 | }, |
463 | .attach = vxpocket_attach, | 416 | .probe = vxpocket_attach, |
464 | .detach = vxpocket_detach, | 417 | .remove = vxpocket_detach, |
465 | .event = vxpocket_event, | ||
466 | .id_table = vxp_ids, | 418 | .id_table = vxp_ids, |
419 | #ifdef CONFIG_PM | ||
420 | .suspend = vxp_suspend, | ||
421 | .resume = vxp_resume, | ||
422 | #endif | ||
467 | }; | 423 | }; |
468 | 424 | ||
469 | static int __init init_vxpocket(void) | 425 | static int __init init_vxpocket(void) |
@@ -474,7 +430,6 @@ static int __init init_vxpocket(void) | |||
474 | static void __exit exit_vxpocket(void) | 430 | static void __exit exit_vxpocket(void) |
475 | { | 431 | { |
476 | pcmcia_unregister_driver(&vxp_cs_driver); | 432 | pcmcia_unregister_driver(&vxp_cs_driver); |
477 | BUG_ON(dev_list != NULL); | ||
478 | } | 433 | } |
479 | 434 | ||
480 | module_init(init_vxpocket); | 435 | module_init(init_vxpocket); |