GIT c2c962969e12be6061c8ee899782434e256dccb2 git+ssh://master.kernel.org/pub/scm/linux/kernel/git/perex/alsa-current.git commit c2c962969e12be6061c8ee899782434e256dccb2 Author: Eric Sesterhenn Date: Wed Apr 12 11:58:21 2006 +0200 [ALSA] Memory leak in sound/pcmcia/pdaudiocf/pdaudiocf.c Modules: PDAudioCF driver if one of the first three CS_CHECKS fails, we goto cs_failed: In this case parse we donr kfree() parse. Since the the last three CS_CHECKS might also fail, i moved the kfree() below all the CS_CHECKs and added one in the error path. This fixes coverity bug id #1099 Signed-off-by: Eric Sesterhenn Signed-off-by: Takashi Iwai commit 6a8d829b397669c6071d4f82700ceef00d976311 Author: Takashi Iwai Date: Wed Apr 12 11:57:45 2006 +0200 [ALSA] vxpocket - Fix a typo Modules: Digigram VX Pocket driver Fix a typo of return value from vxpocket_config(). Signed-off-by: Takashi Iwai commit a680b707d9c75dca5bd44ee94e4947ce5ce69672 Author: James Courtier-Dutton Date: Tue Apr 11 21:46:47 2006 +0200 [ALSA] AC97: correct Mic Boost label. Modules: AC97 Codec Signed-off-by: James Courtier-Dutton commit a910fc03f41907a6e8072d1f507f35e5f9b2725a Author: James Courtier-Dutton Date: Sun Apr 9 20:46:09 2006 +0200 [ALSA] ca0106: Fixed alsa bug#1331 Modules: CA0106 driver Fix MSI K8N's SB Live 24 bit, no sound from line-in. Signed-off-by: James Courtier-Dutton commit caaa2388e4406fb0e6f58d9dfbaeed9de64b2590 Author: James Courtier-Dutton Date: Sun Apr 9 17:43:16 2006 +0200 [ALSA] emu10k1: Add p17v.h file. Modules: EMU10K1/EMU10K2 driver Signed-off-by: James Courtier-Dutton commit 38506adeff29479d12c8957a9a18663feadce410 Author: James Courtier-Dutton Date: Sun Apr 9 17:34:50 2006 +0200 [ALSA] emu10k1: Added support for Audigy 4 (not Pro) Modules: EMU10K1/EMU10K2 driver,AC97 Codec Signed-off-by: James Courtier-Dutton commit a94d11cf6a7301cdb8b7fb55ee24972706490bd1 Author: James Courtier-Dutton Date: Sun Apr 9 12:46:52 2006 +0200 [ALSA] ca0106 Add Analog capture controls Modules: CA0106 driver Signed-off-by: James Courtier-Dutton --- diff --git a/include/sound/emu10k1.h b/include/sound/emu10k1.h index 186e00a..884bbf5 100644 --- a/include/sound/emu10k1.h +++ b/include/sound/emu10k1.h @@ -245,6 +245,7 @@ #define A_IOCFG_GPOUT0 0x0044 /* analog/digital */ #define A_IOCFG_DISABLE_ANALOG 0x0040 /* = 'enable' for Audigy2 (chiprev=4) */ #define A_IOCFG_ENABLE_DIGITAL 0x0004 +#define A_IOCFG_ENABLE_DIGITAL_AUDIGY4 0x0080 #define A_IOCFG_UNKNOWN_20 0x0020 #define A_IOCFG_DISABLE_AC97_FRONT 0x0080 /* turn off ac97 front -> front (10k2.1) */ #define A_IOCFG_GPOUT1 0x0002 /* IR? drive's internal bypass (?) */ @@ -1065,6 +1066,7 @@ struct snd_emu_chip_details { unsigned char emu1212m; /* EMU 1212m card */ unsigned char spi_dac; /* SPI interface for DAC */ unsigned char i2c_adc; /* I2C interface for ADC */ + unsigned char adc_1361t; /* Use Philips 1361T ADC */ const char *driver; const char *name; const char *id; /* for backward compatibility - can be NULL if not needed */ diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c index d052007..6c1937f 100644 --- a/sound/pci/ac97/ac97_codec.c +++ b/sound/pci/ac97/ac97_codec.c @@ -563,7 +563,7 @@ AC97_SINGLE("PC Speaker Playback Volume" }; static const struct snd_kcontrol_new snd_ac97_controls_mic_boost = - AC97_SINGLE("Mic Boost (+20dB)", AC97_MIC, 6, 1, 0); + AC97_SINGLE("Mic Boost (+20dB) Switch", AC97_MIC, 6, 1, 0); static const char* std_rec_sel[] = {"Mic", "CD", "Video", "Aux", "Line", "Mix", "Mix Mono", "Phone"}; @@ -605,7 +605,7 @@ AC97_SINGLE("Simulated Stereo Enhancemen AC97_SINGLE("3D Control - Switch", AC97_GENERAL_PURPOSE, 13, 1, 0), AC97_SINGLE("Loudness (bass boost)", AC97_GENERAL_PURPOSE, 12, 1, 0), AC97_ENUM("Mono Output Select", std_enum[2]), -AC97_ENUM("Mic Select", std_enum[3]), +AC97_ENUM("Mic Select Capture Switch", std_enum[3]), AC97_SINGLE("ADC/DAC Loopback", AC97_GENERAL_PURPOSE, 7, 1, 0) }; diff --git a/sound/pci/ca0106/ca0106.h b/sound/pci/ca0106/ca0106.h index c8131ea..9cb66c5 100644 --- a/sound/pci/ca0106/ca0106.h +++ b/sound/pci/ca0106/ca0106.h @@ -537,9 +537,9 @@ #endif #define ADC_MUX_MASK 0x0000000f //Mask for ADC Mux +#define ADC_MUX_PHONE 0x00000001 //Value to select TAD at ADC Mux (Not used) #define ADC_MUX_MIC 0x00000002 //Value to select Mic at ADC Mux #define ADC_MUX_LINEIN 0x00000004 //Value to select LineIn at ADC Mux -#define ADC_MUX_PHONE 0x00000001 //Value to select TAD at ADC Mux (Not used) #define ADC_MUX_AUX 0x00000008 //Value to select Aux at ADC Mux #define SET_CHANNEL 0 /* Testing channel outputs 0=Front, 1=Center/LFE, 2=Unknown, 3=Rear */ @@ -604,6 +604,8 @@ struct snd_ca0106 { u32 spdif_bits[4]; /* s/pdif out setup */ int spdif_enable; int capture_source; + int i2c_capture_source; + u8 i2c_capture_volume[4][2]; int capture_mic_line_in; struct snd_dma_buffer buffer; diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c index 9477838..bdbd969 100644 --- a/sound/pci/ca0106/ca0106_main.c +++ b/sound/pci/ca0106/ca0106_main.c @@ -195,9 +195,14 @@ static struct snd_ca0106_details ca0106_ .i2c_adc = 1, .spi_dac = 1 } , /* MSI K8N Diamond Motherboard with onboard SB Live 24bit without AC97 */ + /* SB0438 + * CTRL:CA0106-DAT + * ADC: WM8775SEDS + * DAC: CS4382-KQZ + */ { .serial = 0x10091462, .name = "MSI K8N Diamond MB [SB0438]", - .gpio_type = 1, + .gpio_type = 2, .i2c_adc = 1 } , /* Shuttle XPC SD31P which has an onboard Creative Labs * Sound Blaster Live! 24-bit EAX @@ -326,6 +331,7 @@ int snd_ca0106_spi_write(struct snd_ca01 return 0; } +/* The ADC does not support i2c read, so only write is implemented */ int snd_ca0106_i2c_write(struct snd_ca0106 *emu, u32 reg, u32 value) @@ -340,6 +346,7 @@ int snd_ca0106_i2c_write(struct snd_ca01 } tmp = reg << 25 | value << 16; + // snd_printk("I2C-write:reg=0x%x, value=0x%x\n", reg, value); /* Not sure what this I2C channel controls. */ /* snd_ca0106_ptr_write(emu, I2C_D0, 0, tmp); */ @@ -348,8 +355,9 @@ int snd_ca0106_i2c_write(struct snd_ca01 for (retry = 0; retry < 10; retry++) { /* Send the data to i2c */ - tmp = snd_ca0106_ptr_read(emu, I2C_A, 0); - tmp = tmp & ~(I2C_A_ADC_READ|I2C_A_ADC_LAST|I2C_A_ADC_START|I2C_A_ADC_ADD_MASK); + //tmp = snd_ca0106_ptr_read(emu, I2C_A, 0); + //tmp = tmp & ~(I2C_A_ADC_READ|I2C_A_ADC_LAST|I2C_A_ADC_START|I2C_A_ADC_ADD_MASK); + tmp = 0; tmp = tmp | (I2C_A_ADC_LAST|I2C_A_ADC_START|I2C_A_ADC_ADD); snd_ca0106_ptr_write(emu, I2C_A, 0, tmp); @@ -1200,6 +1208,22 @@ static unsigned int spi_dac_init[] = { 0x1400, }; +static unsigned int i2c_adc_init[][2] = { + { 0x17, 0x00 }, /* Reset */ + { 0x07, 0x00 }, /* Timeout */ + { 0x0b, 0x22 }, /* Interface control */ + { 0x0c, 0x22 }, /* Master mode control */ + { 0x0d, 0x08 }, /* Powerdown control */ + { 0x0e, 0xcf }, /* Attenuation Left 0x01 = -103dB, 0xff = 24dB */ + { 0x0f, 0xcf }, /* Attenuation Right 0.5dB steps */ + { 0x10, 0x7b }, /* ALC Control 1 */ + { 0x11, 0x00 }, /* ALC Control 2 */ + { 0x12, 0x32 }, /* ALC Control 3 */ + { 0x13, 0x00 }, /* Noise gate control */ + { 0x14, 0xa6 }, /* Limiter control */ + { 0x15, ADC_MUX_LINEIN }, /* ADC Mixer control */ +}; + static int __devinit snd_ca0106_create(struct snd_card *card, struct pci_dev *pci, struct snd_ca0106 **rchip) @@ -1361,7 +1385,12 @@ static int __devinit snd_ca0106_create(s snd_ca0106_ptr_write(chip, CAPTURE_SOURCE, 0x0, 0x333300e4); /* Select MIC, Line in, TAD in, AUX in */ chip->capture_source = 3; /* Set CAPTURE_SOURCE */ - if (chip->details->gpio_type == 1) { /* The SB0410 and SB0413 use GPIO differently. */ + if (chip->details->gpio_type == 2) { /* The SB0438 use GPIO differently. */ + /* FIXME: Still need to find out what the other GPIO bits do. E.g. For digital spdif out. */ + outl(0x0, chip->port+GPIO); + //outl(0x00f0e000, chip->port+GPIO); /* Analog */ + outl(0x005f5301, chip->port+GPIO); /* Analog */ + } else if (chip->details->gpio_type == 1) { /* The SB0410 and SB0413 use GPIO differently. */ /* FIXME: Still need to find out what the other GPIO bits do. E.g. For digital spdif out. */ outl(0x0, chip->port+GPIO); //outl(0x00f0e000, chip->port+GPIO); /* Analog */ @@ -1379,7 +1408,19 @@ static int __devinit snd_ca0106_create(s outl(HCFG_AC97 | HCFG_AUDIOENABLE, chip->port+HCFG); /* AC97 2.0, Enable outputs. */ if (chip->details->i2c_adc == 1) { /* The SB0410 and SB0413 use I2C to control ADC. */ - snd_ca0106_i2c_write(chip, ADC_MUX, ADC_MUX_LINEIN); /* Enable Line-in capture. MIC in currently untested. */ + int size, n; + + size = ARRAY_SIZE(i2c_adc_init); + //snd_printk("I2C:array size=0x%x\n", size); + for (n=0; n < size; n++) { + snd_ca0106_i2c_write(chip, i2c_adc_init[n][0], i2c_adc_init[n][1]); + } + for (n=0; n < 4; n++) { + chip->i2c_capture_volume[n][0]= 0xcf; + chip->i2c_capture_volume[n][1]= 0xcf; + } + chip->i2c_capture_source=2; /* Line in */ + //snd_ca0106_i2c_write(chip, ADC_MUX, ADC_MUX_LINEIN); /* Enable Line-in capture. MIC in currently untested. */ } if (chip->details->spi_dac == 1) { /* The SB0570 use SPI to control DAC. */ int size, n; diff --git a/sound/pci/ca0106/ca0106_mixer.c b/sound/pci/ca0106/ca0106_mixer.c index 06fe055..146eed7 100644 --- a/sound/pci/ca0106/ca0106_mixer.c +++ b/sound/pci/ca0106/ca0106_mixer.c @@ -171,6 +171,76 @@ static int snd_ca0106_capture_source_put return change; } +static int snd_ca0106_i2c_capture_source_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + static char *texts[6] = { + "Phone", "Mic", "Line in", "Aux" + }; + + uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; + uinfo->count = 1; + uinfo->value.enumerated.items = 4; + if (uinfo->value.enumerated.item > 3) + uinfo->value.enumerated.item = 3; + strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); + return 0; +} + +static int snd_ca0106_i2c_capture_source_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol); + + ucontrol->value.enumerated.item[0] = emu->i2c_capture_source; + return 0; +} + +static int snd_ca0106_i2c_capture_source_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol); + unsigned int source_id; + unsigned int ngain, ogain; + int change = 0; + u32 source; + /* If the capture source has changed, + * update the capture volume from the cached value + * for the particular source. + */ + source_id = ucontrol->value.enumerated.item[0] ; + change = (emu->i2c_capture_source != source_id); + if (change) { + snd_ca0106_i2c_write(emu, ADC_MUX, 0); /* Mute input */ + ngain = emu->i2c_capture_volume[source_id][0]; /* Left */ + ogain = emu->i2c_capture_volume[emu->i2c_capture_source][0]; /* Left */ + if (ngain != ogain) + snd_ca0106_i2c_write(emu, ADC_ATTEN_ADCL, ((ngain) & 0xff)); + ngain = emu->i2c_capture_volume[source_id][1]; /* Left */ + ogain = emu->i2c_capture_volume[emu->i2c_capture_source][1]; /* Left */ + if (ngain != ogain) + snd_ca0106_i2c_write(emu, ADC_ATTEN_ADCR, ((ngain) & 0xff)); + source = 1 << source_id; + snd_ca0106_i2c_write(emu, ADC_MUX, source); /* Set source */ + emu->i2c_capture_source = source_id; + } + return change; +} + +static int snd_ca0106_capture_line_in_side_out_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + static char *texts[2] = { "Side out", "Line in" }; + + 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; + strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); + return 0; +} + static int snd_ca0106_capture_mic_line_in_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { @@ -207,16 +277,16 @@ static int snd_ca0106_capture_mic_line_i if (change) { emu->capture_mic_line_in = val; if (val) { - snd_ca0106_i2c_write(emu, ADC_MUX, ADC_MUX_PHONE); /* Mute input */ + //snd_ca0106_i2c_write(emu, ADC_MUX, 0); /* Mute input */ tmp = inl(emu->port+GPIO) & ~0x400; tmp = tmp | 0x400; outl(tmp, emu->port+GPIO); - snd_ca0106_i2c_write(emu, ADC_MUX, ADC_MUX_MIC); + //snd_ca0106_i2c_write(emu, ADC_MUX, ADC_MUX_MIC); } else { - snd_ca0106_i2c_write(emu, ADC_MUX, ADC_MUX_PHONE); /* Mute input */ + //snd_ca0106_i2c_write(emu, ADC_MUX, 0); /* Mute input */ tmp = inl(emu->port+GPIO) & ~0x400; outl(tmp, emu->port+GPIO); - snd_ca0106_i2c_write(emu, ADC_MUX, ADC_MUX_LINEIN); + //snd_ca0106_i2c_write(emu, ADC_MUX, ADC_MUX_LINEIN); } } return change; @@ -225,12 +295,22 @@ static int snd_ca0106_capture_mic_line_i static struct snd_kcontrol_new snd_ca0106_capture_mic_line_in __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Mic/Line in Capture", + .name = "Shared Mic/Line in Capture Switch", .info = snd_ca0106_capture_mic_line_in_info, .get = snd_ca0106_capture_mic_line_in_get, .put = snd_ca0106_capture_mic_line_in_put }; +static struct snd_kcontrol_new snd_ca0106_capture_line_in_side_out __devinitdata = +{ + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Shared Line in/Side out Capture Switch", + .info = snd_ca0106_capture_line_in_side_out_info, + .get = snd_ca0106_capture_mic_line_in_get, + .put = snd_ca0106_capture_mic_line_in_put +}; + + static int snd_ca0106_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { @@ -329,15 +409,81 @@ static int snd_ca0106_volume_put(struct return 1; } +static int snd_ca0106_i2c_volume_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = 2; + uinfo->value.integer.min = 0; + uinfo->value.integer.max = 255; + return 0; +} + +static int snd_ca0106_i2c_volume_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol); + int source_id; + + source_id = kcontrol->private_value; + + ucontrol->value.integer.value[0] = emu->i2c_capture_volume[source_id][0]; + ucontrol->value.integer.value[1] = emu->i2c_capture_volume[source_id][1]; + return 0; +} + +static int snd_ca0106_i2c_volume_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol); + unsigned int ogain; + unsigned int ngain; + int source_id; + int change = 0; + + source_id = kcontrol->private_value; + ogain = emu->i2c_capture_volume[source_id][0]; /* Left */ + ngain = ucontrol->value.integer.value[0]; + if (ngain > 0xff) + return 0; + if (ogain != ngain) { + if (emu->i2c_capture_source == source_id) + snd_ca0106_i2c_write(emu, ADC_ATTEN_ADCL, ((ngain) & 0xff) ); + emu->i2c_capture_volume[source_id][0] = ucontrol->value.integer.value[0]; + change = 1; + } + ogain = emu->i2c_capture_volume[source_id][1]; /* Right */ + ngain = ucontrol->value.integer.value[1]; + if (ngain > 0xff) + return 0; + if (ogain != ngain) { + if (emu->i2c_capture_source == source_id) + snd_ca0106_i2c_write(emu, ADC_ATTEN_ADCR, ((ngain) & 0xff)); + emu->i2c_capture_volume[source_id][1] = ucontrol->value.integer.value[1]; + change = 1; + } + + return change; +} + #define CA_VOLUME(xname,chid,reg) \ { \ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ - .info = snd_ca0106_volume_info, \ - .get = snd_ca0106_volume_get, \ - .put = snd_ca0106_volume_put, \ + .info = snd_ca0106_volume_info, \ + .get = snd_ca0106_volume_get, \ + .put = snd_ca0106_volume_put, \ .private_value = ((chid) << 8) | (reg) \ } +#define I2C_VOLUME(xname,chid) \ +{ \ + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ + .info = snd_ca0106_i2c_volume_info, \ + .get = snd_ca0106_i2c_volume_get, \ + .put = snd_ca0106_i2c_volume_put, \ + .private_value = chid \ +} + static struct snd_kcontrol_new snd_ca0106_volume_ctls[] __devinitdata = { CA_VOLUME("Analog Front Playback Volume", @@ -361,6 +507,11 @@ static struct snd_kcontrol_new snd_ca010 CA_VOLUME("CAPTURE feedback Playback Volume", 1, CAPTURE_CONTROL), + I2C_VOLUME("Phone Capture Volume", 0), + I2C_VOLUME("Mic Capture Volume", 1), + I2C_VOLUME("Line in Capture Volume", 2), + I2C_VOLUME("Aux Capture Volume", 3), + { .access = SNDRV_CTL_ELEM_ACCESS_READ, .iface = SNDRV_CTL_ELEM_IFACE_PCM, @@ -378,12 +529,19 @@ static struct snd_kcontrol_new snd_ca010 }, { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Capture Source", + .name = "Digital Capture Source", .info = snd_ca0106_capture_source_info, .get = snd_ca0106_capture_source_get, .put = snd_ca0106_capture_source_put }, { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Capture Source", + .info = snd_ca0106_i2c_capture_source_info, + .get = snd_ca0106_i2c_capture_source_get, + .put = snd_ca0106_i2c_capture_source_put + }, + { .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), .count = 4, @@ -477,7 +635,10 @@ int __devinit snd_ca0106_mixer(struct sn return err; } if (emu->details->i2c_adc == 1) { - err = snd_ctl_add(card, snd_ctl_new1(&snd_ca0106_capture_mic_line_in, emu)); + if (emu->details->gpio_type == 1) + err = snd_ctl_add(card, snd_ctl_new1(&snd_ca0106_capture_mic_line_in, emu)); + else /* gpio_type == 2 */ + err = snd_ctl_add(card, snd_ctl_new1(&snd_ca0106_capture_line_in_side_out, emu)); if (err < 0) return err; } diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c index 6bfa084..e71485c 100644 --- a/sound/pci/emu10k1/emu10k1_main.c +++ b/sound/pci/emu10k1/emu10k1_main.c @@ -777,14 +777,6 @@ static int snd_emu10k1_dev_free(struct s static struct snd_emu_chip_details emu_chip_details[] = { /* Audigy 2 Value AC3 out does not work yet. Need to find out how to turn off interpolators.*/ - /* Audigy4 SB0400 */ - {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x10211102, - .driver = "Audigy2", .name = "Audigy 4 [SB0400]", - .id = "Audigy2", - .emu10k2_chip = 1, - .ca0108_chip = 1, - .spk71 = 1, - .ac97_chip = 1} , /* Tested by James@superbug.co.uk 3rd July 2005 */ /* DSP: CA0108-IAT * DAC: CS4382-KQ @@ -799,13 +791,59 @@ static struct snd_emu_chip_details emu_c .ca0108_chip = 1, .spk71 = 1, .ac97_chip = 1} , + /* Audigy4 (Not PRO) SB0610 */ + /* Tested by James@superbug.co.uk 4th April 2006 */ + /* A_IOCFG bits + * Output + * 0: ? + * 1: ? + * 2: ? + * 3: 0 - Digital Out, 1 - Line in + * 4: ? + * 5: ? + * 6: ? + * 7: ? + * Input + * 8: ? + * 9: ? + * A: Green jack sense (Front) + * B: ? + * C: Black jack sense (Rear/Side Right) + * D: Yellow jack sense (Center/LFE/Side Left) + * E: ? + * F: ? + * + * Digital Out/Line in switch using A_IOCFG bit 3 (0x08) + * 0 - Digital Out + * 1 - Line in + */ + /* Mic input not tested. + * Analog CD input not tested + * Digital Out not tested. + * Line in working. + * Audio output 5.1 working. Side outputs not working. + */ + /* DSP: CA10300-IAT LF + * DAC: Cirrus Logic CS4382-KQZ + * ADC: Philips 1361T + * AC97: Sigmatel STAC9750 + * CA0151: None + */ + {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x10211102, + .driver = "Audigy2", .name = "Audigy 4 [SB0610]", + .id = "Audigy2", + .emu10k2_chip = 1, + .ca0108_chip = 1, + .spk71 = 1, + .adc_1361t = 1, /* 24 bit capture instead of 16bit */ + .ac97_chip = 1} , /* Audigy 2 ZS Notebook Cardbus card.*/ /* Tested by James@superbug.co.uk 22th December 2005 */ /* Audio output 7.1/Headphones working. * Digital output working. (AC3 not checked, only PCM) * Audio inputs not tested. */ - /* DSP: Tiny2 + /* DSP: Tina2 * DAC: Wolfson WM8768/WM8568 * ADC: Wolfson WM8775 * AC97: None diff --git a/sound/pci/emu10k1/emumixer.c b/sound/pci/emu10k1/emumixer.c index 2a9d12d..c31f3d0 100644 --- a/sound/pci/emu10k1/emumixer.c +++ b/sound/pci/emu10k1/emumixer.c @@ -777,6 +777,8 @@ int __devinit snd_emu10k1_mixer(struct s }; static char *audigy_remove_ctls[] = { /* Master/PCM controls on ac97 of Audigy has no effect */ + /* On the Audigy2 the AC97 playback is piped into + * the Philips ADC for 24bit capture */ "PCM Playback Switch", "PCM Playback Volume", "Master Mono Playback Switch", @@ -804,6 +806,47 @@ int __devinit snd_emu10k1_mixer(struct s "AMic Playback Volume", "Mic Playback Volume", NULL }; + static char *audigy_remove_ctls_1361t_adc[] = { + /* On the Audigy2 the AC97 playback is piped into + * the Philips ADC for 24bit capture */ + "PCM Playback Switch", + "PCM Playback Volume", + "Master Mono Playback Switch", + "Master Mono Playback Volume", + "Capture Source", + "Capture Switch", + "Capture Volume", + "Mic Capture Volume", + "Headphone Playback Switch", + "Headphone Playback Volume", + "3D Control - Center", + "3D Control - Depth", + "3D Control - Switch", + "Line2 Playback Volume", + "Line2 Capture Volume", + NULL + }; + static char *audigy_rename_ctls_1361t_adc[] = { + "Master Playback Switch", "Master Capture Switch", + "Master Playback Volume", "Master Capture Volume", + "Wave Master Playback Volume", "Master Playback Volume", + "PC Speaker Playback Switch", "PC Speaker Capture Switch", + "PC Speaker Playback Volume", "PC Speaker Capture Volume", + "Phone Playback Switch", "Phone Capture Switch", + "Phone Playback Volume", "Phone Capture Volume", + "Mic Playback Switch", "Mic Capture Switch", + "Mic Playback Volume", "Mic Capture Volume", + "Line Playback Switch", "Line Capture Switch", + "Line Playback Volume", "Line Capture Volume", + "CD Playback Switch", "CD Capture Switch", + "CD Playback Volume", "CD Capture Volume", + "Aux Playback Switch", "Aux Capture Switch", + "Aux Playback Volume", "Aux Capture Volume", + "Video Playback Switch", "Video Capture Switch", + "Video Playback Volume", "Video Capture Volume", + + NULL + }; if (emu->card_capabilities->ac97_chip) { struct snd_ac97_bus *pbus; @@ -834,7 +877,10 @@ int __devinit snd_emu10k1_mixer(struct s snd_ac97_write_cache(emu->ac97, AC97_MASTER, 0x0000); /* set capture source to mic */ snd_ac97_write_cache(emu->ac97, AC97_REC_SEL, 0x0000); - c = audigy_remove_ctls; + if (emu->card_capabilities->adc_1361t) + c = audigy_remove_ctls_1361t_adc; + else + c = audigy_remove_ctls; } else { /* * Credits for cards based on STAC9758: @@ -863,11 +909,15 @@ int __devinit snd_emu10k1_mixer(struct s } if (emu->audigy) - c = audigy_rename_ctls; + if (emu->card_capabilities->adc_1361t) + c = audigy_rename_ctls_1361t_adc; + else + c = audigy_rename_ctls; else c = emu10k1_rename_ctls; for (; *c; c += 2) rename_ctl(card, c[0], c[1]); + if (emu->card_capabilities->subsystem == 0x20071102) { /* Audigy 4 Pro */ rename_ctl(card, "Line2 Capture Volume", "Line1/Mic Capture Volume"); rename_ctl(card, "Analog Mix Capture Volume", "Line2 Capture Volume"); diff --git a/sound/pci/emu10k1/p17v.h b/sound/pci/emu10k1/p17v.h new file mode 100644 index 0000000..7ddb5be --- /dev/null +++ b/sound/pci/emu10k1/p17v.h @@ -0,0 +1,111 @@ +/* + * Copyright (c) by James Courtier-Dutton + * Driver p17v chips + * Version: 0.01 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +/******************************************************************************/ +/* Audigy2Value Tina (P17V) pointer-offset register set, + * accessed through the PTR20 and DATA24 registers */ +/******************************************************************************/ + +/* 00 - 07: Not used */ +#define P17V_PLAYBACK_FIFO_PTR 0x08 /* Current playback fifo pointer + * and number of sound samples in cache. + */ +/* 09 - 12: Not used */ +#define P17V_CAPTURE_FIFO_PTR 0x13 /* Current capture fifo pointer + * and number of sound samples in cache. + */ +/* 14 - 17: Not used */ +#define P17V_PB_CHN_SEL 0x18 /* P17v playback channel select */ +#define P17V_SE_SLOT_SEL_L 0x19 /* Sound Engine slot select low */ +#define P17V_SE_SLOT_SEL_H 0x1a /* Sound Engine slot select high */ +/* 1b - 1f: Not used */ +/* 20 - 2f: Not used */ +/* 30 - 3b: Not used */ +#define P17V_SPI 0x3c /* SPI interface register */ +#define P17V_I2C_ADDR 0x3d /* I2C Address */ +#define P17V_I2C_0 0x3e /* I2C Data */ +#define P17V_I2C_1 0x3f /* I2C Data */ + +#define P17V_START_AUDIO 0x40 /* Start Audio bit */ +/* 41 - 47: Reserved */ +#define P17V_START_CAPTURE 0x48 /* Start Capture bit */ +#define P17V_CAPTURE_FIFO_BASE 0x49 /* Record FIFO base address */ +#define P17V_CAPTURE_FIFO_SIZE 0x4a /* Record FIFO buffer size */ +#define P17V_CAPTURE_FIFO_INDEX 0x4b /* Record FIFO capture index */ +#define P17V_CAPTURE_VOL_H 0x4c /* P17v capture volume control */ +#define P17V_CAPTURE_VOL_L 0x4d /* P17v capture volume control */ +/* 4e - 4f: Not used */ +/* 50 - 5f: Not used */ +#define P17V_SRCSel 0x60 /* SRC48 and SRCMulti sample rate select + * and output select + */ +#define P17V_MIXER_AC97_10K1_VOL_L 0x61 /* 10K to Mixer_AC97 input volume control */ +#define P17V_MIXER_AC97_10K1_VOL_H 0x62 /* 10K to Mixer_AC97 input volume control */ +#define P17V_MIXER_AC97_P17V_VOL_L 0x63 /* P17V to Mixer_AC97 input volume control */ +#define P17V_MIXER_AC97_P17V_VOL_H 0x64 /* P17V to Mixer_AC97 input volume control */ +#define P17V_MIXER_AC97_SRP_REC_VOL_L 0x65 /* SRP Record to Mixer_AC97 input volume control */ +#define P17V_MIXER_AC97_SRP_REC_VOL_H 0x66 /* SRP Record to Mixer_AC97 input volume control */ +/* 67 - 68: Reserved */ +#define P17V_MIXER_Spdif_10K1_VOL_L 0x69 /* 10K to Mixer_Spdif input volume control */ +#define P17V_MIXER_Spdif_10K1_VOL_H 0x6A /* 10K to Mixer_Spdif input volume control */ +#define P17V_MIXER_Spdif_P17V_VOL_L 0x6B /* P17V to Mixer_Spdif input volume control */ +#define P17V_MIXER_Spdif_P17V_VOL_H 0x6C /* P17V to Mixer_Spdif input volume control */ +#define P17V_MIXER_Spdif_SRP_REC_VOL_L 0x6D /* SRP Record to Mixer_Spdif input volume control */ +#define P17V_MIXER_Spdif_SRP_REC_VOL_H 0x6E /* SRP Record to Mixer_Spdif input volume control */ +/* 6f - 70: Reserved */ +#define P17V_MIXER_I2S_10K1_VOL_L 0x71 /* 10K to Mixer_I2S input volume control */ +#define P17V_MIXER_I2S_10K1_VOL_H 0x72 /* 10K to Mixer_I2S input volume control */ +#define P17V_MIXER_I2S_P17V_VOL_L 0x73 /* P17V to Mixer_I2S input volume control */ +#define P17V_MIXER_I2S_P17V_VOL_H 0x74 /* P17V to Mixer_I2S input volume control */ +#define P17V_MIXER_I2S_SRP_REC_VOL_L 0x75 /* SRP Record to Mixer_I2S input volume control */ +#define P17V_MIXER_I2S_SRP_REC_VOL_H 0x76 /* SRP Record to Mixer_I2S input volume control */ +/* 77 - 78: Reserved */ +#define P17V_MIXER_AC97_ENABLE 0x79 /* Mixer AC97 input audio enable */ +#define P17V_MIXER_SPDIF_ENABLE 0x7A /* Mixer SPDIF input audio enable */ +#define P17V_MIXER_I2S_ENABLE 0x7B /* Mixer I2S input audio enable */ +#define P17V_AUDIO_OUT_ENABLE 0x7C /* Audio out enable */ +#define P17V_MIXER_ATT 0x7D /* SRP Mixer Attenuation Select */ +#define P17V_SRP_RECORD_SRR 0x7E /* SRP Record channel source Select */ +#define P17V_SOFT_RESET_SRP_MIXER 0x7F /* SRP and mixer soft reset */ + +#define P17V_AC97_OUT_MASTER_VOL_L 0x80 /* AC97 Output master volume control */ +#define P17V_AC97_OUT_MASTER_VOL_H 0x81 /* AC97 Output master volume control */ +#define P17V_SPDIF_OUT_MASTER_VOL_L 0x82 /* SPDIF Output master volume control */ +#define P17V_SPDIF_OUT_MASTER_VOL_H 0x83 /* SPDIF Output master volume control */ +#define P17V_I2S_OUT_MASTER_VOL_L 0x84 /* I2S Output master volume control */ +#define P17V_I2S_OUT_MASTER_VOL_H 0x85 /* I2S Output master volume control */ +/* 86 - 87: Not used */ +#define P17V_I2S_CHANNEL_SWAP_PHASE_INVERSE 0x88 /* I2S out mono channel swap + * and phase inverse */ +#define P17V_SPDIF_CHANNEL_SWAP_PHASE_INVERSE 0x89 /* SPDIF out mono channel swap + * and phase inverse */ +/* 8A: Not used */ +#define P17V_SRP_P17V_ESR 0x8B /* SRP_P17V estimated sample rate and rate lock */ +#define P17V_SRP_REC_ESR 0x8C /* SRP_REC estimated sample rate and rate lock */ +#define P17V_SRP_BYPASS 0x8D /* srps channel bypass and srps bypass */ +/* 8E - 92: Not used */ +#define P17V_I2S_SRC_SEL 0x93 /* I2SIN mode sel */ + + + + + + diff --git a/sound/pci/emu10k1/tina2.h b/sound/pci/emu10k1/tina2.h index 5c43abf..f2d8eb6 100644 --- a/sound/pci/emu10k1/tina2.h +++ b/sound/pci/emu10k1/tina2.h @@ -1,11 +1,7 @@ /* * Copyright (c) by James Courtier-Dutton - * Driver p16v chips - * Version: 0.21 - * - * - * This code was initally based on code from ALSA's emu10k1x.c which is: - * Copyright (c) by Francisco Moraes + * Driver tina2 chips + * Version: 0.1 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf.c b/sound/pcmcia/pdaudiocf/pdaudiocf.c index adfdce7..1c09e5f 100644 --- a/sound/pcmcia/pdaudiocf/pdaudiocf.c +++ b/sound/pcmcia/pdaudiocf/pdaudiocf.c @@ -241,12 +241,13 @@ static int pdacf_config(struct pcmcia_de CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, parse)); link->conf.ConfigBase = parse->config.base; link->conf.ConfigIndex = 0x5; - kfree(parse); CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io)); CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); + kfree(parse); + if (snd_pdacf_assign_resources(pdacf, link->io.BasePort1, link->irq.AssignedIRQ) < 0) goto failed; @@ -254,6 +255,7 @@ static int pdacf_config(struct pcmcia_de return 0; cs_failed: + kfree(parse); cs_error(link, last_fn, last_ret); failed: pcmcia_disable_device(link); diff --git a/sound/pcmcia/vx/vxpocket.c b/sound/pcmcia/vx/vxpocket.c index 7e0cda2..cafe664 100644 --- a/sound/pcmcia/vx/vxpocket.c +++ b/sound/pcmcia/vx/vxpocket.c @@ -261,7 +261,7 @@ static int vxpocket_config(struct pcmcia link->dev_node = &vxp->node; kfree(parse); - return 9; + return 0; cs_failed: cs_error(link, last_fn, last_ret);