X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=sound%2Fpci%2Femu10k1%2Fio.c;h=ef5304df8c1184a25c5955f94d6c9132e9ddea51;hb=43bc926fffd92024b46cafaf7350d669ba9ca884;hp=95f85d770147dd7cc4aad7719bdd9c1cfa709091;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/sound/pci/emu10k1/io.c b/sound/pci/emu10k1/io.c index 95f85d770..ef5304df8 100644 --- a/sound/pci/emu10k1/io.c +++ b/sound/pci/emu10k1/io.c @@ -29,8 +29,9 @@ #include #include #include +#include -unsigned int snd_emu10k1_ptr_read(emu10k1_t * emu, unsigned int reg, unsigned int chn) +unsigned int snd_emu10k1_ptr_read(struct snd_emu10k1 * emu, unsigned int reg, unsigned int chn) { unsigned long flags; unsigned int regptr, val; @@ -61,7 +62,7 @@ unsigned int snd_emu10k1_ptr_read(emu10k1_t * emu, unsigned int reg, unsigned in } } -void snd_emu10k1_ptr_write(emu10k1_t *emu, unsigned int reg, unsigned int chn, unsigned int data) +void snd_emu10k1_ptr_write(struct snd_emu10k1 *emu, unsigned int reg, unsigned int chn, unsigned int data) { unsigned int regptr; unsigned long flags; @@ -91,7 +92,78 @@ void snd_emu10k1_ptr_write(emu10k1_t *emu, unsigned int reg, unsigned int chn, u } } -void snd_emu10k1_intr_enable(emu10k1_t *emu, unsigned int intrenb) +unsigned int snd_emu10k1_ptr20_read(struct snd_emu10k1 * emu, + unsigned int reg, + unsigned int chn) +{ + unsigned long flags; + unsigned int regptr, val; + + regptr = (reg << 16) | chn; + + spin_lock_irqsave(&emu->emu_lock, flags); + outl(regptr, emu->port + 0x20 + PTR); + val = inl(emu->port + 0x20 + DATA); + spin_unlock_irqrestore(&emu->emu_lock, flags); + return val; +} + +void snd_emu10k1_ptr20_write(struct snd_emu10k1 *emu, + unsigned int reg, + unsigned int chn, + unsigned int data) +{ + unsigned int regptr; + unsigned long flags; + + regptr = (reg << 16) | chn; + + spin_lock_irqsave(&emu->emu_lock, flags); + outl(regptr, emu->port + 0x20 + PTR); + outl(data, emu->port + 0x20 + DATA); + spin_unlock_irqrestore(&emu->emu_lock, flags); +} + +int snd_emu10k1_spi_write(struct snd_emu10k1 * emu, + unsigned int data) +{ + unsigned int reset, set; + unsigned int reg, tmp; + int n, result; + if (emu->card_capabilities->ca0108_chip) + reg = 0x3c; /* PTR20, reg 0x3c */ + else { + /* For other chip types the SPI register + * is currently unknown. */ + return 1; + } + if (data > 0xffff) /* Only 16bit values allowed */ + return 1; + + tmp = snd_emu10k1_ptr20_read(emu, reg, 0); + reset = (tmp & ~0x3ffff) | 0x20000; /* Set xxx20000 */ + set = reset | 0x10000; /* Set xxx1xxxx */ + snd_emu10k1_ptr20_write(emu, reg, 0, reset | data); + tmp = snd_emu10k1_ptr20_read(emu, reg, 0); /* write post */ + snd_emu10k1_ptr20_write(emu, reg, 0, set | data); + result = 1; + /* Wait for status bit to return to 0 */ + for (n = 0; n < 100; n++) { + udelay(10); + tmp = snd_emu10k1_ptr20_read(emu, reg, 0); + if (!(tmp & 0x10000)) { + result = 0; + break; + } + } + if (result) /* Timed out */ + return 1; + snd_emu10k1_ptr20_write(emu, reg, 0, reset | data); + tmp = snd_emu10k1_ptr20_read(emu, reg, 0); /* Write post */ + return 0; +} + +void snd_emu10k1_intr_enable(struct snd_emu10k1 *emu, unsigned int intrenb) { unsigned long flags; unsigned int enable; @@ -102,7 +174,7 @@ void snd_emu10k1_intr_enable(emu10k1_t *emu, unsigned int intrenb) spin_unlock_irqrestore(&emu->emu_lock, flags); } -void snd_emu10k1_intr_disable(emu10k1_t *emu, unsigned int intrenb) +void snd_emu10k1_intr_disable(struct snd_emu10k1 *emu, unsigned int intrenb) { unsigned long flags; unsigned int enable; @@ -113,7 +185,7 @@ void snd_emu10k1_intr_disable(emu10k1_t *emu, unsigned int intrenb) spin_unlock_irqrestore(&emu->emu_lock, flags); } -void snd_emu10k1_voice_intr_enable(emu10k1_t *emu, unsigned int voicenum) +void snd_emu10k1_voice_intr_enable(struct snd_emu10k1 *emu, unsigned int voicenum) { unsigned long flags; unsigned int val; @@ -133,7 +205,7 @@ void snd_emu10k1_voice_intr_enable(emu10k1_t *emu, unsigned int voicenum) spin_unlock_irqrestore(&emu->emu_lock, flags); } -void snd_emu10k1_voice_intr_disable(emu10k1_t *emu, unsigned int voicenum) +void snd_emu10k1_voice_intr_disable(struct snd_emu10k1 *emu, unsigned int voicenum) { unsigned long flags; unsigned int val; @@ -153,7 +225,7 @@ void snd_emu10k1_voice_intr_disable(emu10k1_t *emu, unsigned int voicenum) spin_unlock_irqrestore(&emu->emu_lock, flags); } -void snd_emu10k1_voice_intr_ack(emu10k1_t *emu, unsigned int voicenum) +void snd_emu10k1_voice_intr_ack(struct snd_emu10k1 *emu, unsigned int voicenum) { unsigned long flags; @@ -170,7 +242,64 @@ void snd_emu10k1_voice_intr_ack(emu10k1_t *emu, unsigned int voicenum) spin_unlock_irqrestore(&emu->emu_lock, flags); } -void snd_emu10k1_voice_set_loop_stop(emu10k1_t *emu, unsigned int voicenum) +void snd_emu10k1_voice_half_loop_intr_enable(struct snd_emu10k1 *emu, unsigned int voicenum) +{ + unsigned long flags; + unsigned int val; + + spin_lock_irqsave(&emu->emu_lock, flags); + /* voice interrupt */ + if (voicenum >= 32) { + outl(HLIEH << 16, emu->port + PTR); + val = inl(emu->port + DATA); + val |= 1 << (voicenum - 32); + } else { + outl(HLIEL << 16, emu->port + PTR); + val = inl(emu->port + DATA); + val |= 1 << voicenum; + } + outl(val, emu->port + DATA); + spin_unlock_irqrestore(&emu->emu_lock, flags); +} + +void snd_emu10k1_voice_half_loop_intr_disable(struct snd_emu10k1 *emu, unsigned int voicenum) +{ + unsigned long flags; + unsigned int val; + + spin_lock_irqsave(&emu->emu_lock, flags); + /* voice interrupt */ + if (voicenum >= 32) { + outl(HLIEH << 16, emu->port + PTR); + val = inl(emu->port + DATA); + val &= ~(1 << (voicenum - 32)); + } else { + outl(HLIEL << 16, emu->port + PTR); + val = inl(emu->port + DATA); + val &= ~(1 << voicenum); + } + outl(val, emu->port + DATA); + spin_unlock_irqrestore(&emu->emu_lock, flags); +} + +void snd_emu10k1_voice_half_loop_intr_ack(struct snd_emu10k1 *emu, unsigned int voicenum) +{ + unsigned long flags; + + spin_lock_irqsave(&emu->emu_lock, flags); + /* voice interrupt */ + if (voicenum >= 32) { + outl(HLIPH << 16, emu->port + PTR); + voicenum = 1 << (voicenum - 32); + } else { + outl(HLIPL << 16, emu->port + PTR); + voicenum = 1 << voicenum; + } + outl(voicenum, emu->port + DATA); + spin_unlock_irqrestore(&emu->emu_lock, flags); +} + +void snd_emu10k1_voice_set_loop_stop(struct snd_emu10k1 *emu, unsigned int voicenum) { unsigned long flags; unsigned int sol; @@ -190,7 +319,7 @@ void snd_emu10k1_voice_set_loop_stop(emu10k1_t *emu, unsigned int voicenum) spin_unlock_irqrestore(&emu->emu_lock, flags); } -void snd_emu10k1_voice_clear_loop_stop(emu10k1_t *emu, unsigned int voicenum) +void snd_emu10k1_voice_clear_loop_stop(struct snd_emu10k1 *emu, unsigned int voicenum) { unsigned long flags; unsigned int sol; @@ -210,7 +339,7 @@ void snd_emu10k1_voice_clear_loop_stop(emu10k1_t *emu, unsigned int voicenum) spin_unlock_irqrestore(&emu->emu_lock, flags); } -void snd_emu10k1_wait(emu10k1_t *emu, unsigned int wait) +void snd_emu10k1_wait(struct snd_emu10k1 *emu, unsigned int wait) { volatile unsigned count; unsigned int newtime = 0, curtime; @@ -229,9 +358,9 @@ void snd_emu10k1_wait(emu10k1_t *emu, unsigned int wait) } } -unsigned short snd_emu10k1_ac97_read(ac97_t *ac97, unsigned short reg) +unsigned short snd_emu10k1_ac97_read(struct snd_ac97 *ac97, unsigned short reg) { - emu10k1_t *emu = snd_magic_cast(emu10k1_t, ac97->private_data, return -ENXIO); + struct snd_emu10k1 *emu = ac97->private_data; unsigned long flags; unsigned short val; @@ -242,9 +371,9 @@ unsigned short snd_emu10k1_ac97_read(ac97_t *ac97, unsigned short reg) return val; } -void snd_emu10k1_ac97_write(ac97_t *ac97, unsigned short reg, unsigned short data) +void snd_emu10k1_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short data) { - emu10k1_t *emu = snd_magic_cast(emu10k1_t, ac97->private_data, return); + struct snd_emu10k1 *emu = ac97->private_data; unsigned long flags; spin_lock_irqsave(&emu->emu_lock, flags); @@ -313,28 +442,3 @@ unsigned int snd_emu10k1_rate_to_pitch(unsigned int rate) return 0; /* Should never reach this point */ } -/* - * Returns an attenuation based upon a cumulative volume value - * Algorithm calculates 0x200 - 0x10 log2 (input) - */ - -unsigned char snd_emu10k1_sum_vol_attn(unsigned int value) -{ - unsigned short count = 16, ans; - - if (value == 0) - return 0xFF; - - /* Find first SET bit. This is the integer part of the value */ - while ((value & 0x10000) == 0) { - value <<= 1; - count--; - } - - /* The REST of the data is the fractional part. */ - ans = (unsigned short) (0x110 - ((count << 4) + ((value & 0x0FFFFL) >> 12))); - if (ans > 0xFF) - ans = 0xFF; - - return (unsigned char) ans; -}