X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=sound%2Fpci%2Fcs4281.c;h=8e5519de7115f2897f0d31072fa12194e9d9ef38;hb=97bf2856c6014879bd04983a3e9dfcdac1e7fe85;hp=4f65ec56bf3525125700988e0da03f2e94b00546;hpb=76828883507a47dae78837ab5dec5a5b4513c667;p=linux-2.6.git diff --git a/sound/pci/cs4281.c b/sound/pci/cs4281.c index 4f65ec56b..8e5519de7 100644 --- a/sound/pci/cs4281.c +++ b/sound/pci/cs4281.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -492,7 +493,7 @@ struct cs4281 { }; -static irqreturn_t snd_cs4281_interrupt(int irq, void *dev_id, struct pt_regs *regs); +static irqreturn_t snd_cs4281_interrupt(int irq, void *dev_id); static struct pci_device_id snd_cs4281_ids[] = { { 0x1013, 0x6005, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* CS4281 */ @@ -1046,7 +1047,7 @@ static int snd_cs4281_put_volume(struct snd_kcontrol *kcontrol, snd_cs4281_pokeBA0(chip, regL, volL); change = 1; } - if (ucontrol->value.integer.value[0] != volL) { + if (ucontrol->value.integer.value[1] != volR) { volR = CS_VOL_MASK - (ucontrol->value.integer.value[1] & CS_VOL_MASK); snd_cs4281_pokeBA0(chip, regR, volR); change = 1; @@ -1054,6 +1055,8 @@ static int snd_cs4281_put_volume(struct snd_kcontrol *kcontrol, return change; } +static DECLARE_TLV_DB_SCALE(db_scale_dsp, -4650, 150, 0); + static struct snd_kcontrol_new snd_cs4281_fm_vol = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, @@ -1062,6 +1065,7 @@ static struct snd_kcontrol_new snd_cs4281_fm_vol = .get = snd_cs4281_get_volume, .put = snd_cs4281_put_volume, .private_value = ((BA0_FMLVC << 16) | BA0_FMRVC), + .tlv = { .p = db_scale_dsp }, }; static struct snd_kcontrol_new snd_cs4281_pcm_vol = @@ -1072,6 +1076,7 @@ static struct snd_kcontrol_new snd_cs4281_pcm_vol = .get = snd_cs4281_get_volume, .put = snd_cs4281_put_volume, .private_value = ((BA0_PPLVC << 16) | BA0_PPRVC), + .tlv = { .p = db_scale_dsp }, }; static void snd_cs4281_mixer_free_ac97_bus(struct snd_ac97_bus *bus) @@ -1184,7 +1189,7 @@ static void __devinit snd_cs4281_proc_init(struct cs4281 * chip) struct snd_info_entry *entry; if (! snd_card_proc_new(chip->card, "cs4281", &entry)) - snd_info_set_text_ops(entry, chip, 1024, snd_cs4281_proc_read); + snd_info_set_text_ops(entry, chip, snd_cs4281_proc_read); if (! snd_card_proc_new(chip->card, "cs4281_BA0", &entry)) { entry->content = SNDRV_INFO_CONTENT_DATA; entry->private_data = chip; @@ -1379,14 +1384,6 @@ static int __devinit snd_cs4281_create(struct snd_card *card, chip->ba0_addr = pci_resource_start(pci, 0); chip->ba1_addr = pci_resource_start(pci, 1); - if (request_irq(pci->irq, snd_cs4281_interrupt, SA_INTERRUPT|SA_SHIRQ, - "CS4281", chip)) { - snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq); - snd_cs4281_free(chip); - return -ENOMEM; - } - chip->irq = pci->irq; - chip->ba0 = ioremap_nocache(chip->ba0_addr, pci_resource_len(pci, 0)); chip->ba1 = ioremap_nocache(chip->ba1_addr, pci_resource_len(pci, 1)); if (!chip->ba0 || !chip->ba1) { @@ -1394,6 +1391,14 @@ static int __devinit snd_cs4281_create(struct snd_card *card, return -ENOMEM; } + if (request_irq(pci->irq, snd_cs4281_interrupt, IRQF_SHARED, + "CS4281", chip)) { + snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq); + snd_cs4281_free(chip); + return -ENOMEM; + } + chip->irq = pci->irq; + tmp = snd_cs4281_chip_init(chip); if (tmp) { snd_cs4281_free(chip); @@ -1416,7 +1421,7 @@ static int __devinit snd_cs4281_create(struct snd_card *card, static int snd_cs4281_chip_init(struct cs4281 *chip) { unsigned int tmp; - int timeout; + unsigned long end_time; int retry_count = 2; /* Having EPPMC.FPDN=1 prevent proper chip initialisation */ @@ -1496,7 +1501,7 @@ static int snd_cs4281_chip_init(struct cs4281 *chip) /* * Wait for the DLL ready signal from the clock logic. */ - timeout = 100; + end_time = jiffies + HZ; do { /* * Read the AC97 status register to see if we've seen a CODEC @@ -1504,8 +1509,8 @@ static int snd_cs4281_chip_init(struct cs4281 *chip) */ if (snd_cs4281_peekBA0(chip, BA0_CLKCR1) & BA0_CLKCR1_DLLRDY) goto __ok0; - msleep(1); - } while (timeout-- > 0); + schedule_timeout_uninterruptible(1); + } while (time_after_eq(end_time, jiffies)); snd_printk(KERN_ERR "DLLRDY not seen\n"); return -EIO; @@ -1522,7 +1527,7 @@ static int snd_cs4281_chip_init(struct cs4281 *chip) /* * Wait for the codec ready signal from the AC97 codec. */ - timeout = 100; + end_time = jiffies + HZ; do { /* * Read the AC97 status register to see if we've seen a CODEC @@ -1530,20 +1535,20 @@ static int snd_cs4281_chip_init(struct cs4281 *chip) */ if (snd_cs4281_peekBA0(chip, BA0_ACSTS) & BA0_ACSTS_CRDY) goto __ok1; - msleep(1); - } while (timeout-- > 0); + schedule_timeout_uninterruptible(1); + } while (time_after_eq(end_time, jiffies)); snd_printk(KERN_ERR "never read codec ready from AC'97 (0x%x)\n", snd_cs4281_peekBA0(chip, BA0_ACSTS)); return -EIO; __ok1: if (chip->dual_codec) { - timeout = 100; + end_time = jiffies + HZ; do { if (snd_cs4281_peekBA0(chip, BA0_ACSTS2) & BA0_ACSTS_CRDY) goto __codec2_ok; - msleep(1); - } while (timeout-- > 0); + schedule_timeout_uninterruptible(1); + } while (time_after_eq(end_time, jiffies)); snd_printk(KERN_INFO "secondary codec doesn't respond. disable it...\n"); chip->dual_codec = 0; __codec2_ok: ; @@ -1561,7 +1566,7 @@ static int snd_cs4281_chip_init(struct cs4281 *chip) * the codec is pumping ADC data across the AC-link. */ - timeout = 100; + end_time = jiffies + HZ; do { /* * Read the input slot valid register and see if input slots 3 @@ -1569,8 +1574,8 @@ static int snd_cs4281_chip_init(struct cs4281 *chip) */ if ((snd_cs4281_peekBA0(chip, BA0_ACISV) & (BA0_ACISV_SLV(3) | BA0_ACISV_SLV(4))) == (BA0_ACISV_SLV(3) | BA0_ACISV_SLV(4))) goto __ok2; - msleep(1); - } while (timeout-- > 0); + schedule_timeout_uninterruptible(1); + } while (time_after_eq(end_time, jiffies)); if (--retry_count > 0) goto __retry; @@ -1809,7 +1814,7 @@ static int __devinit snd_cs4281_midi(struct cs4281 * chip, int device, * Interrupt handler */ -static irqreturn_t snd_cs4281_interrupt(int irq, void *dev_id, struct pt_regs *regs) +static irqreturn_t snd_cs4281_interrupt(int irq, void *dev_id) { struct cs4281 *chip = dev_id; unsigned int status, dma, val; @@ -2045,6 +2050,7 @@ static int cs4281_suspend(struct pci_dev *pci, pm_message_t state) pci_disable_device(pci); pci_save_state(pci); + pci_set_power_state(pci, pci_choose_state(pci, state)); return 0; } @@ -2055,8 +2061,14 @@ static int cs4281_resume(struct pci_dev *pci) unsigned int i; u32 ulCLK; + pci_set_power_state(pci, PCI_D0); pci_restore_state(pci); - pci_enable_device(pci); + if (pci_enable_device(pci) < 0) { + printk(KERN_ERR "cs4281: pci_enable_device failed, " + "disabling device\n"); + snd_card_disconnect(card); + return -EIO; + } pci_set_master(pci); ulCLK = snd_cs4281_peekBA0(chip, BA0_CLKCR1);