diff options
Diffstat (limited to 'sound/pci')
28 files changed, 245 insertions, 130 deletions
diff --git a/sound/pci/ad1889.c b/sound/pci/ad1889.c index d1f242b..8f5098f 100644 --- a/sound/pci/ad1889.c +++ b/sound/pci/ad1889.c @@ -909,8 +909,8 @@ snd_ad1889_create(struct snd_card *card, return err; /* check PCI availability (32bit DMA) */ - if (pci_set_dma_mask(pci, DMA_32BIT_MASK) < 0 || - pci_set_consistent_dma_mask(pci, DMA_32BIT_MASK) < 0) { + if (pci_set_dma_mask(pci, DMA_BIT_MASK(32)) < 0 || + pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(32)) < 0) { printk(KERN_ERR PFX "error setting 32-bit DMA mask.\n"); pci_disable_device(pci); return -ENXIO; diff --git a/sound/pci/ali5451/ali5451.c b/sound/pci/ali5451/ali5451.c index 4edf270..c551006 100644 --- a/sound/pci/ali5451/ali5451.c +++ b/sound/pci/ali5451/ali5451.c @@ -2186,8 +2186,8 @@ static int __devinit snd_ali_create(struct snd_card *card, if (err < 0) return err; /* check, if we can restrict PCI DMA transfers to 31 bits */ - if (pci_set_dma_mask(pci, DMA_31BIT_MASK) < 0 || - pci_set_consistent_dma_mask(pci, DMA_31BIT_MASK) < 0) { + if (pci_set_dma_mask(pci, DMA_BIT_MASK(31)) < 0 || + pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(31)) < 0) { snd_printk(KERN_ERR "architecture does not support " "31bit PCI busmaster DMA\n"); pci_disable_device(pci); diff --git a/sound/pci/als300.c b/sound/pci/als300.c index 009b4c8..3aa35af 100644 --- a/sound/pci/als300.c +++ b/sound/pci/als300.c @@ -689,8 +689,8 @@ static int __devinit snd_als300_create(struct snd_card *card, if ((err = pci_enable_device(pci)) < 0) return err; - if (pci_set_dma_mask(pci, DMA_28BIT_MASK) < 0 || - pci_set_consistent_dma_mask(pci, DMA_28BIT_MASK) < 0) { + if (pci_set_dma_mask(pci, DMA_BIT_MASK(28)) < 0 || + pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(28)) < 0) { printk(KERN_ERR "error setting 28bit DMA mask\n"); pci_disable_device(pci); return -ENXIO; diff --git a/sound/pci/als4000.c b/sound/pci/als4000.c index 542a0c6..3dbacde 100644 --- a/sound/pci/als4000.c +++ b/sound/pci/als4000.c @@ -872,8 +872,8 @@ static int __devinit snd_card_als4000_probe(struct pci_dev *pci, return err; } /* check, if we can restrict PCI DMA transfers to 24 bits */ - if (pci_set_dma_mask(pci, DMA_24BIT_MASK) < 0 || - pci_set_consistent_dma_mask(pci, DMA_24BIT_MASK) < 0) { + if (pci_set_dma_mask(pci, DMA_BIT_MASK(24)) < 0 || + pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(24)) < 0) { snd_printk(KERN_ERR "architecture does not support 24bit PCI busmaster DMA\n"); pci_disable_device(pci); return -ENXIO; diff --git a/sound/pci/au88x0/au88x0.c b/sound/pci/au88x0/au88x0.c index 9ec1223..7b72c88 100644 --- a/sound/pci/au88x0/au88x0.c +++ b/sound/pci/au88x0/au88x0.c @@ -151,8 +151,8 @@ snd_vortex_create(struct snd_card *card, struct pci_dev *pci, vortex_t ** rchip) // check PCI availability (DMA). if ((err = pci_enable_device(pci)) < 0) return err; - if (pci_set_dma_mask(pci, DMA_32BIT_MASK) < 0 || - pci_set_consistent_dma_mask(pci, DMA_32BIT_MASK) < 0) { + if (pci_set_dma_mask(pci, DMA_BIT_MASK(32)) < 0 || + pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(32)) < 0) { printk(KERN_ERR "error to set DMA mask\n"); pci_disable_device(pci); return -ENXIO; diff --git a/sound/pci/aw2/aw2-alsa.c b/sound/pci/aw2/aw2-alsa.c index 8eea29f..4d34bb0 100644 --- a/sound/pci/aw2/aw2-alsa.c +++ b/sound/pci/aw2/aw2-alsa.c @@ -279,8 +279,8 @@ static int __devinit snd_aw2_create(struct snd_card *card, pci_set_master(pci); /* check PCI availability (32bit DMA) */ - if ((pci_set_dma_mask(pci, DMA_32BIT_MASK) < 0) || - (pci_set_consistent_dma_mask(pci, DMA_32BIT_MASK) < 0)) { + if ((pci_set_dma_mask(pci, DMA_BIT_MASK(32)) < 0) || + (pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(32)) < 0)) { printk(KERN_ERR "aw2: Impossible to set 32bit mask DMA\n"); pci_disable_device(pci); return -ENXIO; diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c index e9e9b58..f290bc5 100644 --- a/sound/pci/azt3328.c +++ b/sound/pci/azt3328.c @@ -2125,8 +2125,8 @@ snd_azf3328_create(struct snd_card *card, chip->irq = -1; /* check if we can restrict PCI DMA transfers to 24 bits */ - if (pci_set_dma_mask(pci, DMA_24BIT_MASK) < 0 || - pci_set_consistent_dma_mask(pci, DMA_24BIT_MASK) < 0) { + if (pci_set_dma_mask(pci, DMA_BIT_MASK(24)) < 0 || + pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(24)) < 0) { snd_printk(KERN_ERR "architecture does not support " "24bit PCI busmaster DMA\n" ); diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c index df75757..bfac30f 100644 --- a/sound/pci/ca0106/ca0106_main.c +++ b/sound/pci/ca0106/ca0106_main.c @@ -1589,8 +1589,8 @@ static int __devinit snd_ca0106_create(int dev, struct snd_card *card, err = pci_enable_device(pci); if (err < 0) return err; - if (pci_set_dma_mask(pci, DMA_32BIT_MASK) < 0 || - pci_set_consistent_dma_mask(pci, DMA_32BIT_MASK) < 0) { + if (pci_set_dma_mask(pci, DMA_BIT_MASK(32)) < 0 || + pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(32)) < 0) { printk(KERN_ERR "error to set 32bit mask DMA\n"); pci_disable_device(pci); return -ENXIO; diff --git a/sound/pci/cs5535audio/cs5535audio.c b/sound/pci/cs5535audio/cs5535audio.c index c89ed1f..05f56e0 100644 --- a/sound/pci/cs5535audio/cs5535audio.c +++ b/sound/pci/cs5535audio/cs5535audio.c @@ -285,8 +285,8 @@ static int __devinit snd_cs5535audio_create(struct snd_card *card, if ((err = pci_enable_device(pci)) < 0) return err; - if (pci_set_dma_mask(pci, DMA_32BIT_MASK) < 0 || - pci_set_consistent_dma_mask(pci, DMA_32BIT_MASK) < 0) { + if (pci_set_dma_mask(pci, DMA_BIT_MASK(32)) < 0 || + pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(32)) < 0) { printk(KERN_WARNING "unable to get 32bit dma\n"); err = -ENXIO; goto pcifail; diff --git a/sound/pci/emu10k1/emu10k1x.c b/sound/pci/emu10k1/emu10k1x.c index 31542ad..1970f0e 100644 --- a/sound/pci/emu10k1/emu10k1x.c +++ b/sound/pci/emu10k1/emu10k1x.c @@ -897,8 +897,8 @@ static int __devinit snd_emu10k1x_create(struct snd_card *card, if ((err = pci_enable_device(pci)) < 0) return err; - if (pci_set_dma_mask(pci, DMA_28BIT_MASK) < 0 || - pci_set_consistent_dma_mask(pci, DMA_28BIT_MASK) < 0) { + if (pci_set_dma_mask(pci, DMA_BIT_MASK(28)) < 0 || + pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(28)) < 0) { snd_printk(KERN_ERR "error to set 28bit mask DMA\n"); pci_disable_device(pci); return -ENXIO; diff --git a/sound/pci/emu10k1/emufx.c b/sound/pci/emu10k1/emufx.c index 191e1cd..4b302d8 100644 --- a/sound/pci/emu10k1/emufx.c +++ b/sound/pci/emu10k1/emufx.c @@ -2493,24 +2493,17 @@ static int snd_emu10k1_fx8010_ioctl(struct snd_hwdep * hw, struct file *file, un case SNDRV_EMU10K1_IOCTL_CODE_POKE: if (!capable(CAP_SYS_ADMIN)) return -EPERM; - icode = kmalloc(sizeof(*icode), GFP_KERNEL); - if (icode == NULL) - return -ENOMEM; - if (copy_from_user(icode, argp, sizeof(*icode))) { - kfree(icode); - return -EFAULT; - } + + icode = memdup_user(argp, sizeof(*icode)); + if (IS_ERR(icode)) + return PTR_ERR(icode); res = snd_emu10k1_icode_poke(emu, icode); kfree(icode); return res; case SNDRV_EMU10K1_IOCTL_CODE_PEEK: - icode = kmalloc(sizeof(*icode), GFP_KERNEL); - if (icode == NULL) - return -ENOMEM; - if (copy_from_user(icode, argp, sizeof(*icode))) { - kfree(icode); - return -EFAULT; - } + icode = memdup_user(argp, sizeof(*icode)); + if (IS_ERR(icode)) + return PTR_ERR(icode); res = snd_emu10k1_icode_peek(emu, icode); if (res == 0 && copy_to_user(argp, icode, sizeof(*icode))) { kfree(icode); @@ -2519,24 +2512,16 @@ static int snd_emu10k1_fx8010_ioctl(struct snd_hwdep * hw, struct file *file, un kfree(icode); return res; case SNDRV_EMU10K1_IOCTL_PCM_POKE: - ipcm = kmalloc(sizeof(*ipcm), GFP_KERNEL); - if (ipcm == NULL) - return -ENOMEM; - if (copy_from_user(ipcm, argp, sizeof(*ipcm))) { - kfree(ipcm); - return -EFAULT; - } + ipcm = memdup_user(argp, sizeof(*ipcm)); + if (IS_ERR(ipcm)) + return PTR_ERR(ipcm); res = snd_emu10k1_ipcm_poke(emu, ipcm); kfree(ipcm); return res; case SNDRV_EMU10K1_IOCTL_PCM_PEEK: - ipcm = kzalloc(sizeof(*ipcm), GFP_KERNEL); - if (ipcm == NULL) - return -ENOMEM; - if (copy_from_user(ipcm, argp, sizeof(*ipcm))) { - kfree(ipcm); - return -EFAULT; - } + ipcm = memdup_user(argp, sizeof(*ipcm)); + if (IS_ERR(ipcm)) + return PTR_ERR(ipcm); res = snd_emu10k1_ipcm_peek(emu, ipcm); if (res == 0 && copy_to_user(argp, ipcm, sizeof(*ipcm))) { kfree(ipcm); diff --git a/sound/pci/emu10k1/io.c b/sound/pci/emu10k1/io.c index 4bfc31d..c1a5aa1 100644 --- a/sound/pci/emu10k1/io.c +++ b/sound/pci/emu10k1/io.c @@ -490,7 +490,7 @@ void snd_emu10k1_wait(struct snd_emu10k1 *emu, unsigned int wait) if (newtime != curtime) break; } - if (count >= 16384) + if (count > 16384) break; curtime = newtime; } diff --git a/sound/pci/es1938.c b/sound/pci/es1938.c index dd63b13..fbd2ac0 100644 --- a/sound/pci/es1938.c +++ b/sound/pci/es1938.c @@ -1608,8 +1608,8 @@ static int __devinit snd_es1938_create(struct snd_card *card, if ((err = pci_enable_device(pci)) < 0) return err; /* check, if we can restrict PCI DMA transfers to 24 bits */ - if (pci_set_dma_mask(pci, DMA_24BIT_MASK) < 0 || - pci_set_consistent_dma_mask(pci, DMA_24BIT_MASK) < 0) { + if (pci_set_dma_mask(pci, DMA_BIT_MASK(24)) < 0 || + pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(24)) < 0) { snd_printk(KERN_ERR "architecture does not support 24bit PCI busmaster DMA\n"); pci_disable_device(pci); return -ENXIO; diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c index dc97e81..a11f453 100644 --- a/sound/pci/es1968.c +++ b/sound/pci/es1968.c @@ -2539,8 +2539,8 @@ static int __devinit snd_es1968_create(struct snd_card *card, if ((err = pci_enable_device(pci)) < 0) return err; /* check, if we can restrict PCI DMA transfers to 28 bits */ - if (pci_set_dma_mask(pci, DMA_28BIT_MASK) < 0 || - pci_set_consistent_dma_mask(pci, DMA_28BIT_MASK) < 0) { + if (pci_set_dma_mask(pci, DMA_BIT_MASK(28)) < 0 || + pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(28)) < 0) { snd_printk(KERN_ERR "architecture does not support 28bit PCI busmaster DMA\n"); pci_disable_device(pci); return -ENXIO; diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index a4e5e59..8820faf 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -642,19 +642,21 @@ static int get_codec_name(struct hda_codec *codec) */ static void /*__devinit*/ setup_fg_nodes(struct hda_codec *codec) { - int i, total_nodes; + int i, total_nodes, function_id; hda_nid_t nid; total_nodes = snd_hda_get_sub_nodes(codec, AC_NODE_ROOT, &nid); for (i = 0; i < total_nodes; i++, nid++) { - codec->function_id = snd_hda_param_read(codec, nid, + function_id = snd_hda_param_read(codec, nid, AC_PAR_FUNCTION_TYPE) & 0xff; - switch (codec->function_id) { + switch (function_id) { case AC_GRP_AUDIO_FUNCTION: codec->afg = nid; + codec->function_id = function_id; break; case AC_GRP_MODEM_FUNCTION: codec->mfg = nid; + codec->function_id = function_id; break; default: break; @@ -2250,7 +2252,11 @@ int snd_hda_codec_write_cache(struct hda_codec *codec, hda_nid_t nid, err = bus->ops.command(bus, res); if (!err) { struct hda_cache_head *c; - u32 key = build_cmd_cache_key(nid, verb); + u32 key; + /* parm may contain the verb stuff for get/set amp */ + verb = verb | (parm >> 8); + parm &= 0xff; + key = build_cmd_cache_key(nid, verb); c = get_alloc_hash(&codec->cmd_cache, key); if (c) c->val = parm; diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 30829ee..21e99cf 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -312,6 +312,8 @@ struct azx_dev { unsigned int period_bytes; /* size of the period in bytes */ unsigned int frags; /* number for period in the play buffer */ unsigned int fifo_size; /* FIFO size */ + unsigned long start_jiffies; /* start + minimum jiffies */ + unsigned long min_jiffies; /* minimum jiffies before position is valid */ void __iomem *sd_addr; /* stream descriptor pointer */ @@ -330,7 +332,7 @@ struct azx_dev { unsigned int opened :1; unsigned int running :1; unsigned int irq_pending :1; - unsigned int irq_ignore :1; + unsigned int start_flag: 1; /* stream full start flag */ /* * For VIA: * A flag to ensure DMA position is 0 @@ -975,7 +977,7 @@ static irqreturn_t azx_interrupt(int irq, void *dev_id) struct azx *chip = dev_id; struct azx_dev *azx_dev; u32 status; - int i; + int i, ok; spin_lock(&chip->reg_lock); @@ -991,18 +993,14 @@ static irqreturn_t azx_interrupt(int irq, void *dev_id) azx_sd_writeb(azx_dev, SD_STS, SD_INT_MASK); if (!azx_dev->substream || !azx_dev->running) continue; - /* ignore the first dummy IRQ (due to pos_adj) */ - if (azx_dev->irq_ignore) { - azx_dev->irq_ignore = 0; - continue; - } /* check whether this IRQ is really acceptable */ - if (azx_position_ok(chip, azx_dev)) { + ok = azx_position_ok(chip, azx_dev); + if (ok == 1) { azx_dev->irq_pending = 0; spin_unlock(&chip->reg_lock); snd_pcm_period_elapsed(azx_dev->substream); spin_lock(&chip->reg_lock); - } else if (chip->bus && chip->bus->workq) { + } else if (ok == 0 && chip->bus && chip->bus->workq) { /* bogus IRQ, process it later */ azx_dev->irq_pending = 1; queue_work(chip->bus->workq, @@ -1088,7 +1086,6 @@ static int azx_setup_periods(struct azx *chip, bdl = (u32 *)azx_dev->bdl.area; ofs = 0; azx_dev->frags = 0; - azx_dev->irq_ignore = 0; pos_adj = bdl_pos_adj[chip->dev_index]; if (pos_adj > 0) { struct snd_pcm_runtime *runtime = substream->runtime; @@ -1109,7 +1106,6 @@ static int azx_setup_periods(struct azx *chip, &bdl, ofs, pos_adj, 1); if (ofs < 0) goto error; - azx_dev->irq_ignore = 1; } } else pos_adj = 0; @@ -1155,6 +1151,9 @@ static void azx_stream_reset(struct azx *chip, struct azx_dev *azx_dev) while (((val = azx_sd_readb(azx_dev, SD_CTL)) & SD_CTL_STREAM_RESET) && --timeout) ; + + /* reset first position - may not be synced with hw at this time */ + *azx_dev->posbuf = 0; } /* @@ -1409,7 +1408,6 @@ static int azx_pcm_open(struct snd_pcm_substream *substream) snd_pcm_set_sync(substream); mutex_unlock(&chip->open_mutex); - azx_stream_reset(chip, azx_dev); return 0; } @@ -1474,6 +1472,7 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream) unsigned int bufsize, period_bytes, format_val; int err; + azx_stream_reset(chip, azx_dev); format_val = snd_hda_calc_stream_format(runtime->rate, runtime->channels, runtime->format, @@ -1502,6 +1501,8 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream) return err; } + azx_dev->min_jiffies = (runtime->period_size * HZ) / + (runtime->rate * 2); azx_setup_controller(chip, azx_dev); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) azx_dev->fifo_size = azx_sd_readw(azx_dev, SD_FIFOSIZE) + 1; @@ -1518,13 +1519,14 @@ static int azx_pcm_trigger(struct snd_pcm_substream *substream, int cmd) struct azx *chip = apcm->chip; struct azx_dev *azx_dev; struct snd_pcm_substream *s; - int start, nsync = 0, sbits = 0; + int rstart = 0, start, nsync = 0, sbits = 0; int nwait, timeout; switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + rstart = 1; case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: case SNDRV_PCM_TRIGGER_RESUME: - case SNDRV_PCM_TRIGGER_START: start = 1; break; case SNDRV_PCM_TRIGGER_PAUSE_PUSH: @@ -1554,6 +1556,10 @@ static int azx_pcm_trigger(struct snd_pcm_substream *substream, int cmd) if (s->pcm->card != substream->pcm->card) continue; azx_dev = get_azx_dev(s); + if (rstart) { + azx_dev->start_flag = 1; + azx_dev->start_jiffies = jiffies + azx_dev->min_jiffies; + } if (start) azx_stream_start(chip, azx_dev); else @@ -1703,6 +1709,11 @@ static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev) { unsigned int pos; + if (azx_dev->start_flag && + time_before_eq(jiffies, azx_dev->start_jiffies)) + return -1; /* bogus (too early) interrupt */ + azx_dev->start_flag = 0; + pos = azx_get_position(chip, azx_dev); if (chip->position_fix == POS_FIX_AUTO) { if (!pos) { @@ -2260,11 +2271,11 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, gcap &= ~0x01; /* allow 64bit DMA address if supported by H/W */ - if ((gcap & 0x01) && !pci_set_dma_mask(pci, DMA_64BIT_MASK)) - pci_set_consistent_dma_mask(pci, DMA_64BIT_MASK); + if ((gcap & 0x01) && !pci_set_dma_mask(pci, DMA_BIT_MASK(64))) + pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(64)); else { - pci_set_dma_mask(pci, DMA_32BIT_MASK); - pci_set_consistent_dma_mask(pci, DMA_32BIT_MASK); + pci_set_dma_mask(pci, DMA_BIT_MASK(32)); + pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(32)); } /* read number of streams from GCAP register instead of using diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index 5bb48ee..9bcd8ab 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c @@ -3256,7 +3256,7 @@ static const char *ad1884_slave_vols[] = { "Mic Playback Volume", "CD Playback Volume", "Internal Mic Playback Volume", - "Docking Mic Playback Volume" + "Docking Mic Playback Volume", /* "Beep Playback Volume", */ "IEC958 Playback Volume", NULL @@ -3977,6 +3977,14 @@ static int patch_ad1884a(struct hda_codec *codec) spec->input_mux = &ad1884a_laptop_capture_source; codec->patch_ops.unsol_event = ad1884a_hp_unsol_event; codec->patch_ops.init = ad1884a_hp_init; + /* set the upper-limit for mixer amp to 0dB for avoiding the + * possible damage by overloading + */ + snd_hda_override_amp_caps(codec, 0x20, HDA_INPUT, + (0x17 << AC_AMPCAP_OFFSET_SHIFT) | + (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) | + (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) | + (1 << AC_AMPCAP_MUTE_SHIFT)); break; case AD1884A_MOBILE: spec->mixers[0] = ad1884a_mobile_mixers; diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 1f2ad76..56ce19e 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -350,12 +350,20 @@ static int conexant_mux_enum_put(struct snd_kcontrol *kcontrol, } #ifdef CONFIG_SND_JACK +static void conexant_free_jack_priv(struct snd_jack *jack) +{ + struct conexant_jack *jacks = jack->private_data; + jacks->nid = 0; + jacks->jack = NULL; +} + static int conexant_add_jack(struct hda_codec *codec, hda_nid_t nid, int type) { struct conexant_spec *spec; struct conexant_jack *jack; const char *name; + int err; spec = codec->spec; snd_array_init(&spec->jacks, sizeof(*jack), 32); @@ -368,7 +376,12 @@ static int conexant_add_jack(struct hda_codec *codec, jack->nid = nid; jack->type = type; - return snd_jack_new(codec->bus->card, name, type, &jack->jack); + err = snd_jack_new(codec->bus->card, name, type, &jack->jack); + if (err < 0) + return err; + jack->jack->private_data = jack; + jack->jack->private_free = conexant_free_jack_priv; + return 0; } static void conexant_report_jack(struct hda_codec *codec, hda_nid_t nid) @@ -455,8 +468,10 @@ static void conexant_free(struct hda_codec *codec) if (spec->jacks.list) { struct conexant_jack *jacks = spec->jacks.list; int i; - for (i = 0; i < spec->jacks.used; i++) - snd_device_free(codec->bus->card, &jacks[i].jack); + for (i = 0; i < spec->jacks.used; i++, jacks++) { + if (jacks->jack) + snd_device_free(codec->bus->card, jacks->jack); + } snd_array_free(&spec->jacks); } #endif diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 8209779..6ed787e 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -8742,10 +8742,9 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = { SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD), SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch), SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION), - SND_PCI_QUIRK(0x1734, 0x1107, "FSC AMILO Xi2550", + SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx", ALC883_FUJITSU_PI2515), - SND_PCI_QUIRK(0x1734, 0x1108, "Fujitsu AMILO Pi2515", ALC883_FUJITSU_PI2515), - SND_PCI_QUIRK(0x1734, 0x113d, "Fujitsu AMILO Xa3530", + SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx", ALC888_FUJITSU_XA3530), SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch), SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763), @@ -8764,6 +8763,10 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = { {} }; +static hda_nid_t alc883_slave_dig_outs[] = { + ALC1200_DIGOUT_NID, 0, +}; + static hda_nid_t alc1200_slave_dig_outs[] = { ALC883_DIGOUT_NID, 0, }; @@ -8809,6 +8812,7 @@ static struct alc_config_preset alc883_presets[] = { .dac_nids = alc883_dac_nids, .dig_out_nid = ALC883_DIGOUT_NID, .dig_in_nid = ALC883_DIGIN_NID, + .slave_dig_outs = alc883_slave_dig_outs, .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes), .channel_mode = alc883_3ST_6ch_intel_modes, .need_dac_fix = 1, diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index b5e108a..917bc5d 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -3076,6 +3076,11 @@ static int create_multi_out_ctls(struct hda_codec *codec, int num_outs, unsigned int wid_caps; for (i = 0; i < num_outs && i < ARRAY_SIZE(chname); i++) { + if (type == AUTO_PIN_HP_OUT && !spec->hp_detect) { + wid_caps = get_wcaps(codec, pins[i]); + if (wid_caps & AC_WCAP_UNSOL_CAP) + spec->hp_detect = 1; + } nid = dac_nids[i]; if (!nid) continue; @@ -3119,11 +3124,6 @@ static int create_multi_out_ctls(struct hda_codec *codec, int num_outs, err = create_controls_idx(codec, name, idx, nid, 3); if (err < 0) return err; - if (type == AUTO_PIN_HP_OUT && !spec->hp_detect) { - wid_caps = get_wcaps(codec, pins[i]); - if (wid_caps & AC_WCAP_UNSOL_CAP) - spec->hp_detect = 1; - } } } return 0; @@ -3851,6 +3851,15 @@ static void stac_gpio_set(struct hda_codec *codec, unsigned int mask, AC_VERB_SET_GPIO_DATA, gpiostate); /* sync */ } +#ifdef CONFIG_SND_JACK +static void stac92xx_free_jack_priv(struct snd_jack *jack) +{ + struct sigmatel_jack *jacks = jack->private_data; + jacks->nid = 0; + jacks->jack = NULL; +} +#endif + static int stac92xx_add_jack(struct hda_codec *codec, hda_nid_t nid, int type) { @@ -3860,6 +3869,7 @@ static int stac92xx_add_jack(struct hda_codec *codec, int def_conf = snd_hda_codec_get_pincfg(codec, nid); int connectivity = get_defcfg_connect(def_conf); char name[32]; + int err; if (connectivity && connectivity != AC_JACK_PORT_FIXED) return 0; @@ -3876,10 +3886,15 @@ static int stac92xx_add_jack(struct hda_codec *codec, snd_hda_get_jack_connectivity(def_conf), snd_hda_get_jack_location(def_conf)); - return snd_jack_new(codec->bus->card, name, type, &jack->jack); -#else - return 0; + err = snd_jack_new(codec->bus->card, name, type, &jack->jack); + if (err < 0) { + jack->nid = 0; + return err; + } + jack->jack->private_data = jack; + jack->jack->private_free = stac92xx_free_jack_priv; #endif + return 0; } static int stac_add_event(struct sigmatel_spec *spec, hda_nid_t nid, @@ -4138,8 +4153,10 @@ static void stac92xx_free_jacks(struct hda_codec *codec) if (!codec->bus->shutdown && spec->jacks.list) { struct sigmatel_jack *jacks = spec->jacks.list; int i; - for (i = 0; i < spec->jacks.used; i++) - snd_device_free(codec->bus->card, &jacks[i].jack); + for (i = 0; i < spec->jacks.used; i++, jacks++) { + if (jacks->jack) + snd_device_free(codec->bus->card, jacks->jack); + } } snd_array_free(&spec->jacks); #endif @@ -4413,6 +4430,24 @@ static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res) if (spec->num_pwrs > 0) stac92xx_pin_sense(codec, event->nid); stac92xx_report_jack(codec, event->nid); + + switch (codec->subsystem_id) { + case 0x103c308f: + if (event->nid == 0xb) { + int pin = AC_PINCTL_IN_EN; + + if (get_pin_presence(codec, 0xa) + && get_pin_presence(codec, 0xb)) + pin |= AC_PINCTL_VREF_80; + if (!get_pin_presence(codec, 0xb)) + pin |= AC_PINCTL_VREF_80; + + /* toggle VREF state based on mic + hp pin + * status + */ + stac92xx_auto_set_pinctl(codec, 0x0a, pin); + } + } break; case STAC_VREF_EVENT: data = snd_hda_codec_read(codec, codec->afg, 0, @@ -4895,6 +4930,7 @@ again: switch (codec->vendor_id) { case 0x111d7604: case 0x111d7605: + case 0x111d76d5: if (spec->board_config == STAC_92HD83XXX_PWR_REF) break; spec->num_pwrs = 0; @@ -5707,6 +5743,7 @@ static struct hda_codec_preset snd_hda_preset_sigmatel[] = { { .id = 0x111d7603, .name = "92HD75B3X5", .patch = patch_stac92hd71bxx}, { .id = 0x111d7604, .name = "92HD83C1X5", .patch = patch_stac92hd83xxx}, { .id = 0x111d7605, .name = "92HD81B1X5", .patch = patch_stac92hd83xxx}, + { .id = 0x111d76d5, .name = "92HD81B1C5", .patch = patch_stac92hd83xxx}, { .id = 0x111d7608, .name = "92HD75B2X5", .patch = patch_stac92hd71bxx}, { .id = 0x111d7674, .name = "92HD73D1X5", .patch = patch_stac92hd73xx }, { .id = 0x111d7675, .name = "92HD73C1X5", .patch = patch_stac92hd73xx }, diff --git a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c index 3dd63f1..0d0cdbd 100644 --- a/sound/pci/ice1712/ice1712.c +++ b/sound/pci/ice1712/ice1712.c @@ -2533,8 +2533,8 @@ static int __devinit snd_ice1712_create(struct snd_card *card, if (err < 0) return err; /* check, if we can restrict PCI DMA transfers to 28 bits */ - if (pci_set_dma_mask(pci, DMA_28BIT_MASK) < 0 || - pci_set_consistent_dma_mask(pci, DMA_28BIT_MASK) < 0) { + if (pci_set_dma_mask(pci, DMA_BIT_MASK(28)) < 0 || + pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(28)) < 0) { snd_printk(KERN_ERR "architecture does not support 28bit PCI busmaster DMA\n"); pci_disable_device(pci); return -ENXIO; diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c index 5764881..8042d53 100644 --- a/sound/pci/intel8x0.c +++ b/sound/pci/intel8x0.c @@ -355,6 +355,9 @@ struct ichdev { unsigned int fragsize1; unsigned int position; unsigned int pos_shift; + unsigned int last_pos; + unsigned long last_pos_jiffies; + unsigned int jiffy_to_bytes; int frags; int lvi; int lvi_frag; @@ -838,7 +841,10 @@ static int snd_intel8x0_pcm_trigger(struct snd_pcm_substream *substream, int cmd ichdev->suspended = 0; /* fallthru */ case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: val = ICH_IOCE | ICH_STARTBM; + ichdev->last_pos = ichdev->position; + ichdev->last_pos_jiffies = jiffies; break; case SNDRV_PCM_TRIGGER_SUSPEND: ichdev->suspended = 1; @@ -849,9 +855,6 @@ static int snd_intel8x0_pcm_trigger(struct snd_pcm_substream *substream, int cmd case SNDRV_PCM_TRIGGER_PAUSE_PUSH: val = ICH_IOCE; break; - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - val = ICH_IOCE | ICH_STARTBM; - break; default: return -EINVAL; } @@ -1045,6 +1048,7 @@ static int snd_intel8x0_pcm_prepare(struct snd_pcm_substream *substream) ichdev->pos_shift = (runtime->sample_bits > 16) ? 2 : 1; } snd_intel8x0_setup_periods(chip, ichdev); + ichdev->jiffy_to_bytes = (runtime->rate * 4 * ichdev->pos_shift) / HZ; return 0; } @@ -1053,7 +1057,7 @@ static snd_pcm_uframes_t snd_intel8x0_pcm_pointer(struct snd_pcm_substream *subs struct intel8x0 *chip = snd_pcm_substream_chip(substream); struct ichdev *ichdev = get_ichdev(substream); size_t ptr1, ptr; - int civ, timeout = 100; + int civ, timeout = 10; unsigned int position; spin_lock(&chip->reg_lock); @@ -1069,9 +1073,19 @@ static snd_pcm_uframes_t snd_intel8x0_pcm_pointer(struct snd_pcm_substream *subs ptr1 == igetword(chip, ichdev->reg_offset + ichdev->roff_picb)) break; } while (timeout--); - ptr1 <<= ichdev->pos_shift; - ptr = ichdev->fragsize1 - ptr1; - ptr += position; + if (ptr1 != 0) { + ptr1 <<= ichdev->pos_shift; + ptr = ichdev->fragsize1 - ptr1; + ptr += position; + ichdev->last_pos = ptr; + ichdev->last_pos_jiffies = jiffies; + } else { + ptr1 = jiffies - ichdev->last_pos_jiffies; + if (ptr1) + ptr1 -= 1; + ptr = ichdev->last_pos + ptr1 * ichdev->jiffy_to_bytes; + ptr %= ichdev->size; + } spin_unlock(&chip->reg_lock); if (ptr >= ichdev->size) return 0; @@ -1840,6 +1854,12 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = { }, { .subvendor = 0x1028, + .subdevice = 0x016a, + .name = "Dell Inspiron 8600", /* STAC9750/51 */ + .type = AC97_TUNE_HP_ONLY + }, + { + .subvendor = 0x1028, .subdevice = 0x0186, .name = "Dell Latitude D810", /* cf. Malone #41015 */ .type = AC97_TUNE_HP_MUTE_LED @@ -1882,12 +1902,6 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = { }, { .subvendor = 0x103c, - .subdevice = 0x0934, - .name = "HP nx8220", - .type = AC97_TUNE_MUTE_LED - }, - { - .subvendor = 0x103c, .subdevice = 0x129d, .name = "HP xw8000", .type = AC97_TUNE_HP_ONLY @@ -2661,12 +2675,14 @@ static void __devinit intel8x0_measure_ac97_clock(struct intel8x0 *chip) struct snd_pcm_substream *subs; struct ichdev *ichdev; unsigned long port; - unsigned long pos, t; - struct timeval start_time, stop_time; + unsigned long pos, pos1, t; + int civ, timeout = 1000, attempt = 1; + struct timespec start_time, stop_time; if (chip->ac97_bus->clock != 48000) return; /* specified in module option */ + __again: subs = chip->pcm[0]->streams[0].substream; if (! subs || subs->dma_buffer.bytes < INTEL8X0_TESTBUF_SIZE) { snd_printk(KERN_WARNING "no playback buffer allocated - aborting measure ac97 clock\n"); @@ -2674,7 +2690,7 @@ static void __devinit intel8x0_measure_ac97_clock(struct intel8x0 *chip) } ichdev = &chip->ichd[ICHD_PCMOUT]; ichdev->physbuf = subs->dma_buffer.addr; - ichdev->size = chip->ichd[ICHD_PCMOUT].fragsize = INTEL8X0_TESTBUF_SIZE; + ichdev->size = ichdev->fragsize = INTEL8X0_TESTBUF_SIZE; ichdev->substream = NULL; /* don't process interrupts */ /* set rate */ @@ -2693,16 +2709,31 @@ static void __devinit intel8x0_measure_ac97_clock(struct intel8x0 *chip) iputbyte(chip, port + ICH_REG_OFF_CR, ICH_IOCE); iputdword(chip, ICHREG(ALI_DMACR), 1 << ichdev->ali_slot); } - do_gettimeofday(&start_time); + do_posix_clock_monotonic_gettime(&start_time); spin_unlock_irq(&chip->reg_lock); msleep(50); spin_lock_irq(&chip->reg_lock); /* check the position */ - pos = ichdev->fragsize1; - pos -= igetword(chip, ichdev->reg_offset + ichdev->roff_picb) << ichdev->pos_shift; - pos += ichdev->position; + do { + civ = igetbyte(chip, ichdev->reg_offset + ICH_REG_OFF_CIV); + pos1 = igetword(chip, ichdev->reg_offset + ichdev->roff_picb); + if (pos1 == 0) { + udelay(10); + continue; + } + if (civ == igetbyte(chip, ichdev->reg_offset + ICH_REG_OFF_CIV) && + pos1 == igetword(chip, ichdev->reg_offset + ichdev->roff_picb)) + break; + } while (timeout--); + if (pos1 == 0) { /* oops, this value is not reliable */ + pos = 0; + } else { + pos = ichdev->fragsize1; + pos -= pos1 << ichdev->pos_shift; + pos += ichdev->position; + } chip->in_measurement = 0; - do_gettimeofday(&stop_time); + do_posix_clock_monotonic_gettime(&stop_time); /* stop */ if (chip->device_type == DEVICE_ALI) { iputdword(chip, ICHREG(ALI_DMACR), 1 << (ichdev->ali_slot + 16)); @@ -2717,19 +2748,37 @@ static void __devinit intel8x0_measure_ac97_clock(struct intel8x0 *chip) iputbyte(chip, port + ICH_REG_OFF_CR, ICH_RESETREGS); spin_unlock_irq(&chip->reg_lock); + if (pos == 0) { + snd_printk(KERN_ERR "intel8x0: measure - unreliable DMA position..\n"); + __retry: + if (attempt < 2) { + attempt++; + goto __again; + } + return; + } + + pos /= 4; t = stop_time.tv_sec - start_time.tv_sec; t *= 1000000; - t += stop_time.tv_usec - start_time.tv_usec; - printk(KERN_INFO "%s: measured %lu usecs\n", __func__, t); + t += (stop_time.tv_nsec - start_time.tv_nsec) / 1000; + printk(KERN_INFO "%s: measured %lu usecs (%lu samples)\n", __func__, t, pos); if (t == 0) { - snd_printk(KERN_ERR "?? calculation error..\n"); - return; + snd_printk(KERN_ERR "intel8x0: ?? calculation error..\n"); + goto __retry; } - pos = (pos / 4) * 1000; + pos *= 1000; pos = (pos / t) * 1000 + ((pos % t) * 1000) / t; - if (pos < 40000 || pos >= 60000) + if (pos < 40000 || pos >= 60000) { /* abnormal value. hw problem? */ printk(KERN_INFO "intel8x0: measured clock %ld rejected\n", pos); + goto __retry; + } else if (pos > 40500 && pos < 41500) + /* first exception - 41000Hz reference clock */ + chip->ac97_bus->clock = 41000; + else if (pos > 43600 && pos < 44600) + /* second exception - 44100HZ reference clock */ + chip->ac97_bus->clock = 44100; else if (pos < 47500 || pos > 48500) /* not 48000Hz, tuning the clock.. */ chip->ac97_bus->clock = (chip->ac97_bus->clock * 48000) / pos; diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c index 7014154..75283fbb 100644 --- a/sound/pci/maestro3.c +++ b/sound/pci/maestro3.c @@ -2530,8 +2530,8 @@ snd_m3_create(struct snd_card *card, struct pci_dev *pci, return -EIO; /* check, if we can restrict PCI DMA transfers to 28 bits */ - if (pci_set_dma_mask(pci, DMA_28BIT_MASK) < 0 || - pci_set_consistent_dma_mask(pci, DMA_28BIT_MASK) < 0) { + if (pci_set_dma_mask(pci, DMA_BIT_MASK(28)) < 0 || + pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(28)) < 0) { snd_printk(KERN_ERR "architecture does not support 28bit PCI busmaster DMA\n"); pci_disable_device(pci); return -ENXIO; diff --git a/sound/pci/mixart/mixart.c b/sound/pci/mixart/mixart.c index c1eb84a..82bc5b9e 100644 --- a/sound/pci/mixart/mixart.c +++ b/sound/pci/mixart/mixart.c @@ -1291,7 +1291,7 @@ static int __devinit snd_mixart_probe(struct pci_dev *pci, pci_set_master(pci); /* check if we can restrict PCI DMA transfers to 32 bits */ - if (pci_set_dma_mask(pci, DMA_32BIT_MASK) < 0) { + if (pci_set_dma_mask(pci, DMA_BIT_MASK(32)) < 0) { snd_printk(KERN_ERR "architecture does not support 32bit PCI busmaster DMA\n"); pci_disable_device(pci); return -ENXIO; diff --git a/sound/pci/pcxhr/pcxhr.c b/sound/pci/pcxhr/pcxhr.c index 80e064a..833e9c7 100644 --- a/sound/pci/pcxhr/pcxhr.c +++ b/sound/pci/pcxhr/pcxhr.c @@ -1449,7 +1449,7 @@ static int __devinit pcxhr_probe(struct pci_dev *pci, pci_set_master(pci); /* check if we can restrict PCI DMA transfers to 32 bits */ - if (pci_set_dma_mask(pci, DMA_32BIT_MASK) < 0) { + if (pci_set_dma_mask(pci, DMA_BIT_MASK(32)) < 0) { snd_printk(KERN_ERR "architecture does not support " "32bit PCI busmaster DMA\n"); pci_disable_device(pci); diff --git a/sound/pci/sis7019.c b/sound/pci/sis7019.c index baf6d8e..1a5ff06 100644 --- a/sound/pci/sis7019.c +++ b/sound/pci/sis7019.c @@ -1300,7 +1300,7 @@ static int __devinit sis_chip_create(struct snd_card *card, if (rc) goto error_out; - if (pci_set_dma_mask(pci, DMA_30BIT_MASK) < 0) { + if (pci_set_dma_mask(pci, DMA_BIT_MASK(30)) < 0) { printk(KERN_ERR "sis7019: architecture does not support " "30-bit PCI busmaster DMA"); goto error_out_enabled; diff --git a/sound/pci/sonicvibes.c b/sound/pci/sonicvibes.c index d989215..7dc60ad 100644 --- a/sound/pci/sonicvibes.c +++ b/sound/pci/sonicvibes.c @@ -1264,8 +1264,8 @@ static int __devinit snd_sonicvibes_create(struct snd_card *card, if ((err = pci_enable_device(pci)) < 0) return err; /* check, if we can restrict PCI DMA transfers to 24 bits */ - if (pci_set_dma_mask(pci, DMA_24BIT_MASK) < 0 || - pci_set_consistent_dma_mask(pci, DMA_24BIT_MASK) < 0) { + if (pci_set_dma_mask(pci, DMA_BIT_MASK(24)) < 0 || + pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(24)) < 0) { snd_printk(KERN_ERR "architecture does not support 24bit PCI busmaster DMA\n"); pci_disable_device(pci); return -ENXIO; diff --git a/sound/pci/trident/trident_main.c b/sound/pci/trident/trident_main.c index a9da9c1..6d943f6 100644 --- a/sound/pci/trident/trident_main.c +++ b/sound/pci/trident/trident_main.c @@ -3559,8 +3559,8 @@ int __devinit snd_trident_create(struct snd_card *card, if ((err = pci_enable_device(pci)) < 0) return err; /* check, if we can restrict PCI DMA transfers to 30 bits */ - if (pci_set_dma_mask(pci, DMA_30BIT_MASK) < 0 || - pci_set_consistent_dma_mask(pci, DMA_30BIT_MASK) < 0) { + if (pci_set_dma_mask(pci, DMA_BIT_MASK(30)) < 0 || + pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(30)) < 0) { snd_printk(KERN_ERR "architecture does not support 30bit PCI busmaster DMA\n"); pci_disable_device(pci); return -ENXIO; |