diff options
Diffstat (limited to 'sound/pci/emu10k1')
-rw-r--r-- | sound/pci/emu10k1/Makefile | 2 | ||||
-rw-r--r-- | sound/pci/emu10k1/emu10k1.c | 4 | ||||
-rw-r--r-- | sound/pci/emu10k1/emu10k1_main.c | 130 | ||||
-rw-r--r-- | sound/pci/emu10k1/emu10k1x.c | 9 | ||||
-rw-r--r-- | sound/pci/emu10k1/emufx.c | 251 | ||||
-rw-r--r-- | sound/pci/emu10k1/emumixer.c | 86 | ||||
-rw-r--r-- | sound/pci/emu10k1/emumpu401.c | 2 | ||||
-rw-r--r-- | sound/pci/emu10k1/emupcm.c | 2 | ||||
-rw-r--r-- | sound/pci/emu10k1/emuproc.c | 58 | ||||
-rw-r--r-- | sound/pci/emu10k1/io.c | 12 | ||||
-rw-r--r-- | sound/pci/emu10k1/irq.c | 2 | ||||
-rw-r--r-- | sound/pci/emu10k1/memory.c | 2 | ||||
-rw-r--r-- | sound/pci/emu10k1/p16v.c | 19 | ||||
-rw-r--r-- | sound/pci/emu10k1/voice.c | 2 |
14 files changed, 339 insertions, 242 deletions
diff --git a/sound/pci/emu10k1/Makefile b/sound/pci/emu10k1/Makefile index e521c38cef4..cf2d5636d8b 100644 --- a/sound/pci/emu10k1/Makefile +++ b/sound/pci/emu10k1/Makefile @@ -1,6 +1,6 @@ # # Makefile for ALSA -# Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz> +# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz> # snd-emu10k1-objs := emu10k1.o emu10k1_main.o \ diff --git a/sound/pci/emu10k1/emu10k1.c b/sound/pci/emu10k1/emu10k1.c index 55caf341933..9680caff90c 100644 --- a/sound/pci/emu10k1/emu10k1.c +++ b/sound/pci/emu10k1/emu10k1.c @@ -1,6 +1,6 @@ /* * The driver for the EMU10K1 (SB Live!) based soundcards - * Copyright (c) by Jaroslav Kysela <perex@suse.cz> + * Copyright (c) by Jaroslav Kysela <perex@perex.cz> * * Copyright (c) by James Courtier-Dutton <James@superbug.demon.co.uk> * Added support for Audigy 2 Value. @@ -32,7 +32,7 @@ #include <sound/emu10k1.h> #include <sound/initval.h> -MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>"); +MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>"); MODULE_DESCRIPTION("EMU10K1"); MODULE_LICENSE("GPL"); MODULE_SUPPORTED_DEVICE("{{Creative Labs,SB Live!/PCI512/E-mu APS}," diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c index 404ae1be0a4..97c41d72a25 100644 --- a/sound/pci/emu10k1/emu10k1_main.c +++ b/sound/pci/emu10k1/emu10k1_main.c @@ -1,5 +1,5 @@ /* - * Copyright (c) by Jaroslav Kysela <perex@suse.cz> + * Copyright (c) by Jaroslav Kysela <perex@perex.cz> * Creative Labs, Inc. * Routines for control of EMU10K1 chips * @@ -31,6 +31,8 @@ * */ +#include <linux/sched.h> +#include <linux/kthread.h> #include <sound/driver.h> #include <linux/delay.h> #include <linux/init.h> @@ -702,6 +704,65 @@ static int snd_emu1010_load_firmware(struct snd_emu10k1 * emu, const char * file return 0; } +int emu1010_firmware_thread(void *data) { + struct snd_emu10k1 * emu = data; + int tmp,tmp2; + int reg; + int err; + + for (;;) { + /* Delay to allow Audio Dock to settle */ + msleep(1000); + if (kthread_should_stop()) + break; + snd_emu1010_fpga_read(emu, EMU_HANA_IRQ_STATUS, &tmp ); /* IRQ Status */ + snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, ® ); /* OPTIONS: Which cards are attached to the EMU */ + if (reg & EMU_HANA_OPTION_DOCK_OFFLINE) { + /* Audio Dock attached */ + /* Return to Audio Dock programming mode */ + snd_printk(KERN_INFO "emu1010: Loading Audio Dock Firmware\n"); + snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, EMU_HANA_FPGA_CONFIG_AUDIODOCK ); + if (emu->card_capabilities->emu1010 == 1) { + if ((err = snd_emu1010_load_firmware(emu, DOCK_FILENAME)) != 0) { + return err; + } + } else if (emu->card_capabilities->emu1010 == 2) { + if ((err = snd_emu1010_load_firmware(emu, MICRO_DOCK_FILENAME)) != 0) { + return err; + } + } else if (emu->card_capabilities->emu1010 == 3) { + if ((err = snd_emu1010_load_firmware(emu, MICRO_DOCK_FILENAME)) != 0) { + return err; + } + } + + snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, 0 ); + snd_emu1010_fpga_read(emu, EMU_HANA_IRQ_STATUS, ® ); + snd_printk(KERN_INFO "emu1010: EMU_HANA+DOCK_IRQ_STATUS=0x%x\n",reg); + /* ID, should read & 0x7f = 0x55 when FPGA programmed. */ + snd_emu1010_fpga_read(emu, EMU_HANA_ID, ® ); + snd_printk(KERN_INFO "emu1010: EMU_HANA+DOCK_ID=0x%x\n",reg); + if ((reg & 0x1f) != 0x15) { + /* FPGA failed to be programmed */ + snd_printk(KERN_INFO "emu1010: Loading Audio Dock Firmware file failed, reg=0x%x\n", reg); + return 0; + return -ENODEV; + } + snd_printk(KERN_INFO "emu1010: Audio Dock Firmware loaded\n"); + snd_emu1010_fpga_read(emu, EMU_DOCK_MAJOR_REV, &tmp ); + snd_emu1010_fpga_read(emu, EMU_DOCK_MINOR_REV, &tmp2 ); + snd_printk("Audio Dock ver:%d.%d\n",tmp ,tmp2); + /* Sync clocking between 1010 and Dock */ + /* Allow DLL to settle */ + msleep(10); + /* Unmute all. Default is muted after a firmware load */ + snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_UNMUTE ); + break; + } + } + return 0; +} + /* * EMU-1010 - details found out from this driver, official MS Win drivers, * testing the card: @@ -817,8 +878,16 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu) snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, ® ); snd_printk(KERN_INFO "emu1010: Card options=0x%x\n",reg); snd_emu1010_fpga_read(emu, EMU_HANA_OPTICAL_TYPE, &tmp ); - /* ADAT input. */ - snd_emu1010_fpga_write(emu, EMU_HANA_OPTICAL_TYPE, 0x01 ); + /* Optical -> ADAT I/O */ + /* 0 : SPDIF + * 1 : ADAT + */ + emu->emu1010.optical_in = 1; /* IN_ADAT */ + emu->emu1010.optical_out = 1; /* IN_ADAT */ + tmp = 0; + tmp = (emu->emu1010.optical_in ? EMU_HANA_OPTICAL_IN_ADAT : 0) | + (emu->emu1010.optical_out ? EMU_HANA_OPTICAL_OUT_ADAT : 0); + snd_emu1010_fpga_write(emu, EMU_HANA_OPTICAL_TYPE, tmp ); snd_emu1010_fpga_read(emu, EMU_HANA_ADC_PADS, &tmp ); /* Set no attenuation on Audio Dock pads. */ snd_emu1010_fpga_write(emu, EMU_HANA_ADC_PADS, 0x00 ); @@ -1004,49 +1073,12 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu) snd_emu1010_fpga_read(emu, EMU_HANA_SPDIF_MODE, &tmp ); snd_emu1010_fpga_write(emu, EMU_HANA_SPDIF_MODE, 0x10 ); /* SPDIF Format spdif (or 0x11 for aes/ebu) */ - /* Delay to allow Audio Dock to settle */ - msleep(100); - snd_emu1010_fpga_read(emu, EMU_HANA_IRQ_STATUS, &tmp ); /* IRQ Status */ - snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, ® ); /* OPTIONS: Which cards are attached to the EMU */ - /* FIXME: The loading of this should be able to happen any time, - * as the user can plug/unplug it at any time - */ - if (reg & (EMU_HANA_OPTION_DOCK_ONLINE | EMU_HANA_OPTION_DOCK_OFFLINE) ) { - /* Audio Dock attached */ - /* Return to Audio Dock programming mode */ - snd_printk(KERN_INFO "emu1010: Loading Audio Dock Firmware\n"); - snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, EMU_HANA_FPGA_CONFIG_AUDIODOCK ); - if (emu->card_capabilities->emu1010 == 1) { - if ((err = snd_emu1010_load_firmware(emu, DOCK_FILENAME)) != 0) { - return err; - } - } else if (emu->card_capabilities->emu1010 == 2) { - if ((err = snd_emu1010_load_firmware(emu, MICRO_DOCK_FILENAME)) != 0) { - return err; - } - } else if (emu->card_capabilities->emu1010 == 3) { - if ((err = snd_emu1010_load_firmware(emu, MICRO_DOCK_FILENAME)) != 0) { - return err; - } - } + /* Start Micro/Audio Dock firmware loader thread */ + emu->emu1010.firmware_thread = kthread_create(&emu1010_firmware_thread, + emu, + "emu1010_firmware"); + wake_up_process(emu->emu1010.firmware_thread); - snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, 0 ); - snd_emu1010_fpga_read(emu, EMU_HANA_IRQ_STATUS, ® ); - snd_printk(KERN_INFO "emu1010: EMU_HANA+DOCK_IRQ_STATUS=0x%x\n",reg); - /* ID, should read & 0x7f = 0x55 when FPGA programmed. */ - snd_emu1010_fpga_read(emu, EMU_HANA_ID, ® ); - snd_printk(KERN_INFO "emu1010: EMU_HANA+DOCK_ID=0x%x\n",reg); - if ((reg & 0x3f) != 0x15) { - /* FPGA failed to be programmed */ - snd_printk(KERN_INFO "emu1010: Loading Audio Dock Firmware file failed, reg=0x%x\n", reg); - return 0; - return -ENODEV; - } - snd_printk(KERN_INFO "emu1010: Audio Dock Firmware loaded\n"); - snd_emu1010_fpga_read(emu, EMU_DOCK_MAJOR_REV, &tmp ); - snd_emu1010_fpga_read(emu, EMU_DOCK_MINOR_REV, &tmp2 ); - snd_printk("Audio Dock ver:%d.%d\n",tmp ,tmp2); - } #if 0 snd_emu1010_fpga_link_dst_src_write(emu, EMU_DST_HAMOA_DAC_LEFT1, EMU_SRC_ALICE_EMU32B + 2); /* ALICE2 bus 0xa2 */ @@ -1132,7 +1164,7 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu) emu->emu1010.output_source[23] = 28; /* TEMP: Select SPDIF in/out */ - snd_emu1010_fpga_write(emu, EMU_HANA_OPTICAL_TYPE, 0x0); /* Output spdif */ + //snd_emu1010_fpga_write(emu, EMU_HANA_OPTICAL_TYPE, 0x0); /* Output spdif */ /* TEMP: Select 48kHz SPDIF out */ snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, 0x0); /* Mute all */ @@ -1173,6 +1205,7 @@ static int snd_emu10k1_free(struct snd_emu10k1 *emu) if (emu->card_capabilities->emu1010) { /* Disable 48Volt power to Audio Dock */ snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_PWR, 0 ); + kthread_stop(emu->emu1010.firmware_thread); } if (emu->memhdr) snd_util_memhdr_free(emu->memhdr); @@ -1722,8 +1755,9 @@ int __devinit snd_emu10k1_create(struct snd_card *card, goto error; } - emu->page_ptr_table = (void **)vmalloc(emu->max_cache_pages * sizeof(void*)); - emu->page_addr_table = (unsigned long*)vmalloc(emu->max_cache_pages * sizeof(unsigned long)); + emu->page_ptr_table = vmalloc(emu->max_cache_pages * sizeof(void *)); + emu->page_addr_table = vmalloc(emu->max_cache_pages * + sizeof(unsigned long)); if (emu->page_ptr_table == NULL || emu->page_addr_table == NULL) { err = -ENOMEM; goto error; diff --git a/sound/pci/emu10k1/emu10k1x.c b/sound/pci/emu10k1/emu10k1x.c index e4af7a9b808..1ec7ebaff9e 100644 --- a/sound/pci/emu10k1/emu10k1x.c +++ b/sound/pci/emu10k1/emu10k1x.c @@ -1062,14 +1062,7 @@ static int __devinit snd_emu10k1x_proc_init(struct emu10k1x * emu) return 0; } -static int snd_emu10k1x_shared_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; - uinfo->count = 1; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = 1; - return 0; -} +#define snd_emu10k1x_shared_spdif_info snd_ctl_boolean_mono_info static int snd_emu10k1x_shared_spdif_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) diff --git a/sound/pci/emu10k1/emufx.c b/sound/pci/emu10k1/emufx.c index 7206c0fa06f..9bf1cd59219 100644 --- a/sound/pci/emu10k1/emufx.c +++ b/sound/pci/emu10k1/emufx.c @@ -1,5 +1,5 @@ /* - * Copyright (c) by Jaroslav Kysela <perex@suse.cz> + * Copyright (c) by Jaroslav Kysela <perex@perex.cz> * Creative Labs, Inc. * Routines for effect processor FX8010 * @@ -642,10 +642,8 @@ snd_emu10k1_look_for_ctl(struct snd_emu10k1 *emu, struct snd_ctl_elem_id *id) { struct snd_emu10k1_fx8010_ctl *ctl; struct snd_kcontrol *kcontrol; - struct list_head *list; - - list_for_each(list, &emu->fx8010.gpr_ctl) { - ctl = emu10k1_gpr_ctl(list); + + list_for_each_entry(ctl, &emu->fx8010.gpr_ctl, list) { kcontrol = ctl->kcontrol; if (kcontrol->id.iface == id->iface && !strcmp(kcontrol->id.name, id->name) && @@ -895,14 +893,12 @@ static int snd_emu10k1_list_controls(struct snd_emu10k1 *emu, struct snd_emu10k1_fx8010_control_gpr *gctl; struct snd_emu10k1_fx8010_ctl *ctl; struct snd_ctl_elem_id *id; - struct list_head *list; gctl = kmalloc(sizeof(*gctl), GFP_KERNEL); if (! gctl) return -ENOMEM; - list_for_each(list, &emu->fx8010.gpr_ctl) { - ctl = emu10k1_gpr_ctl(list); + list_for_each_entry(ctl, &emu->fx8010.gpr_ctl, list) { total++; if (icode->gpr_list_controls && i < icode->gpr_list_control_count) { @@ -1207,7 +1203,7 @@ static int __devinit _snd_emu10k1_audigy_init_efx(struct snd_emu10k1 *emu) A_OP(icode, &ptr, iMAC0, A_GPR(playback+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_FRONT)); snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Front Playback Volume", gpr, 100); gpr += 2; - + /* PCM Surround Playback (independent from stereo mix) */ A_OP(icode, &ptr, iMAC0, A_GPR(playback+2), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_REAR)); A_OP(icode, &ptr, iMAC0, A_GPR(playback+3), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_REAR)); @@ -1267,8 +1263,16 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input)) /* emu1212 DSP 0 and DSP 1 Capture */ if (emu->card_capabilities->emu1010) { - A_OP(icode, &ptr, iMAC0, A_GPR(capture+0), A_GPR(capture+0), A_GPR(gpr), A_P16VIN(0x0)); - A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_GPR(capture+1), A_GPR(gpr+1), A_P16VIN(0x1)); + if (emu->card_capabilities->ca0108_chip) { + /* Note:JCD:No longer bit shift lower 16bits to upper 16bits of 32bit value. */ + A_OP(icode, &ptr, iMACINT0, A_GPR(tmp), A_C_00000000, A3_EMU32IN(0x0), A_C_00000001); + A_OP(icode, &ptr, iMAC0, A_GPR(capture+0), A_GPR(capture+0), A_GPR(gpr), A_GPR(tmp)); + A_OP(icode, &ptr, iMACINT0, A_GPR(tmp), A_C_00000000, A3_EMU32IN(0x1), A_C_00000001); + A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_GPR(capture+1), A_GPR(gpr), A_GPR(tmp)); + } else { + A_OP(icode, &ptr, iMAC0, A_GPR(capture+0), A_GPR(capture+0), A_GPR(gpr), A_P16VIN(0x0)); + A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_GPR(capture+1), A_GPR(gpr+1), A_P16VIN(0x1)); + } snd_emu10k1_init_stereo_control(&controls[nctl++], "EMU Capture Volume", gpr, 0); gpr += 2; } @@ -1516,7 +1520,11 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input)) /* EMU1010 Outputs from PCM Front, Rear, Center, LFE, Side */ snd_printk("EMU outputs on\n"); for (z = 0; z < 8; z++) { - A_OP(icode, &ptr, iACC3, A_EMU32OUTL(z), A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), A_C_00000000, A_C_00000000); + if (emu->card_capabilities->ca0108_chip) { + A_OP(icode, &ptr, iACC3, A3_EMU32OUT(z), A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), A_C_00000000, A_C_00000000); + } else { + A_OP(icode, &ptr, iACC3, A_EMU32OUTL(z), A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), A_C_00000000, A_C_00000000); + } } } @@ -1557,106 +1565,116 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input)) #endif if (emu->card_capabilities->emu1010) { - snd_printk("EMU inputs on\n"); - /* Capture 16 (originally 8) channels of S32_LE sound */ - - /* printk("emufx.c: gpr=0x%x, tmp=0x%x\n",gpr, tmp); */ - /* For the EMU1010: How to get 32bit values from the DSP. High 16bits into L, low 16bits into R. */ - /* A_P16VIN(0) is delayed by one sample, - * so all other A_P16VIN channels will need to also be delayed - */ - /* Left ADC in. 1 of 2 */ - snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_P16VIN(0x0), A_FXBUS2(0) ); - /* Right ADC in 1 of 2 */ - gpr_map[gpr++] = 0x00000000; - /* Delaying by one sample: instead of copying the input - * value A_P16VIN to output A_FXBUS2 as in the first channel, - * we use an auxiliary register, delaying the value by one - * sample - */ - snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(2) ); - A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x1), A_C_00000000, A_C_00000000); - gpr_map[gpr++] = 0x00000000; - snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(4) ); - A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x2), A_C_00000000, A_C_00000000); - gpr_map[gpr++] = 0x00000000; - snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(6) ); - A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x3), A_C_00000000, A_C_00000000); - /* For 96kHz mode */ - /* Left ADC in. 2 of 2 */ - gpr_map[gpr++] = 0x00000000; - snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(0x8) ); - A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x4), A_C_00000000, A_C_00000000); - /* Right ADC in 2 of 2 */ - gpr_map[gpr++] = 0x00000000; - snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(0xa) ); - A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x5), A_C_00000000, A_C_00000000); - gpr_map[gpr++] = 0x00000000; - snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(0xc) ); - A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x6), A_C_00000000, A_C_00000000); - gpr_map[gpr++] = 0x00000000; - snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(0xe) ); - A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x7), A_C_00000000, A_C_00000000); - /* Pavel Hofman - we still have voices, A_FXBUS2s, and - * A_P16VINs available - - * let's add 8 more capture channels - total of 16 - */ - gpr_map[gpr++] = 0x00000000; - snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp, - bit_shifter16, - A_GPR(gpr - 1), - A_FXBUS2(0x10)); - A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x8), - A_C_00000000, A_C_00000000); - gpr_map[gpr++] = 0x00000000; - snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp, - bit_shifter16, - A_GPR(gpr - 1), - A_FXBUS2(0x12)); - A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x9), - A_C_00000000, A_C_00000000); - gpr_map[gpr++] = 0x00000000; - snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp, - bit_shifter16, - A_GPR(gpr - 1), - A_FXBUS2(0x14)); - A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xa), - A_C_00000000, A_C_00000000); - gpr_map[gpr++] = 0x00000000; - snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp, - bit_shifter16, - A_GPR(gpr - 1), - A_FXBUS2(0x16)); - A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xb), - A_C_00000000, A_C_00000000); - gpr_map[gpr++] = 0x00000000; - snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp, - bit_shifter16, - A_GPR(gpr - 1), - A_FXBUS2(0x18)); - A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xc), - A_C_00000000, A_C_00000000); - gpr_map[gpr++] = 0x00000000; - snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp, - bit_shifter16, - A_GPR(gpr - 1), - A_FXBUS2(0x1a)); - A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xd), - A_C_00000000, A_C_00000000); - gpr_map[gpr++] = 0x00000000; - snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp, - bit_shifter16, - A_GPR(gpr - 1), - A_FXBUS2(0x1c)); - A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xe), - A_C_00000000, A_C_00000000); - gpr_map[gpr++] = 0x00000000; - snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp, - bit_shifter16, - A_GPR(gpr - 1), - A_FXBUS2(0x1e)); - A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xf), - A_C_00000000, A_C_00000000); + if (emu->card_capabilities->ca0108_chip) { + snd_printk("EMU2 inputs on\n"); + for (z = 0; z < 0x10; z++) { + snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, + bit_shifter16, + A3_EMU32IN(z), + A_FXBUS2(z*2) ); + } + } else { + snd_printk("EMU inputs on\n"); + /* Capture 16 (originally 8) channels of S32_LE sound */ + + /* printk("emufx.c: gpr=0x%x, tmp=0x%x\n",gpr, tmp); */ + /* For the EMU1010: How to get 32bit values from the DSP. High 16bits into L, low 16bits into R. */ + /* A_P16VIN(0) is delayed by one sample, + * so all other A_P16VIN channels will need to also be delayed + */ + /* Left ADC in. 1 of 2 */ + snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_P16VIN(0x0), A_FXBUS2(0) ); + /* Right ADC in 1 of 2 */ + gpr_map[gpr++] = 0x00000000; + /* Delaying by one sample: instead of copying the input + * value A_P16VIN to output A_FXBUS2 as in the first channel, + * we use an auxiliary register, delaying the value by one + * sample + */ + snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(2) ); + A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x1), A_C_00000000, A_C_00000000); + gpr_map[gpr++] = 0x00000000; + snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(4) ); + A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x2), A_C_00000000, A_C_00000000); + gpr_map[gpr++] = 0x00000000; + snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(6) ); + A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x3), A_C_00000000, A_C_00000000); + /* For 96kHz mode */ + /* Left ADC in. 2 of 2 */ + gpr_map[gpr++] = 0x00000000; + snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(0x8) ); + A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x4), A_C_00000000, A_C_00000000); + /* Right ADC in 2 of 2 */ + gpr_map[gpr++] = 0x00000000; + snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(0xa) ); + A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x5), A_C_00000000, A_C_00000000); + gpr_map[gpr++] = 0x00000000; + snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(0xc) ); + A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x6), A_C_00000000, A_C_00000000); + gpr_map[gpr++] = 0x00000000; + snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(0xe) ); + A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x7), A_C_00000000, A_C_00000000); + /* Pavel Hofman - we still have voices, A_FXBUS2s, and + * A_P16VINs available - + * let's add 8 more capture channels - total of 16 + */ + gpr_map[gpr++] = 0x00000000; + snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp, + bit_shifter16, + A_GPR(gpr - 1), + A_FXBUS2(0x10)); + A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x8), + A_C_00000000, A_C_00000000); + gpr_map[gpr++] = 0x00000000; + snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp, + bit_shifter16, + A_GPR(gpr - 1), + A_FXBUS2(0x12)); + A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x9), + A_C_00000000, A_C_00000000); + gpr_map[gpr++] = 0x00000000; + snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp, + bit_shifter16, + A_GPR(gpr - 1), + A_FXBUS2(0x14)); + A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xa), + A_C_00000000, A_C_00000000); + gpr_map[gpr++] = 0x00000000; + snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp, + bit_shifter16, + A_GPR(gpr - 1), + A_FXBUS2(0x16)); + A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xb), + A_C_00000000, A_C_00000000); + gpr_map[gpr++] = 0x00000000; + snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp, + bit_shifter16, + A_GPR(gpr - 1), + A_FXBUS2(0x18)); + A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xc), + A_C_00000000, A_C_00000000); + gpr_map[gpr++] = 0x00000000; + snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp, + bit_shifter16, + A_GPR(gpr - 1), + A_FXBUS2(0x1a)); + A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xd), + A_C_00000000, A_C_00000000); + gpr_map[gpr++] = 0x00000000; + snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp, + bit_shifter16, + A_GPR(gpr - 1), + A_FXBUS2(0x1c)); + A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xe), + A_C_00000000, A_C_00000000); + gpr_map[gpr++] = 0x00000000; + snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp, + bit_shifter16, + A_GPR(gpr - 1), + A_FXBUS2(0x1e)); + A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xf), + A_C_00000000, A_C_00000000); + } #if 0 for (z = 4; z < 8; z++) { @@ -2418,14 +2436,13 @@ static void copy_string(char *dst, char *src, char *null, int idx) strcpy(dst, src); } -static int snd_emu10k1_fx8010_info(struct snd_emu10k1 *emu, +static void snd_emu10k1_fx8010_info(struct snd_emu10k1 *emu, struct snd_emu10k1_fx8010_info *info) { char **fxbus, **extin, **extout; unsigned short fxbus_mask, extin_mask, extout_mask; int res; - memset(info, 0, sizeof(info)); info->internal_tram_size = emu->fx8010.itram_size; info->external_tram_size = emu->fx8010.etram_pages.bytes / 2; fxbus = fxbuses; @@ -2442,7 +2459,6 @@ static int snd_emu10k1_fx8010_info(struct snd_emu10k1 *emu, for (res = 16; res < 32; res++, extout++) copy_string(info->extout_names[res], extout_mask & (1 << res) ? *extout : NULL, "Unused", res); info->gpr_controls = emu->fx8010.gpr_count; - return 0; } static int snd_emu10k1_fx8010_ioctl(struct snd_hwdep * hw, struct file *file, unsigned int cmd, unsigned long arg) @@ -2463,10 +2479,7 @@ static int snd_emu10k1_fx8010_ioctl(struct snd_hwdep * hw, struct file *file, un info = kmalloc(sizeof(*info), GFP_KERNEL); if (!info) return -ENOMEM; - if ((res = snd_emu10k1_fx8010_info(emu, info)) < 0) { - kfree(info); - return res; - } + snd_emu10k1_fx8010_info(emu, info); if (copy_to_user(argp, info, sizeof(*info))) { kfree(info); return -EFAULT; diff --git a/sound/pci/emu10k1/emumixer.c b/sound/pci/emu10k1/emumixer.c index 7b2c1dcc533..54a2034d8ed 100644 --- a/sound/pci/emu10k1/emumixer.c +++ b/sound/pci/emu10k1/emumixer.c @@ -1,5 +1,5 @@ /* - * Copyright (c) by Jaroslav Kysela <perex@suse.cz>, + * Copyright (c) by Jaroslav Kysela <perex@perex.cz>, * Takashi Iwai <tiwai@suse.de> * Creative Labs, Inc. * Routines for control of EMU10K1 chips / mixer routines @@ -400,15 +400,7 @@ static struct snd_kcontrol_new snd_emu1010_input_enum_ctls[] __devinitdata = { - -static int snd_emu1010_adc_pads_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; - uinfo->count = 1; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = 1; - return 0; -} +#define snd_emu1010_adc_pads_info snd_ctl_boolean_mono_info static int snd_emu1010_adc_pads_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -456,14 +448,7 @@ static struct snd_kcontrol_new snd_emu1010_adc_pads[] __devinitdata = { EMU1010_ADC_PADS("ADC1 14dB PAD 0202 Capture Switch", EMU_HANA_0202_ADC_PAD1), }; -static int snd_emu1010_dac_pads_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; - uinfo->count = 1; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = 1; - return 0; -} +#define snd_emu1010_dac_pads_info snd_ctl_boolean_mono_info static int snd_emu1010_dac_pads_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -516,17 +501,19 @@ static struct snd_kcontrol_new snd_emu1010_dac_pads[] __devinitdata = { static int snd_emu1010_internal_clock_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static char *texts[2] = { - "44100", "48000" + static char *texts[4] = { + "44100", "48000", "SPDIF", "ADAT" }; - + uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; uinfo->count = 1; - uinfo->value.enumerated.items = 2; - if (uinfo->value.enumerated.item > 1) - uinfo->value.enumerated.item = 1; + uinfo->value.enumerated.items = 4; + if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) + uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); return 0; + + } static int snd_emu1010_internal_clock_get(struct snd_kcontrol *kcontrol, @@ -584,6 +571,44 @@ static int snd_emu1010_internal_clock_put(struct snd_kcontrol *kcontrol, /* Unmute all */ snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_UNMUTE ); break; + + case 2: /* Take clock from S/PDIF IN */ + /* Mute all */ + snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_MUTE ); + /* Default fallback clock 48kHz */ + snd_emu1010_fpga_write(emu, EMU_HANA_DEFCLOCK, EMU_HANA_DEFCLOCK_48K ); + /* Word Clock source, sync to S/PDIF input */ + snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK, + EMU_HANA_WCLOCK_HANA_SPDIF_IN | EMU_HANA_WCLOCK_1X ); + /* Set LEDs on Audio Dock */ + snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_LEDS_2, + EMU_HANA_DOCK_LEDS_2_EXT | EMU_HANA_DOCK_LEDS_2_LOCK ); + /* FIXME: We should set EMU_HANA_DOCK_LEDS_2_LOCK only when clock signal is present and valid */ + /* Allow DLL to settle */ + msleep(10); + /* Unmute all */ + snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_UNMUTE ); + break; + + case 3: + /* Take clock from ADAT IN */ + /* Mute all */ + snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_MUTE ); + /* Default fallback clock 48kHz */ + snd_emu1010_fpga_write(emu, EMU_HANA_DEFCLOCK, EMU_HANA_DEFCLOCK_48K ); + /* Word Clock source, sync to ADAT input */ + snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK, + EMU_HANA_WCLOCK_HANA_ADAT_IN | EMU_HANA_WCLOCK_1X ); + /* Set LEDs on Audio Dock */ + snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_LEDS_2, EMU_HANA_DOCK_LEDS_2_EXT | EMU_HANA_DOCK_LEDS_2_LOCK ); + /* FIXME: We should set EMU_HANA_DOCK_LEDS_2_LOCK only when clock signal is present and valid */ + /* Allow DLL to settle */ + msleep(10); + /* Unmute all */ + snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_UNMUTE ); + + + break; } } return change; @@ -871,7 +896,7 @@ static struct snd_kcontrol_new snd_emu10k1_spdif_mask_control = .access = SNDRV_CTL_ELEM_ACCESS_READ, .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK), - .count = 4, + .count = 3, .info = snd_emu10k1_spdif_info, .get = snd_emu10k1_spdif_get_mask }; @@ -880,7 +905,7 @@ static struct snd_kcontrol_new snd_emu10k1_spdif_control = { .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), - .count = 4, + .count = 3, .info = snd_emu10k1_spdif_info, .get = snd_emu10k1_spdif_get, .put = snd_emu10k1_spdif_put @@ -1326,14 +1351,7 @@ static struct snd_kcontrol_new snd_emu10k1_efx_attn_control = .put = snd_emu10k1_efx_attn_put }; -static int snd_emu10k1_shared_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; - uinfo->count = 1; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = 1; - return 0; -} +#define snd_emu10k1_shared_spdif_info snd_ctl_boolean_mono_info static int snd_emu10k1_shared_spdif_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) diff --git a/sound/pci/emu10k1/emumpu401.c b/sound/pci/emu10k1/emumpu401.c index 950c6bcd6b7..04c7cf70353 100644 --- a/sound/pci/emu10k1/emumpu401.c +++ b/sound/pci/emu10k1/emumpu401.c @@ -1,5 +1,5 @@ /* - * Copyright (c) by Jaroslav Kysela <perex@suse.cz> + * Copyright (c) by Jaroslav Kysela <perex@perex.cz> * Routines for control of EMU10K1 MPU-401 in UART mode * * diff --git a/sound/pci/emu10k1/emupcm.c b/sound/pci/emu10k1/emupcm.c index eda5cb373de..5ce5befc701 100644 --- a/sound/pci/emu10k1/emupcm.c +++ b/sound/pci/emu10k1/emupcm.c @@ -1,5 +1,5 @@ /* - * Copyright (c) by Jaroslav Kysela <perex@suse.cz> + * Copyright (c) by Jaroslav Kysela <perex@perex.cz> * Creative Labs, Inc. * Routines for control of EMU10K1 chips / PCM routines * Multichannel PCM support Copyright (c) Lee Revell <rlrevell@joe-job.com> diff --git a/sound/pci/emu10k1/emuproc.c b/sound/pci/emu10k1/emuproc.c index 2c1585991bc..c3fb10e81c9 100644 --- a/sound/pci/emu10k1/emuproc.c +++ b/sound/pci/emu10k1/emuproc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) by Jaroslav Kysela <perex@suse.cz> + * Copyright (c) by Jaroslav Kysela <perex@perex.cz> * Creative Labs, Inc. * Routines for control of EMU10K1 chips / proc interface routines * @@ -240,8 +240,42 @@ static void snd_emu10k1_proc_spdif_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer) { struct snd_emu10k1 *emu = entry->private_data; - snd_emu10k1_proc_spdif_status(emu, buffer, "CD-ROM S/PDIF In", CDCS, CDSRCS); - snd_emu10k1_proc_spdif_status(emu, buffer, "Optical or Coax S/PDIF In", GPSCS, GPSRCS); + u32 value; + u32 value2; + unsigned long flags; + u32 rate; + + if (emu->card_capabilities->emu1010) { + spin_lock_irqsave(&emu->emu_lock, flags); + snd_emu1010_fpga_read(emu, 0x38, &value); + spin_unlock_irqrestore(&emu->emu_lock, flags); + if ((value & 0x1) == 0) { + spin_lock_irqsave(&emu->emu_lock, flags); + snd_emu1010_fpga_read(emu, 0x2a, &value); + snd_emu1010_fpga_read(emu, 0x2b, &value2); + spin_unlock_irqrestore(&emu->emu_lock, flags); + rate = 0x1770000 / (((value << 5) | value2)+1); + snd_iprintf(buffer, "ADAT Locked : %u\n", rate); + } else { + snd_iprintf(buffer, "ADAT Unlocked\n"); + } + spin_lock_irqsave(&emu->emu_lock, flags); + snd_emu1010_fpga_read(emu, 0x20, &value); + spin_unlock_irqrestore(&emu->emu_lock, flags); + if ((value & 0x4) == 0) { + spin_lock_irqsave(&emu->emu_lock, flags); + snd_emu1010_fpga_read(emu, 0x28, &value); + snd_emu1010_fpga_read(emu, 0x29, &value2); + spin_unlock_irqrestore(&emu->emu_lock, flags); + rate = 0x1770000 / (((value << 5) | value2)+1); + snd_iprintf(buffer, "SPDIF Locked : %d\n", rate); + } else { + snd_iprintf(buffer, "SPDIF Unlocked\n"); + } + } else { + snd_emu10k1_proc_spdif_status(emu, buffer, "CD-ROM S/PDIF In", CDCS, CDSRCS); + snd_emu10k1_proc_spdif_status(emu, buffer, "Optical or Coax S/PDIF In", GPSCS, GPSRCS); + } #if 0 val = snd_emu10k1_ptr_read(emu, ZVSRCS, 0); snd_iprintf(buffer, "\nZoomed Video\n"); @@ -379,20 +413,16 @@ static void snd_emu_proc_emu1010_reg_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer) { struct snd_emu10k1 *emu = entry->private_data; - unsigned long value; + int value; unsigned long flags; - unsigned long regs; int i; snd_iprintf(buffer, "EMU1010 Registers:\n\n"); - for(i = 0; i < 0x30; i+=1) { + for(i = 0; i < 0x40; i+=1) { spin_lock_irqsave(&emu->emu_lock, flags); - regs=i+0x40; /* 0x40 upwards are registers. */ - outl(regs, emu->port + A_IOCFG); - outl(regs | 0x80, emu->port + A_IOCFG); /* High bit clocks the value into the fpga. */ - value = inl(emu->port + A_IOCFG); + snd_emu1010_fpga_read(emu, i, &value); spin_unlock_irqrestore(&emu->emu_lock, flags); - snd_iprintf(buffer, "%02X: %08lX, %02lX\n", i, value, (value >> 8) & 0x7f); + snd_iprintf(buffer, "%02X: %08X, %02X\n", i, value, (value >> 8) & 0x7f); } } @@ -555,9 +585,9 @@ int __devinit snd_emu10k1_proc_init(struct snd_emu10k1 * emu) { struct snd_info_entry *entry; #ifdef CONFIG_SND_DEBUG - if ((emu->card_capabilities->emu1010) && - snd_card_proc_new(emu->card, "emu1010_regs", &entry)) { - snd_info_set_text_ops(entry, emu, snd_emu_proc_emu1010_reg_read); + if (emu->card_capabilities->emu1010) { + if (! snd_card_proc_new(emu->card, "emu1010_regs", &entry)) + snd_info_set_text_ops(entry, emu, snd_emu_proc_emu1010_reg_read); } if (! snd_card_proc_new(emu->card, "io_regs", &entry)) { snd_info_set_text_ops(entry, emu, snd_emu_proc_io_reg_read); diff --git a/sound/pci/emu10k1/io.c b/sound/pci/emu10k1/io.c index 116e1c8d936..6702c15fefa 100644 --- a/sound/pci/emu10k1/io.c +++ b/sound/pci/emu10k1/io.c @@ -1,5 +1,5 @@ /* - * Copyright (c) by Jaroslav Kysela <perex@suse.cz> + * Copyright (c) by Jaroslav Kysela <perex@perex.cz> * Creative Labs, Inc. * Routines for control of EMU10K1 chips * @@ -226,9 +226,9 @@ int snd_emu10k1_i2c_write(struct snd_emu10k1 *emu, return 0; } -int snd_emu1010_fpga_write(struct snd_emu10k1 * emu, int reg, int value) +int snd_emu1010_fpga_write(struct snd_emu10k1 * emu, u32 reg, u32 value) { - if (reg < 0 || reg > 0x3f) + if (reg > 0x3f) return 1; reg += 0x40; /* 0x40 upwards are registers. */ if (value < 0 || value > 0x3f) /* 0 to 0x3f are values */ @@ -244,9 +244,9 @@ int snd_emu1010_fpga_write(struct snd_emu10k1 * emu, int reg, int value) return 0; } -int snd_emu1010_fpga_read(struct snd_emu10k1 * emu, int reg, int *value) +int snd_emu1010_fpga_read(struct snd_emu10k1 * emu, u32 reg, u32 *value) { - if (reg < 0 || reg > 0x3f) + if (reg > 0x3f) return 1; reg += 0x40; /* 0x40 upwards are registers. */ outl(reg, emu->port + A_IOCFG); @@ -261,7 +261,7 @@ int snd_emu1010_fpga_read(struct snd_emu10k1 * emu, int reg, int *value) /* Each Destination has one and only one Source, * but one Source can feed any number of Destinations simultaneously. */ -int snd_emu1010_fpga_link_dst_src_write(struct snd_emu10k1 * emu, int dst, int src) +int snd_emu1010_fpga_link_dst_src_write(struct snd_emu10k1 * emu, u32 dst, u32 src) { snd_emu1010_fpga_write(emu, 0x00, ((dst >> 8) & 0x3f) ); snd_emu1010_fpga_write(emu, 0x01, (dst & 0x3f) ); diff --git a/sound/pci/emu10k1/irq.c b/sound/pci/emu10k1/irq.c index 4f18f7e8bcf..3c114b45e0b 100644 --- a/sound/pci/emu10k1/irq.c +++ b/sound/pci/emu10k1/irq.c @@ -1,5 +1,5 @@ /* - * Copyright (c) by Jaroslav Kysela <perex@suse.cz> + * Copyright (c) by Jaroslav Kysela <perex@perex.cz> * Creative Labs, Inc. * Routines for IRQ control of EMU10K1 chips * diff --git a/sound/pci/emu10k1/memory.c b/sound/pci/emu10k1/memory.c index 4fcaefe5a3c..48097c6bb15 100644 --- a/sound/pci/emu10k1/memory.c +++ b/sound/pci/emu10k1/memory.c @@ -1,5 +1,5 @@ /* - * Copyright (c) by Jaroslav Kysela <perex@suse.cz> + * Copyright (c) by Jaroslav Kysela <perex@perex.cz> * Copyright (c) by Takashi Iwai <tiwai@suse.de> * * EMU10K1 memory page allocation (PTB area) diff --git a/sound/pci/emu10k1/p16v.c b/sound/pci/emu10k1/p16v.c index 7ee19c63c2c..d619a3842cd 100644 --- a/sound/pci/emu10k1/p16v.c +++ b/sound/pci/emu10k1/p16v.c @@ -124,11 +124,12 @@ /* hardware definition */ static struct snd_pcm_hardware snd_p16v_playback_hw = { - .info = (SNDRV_PCM_INFO_MMAP | - SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_BLOCK_TRANSFER | - SNDRV_PCM_INFO_RESUME | - SNDRV_PCM_INFO_MMAP_VALID), + .info = SNDRV_PCM_INFO_MMAP | + SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_BLOCK_TRANSFER | + SNDRV_PCM_INFO_RESUME | + SNDRV_PCM_INFO_MMAP_VALID | + SNDRV_PCM_INFO_SYNC_START, .formats = SNDRV_PCM_FMTBIT_S32_LE, /* Only supports 24-bit samples padded to 32 bits. */ .rates = SNDRV_PCM_RATE_192000 | SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_44100, .rate_min = 44100, @@ -207,6 +208,11 @@ static int snd_p16v_pcm_open_playback_channel(struct snd_pcm_substream *substrea if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0) return err; + runtime->sync.id32[0] = substream->pcm->card->number; + runtime->sync.id32[1] = 'P'; + runtime->sync.id32[2] = 16; + runtime->sync.id32[3] = 'V'; + return 0; } /* open_capture callback */ @@ -448,6 +454,9 @@ static int snd_p16v_pcm_trigger_playback(struct snd_pcm_substream *substream, break; } snd_pcm_group_for_each_entry(s, substream) { + if (snd_pcm_substream_chip(s) != emu || + s->stream != SNDRV_PCM_STREAM_PLAYBACK) + continue; runtime = s->runtime; epcm = runtime->private_data; channel = substream->pcm->device-emu->p16v_device_offset; diff --git a/sound/pci/emu10k1/voice.c b/sound/pci/emu10k1/voice.c index 1db50fe6147..04fa8492abb 100644 --- a/sound/pci/emu10k1/voice.c +++ b/sound/pci/emu10k1/voice.c @@ -1,5 +1,5 @@ /* - * Copyright (c) by Jaroslav Kysela <perex@suse.cz> + * Copyright (c) by Jaroslav Kysela <perex@perex.cz> * Creative Labs, Inc. * Lee Revell <rlrevell@joe-job.com> * Routines for control of EMU10K1 chips - voice manager |