aboutsummaryrefslogtreecommitdiff
path: root/sound/pci/es1968.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-04-24 08:41:44 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2008-04-24 08:41:44 -0700
commit38ccc197eb85cad594eb5863ba5a408655da0062 (patch)
tree0066a0160e5dd28280a8db2a5814af7111ae3e1b /sound/pci/es1968.c
parentd02aacff4467806ee56f147ac8eff6911d95811a (diff)
parent3a841d519f91463361bbbe7addc24a0c1b2e9f99 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6: (250 commits) [ALSA] ice1724 - Fix IRQ lock-up with MPU access [ALSA] Define MPU401 registers in sound/mpu401_uart.h [ALSA] pcsp: fix wording in DEBUG_PAGEALLOC warning [ALSA] pcsp - Fix dependency in Kconfig [ALSA] soc - ac97 - Clean up checkpatch warnings [ALSA] soc - wm8750 - Clean up checkpatch warnings [ALSA] soc - wm8731 - Clean up checkpatch warnings [ALSA] soc - pxa2xx-pcm - Fix checkpatch warnings [ALSA] soc - spitz - Fix checkpatch warnings [ALSA] soc - poodle - Fix checkpatch warnings [ALSA] soc - corgi - Fix checkpatch warnings [ALSA] soc - s3c24xx-i2s - Add missing spaces [ALSA] soc - s3c24xx-i2s - Fix tab/space breakage [ALSA] soc - s3c24xx-i2s - Use linux/io.h [ALSA] hda - Fix Thinkpad X300 digital mic pcsp - Don't build pcspkr when snd-pcsp is enabled [ALSA] hda - Fix model for Acer Aspire 5720z [ALSA] soc - s3c24xx - Declare suspend and resume static [ALSA] soc - s3c24xx - Improve diagnostic output [ALSA] Fix possible races at free_irq in PCI drivers ...
Diffstat (limited to 'sound/pci/es1968.c')
-rw-r--r--sound/pci/es1968.c42
1 files changed, 31 insertions, 11 deletions
diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c
index 7d911a18c08..1bf298d214b 100644
--- a/sound/pci/es1968.c
+++ b/sound/pci/es1968.c
@@ -1827,6 +1827,22 @@ snd_es1968_pcm(struct es1968 *chip, int device)
return 0;
}
+/*
+ * suppress jitter on some maestros when playing stereo
+ */
+static void snd_es1968_suppress_jitter(struct es1968 *chip, struct esschan *es)
+{
+ unsigned int cp1;
+ unsigned int cp2;
+ unsigned int diff;
+
+ cp1 = __apu_get_register(chip, 0, 5);
+ cp2 = __apu_get_register(chip, 1, 5);
+ diff = (cp1 > cp2 ? cp1 - cp2 : cp2 - cp1);
+
+ if (diff > 1)
+ __maestro_write(chip, IDR0_DATA_PORT, cp1);
+}
/*
* update pointer
@@ -1948,8 +1964,11 @@ static irqreturn_t snd_es1968_interrupt(int irq, void *dev_id)
struct esschan *es;
spin_lock(&chip->substream_lock);
list_for_each_entry(es, &chip->substream_list, list) {
- if (es->running)
+ if (es->running) {
snd_es1968_update_pcm(chip, es);
+ if (es->fmt & ESS_FMT_STEREO)
+ snd_es1968_suppress_jitter(chip, es);
+ }
}
spin_unlock(&chip->substream_lock);
if (chip->in_measurement) {
@@ -1972,7 +1991,7 @@ snd_es1968_mixer(struct es1968 *chip)
{
struct snd_ac97_bus *pbus;
struct snd_ac97_template ac97;
- struct snd_ctl_elem_id id;
+ struct snd_ctl_elem_id elem_id;
int err;
static struct snd_ac97_bus_ops ops = {
.write = snd_es1968_ac97_write,
@@ -1989,14 +2008,14 @@ snd_es1968_mixer(struct es1968 *chip)
return err;
/* attach master switch / volumes for h/w volume control */
- memset(&id, 0, sizeof(id));
- id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
- strcpy(id.name, "Master Playback Switch");
- chip->master_switch = snd_ctl_find_id(chip->card, &id);
- memset(&id, 0, sizeof(id));
- id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
- strcpy(id.name, "Master Playback Volume");
- chip->master_volume = snd_ctl_find_id(chip->card, &id);
+ memset(&elem_id, 0, sizeof(elem_id));
+ elem_id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
+ strcpy(elem_id.name, "Master Playback Switch");
+ chip->master_switch = snd_ctl_find_id(chip->card, &elem_id);
+ memset(&elem_id, 0, sizeof(elem_id));
+ elem_id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
+ strcpy(elem_id.name, "Master Playback Volume");
+ chip->master_volume = snd_ctl_find_id(chip->card, &elem_id);
return 0;
}
@@ -2456,7 +2475,8 @@ static inline void snd_es1968_free_gameport(struct es1968 *chip) { }
static int snd_es1968_free(struct es1968 *chip)
{
if (chip->io_port) {
- synchronize_irq(chip->irq);
+ if (chip->irq >= 0)
+ synchronize_irq(chip->irq);
outw(1, chip->io_port + 0x04); /* clear WP interrupts */
outw(0, chip->io_port + ESM_PORT_HOST_IRQ); /* disable IRQ */
}