aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/emu10k1/emufx.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2005-11-17 10:14:10 -0500
committerJaroslav Kysela <perex@suse.cz>2006-01-03 06:27:58 -0500
commit09668b441dacdf4640509b640ad73e24efd5204f (patch)
tree177d0548acbcca4432f82ce6f3aa397cba5ba528 /sound/pci/emu10k1/emufx.c
parentfe8be10786c040bce53c18048d75b1b23aec64ae (diff)
[ALSA] emu10k1 - Add PM support
Modules: EMU10K1/EMU10K2 driver Add PM support to emu10k1 driver. Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/emu10k1/emufx.c')
-rw-r--r--sound/pci/emu10k1/emufx.c121
1 files changed, 114 insertions, 7 deletions
diff --git a/sound/pci/emu10k1/emufx.c b/sound/pci/emu10k1/emufx.c
index f4452c5cb4cd..a44e4fdfc025 100644
--- a/sound/pci/emu10k1/emufx.c
+++ b/sound/pci/emu10k1/emufx.c
@@ -1071,9 +1071,6 @@ static int __devinit _snd_emu10k1_audigy_init_efx(struct snd_emu10k1 *emu)
1071 u32 *gpr_map; 1071 u32 *gpr_map;
1072 mm_segment_t seg; 1072 mm_segment_t seg;
1073 1073
1074 spin_lock_init(&emu->fx8010.irq_lock);
1075 INIT_LIST_HEAD(&emu->fx8010.gpr_ctl);
1076
1077 if ((icode = kzalloc(sizeof(*icode), GFP_KERNEL)) == NULL || 1074 if ((icode = kzalloc(sizeof(*icode), GFP_KERNEL)) == NULL ||
1078 (icode->gpr_map = (u_int32_t __user *) 1075 (icode->gpr_map = (u_int32_t __user *)
1079 kcalloc(512 + 256 + 256 + 2 * 1024, sizeof(u_int32_t), 1076 kcalloc(512 + 256 + 256 + 2 * 1024, sizeof(u_int32_t),
@@ -1541,9 +1538,6 @@ static int __devinit _snd_emu10k1_init_efx(struct snd_emu10k1 *emu)
1541 u32 *gpr_map; 1538 u32 *gpr_map;
1542 mm_segment_t seg; 1539 mm_segment_t seg;
1543 1540
1544 spin_lock_init(&emu->fx8010.irq_lock);
1545 INIT_LIST_HEAD(&emu->fx8010.gpr_ctl);
1546
1547 if ((icode = kzalloc(sizeof(*icode), GFP_KERNEL)) == NULL) 1541 if ((icode = kzalloc(sizeof(*icode), GFP_KERNEL)) == NULL)
1548 return -ENOMEM; 1542 return -ENOMEM;
1549 if ((icode->gpr_map = (u_int32_t __user *) 1543 if ((icode->gpr_map = (u_int32_t __user *)
@@ -2102,6 +2096,8 @@ static int __devinit _snd_emu10k1_init_efx(struct snd_emu10k1 *emu)
2102 2096
2103int __devinit snd_emu10k1_init_efx(struct snd_emu10k1 *emu) 2097int __devinit snd_emu10k1_init_efx(struct snd_emu10k1 *emu)
2104{ 2098{
2099 spin_lock_init(&emu->fx8010.irq_lock);
2100 INIT_LIST_HEAD(&emu->fx8010.gpr_ctl);
2105 if (emu->audigy) 2101 if (emu->audigy)
2106 return _snd_emu10k1_audigy_init_efx(emu); 2102 return _snd_emu10k1_audigy_init_efx(emu);
2107 else 2103 else
@@ -2171,7 +2167,7 @@ int snd_emu10k1_fx8010_tram_setup(struct snd_emu10k1 *emu, u32 size)
2171 snd_emu10k1_ptr_write(emu, TCBS, 0, size_reg); 2167 snd_emu10k1_ptr_write(emu, TCBS, 0, size_reg);
2172 spin_lock_irq(&emu->emu_lock); 2168 spin_lock_irq(&emu->emu_lock);
2173 outl(inl(emu->port + HCFG) & ~HCFG_LOCKTANKCACHE_MASK, emu->port + HCFG); 2169 outl(inl(emu->port + HCFG) & ~HCFG_LOCKTANKCACHE_MASK, emu->port + HCFG);
2174 spin_unlock_irq(&emu->emu_lock); 2170 spin_unlock_irq(&emu->emu_lock);
2175 } 2171 }
2176 2172
2177 return 0; 2173 return 0;
@@ -2387,3 +2383,114 @@ int __devinit snd_emu10k1_fx8010_new(struct snd_emu10k1 *emu, int device, struct
2387 *rhwdep = hw; 2383 *rhwdep = hw;
2388 return 0; 2384 return 0;
2389} 2385}
2386
2387#ifdef CONFIG_PM
2388int __devinit snd_emu10k1_efx_alloc_pm_buffer(struct snd_emu10k1 *emu)
2389{
2390 int len;
2391
2392 len = emu->audigy ? 0x200 : 0x100;
2393 emu->saved_gpr = kmalloc(len * 4, GFP_KERNEL);
2394 if (! emu->saved_gpr)
2395 return -ENOMEM;
2396 len = emu->audigy ? 0x100 : 0xa0;
2397 emu->tram_val_saved = kmalloc(len * 4, GFP_KERNEL);
2398 emu->tram_addr_saved = kmalloc(len * 4, GFP_KERNEL);
2399 if (! emu->tram_val_saved || ! emu->tram_addr_saved)
2400 return -ENOMEM;
2401 len = emu->audigy ? 2 * 1024 : 2 * 512;
2402 emu->saved_icode = vmalloc(len * 4);
2403 if (! emu->saved_icode)
2404 return -ENOMEM;
2405 return 0;
2406}
2407
2408void snd_emu10k1_efx_free_pm_buffer(struct snd_emu10k1 *emu)
2409{
2410 kfree(emu->saved_gpr);
2411 kfree(emu->tram_val_saved);
2412 kfree(emu->tram_addr_saved);
2413 vfree(emu->saved_icode);
2414}
2415
2416/*
2417 * save/restore GPR, TRAM and codes
2418 */
2419void snd_emu10k1_efx_suspend(struct snd_emu10k1 *emu)
2420{
2421 int i, len;
2422
2423 len = emu->audigy ? 0x200 : 0x100;
2424 for (i = 0; i < len; i++)
2425 emu->saved_gpr[i] = snd_emu10k1_ptr_read(emu, emu->gpr_base + i, 0);
2426
2427 len = emu->audigy ? 0x100 : 0xa0;
2428 for (i = 0; i < len; i++) {
2429 emu->tram_val_saved[i] = snd_emu10k1_ptr_read(emu, TANKMEMDATAREGBASE + i, 0);
2430 emu->tram_addr_saved[i] = snd_emu10k1_ptr_read(emu, TANKMEMADDRREGBASE + i, 0);
2431 if (emu->audigy) {
2432 emu->tram_addr_saved[i] >>= 12;
2433 emu->tram_addr_saved[i] |=
2434 snd_emu10k1_ptr_read(emu, A_TANKMEMCTLREGBASE + i, 0) << 20;
2435 }
2436 }
2437
2438 len = emu->audigy ? 2 * 1024 : 2 * 512;
2439 for (i = 0; i < len; i++)
2440 emu->saved_icode[i] = snd_emu10k1_efx_read(emu, i);
2441}
2442
2443void snd_emu10k1_efx_resume(struct snd_emu10k1 *emu)
2444{
2445 int i, len;
2446
2447 /* set up TRAM */
2448 if (emu->fx8010.etram_pages.bytes > 0) {
2449 unsigned size, size_reg = 0;
2450 size = emu->fx8010.etram_pages.bytes / 2;
2451 size = (size - 1) >> 13;
2452 while (size) {
2453 size >>= 1;
2454 size_reg++;
2455 }
2456 outl(HCFG_LOCKTANKCACHE_MASK | inl(emu->port + HCFG), emu->port + HCFG);
2457 snd_emu10k1_ptr_write(emu, TCB, 0, emu->fx8010.etram_pages.addr);
2458 snd_emu10k1_ptr_write(emu, TCBS, 0, size_reg);
2459 outl(inl(emu->port + HCFG) & ~HCFG_LOCKTANKCACHE_MASK, emu->port + HCFG);
2460 }
2461
2462 if (emu->audigy)
2463 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg | A_DBG_SINGLE_STEP);
2464 else
2465 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg | EMU10K1_DBG_SINGLE_STEP);
2466
2467 len = emu->audigy ? 0x200 : 0x100;
2468 for (i = 0; i < len; i++)
2469 snd_emu10k1_ptr_write(emu, emu->gpr_base + i, 0, emu->saved_gpr[i]);
2470
2471 len = emu->audigy ? 0x100 : 0xa0;
2472 for (i = 0; i < len; i++) {
2473 snd_emu10k1_ptr_write(emu, TANKMEMDATAREGBASE + i, 0,
2474 emu->tram_val_saved[i]);
2475 if (! emu->audigy)
2476 snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + i, 0,
2477 emu->tram_addr_saved[i]);
2478 else {
2479 snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + i, 0,
2480 emu->tram_addr_saved[i] << 12);
2481 snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + i, 0,
2482 emu->tram_addr_saved[i] >> 20);
2483 }
2484 }
2485
2486 len = emu->audigy ? 2 * 1024 : 2 * 512;
2487 for (i = 0; i < len; i++)
2488 snd_emu10k1_efx_write(emu, i, emu->saved_icode[i]);
2489
2490 /* start FX processor when the DSP code is updated */
2491 if (emu->audigy)
2492 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg);
2493 else
2494 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg);
2495}
2496#endif