530 |
* common I/O routines |
* common I/O routines |
531 |
*/ |
*/ |
532 |
|
|
533 |
static void snd_cs4281_delay(unsigned int delay, int can_schedule) |
static void snd_cs4281_delay(unsigned int delay) |
534 |
{ |
{ |
535 |
if (delay > 999) { |
if (delay > 999) { |
536 |
if (can_schedule) { |
unsigned long end_time; |
537 |
unsigned long end_time; |
delay = (delay * HZ) / 1000000; |
538 |
delay = (delay * HZ) / 1000000; |
if (delay < 1) |
539 |
if (delay < 1) |
delay = 1; |
540 |
delay = 1; |
end_time = jiffies + delay; |
541 |
end_time = jiffies + delay; |
do { |
542 |
do { |
set_current_state(TASK_UNINTERRUPTIBLE); |
543 |
set_current_state(TASK_UNINTERRUPTIBLE); |
schedule_timeout(1); |
544 |
schedule_timeout(1); |
} while (time_after_eq(end_time, jiffies)); |
|
} while (time_after_eq(end_time, jiffies)); |
|
|
} else { |
|
|
delay += 999; |
|
|
delay /= 1000; |
|
|
mdelay(delay > 0 ? delay : 1); |
|
|
} |
|
545 |
} else { |
} else { |
546 |
udelay(delay); |
udelay(delay); |
547 |
} |
} |
548 |
} |
} |
549 |
|
|
550 |
inline static void snd_cs4281_delay_long(int can_schedule) |
inline static void snd_cs4281_delay_long(void) |
551 |
{ |
{ |
552 |
if (can_schedule) { |
set_current_state(TASK_UNINTERRUPTIBLE); |
553 |
set_current_state(TASK_UNINTERRUPTIBLE); |
schedule_timeout(1); |
|
schedule_timeout(1); |
|
|
} else |
|
|
mdelay(10); |
|
554 |
} |
} |
555 |
|
|
556 |
static inline void snd_cs4281_pokeBA0(cs4281_t *chip, unsigned long offset, unsigned int val) |
static inline void snd_cs4281_pokeBA0(cs4281_t *chip, unsigned long offset, unsigned int val) |
1258 |
* joystick support |
* joystick support |
1259 |
*/ |
*/ |
1260 |
|
|
1261 |
#if defined(CONFIG_GAMEPORT) || defined(CONFIG_GAMEPORT_MODULE) |
#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE)) |
1262 |
|
|
1263 |
typedef struct snd_cs4281_gameport { |
typedef struct snd_cs4281_gameport { |
1264 |
struct gameport info; |
struct gameport info; |
1350 |
|
|
1351 |
#else |
#else |
1352 |
#define snd_cs4281_gameport(chip) /*NOP*/ |
#define snd_cs4281_gameport(chip) /*NOP*/ |
1353 |
#endif /* CONFIG_GAMEPORT || CONFIG_GAMEPORT_MODULE */ |
#endif /* CONFIG_GAMEPORT || (MODULE && CONFIG_GAMEPORT_MODULE) */ |
1354 |
|
|
1355 |
|
|
1356 |
/* |
/* |
1359 |
|
|
1360 |
static int snd_cs4281_free(cs4281_t *chip) |
static int snd_cs4281_free(cs4281_t *chip) |
1361 |
{ |
{ |
1362 |
#if defined(CONFIG_GAMEPORT) || defined(CONFIG_GAMEPORT_MODULE) |
#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE)) |
1363 |
if (chip->gameport) { |
if (chip->gameport) { |
1364 |
gameport_unregister_port(&chip->gameport->info); |
gameport_unregister_port(&chip->gameport->info); |
1365 |
kfree(chip->gameport); |
kfree(chip->gameport); |
1402 |
return snd_cs4281_free(chip); |
return snd_cs4281_free(chip); |
1403 |
} |
} |
1404 |
|
|
1405 |
static int snd_cs4281_chip_init(cs4281_t *chip, int can_schedule); /* defined below */ |
static int snd_cs4281_chip_init(cs4281_t *chip); /* defined below */ |
1406 |
#ifdef CONFIG_PM |
#ifdef CONFIG_PM |
1407 |
static int snd_cs4281_set_power_state(snd_card_t *card, unsigned int power_state); |
static int snd_cs4281_set_power_state(snd_card_t *card, unsigned int power_state); |
1408 |
#endif |
#endif |
1462 |
return -ENOMEM; |
return -ENOMEM; |
1463 |
} |
} |
1464 |
|
|
1465 |
tmp = snd_cs4281_chip_init(chip, 1); |
tmp = snd_cs4281_chip_init(chip); |
1466 |
if (tmp) { |
if (tmp) { |
1467 |
snd_cs4281_free(chip); |
snd_cs4281_free(chip); |
1468 |
return tmp; |
return tmp; |
1484 |
return 0; |
return 0; |
1485 |
} |
} |
1486 |
|
|
1487 |
static int snd_cs4281_chip_init(cs4281_t *chip, int can_schedule) |
static int snd_cs4281_chip_init(cs4281_t *chip) |
1488 |
{ |
{ |
1489 |
unsigned int tmp; |
unsigned int tmp; |
1490 |
int timeout; |
int timeout; |
1538 |
snd_cs4281_pokeBA0(chip, BA0_SPMC, 0); |
snd_cs4281_pokeBA0(chip, BA0_SPMC, 0); |
1539 |
udelay(50); |
udelay(50); |
1540 |
snd_cs4281_pokeBA0(chip, BA0_SPMC, BA0_SPMC_RSTN); |
snd_cs4281_pokeBA0(chip, BA0_SPMC, BA0_SPMC_RSTN); |
1541 |
snd_cs4281_delay(50000, can_schedule); |
snd_cs4281_delay(50000); |
1542 |
|
|
1543 |
if (chip->dual_codec) |
if (chip->dual_codec) |
1544 |
snd_cs4281_pokeBA0(chip, BA0_SPMC, BA0_SPMC_RSTN | BA0_SPMC_ASDI2E); |
snd_cs4281_pokeBA0(chip, BA0_SPMC, BA0_SPMC_RSTN | BA0_SPMC_ASDI2E); |
1554 |
* Start the DLL Clock logic. |
* Start the DLL Clock logic. |
1555 |
*/ |
*/ |
1556 |
snd_cs4281_pokeBA0(chip, BA0_CLKCR1, BA0_CLKCR1_DLLP); |
snd_cs4281_pokeBA0(chip, BA0_CLKCR1, BA0_CLKCR1_DLLP); |
1557 |
snd_cs4281_delay(50000, can_schedule); |
snd_cs4281_delay(50000); |
1558 |
snd_cs4281_pokeBA0(chip, BA0_CLKCR1, BA0_CLKCR1_SWCE | BA0_CLKCR1_DLLP); |
snd_cs4281_pokeBA0(chip, BA0_CLKCR1, BA0_CLKCR1_SWCE | BA0_CLKCR1_DLLP); |
1559 |
|
|
1560 |
/* |
/* |
1568 |
*/ |
*/ |
1569 |
if (snd_cs4281_peekBA0(chip, BA0_CLKCR1) & BA0_CLKCR1_DLLRDY) |
if (snd_cs4281_peekBA0(chip, BA0_CLKCR1) & BA0_CLKCR1_DLLRDY) |
1570 |
goto __ok0; |
goto __ok0; |
1571 |
snd_cs4281_delay_long(can_schedule); |
snd_cs4281_delay_long(); |
1572 |
} while (timeout-- > 0); |
} while (timeout-- > 0); |
1573 |
|
|
1574 |
snd_printk(KERN_ERR "DLLRDY not seen\n"); |
snd_printk(KERN_ERR "DLLRDY not seen\n"); |
1594 |
*/ |
*/ |
1595 |
if (snd_cs4281_peekBA0(chip, BA0_ACSTS) & BA0_ACSTS_CRDY) |
if (snd_cs4281_peekBA0(chip, BA0_ACSTS) & BA0_ACSTS_CRDY) |
1596 |
goto __ok1; |
goto __ok1; |
1597 |
snd_cs4281_delay_long(can_schedule); |
snd_cs4281_delay_long(); |
1598 |
} while (timeout-- > 0); |
} while (timeout-- > 0); |
1599 |
|
|
1600 |
snd_printk(KERN_ERR "never read codec ready from AC'97 (0x%x)\n", snd_cs4281_peekBA0(chip, BA0_ACSTS)); |
snd_printk(KERN_ERR "never read codec ready from AC'97 (0x%x)\n", snd_cs4281_peekBA0(chip, BA0_ACSTS)); |
1606 |
do { |
do { |
1607 |
if (snd_cs4281_peekBA0(chip, BA0_ACSTS2) & BA0_ACSTS_CRDY) |
if (snd_cs4281_peekBA0(chip, BA0_ACSTS2) & BA0_ACSTS_CRDY) |
1608 |
goto __codec2_ok; |
goto __codec2_ok; |
1609 |
snd_cs4281_delay_long(can_schedule); |
snd_cs4281_delay_long(); |
1610 |
} while (timeout-- > 0); |
} while (timeout-- > 0); |
1611 |
snd_printk(KERN_INFO "secondary codec doesn't respond. disable it...\n"); |
snd_printk(KERN_INFO "secondary codec doesn't respond. disable it...\n"); |
1612 |
chip->dual_codec = 0; |
chip->dual_codec = 0; |
1633 |
*/ |
*/ |
1634 |
if ((snd_cs4281_peekBA0(chip, BA0_ACISV) & (BA0_ACISV_SLV(3) | BA0_ACISV_SLV(4))) == (BA0_ACISV_SLV(3) | BA0_ACISV_SLV(4))) |
if ((snd_cs4281_peekBA0(chip, BA0_ACISV) & (BA0_ACISV_SLV(3) | BA0_ACISV_SLV(4))) == (BA0_ACISV_SLV(3) | BA0_ACISV_SLV(4))) |
1635 |
goto __ok2; |
goto __ok2; |
1636 |
snd_cs4281_delay_long(can_schedule); |
snd_cs4281_delay_long(); |
1637 |
} while (timeout-- > 0); |
} while (timeout-- > 0); |
1638 |
|
|
1639 |
snd_printk(KERN_ERR "never read ISV3 and ISV4 from AC'97\n"); |
snd_printk(KERN_ERR "never read ISV3 and ISV4 from AC'97\n"); |
2100 |
ulCLK |= CLKCR1_CKRA; |
ulCLK |= CLKCR1_CKRA; |
2101 |
snd_cs4281_pokeBA0(chip, BA0_CLKCR1, ulCLK); |
snd_cs4281_pokeBA0(chip, BA0_CLKCR1, ulCLK); |
2102 |
|
|
2103 |
snd_cs4281_chip_init(chip, 0); |
snd_cs4281_chip_init(chip); |
2104 |
|
|
2105 |
/* restore the status registers */ |
/* restore the status registers */ |
2106 |
for (i = 0; i < number_of(saved_regs); i++) |
for (i = 0; i < number_of(saved_regs); i++) |
2119 |
snd_power_change_state(card, SNDRV_CTL_POWER_D0); |
snd_power_change_state(card, SNDRV_CTL_POWER_D0); |
2120 |
} |
} |
2121 |
|
|
|
#ifndef PCI_OLD_SUSPEND |
|
2122 |
static int snd_cs4281_suspend(struct pci_dev *dev, u32 state) |
static int snd_cs4281_suspend(struct pci_dev *dev, u32 state) |
2123 |
{ |
{ |
2124 |
cs4281_t *chip = snd_magic_cast(cs4281_t, pci_get_drvdata(dev), return -ENXIO); |
cs4281_t *chip = snd_magic_cast(cs4281_t, pci_get_drvdata(dev), return -ENXIO); |
2131 |
cs4281_resume(chip); |
cs4281_resume(chip); |
2132 |
return 0; |
return 0; |
2133 |
} |
} |
|
#else |
|
|
static void snd_cs4281_suspend(struct pci_dev *dev) |
|
|
{ |
|
|
cs4281_t *chip = snd_magic_cast(cs4281_t, pci_get_drvdata(dev), return); |
|
|
cs4281_suspend(chip); |
|
|
} |
|
|
static void snd_cs4281_resume(struct pci_dev *dev) |
|
|
{ |
|
|
cs4281_t *chip = snd_magic_cast(cs4281_t, pci_get_drvdata(dev), return); |
|
|
cs4281_resume(chip); |
|
|
} |
|
|
#endif |
|
2134 |
|
|
2135 |
/* callback */ |
/* callback */ |
2136 |
static int snd_cs4281_set_power_state(snd_card_t *card, unsigned int power_state) |
static int snd_cs4281_set_power_state(snd_card_t *card, unsigned int power_state) |