From 90fd5ce5f67968d3250eeab9bc1f6822644347ef Mon Sep 17 00:00:00 2001 From: James Courtier-Dutton Date: Mon, 23 Jul 2007 14:01:46 +0100 Subject: [ALSA] snd-emu10k1: Add support for E-Mu 1616 PCI, 1616M PCI, 0404 PCI, E-Mu Notebook. Description: The .device=0x0008 chips have new, but different EMU32 in/out channels. Driver updated to make use of these EMU32 channels. Signed-off-by: James Courtier-Dutton Signed-off-by: Jaroslav Kysela --- sound/pci/emu10k1/emufx.c | 230 ++++++++++++++++++++++++-------------------- sound/pci/emu10k1/emuproc.c | 8 +- 2 files changed, 130 insertions(+), 108 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/emu10k1/emufx.c b/sound/pci/emu10k1/emufx.c index 7206c0fa06f..febdd130a20 100644 --- a/sound/pci/emu10k1/emufx.c +++ b/sound/pci/emu10k1/emufx.c @@ -1207,7 +1207,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 +1267,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 +1524,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 +1569,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++) { diff --git a/sound/pci/emu10k1/emuproc.c b/sound/pci/emu10k1/emuproc.c index 2c1585991bc..a0dae0d916c 100644 --- a/sound/pci/emu10k1/emuproc.c +++ b/sound/pci/emu10k1/emuproc.c @@ -385,7 +385,7 @@ static void snd_emu_proc_emu1010_reg_read(struct snd_info_entry *entry, 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); @@ -555,9 +555,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); -- cgit v1.2.3 From a5ce88909d3007caa7b65996a8f6784350beb2a6 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 23 Jul 2007 15:42:26 +0200 Subject: [ALSA] Clean up with common snd_ctl_boolean_*_info callbacks Clean up codes using the new common snd_ctl_boolean_*_info() callbacks. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/ac97/ac97_patch.c | 19 ++--------- sound/pci/ali5451/ali5451.c | 10 +----- sound/pci/au88x0/au88x0_eq.c | 10 +----- sound/pci/bt87x.c | 10 +----- sound/pci/ca0106/ca0106_mixer.c | 10 +----- sound/pci/cmipci.c | 10 +----- sound/pci/cs46xx/cs46xx_lib.c | 10 +----- sound/pci/echoaudio/echoaudio.c | 33 ++----------------- sound/pci/emu10k1/emu10k1x.c | 9 +----- sound/pci/emu10k1/emumixer.c | 28 ++-------------- sound/pci/ens1370.c | 40 +++-------------------- sound/pci/es1938.c | 20 ++---------- sound/pci/hda/hda_codec.c | 10 +----- sound/pci/hda/patch_analog.c | 10 +----- sound/pci/hda/patch_conexant.c | 10 +----- sound/pci/hda/patch_realtek.c | 20 ++---------- sound/pci/hda/patch_si3054.c | 10 +----- sound/pci/hda/patch_sigmatel.c | 9 +----- sound/pci/ice1712/aureon.c | 45 ++++++-------------------- sound/pci/ice1712/delta.c | 11 ++----- sound/pci/ice1712/ews.c | 18 ++--------- sound/pci/ice1712/ice1712.c | 48 +++------------------------ sound/pci/ice1712/ice1724.c | 40 +++-------------------- sound/pci/ice1712/phase.c | 23 ++----------- sound/pci/ice1712/pontis.c | 27 ++-------------- sound/pci/ice1712/prodigy192.c | 27 ++-------------- sound/pci/ice1712/wtm.c | 29 ++--------------- sound/pci/mixart/mixart_mixer.c | 9 +----- sound/pci/pcxhr/pcxhr_mixer.c | 9 +----- sound/pci/rme32.c | 12 ++----- sound/pci/rme96.c | 11 ++----- sound/pci/rme9652/hdsp.c | 63 ++++-------------------------------- sound/pci/rme9652/hdspm.c | 70 ++++------------------------------------ sound/pci/rme9652/rme9652.c | 27 ++-------------- sound/pci/trident/trident_main.c | 20 ++---------- sound/pci/via82xx.c | 10 +----- sound/pci/ymfpci/ymfpci_main.c | 35 ++------------------ 37 files changed, 92 insertions(+), 720 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c index 581ebba4d1a..630c961895d 100644 --- a/sound/pci/ac97/ac97_patch.c +++ b/sound/pci/ac97/ac97_patch.c @@ -1880,14 +1880,7 @@ static int patch_ad1981b(struct snd_ac97 *ac97) return 0; } -static int snd_ac97_ad1888_lohpsel_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_ac97_ad1888_lohpsel_info snd_ctl_boolean_mono_info static int snd_ac97_ad1888_lohpsel_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -2186,15 +2179,7 @@ static int patch_ad1985(struct snd_ac97 * ac97) return 0; } -static int snd_ac97_ad1986_bool_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_ac97_ad1986_bool_info snd_ctl_boolean_mono_info static int snd_ac97_ad1986_lososel_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) diff --git a/sound/pci/ali5451/ali5451.c b/sound/pci/ali5451/ali5451.c index 05b4c869694..4c2bd7adf67 100644 --- a/sound/pci/ali5451/ali5451.c +++ b/sound/pci/ali5451/ali5451.c @@ -1804,15 +1804,7 @@ static int __devinit snd_ali_build_pcms(struct snd_ali *codec) .info = snd_ali5451_spdif_info, .get = snd_ali5451_spdif_get, \ .put = snd_ali5451_spdif_put, .private_value = value} -static int snd_ali5451_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_ali5451_spdif_info snd_ctl_boolean_mono_info static int snd_ali5451_spdif_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) diff --git a/sound/pci/au88x0/au88x0_eq.c b/sound/pci/au88x0/au88x0_eq.c index 0c86a31c433..38602b85874 100644 --- a/sound/pci/au88x0/au88x0_eq.c +++ b/sound/pci/au88x0/au88x0_eq.c @@ -728,15 +728,7 @@ static void vortex_Eqlzr_shutdown(vortex_t * vortex) /* ALSA interface */ /* Control interface */ -static int -snd_vortex_eqtoggle_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_vortex_eqtoggle_info snd_ctl_boolean_mono_info static int snd_vortex_eqtoggle_get(struct snd_kcontrol *kcontrol, diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c index 131952f5585..f0e12985dc2 100644 --- a/sound/pci/bt87x.c +++ b/sound/pci/bt87x.c @@ -569,15 +569,7 @@ static struct snd_kcontrol_new snd_bt87x_capture_volume = { .put = snd_bt87x_capture_volume_put, }; -static int snd_bt87x_capture_boost_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *info) -{ - info->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; - info->count = 1; - info->value.integer.min = 0; - info->value.integer.max = 1; - return 0; -} +#define snd_bt87x_capture_boost_info snd_ctl_boolean_mono_info static int snd_bt87x_capture_boost_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *value) diff --git a/sound/pci/ca0106/ca0106_mixer.c b/sound/pci/ca0106/ca0106_mixer.c index 9c3a9c8d1dc..a135b9c4c3c 100644 --- a/sound/pci/ca0106/ca0106_mixer.c +++ b/sound/pci/ca0106/ca0106_mixer.c @@ -77,15 +77,7 @@ static const DECLARE_TLV_DB_SCALE(snd_ca0106_db_scale1, -5175, 25, 1); static const DECLARE_TLV_DB_SCALE(snd_ca0106_db_scale2, -10350, 50, 1); -static int snd_ca0106_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_ca0106_shared_spdif_info snd_ctl_boolean_mono_info static int snd_ca0106_shared_spdif_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c index 7d3c5ee0005..f38054ead17 100644 --- a/sound/pci/cmipci.c +++ b/sound/pci/cmipci.c @@ -2139,15 +2139,7 @@ struct cmipci_switch_args { */ }; -static int snd_cmipci_uswitch_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_cmipci_uswitch_info snd_ctl_boolean_mono_info static int _snd_cmipci_uswitch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol, diff --git a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c index 71d7aab9d86..0dc69d07140 100644 --- a/sound/pci/cs46xx/cs46xx_lib.c +++ b/sound/pci/cs46xx/cs46xx_lib.c @@ -1818,15 +1818,7 @@ static int snd_cs46xx_vol_iec958_put(struct snd_kcontrol *kcontrol, struct snd_c } #endif -static int snd_mixer_boolean_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_mixer_boolean_info snd_ctl_boolean_mono_info static int snd_cs46xx_iec958_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) diff --git a/sound/pci/echoaudio/echoaudio.c b/sound/pci/echoaudio/echoaudio.c index f27b6a733b9..499ee1a5319 100644 --- a/sound/pci/echoaudio/echoaudio.c +++ b/sound/pci/echoaudio/echoaudio.c @@ -1595,15 +1595,7 @@ static struct snd_kcontrol_new snd_echo_clock_source_switch __devinitdata = { #ifdef ECHOCARD_HAS_PHANTOM_POWER /******************* Phantom power switch *******************/ -static int snd_echo_phantom_power_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_echo_phantom_power_info snd_ctl_boolean_mono_info static int snd_echo_phantom_power_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) @@ -1646,15 +1638,7 @@ static struct snd_kcontrol_new snd_echo_phantom_power_switch __devinitdata = { #ifdef ECHOCARD_HAS_DIGITAL_IN_AUTOMUTE /******************* Digital input automute switch *******************/ -static int snd_echo_automute_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_echo_automute_info snd_ctl_boolean_mono_info static int snd_echo_automute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) @@ -1695,18 +1679,7 @@ static struct snd_kcontrol_new snd_echo_automute_switch __devinitdata = { /******************* VU-meters switch *******************/ -static int snd_echo_vumeters_switch_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - struct echoaudio *chip; - - chip = snd_kcontrol_chip(kcontrol); - uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; - uinfo->count = 1; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = 1; - return 0; -} +#define snd_echo_vumeters_switch_info snd_ctl_boolean_mono_info static int snd_echo_vumeters_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 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/emumixer.c b/sound/pci/emu10k1/emumixer.c index 7b2c1dcc533..6c26319430d 100644 --- a/sound/pci/emu10k1/emumixer.c +++ b/sound/pci/emu10k1/emumixer.c @@ -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) { @@ -1326,14 +1311,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/ens1370.c b/sound/pci/ens1370.c index 21cb4268a59..9017bdb513a 100644 --- a/sound/pci/ens1370.c +++ b/sound/pci/ens1370.c @@ -1419,15 +1419,7 @@ static int snd_ens1373_spdif_stream_put(struct snd_kcontrol *kcontrol, { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .info = snd_es1371_spdif_info, \ .get = snd_es1371_spdif_get, .put = snd_es1371_spdif_put } -static int snd_es1371_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_es1371_spdif_info snd_ctl_boolean_mono_info static int snd_es1371_spdif_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) @@ -1489,15 +1481,7 @@ static struct snd_kcontrol_new snd_es1371_mixer_spdif[] __devinitdata = { }; -static int snd_es1373_rear_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_es1373_rear_info snd_ctl_boolean_mono_info static int snd_es1373_rear_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) @@ -1542,15 +1526,7 @@ static struct snd_kcontrol_new snd_ens1373_rear __devinitdata = .put = snd_es1373_rear_put, }; -static int snd_es1373_line_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_es1373_line_info snd_ctl_boolean_mono_info static int snd_es1373_line_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) @@ -1707,15 +1683,7 @@ static int __devinit snd_ensoniq_1371_mixer(struct ensoniq *ensoniq, .get = snd_ensoniq_control_get, .put = snd_ensoniq_control_put, \ .private_value = mask } -static int snd_ensoniq_control_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_ensoniq_control_info snd_ctl_boolean_mono_info static int snd_ensoniq_control_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) diff --git a/sound/pci/es1938.c b/sound/pci/es1938.c index fec29a10894..fc686db59ce 100644 --- a/sound/pci/es1938.c +++ b/sound/pci/es1938.c @@ -1066,15 +1066,7 @@ static int snd_es1938_put_mux(struct snd_kcontrol *kcontrol, return snd_es1938_mixer_bits(chip, 0x1c, 0x07, val) != val; } -static int snd_es1938_info_spatializer_enable(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_es1938_info_spatializer_enable snd_ctl_boolean_mono_info static int snd_es1938_get_spatializer_enable(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) @@ -1120,15 +1112,7 @@ static int snd_es1938_get_hw_volume(struct snd_kcontrol *kcontrol, return 0; } -static int snd_es1938_info_hw_switch(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; - uinfo->count = 2; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = 1; - return 0; -} +#define snd_es1938_info_hw_switch snd_ctl_boolean_stereo_info static int snd_es1938_get_hw_switch(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index f87f8f08895..a05db2f214b 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -1129,15 +1129,7 @@ static int snd_hda_spdif_default_put(struct snd_kcontrol *kcontrol, return change; } -static int snd_hda_spdif_out_switch_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_hda_spdif_out_switch_info snd_ctl_boolean_mono_info static int snd_hda_spdif_out_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index 4d7f8d11ad7..fafadf9fab8 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c @@ -350,15 +350,7 @@ static struct hda_codec_ops ad198x_patch_ops = { * EAPD control * the private value = nid | (invert << 8) */ -static int ad198x_eapd_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 ad198x_eapd_info snd_ctl_boolean_mono_info static int ad198x_eapd_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 4d8e8af5c81..26034315197 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -368,15 +368,7 @@ static struct hda_codec_ops conexant_patch_ops = { * the private value = nid | (invert << 8) */ -static int cxt_eapd_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 cxt_eapd_info snd_ctl_boolean_mono_info static int cxt_eapd_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 9a47eec5a27..7e6cc01b521 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -486,15 +486,7 @@ static int alc_pin_mode_put(struct snd_kcontrol *kcontrol, * needed for any "production" models. */ #ifdef CONFIG_SND_DEBUG -static int alc_gpio_data_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 alc_gpio_data_info snd_ctl_boolean_mono_info static int alc_gpio_data_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) @@ -547,15 +539,7 @@ static int alc_gpio_data_put(struct snd_kcontrol *kcontrol, * necessary. */ #ifdef CONFIG_SND_DEBUG -static int alc_spdif_ctrl_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 alc_spdif_ctrl_info snd_ctl_boolean_mono_info static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) diff --git a/sound/pci/hda/patch_si3054.c b/sound/pci/hda/patch_si3054.c index 6d2ecc38905..9838eac9ab5 100644 --- a/sound/pci/hda/patch_si3054.c +++ b/sound/pci/hda/patch_si3054.c @@ -94,15 +94,7 @@ struct si3054_spec { #define PRIVATE_REG(val) ((val>>16)&0xffff) #define PRIVATE_MASK(val) (val&0xffff) -static int si3054_switch_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 si3054_switch_info snd_ctl_boolean_mono_info static int si3054_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *uvalue) diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 3f25de72966..d2c340e45f9 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -1069,14 +1069,7 @@ static void stac92xx_auto_set_pinctl(struct hda_codec *codec, hda_nid_t nid, int snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type); } -static int stac92xx_io_switch_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 stac92xx_io_switch_info snd_ctl_boolean_mono_info static int stac92xx_io_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { diff --git a/sound/pci/ice1712/aureon.c b/sound/pci/ice1712/aureon.c index 66bacde1ead..ec0699c8995 100644 --- a/sound/pci/ice1712/aureon.c +++ b/sound/pci/ice1712/aureon.c @@ -394,7 +394,7 @@ static int aureon_ac97_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_ele /* * AC'97 mute controls */ -#define aureon_ac97_mute_info aureon_mono_bool_info +#define aureon_ac97_mute_info snd_ctl_boolean_mono_info static int aureon_ac97_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -430,7 +430,7 @@ static int aureon_ac97_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_el /* * AC'97 mute controls */ -#define aureon_ac97_micboost_info aureon_mono_bool_info +#define aureon_ac97_micboost_info snd_ctl_boolean_mono_info static int aureon_ac97_micboost_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -621,19 +621,12 @@ static void wm_put(struct snd_ice1712 *ice, int reg, unsigned short val) /* */ -static int aureon_mono_bool_info(struct snd_kcontrol *k, 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 aureon_mono_bool_info snd_ctl_boolean_mono_info /* * AC'97 master playback mute controls (Mute on WM8770 chip) */ -#define aureon_ac97_mmute_info aureon_mono_bool_info +#define aureon_ac97_mmute_info snd_ctl_boolean_mono_info static int aureon_ac97_mmute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -708,7 +701,7 @@ static void wm_set_vol(struct snd_ice1712 *ice, unsigned int index, unsigned sho /* * DAC mute control */ -#define wm_pcm_mute_info aureon_mono_bool_info +#define wm_pcm_mute_info snd_ctl_boolean_mono_info static int wm_pcm_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -879,13 +872,7 @@ static int wm_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value /* * WM8770 master mute control */ -static int wm_master_mute_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; - uinfo->count = 2; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = 1; - return 0; -} +#define wm_master_mute_info snd_ctl_boolean_stereo_info static int wm_master_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -969,14 +956,7 @@ static int wm_pcm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val /* * ADC mute control */ -static int wm_adc_mute_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; - uinfo->count = 2; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = 1; - return 0; -} +#define wm_adc_mute_info snd_ctl_boolean_stereo_info static int wm_adc_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -1210,12 +1190,7 @@ static int aureon_cs8415_rate_get (struct snd_kcontrol *kcontrol, struct snd_ctl /* * CS8415A Mute */ -static int aureon_cs8415_mute_info (struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; - uinfo->count = 1; - return 0; -} +#define aureon_cs8415_mute_info snd_ctl_boolean_mono_info static int aureon_cs8415_mute_get (struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -1316,7 +1291,7 @@ static int aureon_get_headphone_amp(struct snd_ice1712 *ice) return ( tmp & AUREON_HP_SEL )!= 0; } -#define aureon_hpamp_info aureon_mono_bool_info +#define aureon_hpamp_info snd_ctl_boolean_mono_info static int aureon_hpamp_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -1338,7 +1313,7 @@ static int aureon_hpamp_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_v * Deemphasis */ -#define aureon_deemp_info aureon_mono_bool_info +#define aureon_deemp_info snd_ctl_boolean_mono_info static int aureon_deemp_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { diff --git a/sound/pci/ice1712/delta.c b/sound/pci/ice1712/delta.c index af659800c9b..66886dff484 100644 --- a/sound/pci/ice1712/delta.c +++ b/sound/pci/ice1712/delta.c @@ -393,15 +393,8 @@ static void delta_setup_spdif(struct snd_ice1712 *ice, int rate) snd_ice1712_delta_cs8403_spdif_write(ice, tmp); } -static int snd_ice1712_delta1010lt_wordclock_status_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_ice1712_delta1010lt_wordclock_status_info \ + snd_ctl_boolean_mono_info static int snd_ice1712_delta1010lt_wordclock_status_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) diff --git a/sound/pci/ice1712/ews.c b/sound/pci/ice1712/ews.c index b135389fec6..b2b4eff1ac6 100644 --- a/sound/pci/ice1712/ews.c +++ b/sound/pci/ice1712/ews.c @@ -700,14 +700,7 @@ static struct snd_kcontrol_new snd_ice1712_ews88mt_output_sense __devinitdata = * EWS88D specific controls */ -static int snd_ice1712_ews88d_control_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_ice1712_ews88d_control_info snd_ctl_boolean_mono_info static int snd_ice1712_ews88d_control_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -812,14 +805,7 @@ static int snd_ice1712_6fire_write_pca(struct snd_ice1712 *ice, unsigned char re return 0; } -static int snd_ice1712_6fire_control_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_ice1712_6fire_control_info snd_ctl_boolean_mono_info static int snd_ice1712_6fire_control_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { diff --git a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c index 6630a0ae952..cd41c7eb6c6 100644 --- a/sound/pci/ice1712/ice1712.c +++ b/sound/pci/ice1712/ice1712.c @@ -256,14 +256,7 @@ static unsigned short snd_ice1712_pro_ac97_read(struct snd_ac97 *ac97, /* * consumer ac97 digital mix */ -static int snd_ice1712_digmix_route_ac97_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_ice1712_digmix_route_ac97_info snd_ctl_boolean_mono_info static int snd_ice1712_digmix_route_ac97_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -1300,14 +1293,7 @@ static void snd_ice1712_update_volume(struct snd_ice1712 *ice, int index) outw(val, ICEMT(ice, MONITOR_VOLUME)); } -static int snd_ice1712_pro_mixer_switch_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; - uinfo->count = 2; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = 1; - return 0; -} +#define snd_ice1712_pro_mixer_switch_info snd_ctl_boolean_stereo_info static int snd_ice1712_pro_mixer_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -1759,15 +1745,7 @@ static struct snd_kcontrol_new snd_ice1712_spdif_stream __devinitdata = .put = snd_ice1712_spdif_stream_put }; -int snd_ice1712_gpio_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_ice1712_gpio_info snd_ctl_boolean_mono_info int snd_ice1712_gpio_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) @@ -1968,15 +1946,7 @@ static struct snd_kcontrol_new snd_ice1712_pro_internal_clock_default __devinitd .put = snd_ice1712_pro_internal_clock_default_put }; -static int snd_ice1712_pro_rate_locking_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_ice1712_pro_rate_locking_info snd_ctl_boolean_mono_info static int snd_ice1712_pro_rate_locking_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) @@ -2007,15 +1977,7 @@ static struct snd_kcontrol_new snd_ice1712_pro_rate_locking __devinitdata = { .put = snd_ice1712_pro_rate_locking_put }; -static int snd_ice1712_pro_rate_reset_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_ice1712_pro_rate_reset_info snd_ctl_boolean_mono_info static int snd_ice1712_pro_rate_reset_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c index ee620dea7ef..32560cfb6c3 100644 --- a/sound/pci/ice1712/ice1724.c +++ b/sound/pci/ice1712/ice1724.c @@ -1479,15 +1479,7 @@ static struct snd_kcontrol_new snd_vt1724_spdif_maskp __devinitdata = .get = snd_vt1724_spdif_maskp_get, }; -static int snd_vt1724_spdif_sw_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_vt1724_spdif_sw_info snd_ctl_boolean_mono_info static int snd_vt1724_spdif_sw_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) @@ -1532,15 +1524,7 @@ static struct snd_kcontrol_new snd_vt1724_spdif_switch __devinitdata = * GPIO access from extern */ -int snd_vt1724_gpio_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_vt1724_gpio_info snd_ctl_boolean_mono_info int snd_vt1724_gpio_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) @@ -1706,15 +1690,7 @@ static struct snd_kcontrol_new snd_vt1724_pro_internal_clock __devinitdata = { .put = snd_vt1724_pro_internal_clock_put }; -static int snd_vt1724_pro_rate_locking_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_vt1724_pro_rate_locking_info snd_ctl_boolean_mono_info static int snd_vt1724_pro_rate_locking_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) @@ -1745,15 +1721,7 @@ static struct snd_kcontrol_new snd_vt1724_pro_rate_locking __devinitdata = { .put = snd_vt1724_pro_rate_locking_put }; -static int snd_vt1724_pro_rate_reset_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_vt1724_pro_rate_reset_info snd_ctl_boolean_mono_info static int snd_vt1724_pro_rate_reset_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) diff --git a/sound/pci/ice1712/phase.c b/sound/pci/ice1712/phase.c index 40a9098af77..3ac25058bb5 100644 --- a/sound/pci/ice1712/phase.c +++ b/sound/pci/ice1712/phase.c @@ -270,7 +270,7 @@ static void wm_set_vol(struct snd_ice1712 *ice, unsigned int index, unsigned sho /* * DAC mute control */ -#define wm_pcm_mute_info phase28_mono_bool_info +#define wm_pcm_mute_info snd_ctl_boolean_mono_info static int wm_pcm_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -527,13 +527,7 @@ static int wm_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value /* * WM8770 master mute control */ -static int wm_master_mute_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; - uinfo->count = 2; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = 1; - return 0; -} +#define wm_master_mute_info snd_ctl_boolean_stereo_info static int wm_master_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -614,21 +608,10 @@ static int wm_pcm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val return change; } -/* - */ -static int phase28_mono_bool_info(struct snd_kcontrol *k, 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; -} - /* * Deemphasis */ -#define phase28_deemp_info phase28_mono_bool_info +#define phase28_deemp_info snd_ctl_boolean_mono_info static int phase28_deemp_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { diff --git a/sound/pci/ice1712/pontis.c b/sound/pci/ice1712/pontis.c index 01c69453dde..faefd52c1b8 100644 --- a/sound/pci/ice1712/pontis.c +++ b/sound/pci/ice1712/pontis.c @@ -216,14 +216,7 @@ static int wm_adc_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val /* * ADC input mux mixer control */ -static int wm_adc_mux_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 wm_adc_mux_info snd_ctl_boolean_mono_info static int wm_adc_mux_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -260,14 +253,7 @@ static int wm_adc_mux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val /* * Analog bypass (In -> Out) */ -static int wm_bypass_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 wm_bypass_info snd_ctl_boolean_mono_info static int wm_bypass_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -302,14 +288,7 @@ static int wm_bypass_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_valu /* * Left/Right swap */ -static int wm_chswap_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 wm_chswap_info snd_ctl_boolean_mono_info static int wm_chswap_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { diff --git a/sound/pci/ice1712/prodigy192.c b/sound/pci/ice1712/prodigy192.c index 4bae7305a79..4180f9739ec 100644 --- a/sound/pci/ice1712/prodigy192.c +++ b/sound/pci/ice1712/prodigy192.c @@ -81,14 +81,7 @@ static inline unsigned char stac9460_get(struct snd_ice1712 *ice, int reg) /* * DAC mute control */ -static int stac9460_dac_mute_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 stac9460_dac_mute_info snd_ctl_boolean_mono_info static int stac9460_dac_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -177,14 +170,7 @@ static int stac9460_dac_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_el /* * ADC mute control */ -static int stac9460_adc_mute_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; - uinfo->count = 2; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = 1; - return 0; -} +#define stac9460_adc_mute_info snd_ctl_boolean_stereo_info static int stac9460_adc_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -292,14 +278,7 @@ static int aureon_get_headphone_amp(struct snd_ice1712 *ice) return ( tmp & AUREON_HP_SEL )!= 0; } -static int aureon_bool_info(struct snd_kcontrol *k, 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 aureon_bool_info snd_ctl_boolean_mono_info static int aureon_hpamp_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { diff --git a/sound/pci/ice1712/wtm.c b/sound/pci/ice1712/wtm.c index 04e535c8542..7fcce0a506d 100644 --- a/sound/pci/ice1712/wtm.c +++ b/sound/pci/ice1712/wtm.c @@ -71,14 +71,7 @@ static inline unsigned char stac9460_2_get(struct snd_ice1712 *ice, int reg) /* * DAC mute control */ -static int stac9460_dac_mute_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; - return 0; -} +#define stac9460_dac_mute_info snd_ctl_boolean_mono_info static int stac9460_dac_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) @@ -218,15 +211,7 @@ static int stac9460_dac_vol_put(struct snd_kcontrol *kcontrol, /* * ADC mute control */ -static int stac9460_adc_mute_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; - uinfo->count = 2; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = 1; - return 0; -} +#define stac9460_adc_mute_info snd_ctl_boolean_stereo_info static int stac9460_adc_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) @@ -357,15 +342,7 @@ static int stac9460_adc_vol_put(struct snd_kcontrol *kcontrol, * MIC / LINE switch fonction */ -static int stac9460_mic_sw_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 stac9460_mic_sw_info snd_ctl_boolean_mono_info static int stac9460_mic_sw_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) diff --git a/sound/pci/mixart/mixart_mixer.c b/sound/pci/mixart/mixart_mixer.c index d7d15c036e0..0e16512d25f 100644 --- a/sound/pci/mixart/mixart_mixer.c +++ b/sound/pci/mixart/mixart_mixer.c @@ -403,14 +403,7 @@ static struct snd_kcontrol_new mixart_control_analog_level = { }; /* shared */ -static int mixart_sw_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; - uinfo->count = 2; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = 1; - return 0; -} +#define mixart_sw_info snd_ctl_boolean_stereo_info static int mixart_audio_sw_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { diff --git a/sound/pci/pcxhr/pcxhr_mixer.c b/sound/pci/pcxhr/pcxhr_mixer.c index d9cc8d2beb6..b913453063f 100644 --- a/sound/pci/pcxhr/pcxhr_mixer.c +++ b/sound/pci/pcxhr/pcxhr_mixer.c @@ -144,14 +144,7 @@ static struct snd_kcontrol_new pcxhr_control_analog_level = { }; /* shared */ -static int pcxhr_sw_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; - uinfo->count = 2; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = 1; - return 0; -} +#define pcxhr_sw_info snd_ctl_boolean_stereo_info static int pcxhr_audio_sw_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) diff --git a/sound/pci/rme32.c b/sound/pci/rme32.c index 618653e2256..ee0189b756d 100644 --- a/sound/pci/rme32.c +++ b/sound/pci/rme32.c @@ -1582,16 +1582,8 @@ static void __devinit snd_rme32_proc_init(struct rme32 * rme32) * control interface */ -static int -snd_rme32_info_loopback_control(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_rme32_info_loopback_control snd_ctl_boolean_mono_info + static int snd_rme32_get_loopback_control(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) diff --git a/sound/pci/rme96.c b/sound/pci/rme96.c index e3304b7ccbc..9a4596f879e 100644 --- a/sound/pci/rme96.c +++ b/sound/pci/rme96.c @@ -1826,15 +1826,8 @@ snd_rme96_proc_init(struct rme96 *rme96) * control interface */ -static int -snd_rme96_info_loopback_control(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_rme96_info_loopback_control snd_ctl_boolean_mono_info + static int snd_rme96_get_loopback_control(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c index 3b3ef657f73..8f798f2fc04 100644 --- a/sound/pci/rme9652/hdsp.c +++ b/sound/pci/rme9652/hdsp.c @@ -1623,14 +1623,7 @@ static int hdsp_set_spdif_output(struct hdsp *hdsp, int out) return 0; } -static int snd_hdsp_info_spdif_bits(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_hdsp_info_spdif_bits snd_ctl_boolean_mono_info static int snd_hdsp_get_spdif_out(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -2111,14 +2104,7 @@ static int snd_hdsp_put_clock_source(struct snd_kcontrol *kcontrol, struct snd_c return change; } -static int snd_hdsp_info_clock_source_lock(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_hdsp_info_clock_source_lock snd_ctl_boolean_mono_info static int snd_hdsp_get_clock_source_lock(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -2420,14 +2406,7 @@ static int hdsp_set_xlr_breakout_cable(struct hdsp *hdsp, int mode) return 0; } -static int snd_hdsp_info_xlr_breakout_cable(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_hdsp_info_xlr_breakout_cable snd_ctl_boolean_mono_info static int snd_hdsp_get_xlr_breakout_cable(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -2483,14 +2462,7 @@ static int hdsp_set_aeb(struct hdsp *hdsp, int mode) return 0; } -static int snd_hdsp_info_aeb(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_hdsp_info_aeb snd_ctl_boolean_mono_info static int snd_hdsp_get_aeb(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -2729,14 +2701,7 @@ static int hdsp_set_line_output(struct hdsp *hdsp, int out) return 0; } -static int snd_hdsp_info_line_out(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_hdsp_info_line_out snd_ctl_boolean_mono_info static int snd_hdsp_get_line_out(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -2782,14 +2747,7 @@ static int hdsp_set_precise_pointer(struct hdsp *hdsp, int precise) return 0; } -static int snd_hdsp_info_precise_pointer(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_hdsp_info_precise_pointer snd_ctl_boolean_mono_info static int snd_hdsp_get_precise_pointer(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -2835,14 +2793,7 @@ static int hdsp_set_use_midi_tasklet(struct hdsp *hdsp, int use_tasklet) return 0; } -static int snd_hdsp_info_use_midi_tasklet(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_hdsp_info_use_midi_tasklet snd_ctl_boolean_mono_info static int snd_hdsp_get_use_midi_tasklet(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c index 143185e7e4d..83ea4623e77 100644 --- a/sound/pci/rme9652/hdspm.c +++ b/sound/pci/rme9652/hdspm.c @@ -1834,15 +1834,7 @@ static int hdspm_set_line_output(struct hdspm * hdspm, int out) return 0; } -static int snd_hdspm_info_line_out(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_hdspm_info_line_out snd_ctl_boolean_mono_info static int snd_hdspm_get_line_out(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) @@ -1897,15 +1889,7 @@ static int hdspm_set_tx_64(struct hdspm * hdspm, int out) return 0; } -static int snd_hdspm_info_tx_64(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_hdspm_info_tx_64 snd_ctl_boolean_mono_info static int snd_hdspm_get_tx_64(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) @@ -1960,15 +1944,7 @@ static int hdspm_set_c_tms(struct hdspm * hdspm, int out) return 0; } -static int snd_hdspm_info_c_tms(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_hdspm_info_c_tms snd_ctl_boolean_mono_info static int snd_hdspm_get_c_tms(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) @@ -2023,15 +1999,7 @@ static int hdspm_set_safe_mode(struct hdspm * hdspm, int out) return 0; } -static int snd_hdspm_info_safe_mode(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_hdspm_info_safe_mode snd_ctl_boolean_mono_info static int snd_hdspm_get_safe_mode(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) @@ -2086,15 +2054,7 @@ static int hdspm_set_emphasis(struct hdspm * hdspm, int emp) return 0; } -static int snd_hdspm_info_emphasis(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_hdspm_info_emphasis snd_ctl_boolean_mono_info static int snd_hdspm_get_emphasis(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) @@ -2149,15 +2109,7 @@ static int hdspm_set_dolby(struct hdspm * hdspm, int dol) return 0; } -static int snd_hdspm_info_dolby(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_hdspm_info_dolby snd_ctl_boolean_mono_info static int snd_hdspm_get_dolby(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) @@ -2212,15 +2164,7 @@ static int hdspm_set_professional(struct hdspm * hdspm, int dol) return 0; } -static int snd_hdspm_info_professional(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_hdspm_info_professional snd_ctl_boolean_mono_info static int snd_hdspm_get_professional(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) diff --git a/sound/pci/rme9652/rme9652.c b/sound/pci/rme9652/rme9652.c index 2de27405a0b..34f96f12e5b 100644 --- a/sound/pci/rme9652/rme9652.c +++ b/sound/pci/rme9652/rme9652.c @@ -1067,14 +1067,7 @@ static int rme9652_set_spdif_output(struct snd_rme9652 *rme9652, int out) return 0; } -static int snd_rme9652_info_spdif_out(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_rme9652_info_spdif_out snd_ctl_boolean_mono_info static int snd_rme9652_get_spdif_out(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -1338,14 +1331,7 @@ static int snd_rme9652_put_thru(struct snd_kcontrol *kcontrol, struct snd_ctl_el .put = snd_rme9652_put_passthru, \ .get = snd_rme9652_get_passthru } -static int snd_rme9652_info_passthru(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_rme9652_info_passthru snd_ctl_boolean_mono_info static int snd_rme9652_get_passthru(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -1445,14 +1431,7 @@ static int snd_rme9652_get_adat_sync(struct snd_kcontrol *kcontrol, struct snd_c .info = snd_rme9652_info_tc_valid, \ .get = snd_rme9652_get_tc_valid } -static int snd_rme9652_info_tc_valid(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_rme9652_info_tc_valid snd_ctl_boolean_mono_info static int snd_rme9652_get_tc_valid(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { diff --git a/sound/pci/trident/trident_main.c b/sound/pci/trident/trident_main.c index 7ca60627246..00e4004d563 100644 --- a/sound/pci/trident/trident_main.c +++ b/sound/pci/trident/trident_main.c @@ -2317,15 +2317,7 @@ int __devinit snd_trident_spdif_pcm(struct snd_trident * trident, Description: enable/disable S/PDIF out from ac97 mixer ---------------------------------------------------------------------------*/ -static int snd_trident_spdif_control_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_trident_spdif_control_info snd_ctl_boolean_mono_info static int snd_trident_spdif_control_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) @@ -2545,15 +2537,7 @@ static struct snd_kcontrol_new snd_trident_spdif_stream __devinitdata = Description: enable/disable rear path for ac97 ---------------------------------------------------------------------------*/ -static int snd_trident_ac97_control_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_trident_ac97_control_info snd_ctl_boolean_mono_info static int snd_trident_ac97_control_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c index 6ea09df0c73..5faa57956ca 100644 --- a/sound/pci/via82xx.c +++ b/sound/pci/via82xx.c @@ -1572,15 +1572,7 @@ static struct snd_kcontrol_new snd_via8233_capture_source __devinitdata = { .put = snd_via8233_capture_source_put, }; -static int snd_via8233_dxs3_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_via8233_dxs3_spdif_info snd_ctl_boolean_mono_info static int snd_via8233_dxs3_spdif_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c index ab7a81c3570..7fa57c9ecc5 100644 --- a/sound/pci/ymfpci/ymfpci_main.c +++ b/sound/pci/ymfpci/ymfpci_main.c @@ -1443,22 +1443,7 @@ static struct snd_kcontrol_new snd_ymfpci_drec_source __devinitdata = { .get = snd_ymfpci_get_single, .put = snd_ymfpci_put_single, \ .private_value = ((reg) | ((shift) << 16)) } -static int snd_ymfpci_info_single(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - int reg = kcontrol->private_value & 0xffff; - - switch (reg) { - case YDSXGR_SPDIFOUTCTRL: break; - case YDSXGR_SPDIFINCTRL: break; - default: return -EINVAL; - } - uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; - uinfo->count = 1; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = 1; - return 0; -} +#define snd_ymfpci_info_single snd_ctl_boolean_mono_info static int snd_ymfpci_get_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) @@ -1570,14 +1555,7 @@ static int snd_ymfpci_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_e /* * 4ch duplication */ -static int snd_ymfpci_info_dup4ch(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_ymfpci_info_dup4ch snd_ctl_boolean_mono_info static int snd_ymfpci_get_dup4ch(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -1665,14 +1643,7 @@ static int snd_ymfpci_set_gpio_out(struct snd_ymfpci *chip, int pin, int enable) return 0; } -static int snd_ymfpci_gpio_sw_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_ymfpci_gpio_sw_info snd_ctl_boolean_mono_info static int snd_ymfpci_gpio_sw_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { -- cgit v1.2.3 From 177a7cdbd1d88be5cbf957a2793a59ffa50cbef9 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 23 Jul 2007 17:38:44 +0200 Subject: [ALSA] ymfpci: fix volume handling of the 44.1 kHz slot The existing code for handling the 44.1 slot's volume has two problems: the volume is not affected by the 'Wave Playback Volume' mixer control, and the BUF441OUTVOL register, which is used to control the per- substream volume for this slot, uses a different scale than the gain fields of the other slots. This patch makes the BUF441OUTVOL register a shadow of the NATIVEDACOUTVOL register so that the Wave volume is consistent for all substreams. As a consequence of this, the per-substream PCM volume control gets no longer activated for the substream using this slot. The code for (de)activating the mixer control is moved from the open/close to the prepare/trigger_stop callbacks so that it is able to determine the substream's slot. Signed-off-by: Clemens Ladisch Signed-off-by: Jaroslav Kysela --- sound/pci/ymfpci/ymfpci_main.c | 70 +++++++++++++++++++++++++++--------------- 1 file changed, 46 insertions(+), 24 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c index 7fa57c9ecc5..e33e4aa6855 100644 --- a/sound/pci/ymfpci/ymfpci_main.c +++ b/sound/pci/ymfpci/ymfpci_main.c @@ -171,17 +171,6 @@ static u32 snd_ymfpci_calc_lpfQ(u32 rate) return val[0]; } -static void snd_ymfpci_pcm_441_volume_set(struct snd_ymfpci_pcm *ypcm) -{ - unsigned int value; - struct snd_ymfpci_pcm_mixer *mixer; - - mixer = &ypcm->chip->pcm_mixer[ypcm->substream->number]; - value = min_t(unsigned int, mixer->left, 0x7fff) >> 1; - value |= (min_t(unsigned int, mixer->right, 0x7fff) >> 1) << 16; - snd_ymfpci_writel(ypcm->chip, YDSXGR_BUF441OUTVOL, value); -} - /* * Hardware start management */ @@ -389,6 +378,7 @@ static int snd_ymfpci_playback_trigger(struct snd_pcm_substream *substream, { struct snd_ymfpci *chip = snd_pcm_substream_chip(substream); struct snd_ymfpci_pcm *ypcm = substream->runtime->private_data; + struct snd_kcontrol *kctl = NULL; int result = 0; spin_lock(&chip->reg_lock); @@ -406,6 +396,11 @@ static int snd_ymfpci_playback_trigger(struct snd_pcm_substream *substream, ypcm->running = 1; break; case SNDRV_PCM_TRIGGER_STOP: + if (substream->pcm == chip->pcm && !ypcm->use_441_slot) { + kctl = chip->pcm_mixer[substream->number].ctl; + kctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE; + } + /* fall through */ case SNDRV_PCM_TRIGGER_PAUSE_PUSH: case SNDRV_PCM_TRIGGER_SUSPEND: chip->ctrl_playback[ypcm->voices[0]->number + 1] = 0; @@ -419,6 +414,8 @@ static int snd_ymfpci_playback_trigger(struct snd_pcm_substream *substream, } __unlock: spin_unlock(&chip->reg_lock); + if (kctl) + snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_INFO, &kctl->id); return result; } static int snd_ymfpci_capture_trigger(struct snd_pcm_substream *substream, @@ -526,7 +523,6 @@ static void snd_ymfpci_pcm_init_voice(struct snd_ymfpci_pcm *ypcm, unsigned int ypcm->chip->src441_used = voice->number; ypcm->use_441_slot = 1; format |= 0x10000000; - snd_ymfpci_pcm_441_volume_set(ypcm); } if (ypcm->chip->src441_used == voice->number && (format & 0x10000000) == 0) { @@ -667,6 +663,7 @@ static int snd_ymfpci_playback_prepare(struct snd_pcm_substream *substream) struct snd_ymfpci *chip = snd_pcm_substream_chip(substream); struct snd_pcm_runtime *runtime = substream->runtime; struct snd_ymfpci_pcm *ypcm = runtime->private_data; + struct snd_kcontrol *kctl; unsigned int nvoice; ypcm->period_size = runtime->period_size; @@ -676,6 +673,12 @@ static int snd_ymfpci_playback_prepare(struct snd_pcm_substream *substream) for (nvoice = 0; nvoice < runtime->channels; nvoice++) snd_ymfpci_pcm_init_voice(ypcm, nvoice, runtime, substream->pcm == chip->pcm); + + if (substream->pcm == chip->pcm && !ypcm->use_441_slot) { + kctl = chip->pcm_mixer[substream->number].ctl; + kctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE; + snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_INFO, &kctl->id); + } return 0; } @@ -926,7 +929,6 @@ static int snd_ymfpci_playback_open(struct snd_pcm_substream *substream) struct snd_ymfpci *chip = snd_pcm_substream_chip(substream); struct snd_pcm_runtime *runtime = substream->runtime; struct snd_ymfpci_pcm *ypcm; - struct snd_kcontrol *kctl; int err; if ((err = snd_ymfpci_playback_open_1(substream)) < 0) @@ -941,10 +943,6 @@ static int snd_ymfpci_playback_open(struct snd_pcm_substream *substream) chip->rear_opened++; } spin_unlock_irq(&chip->reg_lock); - - kctl = chip->pcm_mixer[substream->number].ctl; - kctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE; - snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_INFO, &kctl->id); return 0; } @@ -1039,7 +1037,6 @@ static int snd_ymfpci_playback_close(struct snd_pcm_substream *substream) { struct snd_ymfpci *chip = snd_pcm_substream_chip(substream); struct snd_ymfpci_pcm *ypcm = substream->runtime->private_data; - struct snd_kcontrol *kctl; spin_lock_irq(&chip->reg_lock); if (ypcm->output_rear && chip->rear_opened > 0) { @@ -1047,9 +1044,6 @@ static int snd_ymfpci_playback_close(struct snd_pcm_substream *substream) ymfpci_close_extension(chip); } spin_unlock_irq(&chip->reg_lock); - kctl = chip->pcm_mixer[substream->number].ctl; - kctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE; - snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_INFO, &kctl->id); return snd_ymfpci_playback_close_1(substream); } @@ -1552,6 +1546,26 @@ static int snd_ymfpci_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_e return change; } +static int snd_ymfpci_put_nativedacvol(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_ymfpci *chip = snd_kcontrol_chip(kcontrol); + unsigned int reg = YDSXGR_NATIVEDACOUTVOL; + unsigned int reg2 = YDSXGR_BUF441OUTVOL; + int change; + unsigned int value, oval; + + value = ucontrol->value.integer.value[0] & 0x3fff; + value |= (ucontrol->value.integer.value[1] & 0x3fff) << 16; + spin_lock_irq(&chip->reg_lock); + oval = snd_ymfpci_readl(chip, reg); + change = value != oval; + snd_ymfpci_writel(chip, reg, value); + snd_ymfpci_writel(chip, reg2, value); + spin_unlock_irq(&chip->reg_lock); + return change; +} + /* * 4ch duplication */ @@ -1576,7 +1590,17 @@ static int snd_ymfpci_put_dup4ch(struct snd_kcontrol *kcontrol, struct snd_ctl_e static struct snd_kcontrol_new snd_ymfpci_controls[] __devinitdata = { -YMFPCI_DOUBLE("Wave Playback Volume", 0, YDSXGR_NATIVEDACOUTVOL), +{ + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Wave Playback Volume", + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | + SNDRV_CTL_ELEM_ACCESS_TLV_READ, + .info = snd_ymfpci_info_double, + .get = snd_ymfpci_get_double, + .put = snd_ymfpci_put_nativedacvol, + .private_value = YDSXGR_NATIVEDACOUTVOL, + .tlv = { .p = db_scale_native }, +}, YMFPCI_DOUBLE("Wave Capture Volume", 0, YDSXGR_NATIVEDACLOOPVOL), YMFPCI_DOUBLE("Digital Capture Volume", 0, YDSXGR_NATIVEDACINVOL), YMFPCI_DOUBLE("Digital Capture Volume", 1, YDSXGR_NATIVEADCINVOL), @@ -1719,8 +1743,6 @@ static int snd_ymfpci_pcm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ymfpci_pcm *ypcm = substream->runtime->private_data; if (!ypcm->use_441_slot) ypcm->update_pcm_vol = 2; - else - snd_ymfpci_pcm_441_volume_set(ypcm); } spin_unlock_irqrestore(&chip->voice_lock, flags); return 1; -- cgit v1.2.3 From 42f53226953b0f2ad16bf55d0c11e08fe86c3666 Mon Sep 17 00:00:00 2001 From: James Courtier-Dutton Date: Mon, 23 Jul 2007 17:52:27 +0100 Subject: [ALSA] snd-emu10k1:Improves firmware loading for E-Mu cards. Details: Fixes http://bugzilla.kernel.org/show_bug.cgi?id=8176 Signed-off-by: James Courtier-Dutton Signed-off-by: Jaroslav Kysela --- sound/pci/emu10k1/emu10k1_main.c | 103 +++++++++++++++++++++++---------------- 1 file changed, 61 insertions(+), 42 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c index 404ae1be0a4..800d6348de7 100644 --- a/sound/pci/emu10k1/emu10k1_main.c +++ b/sound/pci/emu10k1/emu10k1_main.c @@ -31,6 +31,8 @@ * */ +#include +#include #include #include #include @@ -702,6 +704,59 @@ 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); + } + } + return 0; +} + /* * EMU-1010 - details found out from this driver, official MS Win drivers, * testing the card: @@ -1004,49 +1059,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 */ @@ -1173,6 +1191,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); -- cgit v1.2.3 From aaccf54f638dfd39ebd1220936b0ce261e5fced7 Mon Sep 17 00:00:00 2001 From: James Courtier-Dutton Date: Mon, 23 Jul 2007 18:12:41 +0100 Subject: [ALSA] snd-ca0106:Add recognition for new variant. Fixes ALSA bug#3251 Signed-off-by: James Courtier-Dutton Signed-off-by: Jaroslav Kysela --- sound/pci/ca0106/ca0106_main.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'sound/pci') diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c index fcab8fb97e3..58ffa0cacfb 100644 --- a/sound/pci/ca0106/ca0106_main.c +++ b/sound/pci/ca0106/ca0106_main.c @@ -170,6 +170,15 @@ MODULE_PARM_DESC(subsystem, "Force card subsystem model."); static struct snd_ca0106_details ca0106_chip_details[] = { /* Sound Blaster X-Fi Extreme Audio. This does not have an AC97. 53SB079000000 */ /* It is really just a normal SB Live 24bit. */ + /* Tested: + * See ALSA bug#3251 + */ + { .serial = 0x10131102, + .name = "X-Fi Extreme Audio [SBxxxx]", + .gpio_type = 1, + .i2c_adc = 1 } , + /* Sound Blaster X-Fi Extreme Audio. This does not have an AC97. 53SB079000000 */ + /* It is really just a normal SB Live 24bit. */ /* * CTRL:CA0111-WTLF * ADC: WM8775SEDS -- cgit v1.2.3 From edec7bbb22dafdab5f8eae4f049ad9d0f615abc4 Mon Sep 17 00:00:00 2001 From: James Courtier-Dutton Date: Mon, 23 Jul 2007 20:30:22 +0100 Subject: [ALSA] snd-emu10k1:Support for ADAT and S/PDIF. Patch submitted by Ctirad Fertr Signed-off-by: James Courtier-Dutton Signed-off-by: Jaroslav Kysela --- sound/pci/emu10k1/emu10k1_main.c | 6 ++--- sound/pci/emu10k1/emumixer.c | 52 +++++++++++++++++++++++++++++++++++----- 2 files changed, 49 insertions(+), 9 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c index 800d6348de7..b985e660c60 100644 --- a/sound/pci/emu10k1/emu10k1_main.c +++ b/sound/pci/emu10k1/emu10k1_main.c @@ -872,8 +872,8 @@ 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 */ + snd_emu1010_fpga_write(emu, EMU_HANA_OPTICAL_TYPE, EMU_HANA_OPTICAL_IN_ADAT | EMU_HANA_OPTICAL_OUT_ADAT ); 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 ); @@ -1150,7 +1150,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 */ diff --git a/sound/pci/emu10k1/emumixer.c b/sound/pci/emu10k1/emumixer.c index 6c26319430d..692b871bff5 100644 --- a/sound/pci/emu10k1/emumixer.c +++ b/sound/pci/emu10k1/emumixer.c @@ -501,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, @@ -569,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; -- cgit v1.2.3 From 00283886fae4005feeb84bddda6cf5da5675be4d Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 24 Jul 2007 11:21:21 +0200 Subject: [ALSA] ice1712 - Fix missing replacement to snd_ctl_boolean_mono_info There were some places I forgot to replace with snd_ctl_boolean_mono_info. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/ice1712/ice1712.c | 2 -- sound/pci/ice1712/ice1712.h | 3 +-- 2 files changed, 1 insertion(+), 4 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c index cd41c7eb6c6..caa0886d460 100644 --- a/sound/pci/ice1712/ice1712.c +++ b/sound/pci/ice1712/ice1712.c @@ -1745,8 +1745,6 @@ static struct snd_kcontrol_new snd_ice1712_spdif_stream __devinitdata = .put = snd_ice1712_spdif_stream_put }; -#define snd_ice1712_gpio_info snd_ctl_boolean_mono_info - int snd_ice1712_gpio_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { diff --git a/sound/pci/ice1712/ice1712.h b/sound/pci/ice1712/ice1712.h index 6ac486d9c13..d072f7b98b2 100644 --- a/sound/pci/ice1712/ice1712.h +++ b/sound/pci/ice1712/ice1712.h @@ -451,11 +451,10 @@ static inline void snd_ice1712_restore_gpio_status(struct snd_ice1712 *ice) /* for bit controls */ #define ICE1712_GPIO(xiface, xname, xindex, mask, invert, xaccess) \ -{ .iface = xiface, .name = xname, .access = xaccess, .info = snd_ice1712_gpio_info, \ +{ .iface = xiface, .name = xname, .access = xaccess, .info = snd_ctl_boolean_mono_info, \ .get = snd_ice1712_gpio_get, .put = snd_ice1712_gpio_put, \ .private_value = mask | (invert << 24) } -int snd_ice1712_gpio_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo); int snd_ice1712_gpio_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); int snd_ice1712_gpio_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); -- cgit v1.2.3 From 69b311a4dabc9163288be1fe993cb7db47541e67 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Tue, 24 Jul 2007 11:56:45 +0200 Subject: [ALSA] sound/pci/cs46xx/: fix an off-by-one This patch fixes an off-by-one in a snd_assert() spotted by the Coverity checker. Signed-off-by: Adrian Bunk Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/cs46xx/dsp_spos_scb_lib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound/pci') diff --git a/sound/pci/cs46xx/dsp_spos_scb_lib.c b/sound/pci/cs46xx/dsp_spos_scb_lib.c index 57e357de150..eded4dfeba1 100644 --- a/sound/pci/cs46xx/dsp_spos_scb_lib.c +++ b/sound/pci/cs46xx/dsp_spos_scb_lib.c @@ -1480,7 +1480,7 @@ void cs46xx_dsp_destroy_pcm_channel (struct snd_cs46xx * chip, if (!pcm_channel->src_scb->ref_count) { cs46xx_dsp_remove_scb(chip,pcm_channel->src_scb); - snd_assert (pcm_channel->src_slot >= 0 && pcm_channel->src_slot <= DSP_MAX_SRC_NR, + snd_assert (pcm_channel->src_slot >= 0 && pcm_channel->src_slot < DSP_MAX_SRC_NR, return ); ins->src_scb_slots[pcm_channel->src_slot] = 0; -- cgit v1.2.3 From b18cd538a92247307247a53f57c477edbcedbb79 Mon Sep 17 00:00:00 2001 From: Trent Piepho Date: Tue, 24 Jul 2007 12:06:16 +0200 Subject: [ALSA] ca0106: Add analog mute controls for cards with SPI DAC Add four mute controls for the analog output channels for cards that use an SPI DAC, like the SB0570 SB Live! 24-bit / Audigy SE. The Wolfson DAC doesn't support muting left/right so the controls are mono. The chip state struct gets a 32-byte array to act as a shadow of the spi dac registers. Only two registers are used for mute, but more would be needed for analog gain, de-emphasis, DAC power down, phase inversion, and other features. Signed-off-by: Trent Piepho Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/ca0106/ca0106.h | 47 ++++++++++++++++++++++++++-- sound/pci/ca0106/ca0106_main.c | 11 +++++-- sound/pci/ca0106/ca0106_mixer.c | 69 ++++++++++++++++++++++++++++++++++++++++- 3 files changed, 122 insertions(+), 5 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/ca0106/ca0106.h b/sound/pci/ca0106/ca0106.h index a0420bc63f0..7ad03c6afd4 100644 --- a/sound/pci/ca0106/ca0106.h +++ b/sound/pci/ca0106/ca0106.h @@ -1,7 +1,7 @@ /* * Copyright (c) 2004 James Courtier-Dutton * Driver CA0106 chips. e.g. Sound Blaster Audigy LS and Live 24bit - * Version: 0.0.21 + * Version: 0.0.22 * * FEATURES currently supported: * See ca0106_main.c for features. @@ -47,6 +47,8 @@ * Added GPIO info for SB Live 24bit. * 0.0.21 * Implement support for Line-in capture on SB Live 24bit. + * 0.0.22 + * Add support for mute control on SB Live 24bit (cards w/ SPI DAC) * * * This code was initally based on code from ALSA's emu10k1x.c which is: @@ -552,6 +554,44 @@ #define CONTROL_CENTER_LFE_CHANNEL 1 #define CONTROL_UNKNOWN_CHANNEL 2 + +/* Based on WM8768 Datasheet Rev 4.2 page 32 */ +#define SPI_REG_MASK 0x1ff /* 16-bit SPI writes have a 7-bit address */ +#define SPI_REG_SHIFT 9 /* followed by 9 bits of data */ + +/* They really do label the bit for the 4th channel "4" and not "3" */ +#define SPI_DMUTE0_REG 9 +#define SPI_DMUTE1_REG 9 +#define SPI_DMUTE2_REG 9 +#define SPI_DMUTE4_REG 15 +#define SPI_DMUTE0_BIT 3 +#define SPI_DMUTE1_BIT 4 +#define SPI_DMUTE2_BIT 5 +#define SPI_DMUTE4_BIT 2 + +#define SPI_PHASE0_REG 3 +#define SPI_PHASE1_REG 3 +#define SPI_PHASE2_REG 3 +#define SPI_PHASE4_REG 15 +#define SPI_PHASE0_BIT 6 +#define SPI_PHASE1_BIT 7 +#define SPI_PHASE2_BIT 8 +#define SPI_PHASE4_BIT 3 + +#define SPI_PDWN_REG 2 /* power down all DACs */ +#define SPI_PDWN_BIT 2 +#define SPI_DACD0_REG 10 /* power down individual DACs */ +#define SPI_DACD1_REG 10 +#define SPI_DACD2_REG 10 +#define SPI_DACD4_REG 15 +#define SPI_DACD0_BIT 1 +#define SPI_DACD1_BIT 2 +#define SPI_DACD2_BIT 3 +#define SPI_DACD4_BIT 1 + +#define SPI_PWRDNALL_REG 10 /* power down everything */ +#define SPI_PWRDNALL_BIT 4 + #include "ca_midi.h" struct snd_ca0106; @@ -611,6 +651,8 @@ struct snd_ca0106 { struct snd_ca_midi midi; struct snd_ca_midi midi2; + + u16 spi_dac_reg[16]; }; int snd_ca0106_mixer(struct snd_ca0106 *emu); @@ -627,4 +669,5 @@ void snd_ca0106_ptr_write(struct snd_ca0106 *emu, int snd_ca0106_i2c_write(struct snd_ca0106 *emu, u32 reg, u32 value); - +int snd_ca0106_spi_write(struct snd_ca0106 * emu, + unsigned int data); diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c index 58ffa0cacfb..512fda946c6 100644 --- a/sound/pci/ca0106/ca0106_main.c +++ b/sound/pci/ca0106/ca0106_main.c @@ -1,7 +1,7 @@ /* * Copyright (c) 2004 James Courtier-Dutton * Driver CA0106 chips. e.g. Sound Blaster Audigy LS and Live 24bit - * Version: 0.0.23 + * Version: 0.0.24 * * FEATURES currently supported: * Front, Rear and Center/LFE. @@ -79,6 +79,8 @@ * Add support for MSI K8N Diamond Motherboard with onboard SB Live 24bit without AC97. From kiksen, bug #901 * 0.0.23 * Implement support for Line-in capture on SB Live 24bit. + * 0.0.24 + * Add support for mute control on SB Live 24bit (cards w/ SPI DAC) * * BUGS: * Some stability problems when unloading the snd-ca0106 kernel module. @@ -1484,8 +1486,13 @@ static int __devinit snd_ca0106_create(int dev, struct snd_card *card, int size, n; size = ARRAY_SIZE(spi_dac_init); - for (n=0; n < size; n++) + for (n = 0; n < size; n++) { + int reg = spi_dac_init[n] >> SPI_REG_SHIFT; + snd_ca0106_spi_write(chip, spi_dac_init[n]); + if (reg < ARRAY_SIZE(chip->spi_dac_reg)) + chip->spi_dac_reg[reg] = spi_dac_init[n]; + } } if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, diff --git a/sound/pci/ca0106/ca0106_mixer.c b/sound/pci/ca0106/ca0106_mixer.c index a135b9c4c3c..7fbfe17438b 100644 --- a/sound/pci/ca0106/ca0106_mixer.c +++ b/sound/pci/ca0106/ca0106_mixer.c @@ -1,7 +1,7 @@ /* * Copyright (c) 2004 James Courtier-Dutton * Driver CA0106 chips. e.g. Sound Blaster Audigy LS and Live 24bit - * Version: 0.0.17 + * Version: 0.0.18 * * FEATURES currently supported: * See ca0106_main.c for features. @@ -39,6 +39,8 @@ * Modified Copyright message. * 0.0.17 * Implement Mic and Line in Capture. + * 0.0.18 + * Add support for mute control on SB Live 24bit (cards w/ SPI DAC) * * This code was initally based on code from ALSA's emu10k1x.c which is: * Copyright (c) by Francisco Moraes @@ -462,6 +464,42 @@ static int snd_ca0106_i2c_volume_put(struct snd_kcontrol *kcontrol, return change; } +#define spi_mute_info snd_ctl_boolean_mono_info + +static int spi_mute_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol); + unsigned int reg = kcontrol->private_value >> SPI_REG_SHIFT; + unsigned int bit = kcontrol->private_value & SPI_REG_MASK; + + ucontrol->value.integer.value[0] = !(emu->spi_dac_reg[reg] & bit); + return 0; +} + +static int spi_mute_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol); + unsigned int reg = kcontrol->private_value >> SPI_REG_SHIFT; + unsigned int bit = kcontrol->private_value & SPI_REG_MASK; + int ret; + + ret = emu->spi_dac_reg[reg] & bit; + if (ucontrol->value.integer.value[0]) { + if (!ret) /* bit already cleared, do nothing */ + return 0; + emu->spi_dac_reg[reg] &= ~bit; + } else { + if (ret) /* bit already set, do nothing */ + return 0; + emu->spi_dac_reg[reg] |= bit; + } + + ret = snd_ca0106_spi_write(emu, emu->spi_dac_reg[reg]); + return ret ? -1 : 1; +} + #define CA_VOLUME(xname,chid,reg) \ { \ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ @@ -554,6 +592,28 @@ static struct snd_kcontrol_new snd_ca0106_volume_i2c_adc_ctls[] __devinitdata = I2C_VOLUME("Aux Capture Volume", 3), }; +#define SPI_SWITCH(xname,reg,bit) \ +{ \ + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \ + .info = spi_mute_info, \ + .get = spi_mute_get, \ + .put = spi_mute_put, \ + .private_value = (reg<details->spi_dac == 1) { + for (i = 0; i < ARRAY_SIZE(snd_ca0106_volume_spi_dac_ctls); i++) { + err = snd_ctl_add(card, snd_ctl_new1(&snd_ca0106_volume_spi_dac_ctls[i], emu)); + if (err < 0) + return err; + } + } return 0; } -- cgit v1.2.3 From fca7f38892fa713d5221e26fd3ee57817b4bc031 Mon Sep 17 00:00:00 2001 From: Trent Piepho Date: Tue, 24 Jul 2007 12:10:34 +0200 Subject: [ALSA] ca0106: replaced control add sequences with macro Turn a rather long lined for loop that is duplicated multiple times into a macro. Signed-off-by: Trent Piepho Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/ca0106/ca0106_mixer.c | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/ca0106/ca0106_mixer.c b/sound/pci/ca0106/ca0106_mixer.c index 7fbfe17438b..18a0525a6b5 100644 --- a/sound/pci/ca0106/ca0106_mixer.c +++ b/sound/pci/ca0106/ca0106_mixer.c @@ -643,9 +643,19 @@ static int __devinit rename_ctl(struct snd_card *card, const char *src, const ch return -ENOENT; } +#define ADD_CTLS(emu, ctls) \ + do { \ + int i, err; \ + for (i = 0; i < ARRAY_SIZE(ctls); i++) { \ + err = snd_ctl_add(card, snd_ctl_new1(&ctls[i], emu)); \ + if (err < 0) \ + return err; \ + } \ + } while (0) + int __devinit snd_ca0106_mixer(struct snd_ca0106 *emu) { - int i, err; + int err; struct snd_card *card = emu->card; char **c; static char *ca0106_remove_ctls[] = { @@ -692,17 +702,9 @@ int __devinit snd_ca0106_mixer(struct snd_ca0106 *emu) rename_ctl(card, c[0], c[1]); #endif - for (i = 0; i < ARRAY_SIZE(snd_ca0106_volume_ctls); i++) { - err = snd_ctl_add(card, snd_ctl_new1(&snd_ca0106_volume_ctls[i], emu)); - if (err < 0) - return err; - } + ADD_CTLS(emu, snd_ca0106_volume_ctls); if (emu->details->i2c_adc == 1) { - for (i = 0; i < ARRAY_SIZE(snd_ca0106_volume_i2c_adc_ctls); i++) { - err = snd_ctl_add(card, snd_ctl_new1(&snd_ca0106_volume_i2c_adc_ctls[i], emu)); - if (err < 0) - return err; - } + ADD_CTLS(emu, snd_ca0106_volume_i2c_adc_ctls); 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 */ @@ -710,13 +712,8 @@ int __devinit snd_ca0106_mixer(struct snd_ca0106 *emu) if (err < 0) return err; } - if (emu->details->spi_dac == 1) { - for (i = 0; i < ARRAY_SIZE(snd_ca0106_volume_spi_dac_ctls); i++) { - err = snd_ctl_add(card, snd_ctl_new1(&snd_ca0106_volume_spi_dac_ctls[i], emu)); - if (err < 0) - return err; - } - } + if (emu->details->spi_dac == 1) + ADD_CTLS(emu, snd_ca0106_volume_spi_dac_ctls); return 0; } -- cgit v1.2.3 From bddcf5411ffd17bfb86c2baed4a1b859c7071c98 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 24 Jul 2007 18:04:05 +0200 Subject: [ALSA] hda-codec - Fix AD1988 SPDIF output The SPDIF output on AD1988 had some problems due to the wrongly routed analog loopback to SPDIF. This patch fixes the implementation of 'IEC958 Playback Source' mixer to handle the amp bits of mixer widget 0x1d correctly. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_analog.c | 45 ++++++++++++++++++++++++++++++-------------- 1 file changed, 31 insertions(+), 14 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index fafadf9fab8..488724f2e30 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c @@ -1889,16 +1889,19 @@ static int ad1988_spdif_playback_source_get(struct snd_kcontrol *kcontrol, struct hda_codec *codec = snd_kcontrol_chip(kcontrol); unsigned int sel; - sel = snd_hda_codec_read(codec, 0x02, 0, AC_VERB_GET_CONNECT_SEL, 0); - if (sel > 0) { + sel = snd_hda_codec_read(codec, 0x1d, 0, AC_VERB_GET_AMP_GAIN_MUTE, + AC_AMP_GET_INPUT); + if (!(sel & 0x80)) + ucontrol->value.enumerated.item[0] = 0; + else { sel = snd_hda_codec_read(codec, 0x0b, 0, AC_VERB_GET_CONNECT_SEL, 0); if (sel < 3) sel++; else sel = 0; + ucontrol->value.enumerated.item[0] = sel; } - ucontrol->value.enumerated.item[0] = sel; return 0; } @@ -1910,17 +1913,32 @@ static int ad1988_spdif_playback_source_put(struct snd_kcontrol *kcontrol, int change; val = ucontrol->value.enumerated.item[0]; - sel = snd_hda_codec_read(codec, 0x02, 0, AC_VERB_GET_CONNECT_SEL, 0); if (!val) { - change = sel != 0; - if (change || codec->in_resume) - snd_hda_codec_write(codec, 0x02, 0, - AC_VERB_SET_CONNECT_SEL, 0); + sel = snd_hda_codec_read(codec, 0x1d, 0, + AC_VERB_GET_AMP_GAIN_MUTE, + AC_AMP_GET_INPUT); + change = sel & 0x80; + if (change || codec->in_resume) { + snd_hda_codec_write(codec, 0x1d, 0, + AC_VERB_SET_AMP_GAIN_MUTE, + AMP_IN_UNMUTE(0)); + snd_hda_codec_write(codec, 0x1d, 0, + AC_VERB_SET_AMP_GAIN_MUTE, + AMP_IN_MUTE(1)); + } } else { - change = sel == 0; - if (change || codec->in_resume) - snd_hda_codec_write(codec, 0x02, 0, - AC_VERB_SET_CONNECT_SEL, 1); + sel = snd_hda_codec_read(codec, 0x1d, 0, + AC_VERB_GET_AMP_GAIN_MUTE, + AC_AMP_GET_INPUT | 0x01); + change = sel & 0x80; + if (change || codec->in_resume) { + snd_hda_codec_write(codec, 0x1d, 0, + AC_VERB_SET_AMP_GAIN_MUTE, + AMP_IN_MUTE(0)); + snd_hda_codec_write(codec, 0x1d, 0, + AC_VERB_SET_AMP_GAIN_MUTE, + AMP_IN_UNMUTE(1)); + } sel = snd_hda_codec_read(codec, 0x0b, 0, AC_VERB_GET_CONNECT_SEL, 0) + 1; change |= sel != val; @@ -2039,10 +2057,9 @@ static struct hda_verb ad1988_spdif_init_verbs[] = { {0x02, AC_VERB_SET_CONNECT_SEL, 0x0}, /* PCM */ {0x0b, AC_VERB_SET_CONNECT_SEL, 0x0}, /* ADC1 */ {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, + {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* SPDIF out pin */ {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */ - {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x17}, /* 0dB */ { } }; -- cgit v1.2.3 From 485100706b4b397f8072c756839878f634e21f85 Mon Sep 17 00:00:00 2001 From: Trent Piepho Date: Wed, 25 Jul 2007 18:39:59 +0200 Subject: [ALSA] ca0106: power down SPI DAC channels when not in use For cards with an SPI DAC (SB Live 24-bit / Audigy SE), power down channels 0-2 when not in use. They are powered up on PCM open and down again on PCM close. Channel 4 (== Front) is not powered down, as it is used for capture feedback. Powering it down would effectively kill line in pass-through. Signed-off-by: Trent Piepho Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/ca0106/ca0106.h | 2 +- sound/pci/ca0106/ca0106_main.c | 37 +++++++++++++++++++++++++++++++++++-- 2 files changed, 36 insertions(+), 3 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/ca0106/ca0106.h b/sound/pci/ca0106/ca0106.h index 7ad03c6afd4..47d92382140 100644 --- a/sound/pci/ca0106/ca0106.h +++ b/sound/pci/ca0106/ca0106.h @@ -587,7 +587,7 @@ #define SPI_DACD0_BIT 1 #define SPI_DACD1_BIT 2 #define SPI_DACD2_BIT 3 -#define SPI_DACD4_BIT 1 +#define SPI_DACD4_BIT 0 /* datasheet error says it's 1 */ #define SPI_PWRDNALL_REG 10 /* power down everything */ #define SPI_PWRDNALL_BIT 4 diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c index 512fda946c6..36b7cdda7c4 100644 --- a/sound/pci/ca0106/ca0106_main.c +++ b/sound/pci/ca0106/ca0106_main.c @@ -1,7 +1,7 @@ /* * Copyright (c) 2004 James Courtier-Dutton * Driver CA0106 chips. e.g. Sound Blaster Audigy LS and Live 24bit - * Version: 0.0.24 + * Version: 0.0.25 * * FEATURES currently supported: * Front, Rear and Center/LFE. @@ -81,6 +81,8 @@ * Implement support for Line-in capture on SB Live 24bit. * 0.0.24 * Add support for mute control on SB Live 24bit (cards w/ SPI DAC) + * 0.0.25 + * Powerdown SPI DAC channels when not in use * * BUGS: * Some stability problems when unloading the snd-ca0106 kernel module. @@ -458,6 +460,19 @@ static void snd_ca0106_pcm_free_substream(struct snd_pcm_runtime *runtime) kfree(runtime->private_data); } +static const int spi_dacd_reg[] = { + [PCM_FRONT_CHANNEL] = SPI_DACD4_REG, + [PCM_REAR_CHANNEL] = SPI_DACD0_REG, + [PCM_CENTER_LFE_CHANNEL]= SPI_DACD2_REG, + [PCM_UNKNOWN_CHANNEL] = SPI_DACD1_REG, +}; +static const int spi_dacd_bit[] = { + [PCM_FRONT_CHANNEL] = 1<details->spi_dac && channel_id != PCM_FRONT_CHANNEL) { + const int reg = spi_dacd_reg[channel_id]; + + /* Power up dac */ + chip->spi_dac_reg[reg] &= ~spi_dacd_bit[channel_id]; + err = snd_ca0106_spi_write(chip, chip->spi_dac_reg[reg]); + if (err < 0) + return err; + } return 0; } @@ -502,6 +527,14 @@ static int snd_ca0106_pcm_close_playback(struct snd_pcm_substream *substream) struct snd_pcm_runtime *runtime = substream->runtime; struct snd_ca0106_pcm *epcm = runtime->private_data; chip->playback_channels[epcm->channel_id].use = 0; + + if (chip->details->spi_dac && epcm->channel_id != PCM_FRONT_CHANNEL) { + const int reg = spi_dacd_reg[epcm->channel_id]; + + /* Power down DAC */ + chip->spi_dac_reg[reg] |= spi_dacd_bit[epcm->channel_id]; + snd_ca0106_spi_write(chip, chip->spi_dac_reg[reg]); + } /* FIXME: maybe zero others */ return 0; } @@ -1246,7 +1279,7 @@ static unsigned int spi_dac_init[] = { 0x0530, 0x0602, 0x0622, - 0x1400, + 0x140e, }; static unsigned int i2c_adc_init[][2] = { -- cgit v1.2.3 From 18b5d32f201462ef7ed3c01773a88b4645128158 Mon Sep 17 00:00:00 2001 From: Trent Piepho Date: Wed, 25 Jul 2007 18:40:39 +0200 Subject: [ALSA] ca0106: Add more symbol SPI register names and use them Add more symbol name for SPI register values. Change the SPI_XXX_BIT defines from the bit number to a mask. Saves having to write (1< Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/ca0106/ca0106.h | 79 +++++++++++++++++++++++++++++++++-------- sound/pci/ca0106/ca0106_main.c | 51 +++++++++++++------------- sound/pci/ca0106/ca0106_mixer.c | 2 +- 3 files changed, 92 insertions(+), 40 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/ca0106/ca0106.h b/sound/pci/ca0106/ca0106.h index 47d92382140..75da1746e75 100644 --- a/sound/pci/ca0106/ca0106.h +++ b/sound/pci/ca0106/ca0106.h @@ -559,38 +559,89 @@ #define SPI_REG_MASK 0x1ff /* 16-bit SPI writes have a 7-bit address */ #define SPI_REG_SHIFT 9 /* followed by 9 bits of data */ +#define SPI_LDA1_REG 0 /* digital attenuation */ +#define SPI_RDA1_REG 1 +#define SPI_LDA2_REG 4 +#define SPI_RDA2_REG 5 +#define SPI_LDA3_REG 6 +#define SPI_RDA3_REG 7 +#define SPI_LDA4_REG 13 +#define SPI_RDA4_REG 14 +#define SPI_MASTDA_REG 8 + +#define SPI_DA_BIT_UPDATE (1<<8) /* update attenuation values */ +#define SPI_DA_BIT_0dB 0xff /* 0 dB */ +#define SPI_DA_BIT_infdB 0x00 /* inf dB attenuation (mute) */ + +#define SPI_PL_REG 2 +#define SPI_PL_BIT_L_M (0<<5) /* left channel = mute */ +#define SPI_PL_BIT_L_L (1<<5) /* left channel = left */ +#define SPI_PL_BIT_L_R (2<<5) /* left channel = right */ +#define SPI_PL_BIT_L_C (3<<5) /* left channel = (L+R)/2 */ +#define SPI_PL_BIT_R_M (0<<7) /* right channel = mute */ +#define SPI_PL_BIT_R_L (1<<7) /* right channel = left */ +#define SPI_PL_BIT_R_R (2<<7) /* right channel = right */ +#define SPI_PL_BIT_R_C (3<<7) /* right channel = (L+R)/2 */ +#define SPI_IZD_REG 2 +#define SPI_IZD_BIT (1<<4) /* infinite zero detect */ + +#define SPI_FMT_REG 3 +#define SPI_FMT_BIT_RJ (0<<0) /* right justified mode */ +#define SPI_FMT_BIT_LJ (1<<0) /* left justified mode */ +#define SPI_FMT_BIT_I2S (2<<0) /* I2S mode */ +#define SPI_FMT_BIT_DSP (3<<0) /* DSP Modes A or B */ +#define SPI_LRP_REG 3 +#define SPI_LRP_BIT (1<<2) /* invert LRCLK polarity */ +#define SPI_BCP_REG 3 +#define SPI_BCP_BIT (1<<3) /* invert BCLK polarity */ +#define SPI_IWL_REG 3 +#define SPI_IWL_BIT_16 (0<<4) /* 16-bit world length */ +#define SPI_IWL_BIT_20 (1<<4) /* 20-bit world length */ +#define SPI_IWL_BIT_24 (2<<4) /* 24-bit world length */ +#define SPI_IWL_BIT_32 (3<<4) /* 32-bit world length */ + +#define SPI_MS_REG 10 +#define SPI_MS_BIT (1<<5) /* master mode */ +#define SPI_RATE_REG 10 /* only applies in master mode */ +#define SPI_RATE_BIT_128 (0<<6) /* MCLK = LRCLK * 128 */ +#define SPI_RATE_BIT_192 (1<<6) +#define SPI_RATE_BIT_256 (2<<6) +#define SPI_RATE_BIT_384 (3<<6) +#define SPI_RATE_BIT_512 (4<<6) +#define SPI_RATE_BIT_768 (5<<6) + /* They really do label the bit for the 4th channel "4" and not "3" */ #define SPI_DMUTE0_REG 9 #define SPI_DMUTE1_REG 9 #define SPI_DMUTE2_REG 9 #define SPI_DMUTE4_REG 15 -#define SPI_DMUTE0_BIT 3 -#define SPI_DMUTE1_BIT 4 -#define SPI_DMUTE2_BIT 5 -#define SPI_DMUTE4_BIT 2 +#define SPI_DMUTE0_BIT (1<<3) +#define SPI_DMUTE1_BIT (1<<4) +#define SPI_DMUTE2_BIT (1<<5) +#define SPI_DMUTE4_BIT (1<<2) #define SPI_PHASE0_REG 3 #define SPI_PHASE1_REG 3 #define SPI_PHASE2_REG 3 #define SPI_PHASE4_REG 15 -#define SPI_PHASE0_BIT 6 -#define SPI_PHASE1_BIT 7 -#define SPI_PHASE2_BIT 8 -#define SPI_PHASE4_BIT 3 +#define SPI_PHASE0_BIT (1<<6) +#define SPI_PHASE1_BIT (1<<7) +#define SPI_PHASE2_BIT (1<<8) +#define SPI_PHASE4_BIT (1<<3) #define SPI_PDWN_REG 2 /* power down all DACs */ -#define SPI_PDWN_BIT 2 +#define SPI_PDWN_BIT (1<<2) #define SPI_DACD0_REG 10 /* power down individual DACs */ #define SPI_DACD1_REG 10 #define SPI_DACD2_REG 10 #define SPI_DACD4_REG 15 -#define SPI_DACD0_BIT 1 -#define SPI_DACD1_BIT 2 -#define SPI_DACD2_BIT 3 -#define SPI_DACD4_BIT 0 /* datasheet error says it's 1 */ +#define SPI_DACD0_BIT (1<<1) +#define SPI_DACD1_BIT (1<<2) +#define SPI_DACD2_BIT (1<<3) +#define SPI_DACD4_BIT (1<<0) /* datasheet error says it's 1 */ #define SPI_PWRDNALL_REG 10 /* power down everything */ -#define SPI_PWRDNALL_BIT 4 +#define SPI_PWRDNALL_BIT (1<<4) #include "ca_midi.h" diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c index 36b7cdda7c4..252710e4f5c 100644 --- a/sound/pci/ca0106/ca0106_main.c +++ b/sound/pci/ca0106/ca0106_main.c @@ -467,10 +467,10 @@ static const int spi_dacd_reg[] = { [PCM_UNKNOWN_CHANNEL] = SPI_DACD1_REG, }; static const int spi_dacd_bit[] = { - [PCM_FRONT_CHANNEL] = 1< Date: Wed, 25 Jul 2007 18:41:17 +0200 Subject: [ALSA] ca0106: remove extra commands in SPI DAC init sequence The init sequence set a number of registers more than once to different values. It's only necessary to set them once to their final values. It also never actually updated the digital attenuation settings. Signed-off-by: Trent Piepho Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/ca0106/ca0106_main.c | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c index 252710e4f5c..611fc15a054 100644 --- a/sound/pci/ca0106/ca0106_main.c +++ b/sound/pci/ca0106/ca0106_main.c @@ -1262,25 +1262,19 @@ static int __devinit snd_ca0106_pcm(struct snd_ca0106 *emu, int device, struct s static unsigned int spi_dac_init[] = { SPI_REG(SPI_LDA1_REG, SPI_DA_BIT_0dB), /* 0dB dig. attenuation */ SPI_REG(SPI_RDA1_REG, SPI_DA_BIT_0dB), - SPI_REG(SPI_PL_REG, 0x00), - SPI_REG(SPI_PL_REG, SPI_PL_BIT_L_L | SPI_PL_BIT_R_R), - SPI_REG(SPI_FMT_REG, SPI_FMT_BIT_RJ | SPI_IWL_BIT_24), + SPI_REG(SPI_PL_REG, SPI_PL_BIT_L_L | SPI_PL_BIT_R_R | SPI_IZD_BIT), + SPI_REG(SPI_FMT_REG, SPI_FMT_BIT_I2S | SPI_IWL_BIT_24), SPI_REG(SPI_LDA2_REG, SPI_DA_BIT_0dB), SPI_REG(SPI_RDA2_REG, SPI_DA_BIT_0dB), SPI_REG(SPI_LDA3_REG, SPI_DA_BIT_0dB), SPI_REG(SPI_RDA3_REG, SPI_DA_BIT_0dB), SPI_REG(SPI_MASTDA_REG, SPI_DA_BIT_0dB), SPI_REG(9, 0x00), - SPI_REG(SPI_MS_REG, 0x00), - SPI_REG(SPI_MS_REG, SPI_RATE_BIT_256), + SPI_REG(SPI_MS_REG, SPI_DACD0_BIT | SPI_DACD1_BIT | SPI_DACD2_BIT), SPI_REG(12, 0x00), SPI_REG(SPI_LDA4_REG, SPI_DA_BIT_0dB), - SPI_REG(SPI_RDA4_REG, SPI_DA_BIT_0dB), - SPI_REG(15, 0x00), - SPI_REG(SPI_PL_REG, SPI_PL_BIT_L_L | SPI_PL_BIT_R_R | SPI_IZD_BIT), - SPI_REG(SPI_FMT_REG, SPI_FMT_BIT_I2S), - SPI_REG(SPI_FMT_REG, SPI_FMT_BIT_I2S | SPI_IWL_BIT_24), - SPI_REG(SPI_MS_REG, SPI_DACD0_BIT | SPI_DACD1_BIT | SPI_DACD2_BIT), + SPI_REG(SPI_RDA4_REG, SPI_DA_BIT_0dB | SPI_DA_BIT_UPDATE), + SPI_REG(SPI_DACD4_REG, 0x00), }; static unsigned int i2c_adc_init[][2] = { -- cgit v1.2.3 From 5b31954e4b364f811450311e3b31d3512e575f63 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 26 Jul 2007 11:49:22 +0200 Subject: [ALSA] hda-codec - Fix the initial mixer state of ALC262 sony-assamd model Many of ALC262 codes don't call the automute function at the beginning, which may keep the silence until the HP jack is replugged. Now proper init_hook is added. Also, sony-assamd model doesn't handle the widget 0x14 properly, thus calling automute isn't enough. Now Front switch handles both widgets. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_realtek.c | 66 +++++++++++++++++++++++++++---------------- 1 file changed, 41 insertions(+), 25 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 7e6cc01b521..d839d567f8e 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -7140,9 +7140,28 @@ static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = { { } /* end */ }; +static int alc262_sony_sw_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + unsigned long private_save = kcontrol->private_value; + int change; + kcontrol->private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT); + change = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol); + kcontrol->private_value = private_save; + change |= snd_hda_mixer_amp_switch_put(kcontrol, ucontrol); + return change; +} + static struct snd_kcontrol_new alc262_sony_mixer[] = { HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT), + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Front Playback Switch", + .info = snd_hda_mixer_amp_switch_info, + .get = snd_hda_mixer_amp_switch_get, + .put = alc262_sony_sw_put, + .private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT), + }, HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), @@ -7269,20 +7288,17 @@ static struct hda_verb alc262_sony_unsol_verbs[] = { }; /* mute/unmute internal speaker according to the hp jack and mute state */ -static void alc262_hippo_automute(struct hda_codec *codec, int force) +static void alc262_hippo_automute(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; unsigned int mute; + unsigned int present; - if (force || !spec->sense_updated) { - unsigned int present; - /* need to execute and sync at first */ - snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0); - present = snd_hda_codec_read(codec, 0x15, 0, - AC_VERB_GET_PIN_SENSE, 0); - spec->jack_present = (present & 0x80000000) != 0; - spec->sense_updated = 1; - } + /* need to execute and sync at first */ + snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0); + present = snd_hda_codec_read(codec, 0x15, 0, + AC_VERB_GET_PIN_SENSE, 0); + spec->jack_present = (present & 0x80000000) != 0; if (spec->jack_present) { /* mute internal speaker */ snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0, @@ -7306,24 +7322,19 @@ static void alc262_hippo_unsol_event(struct hda_codec *codec, { if ((res >> 26) != ALC880_HP_EVENT) return; - alc262_hippo_automute(codec, 1); + alc262_hippo_automute(codec); } -static void alc262_hippo1_automute(struct hda_codec *codec, int force) +static void alc262_hippo1_automute(struct hda_codec *codec) { - struct alc_spec *spec = codec->spec; unsigned int mute; + unsigned int present; - if (force || !spec->sense_updated) { - unsigned int present; - /* need to execute and sync at first */ - snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0); - present = snd_hda_codec_read(codec, 0x1b, 0, - AC_VERB_GET_PIN_SENSE, 0); - spec->jack_present = (present & 0x80000000) != 0; - spec->sense_updated = 1; - } - if (spec->jack_present) { + snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0); + present = snd_hda_codec_read(codec, 0x1b, 0, + AC_VERB_GET_PIN_SENSE, 0); + present = (present & 0x80000000) != 0; + if (present) { /* mute internal speaker */ snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0, 0x80, 0x80); @@ -7346,7 +7357,7 @@ static void alc262_hippo1_unsol_event(struct hda_codec *codec, { if ((res >> 26) != ALC880_HP_EVENT) return; - alc262_hippo1_automute(codec, 1); + alc262_hippo1_automute(codec); } /* @@ -7923,6 +7934,7 @@ static struct snd_pci_quirk alc262_cfg_tbl[] = { SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1), SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8), SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31), + SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD), SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD), SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD), SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD), @@ -7951,6 +7963,7 @@ static struct alc_config_preset alc262_presets[] = { .channel_mode = alc262_modes, .input_mux = &alc262_capture_source, .unsol_event = alc262_hippo_unsol_event, + .init_hook = alc262_hippo_automute, }, [ALC262_HIPPO_1] = { .mixers = { alc262_hippo1_mixer }, @@ -7963,6 +7976,7 @@ static struct alc_config_preset alc262_presets[] = { .channel_mode = alc262_modes, .input_mux = &alc262_capture_source, .unsol_event = alc262_hippo1_unsol_event, + .init_hook = alc262_hippo1_automute, }, [ALC262_FUJITSU] = { .mixers = { alc262_fujitsu_mixer }, @@ -8027,6 +8041,7 @@ static struct alc_config_preset alc262_presets[] = { .channel_mode = alc262_modes, .input_mux = &alc262_capture_source, .unsol_event = alc262_hippo_unsol_event, + .init_hook = alc262_hippo_automute, }, [ALC262_BENQ_T31] = { .mixers = { alc262_benq_t31_mixer }, @@ -8038,6 +8053,7 @@ static struct alc_config_preset alc262_presets[] = { .channel_mode = alc262_modes, .input_mux = &alc262_capture_source, .unsol_event = alc262_hippo_unsol_event, + .init_hook = alc262_hippo_automute, }, }; -- cgit v1.2.3 From f93abe51e8dc7e929d29e6a9a1991bf7fd234d4a Mon Sep 17 00:00:00 2001 From: James Courtier-Dutton Date: Thu, 26 Jul 2007 18:31:39 +0100 Subject: [ALSA] snd-emu10k1:Implement SPDIF/ADAT status. Signed-off-by: James Courtier-Dutton Signed-off-by: Jaroslav Kysela --- sound/pci/emu10k1/emu10k1_main.c | 10 ++++++++- sound/pci/emu10k1/emuproc.c | 48 ++++++++++++++++++++++++++++++++-------- sound/pci/emu10k1/io.c | 10 ++++----- 3 files changed, 53 insertions(+), 15 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c index b985e660c60..e22bb717e96 100644 --- a/sound/pci/emu10k1/emu10k1_main.c +++ b/sound/pci/emu10k1/emu10k1_main.c @@ -873,7 +873,15 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu) snd_printk(KERN_INFO "emu1010: Card options=0x%x\n",reg); snd_emu1010_fpga_read(emu, EMU_HANA_OPTICAL_TYPE, &tmp ); /* Optical -> ADAT I/O */ - snd_emu1010_fpga_write(emu, EMU_HANA_OPTICAL_TYPE, EMU_HANA_OPTICAL_IN_ADAT | EMU_HANA_OPTICAL_OUT_ADAT ); + /* 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 ); diff --git a/sound/pci/emu10k1/emuproc.c b/sound/pci/emu10k1/emuproc.c index a0dae0d916c..3e2ed1d9d5f 100644 --- a/sound/pci/emu10k1/emuproc.c +++ b/sound/pci/emu10k1/emuproc.c @@ -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 < 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); } } diff --git a/sound/pci/emu10k1/io.c b/sound/pci/emu10k1/io.c index 116e1c8d936..971458b4594 100644 --- a/sound/pci/emu10k1/io.c +++ b/sound/pci/emu10k1/io.c @@ -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) ); -- cgit v1.2.3 From c93d1c25be410c0378d1d3d9e7efab06bf6a1261 Mon Sep 17 00:00:00 2001 From: James Courtier-Dutton Date: Thu, 26 Jul 2007 18:44:49 +0100 Subject: [ALSA] snd-emu10k1:Unmute the Audio/Micro Dock after firmware load. Signed-off-by: James Courtier-Dutton Signed-off-by: Jaroslav Kysela --- sound/pci/emu10k1/emu10k1_main.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'sound/pci') diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c index e22bb717e96..f55395bc911 100644 --- a/sound/pci/emu10k1/emu10k1_main.c +++ b/sound/pci/emu10k1/emu10k1_main.c @@ -752,6 +752,12 @@ int emu1010_firmware_thread(void *data) { 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; -- cgit v1.2.3 From 52a6db82efe345af62aa72c6ce9dcb89a4d993b5 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 26 Jul 2007 19:10:47 +0200 Subject: [ALSA] Clean up Makefile Clean up Makefile using xxx- style instead of ifeq(CONFIG_XXX,y). Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/cs46xx/Makefile | 6 ++---- sound/pci/cs5535audio/Makefile | 7 ++----- 2 files changed, 4 insertions(+), 9 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/cs46xx/Makefile b/sound/pci/cs46xx/Makefile index d8b77b89aec..7fcc967440c 100644 --- a/sound/pci/cs46xx/Makefile +++ b/sound/pci/cs46xx/Makefile @@ -3,10 +3,8 @@ # Copyright (c) 2001 by Jaroslav Kysela # -snd-cs46xx-objs := cs46xx.o cs46xx_lib.o -ifeq ($(CONFIG_SND_CS46XX_NEW_DSP),y) - snd-cs46xx-objs += dsp_spos.o dsp_spos_scb_lib.o -endif +snd-cs46xx-y := cs46xx.o cs46xx_lib.o +snd-cs46xx-$(CONFIG_SND_CS46XX_NEW_DSP) += dsp_spos.o dsp_spos_scb_lib.o # Toplevel Module Dependency obj-$(CONFIG_SND_CS46XX) += snd-cs46xx.o diff --git a/sound/pci/cs5535audio/Makefile b/sound/pci/cs5535audio/Makefile index ad947b4c04c..bb3d57e6a3c 100644 --- a/sound/pci/cs5535audio/Makefile +++ b/sound/pci/cs5535audio/Makefile @@ -2,11 +2,8 @@ # Makefile for cs5535audio # -snd-cs5535audio-objs := cs5535audio.o cs5535audio_pcm.o - -ifeq ($(CONFIG_PM),y) -snd-cs5535audio-objs += cs5535audio_pm.o -endif +snd-cs5535audio-y := cs5535audio.o cs5535audio_pcm.o +snd-cs5535audio-$(CONFIG_PM) += cs5535audio_pm.o # Toplevel Module Dependency obj-$(CONFIG_SND_CS5535AUDIO) += snd-cs5535audio.o -- cgit v1.2.3 From d01ce99fc53271cd8ef0ef6b9a2790177fd410a1 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 27 Jul 2007 16:52:19 +0200 Subject: [ALSA] hda-intel - Coding style fixes Fix codes to follow more to the standard kernel coding style. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/hda_codec.h | 33 +++++--- sound/pci/hda/hda_intel.c | 188 +++++++++++++++++++++++++++++----------------- sound/pci/hda/hda_local.h | 99 ++++++++++++++++-------- sound/pci/hda/hda_proc.c | 27 ++++--- 4 files changed, 225 insertions(+), 122 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index 56c26e7ccdf..6809386109c 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h @@ -199,7 +199,9 @@ enum { #define AC_AMPCAP_OFFSET_SHIFT 0 #define AC_AMPCAP_NUM_STEPS (0x7f<<8) /* number of steps */ #define AC_AMPCAP_NUM_STEPS_SHIFT 8 -#define AC_AMPCAP_STEP_SIZE (0x7f<<16) /* step size 0-32dB in 0.25dB */ +#define AC_AMPCAP_STEP_SIZE (0x7f<<16) /* step size 0-32dB + * in 0.25dB + */ #define AC_AMPCAP_STEP_SIZE_SHIFT 16 #define AC_AMPCAP_MUTE (1<<31) /* mute capable */ #define AC_AMPCAP_MUTE_SHIFT 31 @@ -436,7 +438,8 @@ struct hda_bus { /* codec linked list */ struct list_head codec_list; - struct hda_codec *caddr_tbl[HDA_MAX_CODEC_ADDRESS + 1]; /* caddr -> codec */ + /* link caddr -> codec */ + struct hda_codec *caddr_tbl[HDA_MAX_CODEC_ADDRESS + 1]; struct mutex cmd_mutex; @@ -499,7 +502,7 @@ struct hda_pcm_ops { /* PCM information for each substream */ struct hda_pcm_stream { - unsigned int substreams; /* number of substreams, 0 = not exist */ + unsigned int substreams; /* number of substreams, 0 = not exist*/ unsigned int channels_min; /* min. number of channels */ unsigned int channels_max; /* max. number of channels */ hda_nid_t nid; /* default NID to query rates/formats/bps, or set up */ @@ -582,13 +585,17 @@ int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, /* * low level functions */ -unsigned int snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid, int direct, +unsigned int snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid, + int direct, unsigned int verb, unsigned int parm); int snd_hda_codec_write(struct hda_codec *codec, hda_nid_t nid, int direct, unsigned int verb, unsigned int parm); -#define snd_hda_param_read(codec, nid, param) snd_hda_codec_read(codec, nid, 0, AC_VERB_PARAMETERS, param) -int snd_hda_get_sub_nodes(struct hda_codec *codec, hda_nid_t nid, hda_nid_t *start_id); -int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid, hda_nid_t *conn_list, int max_conns); +#define snd_hda_param_read(codec, nid, param) \ + snd_hda_codec_read(codec, nid, 0, AC_VERB_PARAMETERS, param) +int snd_hda_get_sub_nodes(struct hda_codec *codec, hda_nid_t nid, + hda_nid_t *start_id); +int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid, + hda_nid_t *conn_list, int max_conns); struct hda_verb { hda_nid_t nid; @@ -596,7 +603,8 @@ struct hda_verb { u32 param; }; -void snd_hda_sequence_write(struct hda_codec *codec, const struct hda_verb *seq); +void snd_hda_sequence_write(struct hda_codec *codec, + const struct hda_verb *seq); /* unsolicited event */ int snd_hda_queue_unsol_event(struct hda_bus *bus, u32 res, u32 res_ex); @@ -610,10 +618,13 @@ int snd_hda_build_controls(struct hda_bus *bus); * PCM */ int snd_hda_build_pcms(struct hda_bus *bus); -void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid, u32 stream_tag, +void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid, + u32 stream_tag, int channel_id, int format); -unsigned int snd_hda_calc_stream_format(unsigned int rate, unsigned int channels, - unsigned int format, unsigned int maxbps); +unsigned int snd_hda_calc_stream_format(unsigned int rate, + unsigned int channels, + unsigned int format, + unsigned int maxbps); int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid, u32 *ratesp, u64 *formatsp, unsigned int *bpsp); int snd_hda_is_supported_format(struct hda_codec *codec, hda_nid_t nid, diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 92bc8b3fa2a..ebb442dcc02 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -1,6 +1,7 @@ /* * - * hda_intel.c - Implementation of primary alsa driver code base for Intel HD Audio. + * hda_intel.c - Implementation of primary alsa driver code base + * for Intel HD Audio. * * Copyright(c) 2004 Intel Corporation. All rights reserved. * @@ -64,11 +65,13 @@ MODULE_PARM_DESC(id, "ID string for Intel HD audio interface."); module_param(model, charp, 0444); MODULE_PARM_DESC(model, "Use the given board model."); module_param(position_fix, int, 0444); -MODULE_PARM_DESC(position_fix, "Fix DMA pointer (0 = auto, 1 = none, 2 = POSBUF, 3 = FIFO size)."); +MODULE_PARM_DESC(position_fix, "Fix DMA pointer " + "(0 = auto, 1 = none, 2 = POSBUF, 3 = FIFO size)."); module_param(probe_mask, int, 0444); MODULE_PARM_DESC(probe_mask, "Bitmask to probe codecs (default = -1)."); module_param(single_cmd, bool, 0444); -MODULE_PARM_DESC(single_cmd, "Use single command to communicate with codecs (for debugging only)."); +MODULE_PARM_DESC(single_cmd, "Use single command to communicate with codecs " + "(for debugging only)."); module_param(enable_msi, int, 0); MODULE_PARM_DESC(enable_msi, "Enable Message Signaled Interrupt (MSI)"); @@ -213,15 +216,16 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 }; #define SD_INT_DESC_ERR 0x10 /* descriptor error interrupt */ #define SD_INT_FIFO_ERR 0x08 /* FIFO error interrupt */ #define SD_INT_COMPLETE 0x04 /* completion interrupt */ -#define SD_INT_MASK (SD_INT_DESC_ERR|SD_INT_FIFO_ERR|SD_INT_COMPLETE) +#define SD_INT_MASK (SD_INT_DESC_ERR|SD_INT_FIFO_ERR|\ + SD_INT_COMPLETE) /* SD_STS */ #define SD_STS_FIFO_READY 0x20 /* FIFO ready */ /* INTCTL and INTSTS */ -#define ICH6_INT_ALL_STREAM 0xff /* all stream interrupts */ -#define ICH6_INT_CTRL_EN 0x40000000 /* controller interrupt enable bit */ -#define ICH6_INT_GLOBAL_EN 0x80000000 /* global interrupt enable bit */ +#define ICH6_INT_ALL_STREAM 0xff /* all stream interrupts */ +#define ICH6_INT_CTRL_EN 0x40000000 /* controller interrupt enable bit */ +#define ICH6_INT_GLOBAL_EN 0x80000000 /* global interrupt enable bit */ /* GCTL unsolicited response enable bit */ #define ICH6_GCTL_UREN (1<<8) @@ -257,22 +261,26 @@ enum { */ struct azx_dev { - u32 *bdl; /* virtual address of the BDL */ - dma_addr_t bdl_addr; /* physical address of the BDL */ - u32 *posbuf; /* position buffer pointer */ + u32 *bdl; /* virtual address of the BDL */ + dma_addr_t bdl_addr; /* physical address of the BDL */ + u32 *posbuf; /* position buffer pointer */ - unsigned int bufsize; /* size of the play buffer in bytes */ - unsigned int fragsize; /* size of each period in bytes */ - unsigned int frags; /* number for period in the play buffer */ - unsigned int fifo_size; /* FIFO size */ + unsigned int bufsize; /* size of the play buffer in bytes */ + unsigned int fragsize; /* size of each period in bytes */ + unsigned int frags; /* number for period in the play buffer */ + unsigned int fifo_size; /* FIFO size */ - void __iomem *sd_addr; /* stream descriptor pointer */ + void __iomem *sd_addr; /* stream descriptor pointer */ - u32 sd_int_sta_mask; /* stream int status mask */ + u32 sd_int_sta_mask; /* stream int status mask */ /* pcm support */ - struct snd_pcm_substream *substream; /* assigned substream, set in PCM open */ - unsigned int format_val; /* format value to be set in the controller and the codec */ + struct snd_pcm_substream *substream; /* assigned substream, + * set in PCM open + */ + unsigned int format_val; /* format value to be set in the + * controller and the codec + */ unsigned char stream_tag; /* assigned stream */ unsigned char index; /* stream index */ /* for sanity check of position buffer */ @@ -418,7 +426,8 @@ static int azx_alloc_cmd_io(struct azx *chip) int err; /* single page (at least 4096 bytes) must suffice for both ringbuffes */ - err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci), + err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, + snd_dma_pci_data(chip->pci), PAGE_SIZE, &chip->rb); if (err < 0) { snd_printk(KERN_ERR SFX "cannot allocate CORB/RIRB\n"); @@ -531,7 +540,7 @@ static unsigned int azx_rirb_get_response(struct hda_codec *codec) azx_update_rirb(chip); spin_unlock_irq(&chip->reg_lock); } - if (! chip->rirb.cmds) + if (!chip->rirb.cmds) return chip->rirb.res; /* the last value */ schedule_timeout(1); } while (time_after_eq(timeout, jiffies)); @@ -585,16 +594,19 @@ static int azx_single_send_cmd(struct hda_codec *codec, u32 val) while (timeout--) { /* check ICB busy bit */ - if (! (azx_readw(chip, IRS) & ICH6_IRS_BUSY)) { + if (!((azx_readw(chip, IRS) & ICH6_IRS_BUSY))) { /* Clear IRV valid bit */ - azx_writew(chip, IRS, azx_readw(chip, IRS) | ICH6_IRS_VALID); + azx_writew(chip, IRS, azx_readw(chip, IRS) | + ICH6_IRS_VALID); azx_writel(chip, IC, val); - azx_writew(chip, IRS, azx_readw(chip, IRS) | ICH6_IRS_BUSY); + azx_writew(chip, IRS, azx_readw(chip, IRS) | + ICH6_IRS_BUSY); return 0; } udelay(1); } - snd_printd(SFX "send_cmd timeout: IRS=0x%x, val=0x%x\n", azx_readw(chip, IRS), val); + snd_printd(SFX "send_cmd timeout: IRS=0x%x, val=0x%x\n", + azx_readw(chip, IRS), val); return -EIO; } @@ -610,7 +622,8 @@ static unsigned int azx_single_get_response(struct hda_codec *codec) return azx_readl(chip, IR); udelay(1); } - snd_printd(SFX "get_response timeout: IRS=0x%x\n", azx_readw(chip, IRS)); + snd_printd(SFX "get_response timeout: IRS=0x%x\n", + azx_readw(chip, IRS)); return (unsigned int)-1; } @@ -785,7 +798,8 @@ static void azx_init_chip(struct azx *chip) /* Clear bits 0-2 of PCI register TCSEL (at offset 0x44) * TCSEL == Traffic Class Select Register, which sets PCI express QOS - * Ensuring these bits are 0 clears playback static on some HD Audio codecs + * Ensuring these bits are 0 clears playback static on some HD Audio + * codecs */ pci_read_config_byte (chip->pci, ICH6_PCIREG_TCSEL, ®); pci_write_config_byte(chip->pci, ICH6_PCIREG_TCSEL, reg & 0xf8); @@ -808,10 +822,13 @@ static void azx_init_chip(struct azx *chip) switch (chip->driver_type) { case AZX_DRIVER_ATI: /* For ATI SB450 azalia HD audio, we need to enable snoop */ - pci_read_config_byte(chip->pci, ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR, + pci_read_config_byte(chip->pci, + ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR, ®); - pci_write_config_byte(chip->pci, ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR, - (reg & 0xf8) | ATI_SB450_HDAUDIO_ENABLE_SNOOP); + pci_write_config_byte(chip->pci, + ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR, + (reg & 0xf8) | + ATI_SB450_HDAUDIO_ENABLE_SNOOP); break; case AZX_DRIVER_NVIDIA: /* For NVIDIA HDA, enable snoop */ @@ -857,7 +874,7 @@ static irqreturn_t azx_interrupt(int irq, void *dev_id) /* clear rirb int */ status = azx_readb(chip, RIRBSTS); if (status & RIRB_INT_MASK) { - if (! chip->single_cmd && (status & RIRB_INT_RESPONSE)) + if (!chip->single_cmd && (status & RIRB_INT_RESPONSE)) azx_update_rirb(chip); azx_writeb(chip, RIRBSTS, RIRB_INT_MASK); } @@ -911,9 +928,11 @@ static int azx_setup_controller(struct azx *chip, struct azx_dev *azx_dev) int timeout; /* make sure the run bit is zero for SD */ - azx_sd_writeb(azx_dev, SD_CTL, azx_sd_readb(azx_dev, SD_CTL) & ~SD_CTL_DMA_START); + azx_sd_writeb(azx_dev, SD_CTL, azx_sd_readb(azx_dev, SD_CTL) & + ~SD_CTL_DMA_START); /* reset stream */ - azx_sd_writeb(azx_dev, SD_CTL, azx_sd_readb(azx_dev, SD_CTL) | SD_CTL_STREAM_RESET); + azx_sd_writeb(azx_dev, SD_CTL, azx_sd_readb(azx_dev, SD_CTL) | + SD_CTL_STREAM_RESET); udelay(3); timeout = 300; while (!((val = azx_sd_readb(azx_dev, SD_CTL)) & SD_CTL_STREAM_RESET) && @@ -931,7 +950,7 @@ static int azx_setup_controller(struct azx *chip, struct azx_dev *azx_dev) /* program the stream_tag */ azx_sd_writel(azx_dev, SD_CTL, - (azx_sd_readl(azx_dev, SD_CTL) & ~SD_CTL_STREAM_TAG_MASK) | + (azx_sd_readl(azx_dev, SD_CTL) & ~SD_CTL_STREAM_TAG_MASK)| (azx_dev->stream_tag << SD_CTL_STREAM_TAG_SHIFT)); /* program the length of samples in cyclic buffer */ @@ -951,11 +970,13 @@ static int azx_setup_controller(struct azx *chip, struct azx_dev *azx_dev) azx_sd_writel(azx_dev, SD_BDLPU, upper_32bit(azx_dev->bdl_addr)); /* enable the position buffer */ - if (! (azx_readl(chip, DPLBASE) & ICH6_DPLBASE_ENABLE)) - azx_writel(chip, DPLBASE, (u32)chip->posbuf.addr | ICH6_DPLBASE_ENABLE); + if (!(azx_readl(chip, DPLBASE) & ICH6_DPLBASE_ENABLE)) + azx_writel(chip, DPLBASE, + (u32)chip->posbuf.addr |ICH6_DPLBASE_ENABLE); /* set the interrupt enable bits in the descriptor control register */ - azx_sd_writel(azx_dev, SD_CTL, azx_sd_readl(azx_dev, SD_CTL) | SD_INT_MASK); + azx_sd_writel(azx_dev, SD_CTL, + azx_sd_readl(azx_dev, SD_CTL) | SD_INT_MASK); return 0; } @@ -987,7 +1008,8 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model) bus_temp.ops.command = azx_send_cmd; bus_temp.ops.get_response = azx_get_response; - if ((err = snd_hda_bus_new(chip->card, &bus_temp, &chip->bus)) < 0) + err = snd_hda_bus_new(chip->card, &bus_temp, &chip->bus); + if (err < 0) return err; codecs = audio_codecs = 0; @@ -1038,7 +1060,7 @@ static inline struct azx_dev *azx_assign_device(struct azx *chip, int stream) nums = chip->capture_streams; } for (i = 0; i < nums; i++, dev++) - if (! chip->azx_dev[dev].opened) { + if (!chip->azx_dev[dev].opened) { chip->azx_dev[dev].opened = 1; return &chip->azx_dev[dev]; } @@ -1052,7 +1074,8 @@ static inline void azx_release_device(struct azx_dev *azx_dev) } static struct snd_pcm_hardware azx_pcm_hw = { - .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | + .info = (SNDRV_PCM_INFO_MMAP | + SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP_VALID | /* No full-resume yet implemented */ @@ -1105,7 +1128,8 @@ static int azx_pcm_open(struct snd_pcm_substream *substream) 128); snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 128); - if ((err = hinfo->ops.open(hinfo, apcm->codec, substream)) < 0) { + err = hinfo->ops.open(hinfo, apcm->codec, substream); + if (err < 0) { azx_release_device(azx_dev); mutex_unlock(&chip->open_mutex); return err; @@ -1139,9 +1163,11 @@ static int azx_pcm_close(struct snd_pcm_substream *substream) return 0; } -static int azx_pcm_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *hw_params) +static int azx_pcm_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *hw_params) { - return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); + return snd_pcm_lib_malloc_pages(substream, + params_buffer_bytes(hw_params)); } static int azx_pcm_hw_free(struct snd_pcm_substream *substream) @@ -1175,13 +1201,15 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream) runtime->channels, runtime->format, hinfo->maxbps); - if (! azx_dev->format_val) { - snd_printk(KERN_ERR SFX "invalid format_val, rate=%d, ch=%d, format=%d\n", + if (!azx_dev->format_val) { + snd_printk(KERN_ERR SFX + "invalid format_val, rate=%d, ch=%d, format=%d\n", runtime->rate, runtime->channels, runtime->format); return -EINVAL; } - snd_printdd("azx_pcm_prepare: bufsize=0x%x, fragsize=0x%x, format=0x%x\n", + snd_printdd("azx_pcm_prepare: bufsize=0x%x, fragsize=0x%x, " + "format=0x%x\n", azx_dev->bufsize, azx_dev->fragsize, azx_dev->format_val); azx_setup_periods(azx_dev); azx_setup_controller(chip, azx_dev); @@ -1223,7 +1251,8 @@ static int azx_pcm_trigger(struct snd_pcm_substream *substream, int cmd) cmd == SNDRV_PCM_TRIGGER_SUSPEND || cmd == SNDRV_PCM_TRIGGER_STOP) { int timeout = 5000; - while (azx_sd_readb(azx_dev, SD_CTL) & SD_CTL_DMA_START && --timeout) + while ((azx_sd_readb(azx_dev, SD_CTL) & SD_CTL_DMA_START) && + --timeout) ; } return err; @@ -1241,7 +1270,7 @@ static snd_pcm_uframes_t azx_pcm_pointer(struct snd_pcm_substream *substream) /* use the position buffer */ pos = le32_to_cpu(*azx_dev->posbuf); if (chip->position_fix == POS_FIX_AUTO && - azx_dev->period_intr == 1 && ! pos) { + azx_dev->period_intr == 1 && !pos) { printk(KERN_WARNING "hda-intel: Invalid position buffer, " "using LPIB read method instead.\n"); @@ -1292,7 +1321,8 @@ static int __devinit create_codec_pcm(struct azx *chip, struct hda_codec *codec, snd_assert(cpcm->name, return -EINVAL); err = snd_pcm_new(chip->card, cpcm->name, pcm_dev, - cpcm->stream[0].substreams, cpcm->stream[1].substreams, + cpcm->stream[0].substreams, + cpcm->stream[1].substreams, &pcm); if (err < 0) return err; @@ -1327,7 +1357,8 @@ static int __devinit azx_pcm_create(struct azx *chip) int c, err; int pcm_dev; - if ((err = snd_hda_build_pcms(chip->bus)) < 0) + err = snd_hda_build_pcms(chip->bus); + if (err < 0) return err; /* create audio PCMs */ @@ -1338,10 +1369,12 @@ static int __devinit azx_pcm_create(struct azx *chip) if (codec->pcm_info[c].is_modem) continue; /* create later */ if (pcm_dev >= AZX_MAX_AUDIO_PCMS) { - snd_printk(KERN_ERR SFX "Too many audio PCMs\n"); + snd_printk(KERN_ERR SFX + "Too many audio PCMs\n"); return -EINVAL; } - err = create_codec_pcm(chip, codec, &codec->pcm_info[c], pcm_dev); + err = create_codec_pcm(chip, codec, + &codec->pcm_info[c], pcm_dev); if (err < 0) return err; pcm_dev++; @@ -1353,13 +1386,15 @@ static int __devinit azx_pcm_create(struct azx *chip) list_for_each(p, &chip->bus->codec_list) { codec = list_entry(p, struct hda_codec, list); for (c = 0; c < codec->num_pcms; c++) { - if (! codec->pcm_info[c].is_modem) + if (!codec->pcm_info[c].is_modem) continue; /* already created */ if (pcm_dev >= AZX_MAX_PCMS) { - snd_printk(KERN_ERR SFX "Too many modem PCMs\n"); + snd_printk(KERN_ERR SFX + "Too many modem PCMs\n"); return -EINVAL; } - err = create_codec_pcm(chip, codec, &codec->pcm_info[c], pcm_dev); + err = create_codec_pcm(chip, codec, + &codec->pcm_info[c], pcm_dev); if (err < 0) return err; chip->pcm[pcm_dev]->dev_class = SNDRV_PCM_CLASS_MODEM; @@ -1386,7 +1421,8 @@ static int __devinit azx_init_stream(struct azx *chip) int i; /* initialize each stream (aka device) - * assign the starting bdl address to each stream (device) and initialize + * assign the starting bdl address to each stream (device) + * and initialize */ for (i = 0; i < chip->num_streams; i++) { unsigned int off = sizeof(u32) * (i * AZX_MAX_FRAG * 4); @@ -1650,28 +1686,35 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, break; } chip->num_streams = chip->playback_streams + chip->capture_streams; - chip->azx_dev = kcalloc(chip->num_streams, sizeof(*chip->azx_dev), GFP_KERNEL); + chip->azx_dev = kcalloc(chip->num_streams, sizeof(*chip->azx_dev), + GFP_KERNEL); if (!chip->azx_dev) { snd_printk(KERN_ERR "cannot malloc azx_dev\n"); goto errout; } /* allocate memory for the BDL for each stream */ - if ((err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci), - BDL_SIZE, &chip->bdl)) < 0) { + err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, + snd_dma_pci_data(chip->pci), + BDL_SIZE, &chip->bdl); + if (err < 0) { snd_printk(KERN_ERR SFX "cannot allocate BDL\n"); goto errout; } /* allocate memory for the position buffer */ - if ((err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci), - chip->num_streams * 8, &chip->posbuf)) < 0) { + err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, + snd_dma_pci_data(chip->pci), + chip->num_streams * 8, &chip->posbuf); + if (err < 0) { snd_printk(KERN_ERR SFX "cannot allocate posbuf\n"); goto errout; } /* allocate CORB/RIRB */ - if (! chip->single_cmd) - if ((err = azx_alloc_cmd_io(chip)) < 0) + if (!chip->single_cmd) { + err = azx_alloc_cmd_io(chip); + if (err < 0) goto errout; + } /* initialize streams */ azx_init_stream(chip); @@ -1688,14 +1731,16 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, goto errout; } - if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) <0) { + err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops); + if (err <0) { snd_printk(KERN_ERR SFX "Error creating device [card]!\n"); goto errout; } strcpy(card->driver, "HDA-Intel"); strcpy(card->shortname, driver_short_names[chip->driver_type]); - sprintf(card->longname, "%s at 0x%lx irq %i", card->shortname, chip->addr, chip->irq); + sprintf(card->longname, "%s at 0x%lx irq %i", + card->shortname, chip->addr, chip->irq); *rchip = chip; return 0; @@ -1705,7 +1750,8 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, return err; } -static int __devinit azx_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) +static int __devinit azx_probe(struct pci_dev *pci, + const struct pci_device_id *pci_id) { struct snd_card *card; struct azx *chip; @@ -1725,26 +1771,30 @@ static int __devinit azx_probe(struct pci_dev *pci, const struct pci_device_id * card->private_data = chip; /* create codec instances */ - if ((err = azx_codec_create(chip, model)) < 0) { + err = azx_codec_create(chip, model); + if (err < 0) { snd_card_free(card); return err; } /* create PCM streams */ - if ((err = azx_pcm_create(chip)) < 0) { + err = azx_pcm_create(chip); + if (err < 0) { snd_card_free(card); return err; } /* create mixer controls */ - if ((err = azx_mixer_create(chip)) < 0) { + err = azx_mixer_create(chip); + if (err < 0) { snd_card_free(card); return err; } snd_card_set_dev(card, &pci->dev); - if ((err = snd_card_register(card)) < 0) { + err = snd_card_register(card); + if (err < 0) { snd_card_free(card); return err; } diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h index f91ea5ec9f6..c8d34a5b081 100644 --- a/sound/pci/hda/hda_local.h +++ b/sound/pci/hda/hda_local.h @@ -26,7 +26,8 @@ /* * for mixer controls */ -#define HDA_COMPOSE_AMP_VAL(nid,chs,idx,dir) ((nid) | ((chs)<<16) | ((dir)<<18) | ((idx)<<19)) +#define HDA_COMPOSE_AMP_VAL(nid,chs,idx,dir) \ + ((nid) | ((chs)<<16) | ((dir)<<18) | ((idx)<<19)) /* mono volume with index (index=0,1,...) (channel=1,2) */ #define HDA_CODEC_VOLUME_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \ @@ -64,13 +65,20 @@ #define HDA_CODEC_MUTE(xname, nid, xindex, direction) \ HDA_CODEC_MUTE_MONO(xname, nid, 3, xindex, direction) -int snd_hda_mixer_amp_volume_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo); -int snd_hda_mixer_amp_volume_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); -int snd_hda_mixer_amp_volume_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); -int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag, unsigned int size, unsigned int __user *tlv); -int snd_hda_mixer_amp_switch_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo); -int snd_hda_mixer_amp_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); -int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); +int snd_hda_mixer_amp_volume_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo); +int snd_hda_mixer_amp_volume_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol); +int snd_hda_mixer_amp_volume_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol); +int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag, + unsigned int size, unsigned int __user *tlv); +int snd_hda_mixer_amp_switch_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo); +int snd_hda_mixer_amp_switch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol); +int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol); /* lowlevel accessor with caching; use carefully */ int snd_hda_codec_amp_read(struct hda_codec *codec, hda_nid_t nid, int ch, int direction, int index); @@ -86,10 +94,13 @@ int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch, .private_value = HDA_COMPOSE_AMP_VAL(nid, channel, indices, direction) } /* stereo switch binding multiple inputs */ -#define HDA_BIND_MUTE(xname,nid,indices,dir) HDA_BIND_MUTE_MONO(xname,nid,3,indices,dir) +#define HDA_BIND_MUTE(xname,nid,indices,dir) \ + HDA_BIND_MUTE_MONO(xname,nid,3,indices,dir) -int snd_hda_mixer_bind_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); -int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); +int snd_hda_mixer_bind_switch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol); +int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol); int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid); int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid); @@ -107,8 +118,10 @@ struct hda_input_mux { struct hda_input_mux_item items[HDA_MAX_NUM_INPUTS]; }; -int snd_hda_input_mux_info(const struct hda_input_mux *imux, struct snd_ctl_elem_info *uinfo); -int snd_hda_input_mux_put(struct hda_codec *codec, const struct hda_input_mux *imux, +int snd_hda_input_mux_info(const struct hda_input_mux *imux, + struct snd_ctl_elem_info *uinfo); +int snd_hda_input_mux_put(struct hda_codec *codec, + const struct hda_input_mux *imux, struct snd_ctl_elem_value *ucontrol, hda_nid_t nid, unsigned int *cur_val); @@ -120,13 +133,19 @@ struct hda_channel_mode { const struct hda_verb *sequence; }; -int snd_hda_ch_mode_info(struct hda_codec *codec, struct snd_ctl_elem_info *uinfo, - const struct hda_channel_mode *chmode, int num_chmodes); -int snd_hda_ch_mode_get(struct hda_codec *codec, struct snd_ctl_elem_value *ucontrol, - const struct hda_channel_mode *chmode, int num_chmodes, +int snd_hda_ch_mode_info(struct hda_codec *codec, + struct snd_ctl_elem_info *uinfo, + const struct hda_channel_mode *chmode, + int num_chmodes); +int snd_hda_ch_mode_get(struct hda_codec *codec, + struct snd_ctl_elem_value *ucontrol, + const struct hda_channel_mode *chmode, + int num_chmodes, int max_channels); -int snd_hda_ch_mode_put(struct hda_codec *codec, struct snd_ctl_elem_value *ucontrol, - const struct hda_channel_mode *chmode, int num_chmodes, +int snd_hda_ch_mode_put(struct hda_codec *codec, + struct snd_ctl_elem_value *ucontrol, + const struct hda_channel_mode *chmode, + int num_chmodes, int *max_channelsp); /* @@ -146,20 +165,25 @@ struct hda_multi_out { int dig_out_used; /* current usage of digital out (HDA_DIG_XXX) */ }; -int snd_hda_multi_out_dig_open(struct hda_codec *codec, struct hda_multi_out *mout); -int snd_hda_multi_out_dig_close(struct hda_codec *codec, struct hda_multi_out *mout); +int snd_hda_multi_out_dig_open(struct hda_codec *codec, + struct hda_multi_out *mout); +int snd_hda_multi_out_dig_close(struct hda_codec *codec, + struct hda_multi_out *mout); int snd_hda_multi_out_dig_prepare(struct hda_codec *codec, struct hda_multi_out *mout, unsigned int stream_tag, unsigned int format, struct snd_pcm_substream *substream); -int snd_hda_multi_out_analog_open(struct hda_codec *codec, struct hda_multi_out *mout, +int snd_hda_multi_out_analog_open(struct hda_codec *codec, + struct hda_multi_out *mout, struct snd_pcm_substream *substream); -int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, struct hda_multi_out *mout, +int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, + struct hda_multi_out *mout, unsigned int stream_tag, unsigned int format, struct snd_pcm_substream *substream); -int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec, struct hda_multi_out *mout); +int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec, + struct hda_multi_out *mout); /* * generic codec parser @@ -181,7 +205,8 @@ static inline int snd_hda_codec_proc_new(struct hda_codec *codec) { return 0; } int snd_hda_check_board_config(struct hda_codec *codec, int num_configs, const char **modelnames, const struct snd_pci_quirk *pci_list); -int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew); +int snd_hda_add_new_ctls(struct hda_codec *codec, + struct snd_kcontrol_new *knew); /* * power management @@ -232,7 +257,9 @@ extern const char *auto_pin_cfg_labels[AUTO_PIN_LAST]; struct auto_pin_cfg { int line_outs; - hda_nid_t line_out_pins[5]; /* sorted in the order of Front/Surr/CLFE/Side */ + hda_nid_t line_out_pins[5]; /* sorted in the order of + * Front/Surr/CLFE/Side + */ int speaker_outs; hda_nid_t speaker_pins[5]; int hp_outs; @@ -243,13 +270,19 @@ struct auto_pin_cfg { hda_nid_t dig_in_pin; }; -#define get_defcfg_connect(cfg) ((cfg & AC_DEFCFG_PORT_CONN) >> AC_DEFCFG_PORT_CONN_SHIFT) -#define get_defcfg_association(cfg) ((cfg & AC_DEFCFG_DEF_ASSOC) >> AC_DEFCFG_ASSOC_SHIFT) -#define get_defcfg_location(cfg) ((cfg & AC_DEFCFG_LOCATION) >> AC_DEFCFG_LOCATION_SHIFT) -#define get_defcfg_sequence(cfg) (cfg & AC_DEFCFG_SEQUENCE) -#define get_defcfg_device(cfg) ((cfg & AC_DEFCFG_DEVICE) >> AC_DEFCFG_DEVICE_SHIFT) - -int snd_hda_parse_pin_def_config(struct hda_codec *codec, struct auto_pin_cfg *cfg, +#define get_defcfg_connect(cfg) \ + ((cfg & AC_DEFCFG_PORT_CONN) >> AC_DEFCFG_PORT_CONN_SHIFT) +#define get_defcfg_association(cfg) \ + ((cfg & AC_DEFCFG_DEF_ASSOC) >> AC_DEFCFG_ASSOC_SHIFT) +#define get_defcfg_location(cfg) \ + ((cfg & AC_DEFCFG_LOCATION) >> AC_DEFCFG_LOCATION_SHIFT) +#define get_defcfg_sequence(cfg) \ + (cfg & AC_DEFCFG_SEQUENCE) +#define get_defcfg_device(cfg) \ + ((cfg & AC_DEFCFG_DEVICE) >> AC_DEFCFG_DEVICE_SHIFT) + +int snd_hda_parse_pin_def_config(struct hda_codec *codec, + struct auto_pin_cfg *cfg, hda_nid_t *ignore_nids); /* amp values */ diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c index ac15066fd30..ccd19180e54 100644 --- a/sound/pci/hda/hda_proc.c +++ b/sound/pci/hda/hda_proc.c @@ -58,7 +58,8 @@ static void print_amp_caps(struct snd_info_buffer *buffer, snd_iprintf(buffer, "N/A\n"); return; } - snd_iprintf(buffer, "ofs=0x%02x, nsteps=0x%02x, stepsize=0x%02x, mute=%x\n", + snd_iprintf(buffer, "ofs=0x%02x, nsteps=0x%02x, stepsize=0x%02x, " + "mute=%x\n", caps & AC_AMPCAP_OFFSET, (caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT, (caps & AC_AMPCAP_STEP_SIZE) >> AC_AMPCAP_STEP_SIZE_SHIFT, @@ -76,11 +77,13 @@ static void print_amp_vals(struct snd_info_buffer *buffer, for (i = 0; i < indices; i++) { snd_iprintf(buffer, " ["); if (stereo) { - val = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_AMP_GAIN_MUTE, + val = snd_hda_codec_read(codec, nid, 0, + AC_VERB_GET_AMP_GAIN_MUTE, AC_AMP_GET_LEFT | dir | i); snd_iprintf(buffer, "0x%02x ", val); } - val = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_AMP_GAIN_MUTE, + val = snd_hda_codec_read(codec, nid, 0, + AC_VERB_GET_AMP_GAIN_MUTE, AC_AMP_GET_RIGHT | dir | i); snd_iprintf(buffer, "0x%02x]", val); } @@ -237,7 +240,8 @@ static void print_pin_caps(struct snd_info_buffer *buffer, } -static void print_codec_info(struct snd_info_entry *entry, struct snd_info_buffer *buffer) +static void print_codec_info(struct snd_info_entry *entry, + struct snd_info_buffer *buffer) { struct hda_codec *codec = entry->private_data; char buf[32]; @@ -271,9 +275,11 @@ static void print_codec_info(struct snd_info_entry *entry, struct snd_info_buffe return; } for (i = 0; i < nodes; i++, nid++) { - unsigned int wid_caps = snd_hda_param_read(codec, nid, - AC_PAR_AUDIO_WIDGET_CAP); - unsigned int wid_type = (wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; + unsigned int wid_caps = + snd_hda_param_read(codec, nid, + AC_PAR_AUDIO_WIDGET_CAP); + unsigned int wid_type = + (wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; int conn_len = 0; hda_nid_t conn[HDA_MAX_CONNECTIONS]; @@ -313,7 +319,9 @@ static void print_codec_info(struct snd_info_entry *entry, struct snd_info_buffe if (wid_type == AC_WID_PIN) { unsigned int pinctls; print_pin_caps(buffer, codec, nid); - pinctls = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0); + pinctls = snd_hda_codec_read(codec, nid, 0, + AC_VERB_GET_PIN_WIDGET_CONTROL, + 0); snd_iprintf(buffer, " Pin-ctls: 0x%02x:", pinctls); if (pinctls & AC_PINCTL_IN_EN) snd_iprintf(buffer, " IN"); @@ -333,7 +341,8 @@ static void print_codec_info(struct snd_info_entry *entry, struct snd_info_buffe if (wid_caps & AC_WCAP_POWER) snd_iprintf(buffer, " Power: 0x%x\n", snd_hda_codec_read(codec, nid, 0, - AC_VERB_GET_POWER_STATE, 0)); + AC_VERB_GET_POWER_STATE, + 0)); if (wid_caps & AC_WCAP_CONN_LIST) { int c, curr = -1; -- cgit v1.2.3 From ef5fa1a49fc3b5fe8e734f25fa61bc73ccba344e Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 27 Jul 2007 16:52:46 +0200 Subject: [ALSA] hdspm - Coding style fixes Fix codes to follow more to the standard kernel coding style. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/rme9652/hdspm.c | 599 +++++++++++++++++++++++++--------------------- 1 file changed, 325 insertions(+), 274 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c index 83ea4623e77..30e0c4dc948 100644 --- a/sound/pci/rme9652/hdspm.c +++ b/sound/pci/rme9652/hdspm.c @@ -1,5 +1,4 @@ -/* -*- linux-c -*- - * +/* * ALSA driver for RME Hammerfall DSP MADI audio interface(s) * * Copyright (c) 2003 Winfried Ritsch (IEM) @@ -78,7 +77,8 @@ MODULE_PARM_DESC(enable_monitor, "Enable Analog Out on Channel 63/64 by default."); MODULE_AUTHOR - ("Winfried Ritsch , Paul Davis , " + ("Winfried Ritsch , " + "Paul Davis , " "Marcus Andersson, Thomas Charbonnel , " "Remy Bruno "); MODULE_DESCRIPTION("RME HDSPM"); @@ -161,7 +161,9 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}"); 0=off, 1=on */ /* MADI ONLY */ #define HDSPM_Dolby (1<<11) /* Dolby = "NonAudio" ?? */ /* AES32 ONLY */ -#define HDSPM_InputSelect0 (1<<14) /* Input select 0= optical, 1=coax */ /* MADI ONLY*/ +#define HDSPM_InputSelect0 (1<<14) /* Input select 0= optical, 1=coax + * -- MADI ONLY + */ #define HDSPM_InputSelect1 (1<<15) /* should be 0 */ #define HDSPM_SyncRef0 (1<<16) /* 0=WOrd, 1=MADI */ @@ -189,11 +191,13 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}"); /* --- bit helper defines */ #define HDSPM_LatencyMask (HDSPM_Latency0|HDSPM_Latency1|HDSPM_Latency2) -#define HDSPM_FrequencyMask (HDSPM_Frequency0|HDSPM_Frequency1|HDSPM_DoubleSpeed|HDSPM_QuadSpeed) +#define HDSPM_FrequencyMask (HDSPM_Frequency0|HDSPM_Frequency1|\ + HDSPM_DoubleSpeed|HDSPM_QuadSpeed) #define HDSPM_InputMask (HDSPM_InputSelect0|HDSPM_InputSelect1) #define HDSPM_InputOptical 0 #define HDSPM_InputCoaxial (HDSPM_InputSelect0) -#define HDSPM_SyncRefMask (HDSPM_SyncRef0|HDSPM_SyncRef1|HDSPM_SyncRef2|HDSPM_SyncRef3) +#define HDSPM_SyncRefMask (HDSPM_SyncRef0|HDSPM_SyncRef1|\ + HDSPM_SyncRef2|HDSPM_SyncRef3) #define HDSPM_SyncRef_Word 0 #define HDSPM_SyncRef_MADI (HDSPM_SyncRef0) @@ -205,10 +209,12 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}"); #define HDSPM_Frequency48KHz (HDSPM_Frequency1|HDSPM_Frequency0) #define HDSPM_Frequency64KHz (HDSPM_DoubleSpeed|HDSPM_Frequency0) #define HDSPM_Frequency88_2KHz (HDSPM_DoubleSpeed|HDSPM_Frequency1) -#define HDSPM_Frequency96KHz (HDSPM_DoubleSpeed|HDSPM_Frequency1|HDSPM_Frequency0) +#define HDSPM_Frequency96KHz (HDSPM_DoubleSpeed|HDSPM_Frequency1|\ + HDSPM_Frequency0) #define HDSPM_Frequency128KHz (HDSPM_QuadSpeed|HDSPM_Frequency0) #define HDSPM_Frequency176_4KHz (HDSPM_QuadSpeed|HDSPM_Frequency1) -#define HDSPM_Frequency192KHz (HDSPM_QuadSpeed|HDSPM_Frequency1|HDSPM_Frequency0) +#define HDSPM_Frequency192KHz (HDSPM_QuadSpeed|HDSPM_Frequency1|\ + HDSPM_Frequency0) /* --- for internal discrimination */ #define HDSPM_CLOCK_SOURCE_AUTOSYNC 0 /* Sample Clock Sources */ @@ -256,10 +262,14 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}"); #define HDSPM_RD_MULTIPLE (1<<10) /* --- Status Register bits --- */ /* MADI ONLY */ /* Bits defined here and - that do not conflict with specific bits for AES32 seem to be valid also for the AES32 */ + that do not conflict with specific bits for AES32 seem to be valid also + for the AES32 + */ #define HDSPM_audioIRQPending (1<<0) /* IRQ is high and pending */ -#define HDSPM_RX_64ch (1<<1) /* Input 64chan. MODE=1, 56chn. MODE=0 */ -#define HDSPM_AB_int (1<<2) /* InputChannel Opt=0, Coax=1 (like inp0) */ +#define HDSPM_RX_64ch (1<<1) /* Input 64chan. MODE=1, 56chn MODE=0 */ +#define HDSPM_AB_int (1<<2) /* InputChannel Opt=0, Coax=1 + * (like inp0) + */ #define HDSPM_madiLock (1<<3) /* MADI Locked =1, no=0 */ #define HDSPM_BufferPositionMask 0x000FFC0 /* Bit 6..15 : h/w buffer pointer */ @@ -274,12 +284,15 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}"); #define HDSPM_madiFreq2 (1<<24) /* 4=64, 5=88.2 6=96 */ #define HDSPM_madiFreq3 (1<<25) /* 7=128, 8=176.4 9=192 */ -#define HDSPM_BufferID (1<<26) /* (Double)Buffer ID toggles with Interrupt */ +#define HDSPM_BufferID (1<<26) /* (Double)Buffer ID toggles with + * Interrupt + */ #define HDSPM_midi0IRQPending (1<<30) /* MIDI IRQ is pending */ #define HDSPM_midi1IRQPending (1<<31) /* and aktiv */ /* --- status bit helpers */ -#define HDSPM_madiFreqMask (HDSPM_madiFreq0|HDSPM_madiFreq1|HDSPM_madiFreq2|HDSPM_madiFreq3) +#define HDSPM_madiFreqMask (HDSPM_madiFreq0|HDSPM_madiFreq1|\ + HDSPM_madiFreq2|HDSPM_madiFreq3) #define HDSPM_madiFreq32 (HDSPM_madiFreq0) #define HDSPM_madiFreq44_1 (HDSPM_madiFreq1) #define HDSPM_madiFreq48 (HDSPM_madiFreq0|HDSPM_madiFreq1) @@ -319,10 +332,12 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}"); #define HDSPM_wcFreq96 (HDSPM_wc_freq1|HDSPM_wc_freq2) -#define HDSPM_SelSyncRefMask (HDSPM_SelSyncRef0|HDSPM_SelSyncRef1|HDSPM_SelSyncRef2) +#define HDSPM_SelSyncRefMask (HDSPM_SelSyncRef0|HDSPM_SelSyncRef1|\ + HDSPM_SelSyncRef2) #define HDSPM_SelSyncRef_WORD 0 #define HDSPM_SelSyncRef_MADI (HDSPM_SelSyncRef0) -#define HDSPM_SelSyncRef_NVALID (HDSPM_SelSyncRef0|HDSPM_SelSyncRef1|HDSPM_SelSyncRef2) +#define HDSPM_SelSyncRef_NVALID (HDSPM_SelSyncRef0|HDSPM_SelSyncRef1|\ + HDSPM_SelSyncRef2) /* For AES32, bits for status, status2 and timecode are different @@ -412,8 +427,9 @@ struct hdspm_midi { struct hdspm { spinlock_t lock; - struct snd_pcm_substream *capture_substream; /* only one playback */ - struct snd_pcm_substream *playback_substream; /* and/or capture stream */ + /* only one playback and/or capture stream */ + struct snd_pcm_substream *capture_substream; + struct snd_pcm_substream *playback_substream; char *card_name; /* for procinfo */ unsigned short firmware_rev; /* dont know if relevant (yes if AES32)*/ @@ -460,9 +476,12 @@ struct hdspm { struct pci_dev *pci; /* and an pci info */ /* Mixer vars */ - struct snd_kcontrol *playback_mixer_ctls[HDSPM_MAX_CHANNELS]; /* fast alsa mixer */ - struct snd_kcontrol *input_mixer_ctls[HDSPM_MAX_CHANNELS]; /* but input to much, so not used */ - struct hdspm_mixer *mixer; /* full mixer accessable over mixer ioctl or hwdep-device */ + /* fast alsa mixer */ + struct snd_kcontrol *playback_mixer_ctls[HDSPM_MAX_CHANNELS]; + /* but input to much, so not used */ + struct snd_kcontrol *input_mixer_ctls[HDSPM_MAX_CHANNELS]; + /* full mixer accessable over mixer ioctl or hwdep-device */ + struct hdspm_mixer *mixer; }; @@ -616,13 +635,15 @@ static inline int hdspm_external_sample_rate(struct hdspm * hdspm) if (hdspm->is_aes32) { unsigned int status2 = hdspm_read(hdspm, HDSPM_statusRegister2); unsigned int status = hdspm_read(hdspm, HDSPM_statusRegister); - unsigned int timecode = hdspm_read(hdspm, HDSPM_timecodeRegister); + unsigned int timecode = + hdspm_read(hdspm, HDSPM_timecodeRegister); int syncref = hdspm_autosync_ref(hdspm); if (syncref == HDSPM_AES32_AUTOSYNC_FROM_WORD && status & HDSPM_AES32_wcLock) - return HDSPM_bit2freq((status >> HDSPM_AES32_wcFreq_bit) & 0xF); + return HDSPM_bit2freq((status >> HDSPM_AES32_wcFreq_bit) + & 0xF); if (syncref >= HDSPM_AES32_AUTOSYNC_FROM_AES1 && syncref <= HDSPM_AES32_AUTOSYNC_FROM_AES8 && status2 & (HDSPM_LockAES >> @@ -668,7 +689,9 @@ static inline int hdspm_external_sample_rate(struct hdspm * hdspm) } } - /* if rate detected and Syncref is Word than have it, word has priority to MADI */ + /* if rate detected and Syncref is Word than have it, + * word has priority to MADI + */ if (rate != 0 && (status2 & HDSPM_SelSyncRefMask) == HDSPM_SelSyncRef_WORD) return rate; @@ -727,12 +750,12 @@ static snd_pcm_uframes_t hdspm_hw_pointer(struct hdspm * hdspm) position = hdspm_read(hdspm, HDSPM_statusRegister); - if (!hdspm->precise_ptr) { - return (position & HDSPM_BufferID) ? (hdspm->period_bytes / - 4) : 0; - } + if (!hdspm->precise_ptr) + return (position & HDSPM_BufferID) ? + (hdspm->period_bytes / 4) : 0; - /* hwpointer comes in bytes and is 64Bytes accurate (by docu since PCI Burst) + /* hwpointer comes in bytes and is 64Bytes accurate (by docu since + PCI Burst) i have experimented that it is at most 64 Byte to much for playing so substraction of 64 byte should be ok for ALSA, but use it only for application where you know what you do since if you come to @@ -808,10 +831,10 @@ static void hdspm_set_dds_value(struct hdspm *hdspm, int rate) rate /= 2; /* RME says n = 104857600000000, but in the windows MADI driver, I see: -// return 104857600000000 / rate; // 100 MHz + return 104857600000000 / rate; // 100 MHz return 110100480000000 / rate; // 105 MHz */ - //n = 104857600000000ULL; /* = 2^20 * 10^8 */ + /* n = 104857600000000ULL; */ /* = 2^20 * 10^8 */ n = 110100480000000ULL; /* Value checked for AES32 and MADI */ div64_32(&n, rate, &r); /* n should be less than 2^32 for being written to FREQ register */ @@ -841,8 +864,9 @@ static int hdspm_set_rate(struct hdspm * hdspm, int rate, int called_internally) just make a warning an remember setting for future master mode switching */ - snd_printk - (KERN_WARNING "HDSPM: Warning: device is not running as a clock master.\n"); + snd_printk(KERN_WARNING "HDSPM: " + "Warning: device is not running " + "as a clock master.\n"); not_set = 1; } else { @@ -850,16 +874,18 @@ static int hdspm_set_rate(struct hdspm * hdspm, int rate, int called_internally) int external_freq = hdspm_external_sample_rate(hdspm); - if ((hdspm_autosync_ref(hdspm) == - HDSPM_AUTOSYNC_FROM_NONE)) { + if (hdspm_autosync_ref(hdspm) == + HDSPM_AUTOSYNC_FROM_NONE) { - snd_printk(KERN_WARNING "HDSPM: Detected no Externel Sync \n"); + snd_printk(KERN_WARNING "HDSPM: " + "Detected no Externel Sync \n"); not_set = 1; } else if (rate != external_freq) { - snd_printk - (KERN_WARNING "HDSPM: Warning: No AutoSync source for requested rate\n"); + snd_printk(KERN_WARNING "HDSPM: " + "Warning: No AutoSync source for " + "requested rate\n"); not_set = 1; } } @@ -934,7 +960,9 @@ static int hdspm_set_rate(struct hdspm * hdspm, int rate, int called_internally) if (reject_if_open && (hdspm->capture_pid >= 0 || hdspm->playback_pid >= 0)) { snd_printk - (KERN_ERR "HDSPM: cannot change between single- and double-speed mode (capture PID = %d, playback PID = %d)\n", + (KERN_ERR "HDSPM: " + "cannot change between single- and double-speed mode " + "(capture PID = %d, playback PID = %d)\n", hdspm->capture_pid, hdspm->playback_pid); return -EBUSY; } @@ -966,8 +994,14 @@ static int hdspm_set_rate(struct hdspm * hdspm, int rate, int called_internally) static void all_in_all_mixer(struct hdspm * hdspm, int sgain) { int i, j; - unsigned int gain = - (sgain > UNITY_GAIN) ? UNITY_GAIN : (sgain < 0) ? 0 : sgain; + unsigned int gain; + + if (sgain > UNITY_GAIN) + gain = UNITY_GAIN; + else if (sgain < 0) + gain = 0; + else + gain = sgain; for (i = 0; i < HDSPM_MIXER_CHANNELS; i++) for (j = 0; j < HDSPM_MIXER_CHANNELS; j++) { @@ -980,7 +1014,8 @@ static void all_in_all_mixer(struct hdspm * hdspm, int sgain) MIDI ----------------------------------------------------------------------------*/ -static inline unsigned char snd_hdspm_midi_read_byte (struct hdspm *hdspm, int id) +static inline unsigned char snd_hdspm_midi_read_byte (struct hdspm *hdspm, + int id) { /* the hardware already does the relevant bit-mask with 0xff */ if (id) @@ -989,7 +1024,8 @@ static inline unsigned char snd_hdspm_midi_read_byte (struct hdspm *hdspm, int i return hdspm_read(hdspm, HDSPM_midiDataIn0); } -static inline void snd_hdspm_midi_write_byte (struct hdspm *hdspm, int id, int val) +static inline void snd_hdspm_midi_write_byte (struct hdspm *hdspm, int id, + int val) { /* the hardware already does the relevant bit-mask with 0xff */ if (id) @@ -1011,9 +1047,10 @@ static inline int snd_hdspm_midi_output_possible (struct hdspm *hdspm, int id) int fifo_bytes_used; if (id) - fifo_bytes_used = hdspm_read(hdspm, HDSPM_midiStatusOut1) & 0xff; + fifo_bytes_used = hdspm_read(hdspm, HDSPM_midiStatusOut1); else - fifo_bytes_used = hdspm_read(hdspm, HDSPM_midiStatusOut0) & 0xff; + fifo_bytes_used = hdspm_read(hdspm, HDSPM_midiStatusOut0); + fifo_bytes_used &= 0xff; if (fifo_bytes_used < 128) return 128 - fifo_bytes_used; @@ -1038,16 +1075,21 @@ static int snd_hdspm_midi_output_write (struct hdspm_midi *hmidi) /* Output is not interrupt driven */ spin_lock_irqsave (&hmidi->lock, flags); - if (hmidi->output) { - if (!snd_rawmidi_transmit_empty (hmidi->output)) { - if ((n_pending = snd_hdspm_midi_output_possible (hmidi->hdspm, hmidi->id)) > 0) { - if (n_pending > (int)sizeof (buf)) - n_pending = sizeof (buf); - - if ((to_write = snd_rawmidi_transmit (hmidi->output, buf, n_pending)) > 0) { - for (i = 0; i < to_write; ++i) - snd_hdspm_midi_write_byte (hmidi->hdspm, hmidi->id, buf[i]); - } + if (hmidi->output && + !snd_rawmidi_transmit_empty (hmidi->output)) { + n_pending = snd_hdspm_midi_output_possible (hmidi->hdspm, + hmidi->id); + if (n_pending > 0) { + if (n_pending > (int)sizeof (buf)) + n_pending = sizeof (buf); + + to_write = snd_rawmidi_transmit (hmidi->output, buf, + n_pending); + if (to_write > 0) { + for (i = 0; i < to_write; ++i) + snd_hdspm_midi_write_byte (hmidi->hdspm, + hmidi->id, + buf[i]); } } } @@ -1057,51 +1099,55 @@ static int snd_hdspm_midi_output_write (struct hdspm_midi *hmidi) static int snd_hdspm_midi_input_read (struct hdspm_midi *hmidi) { - unsigned char buf[128]; /* this buffer is designed to match the MIDI input FIFO size */ + unsigned char buf[128]; /* this buffer is designed to match the MIDI + * input FIFO size + */ unsigned long flags; int n_pending; int i; spin_lock_irqsave (&hmidi->lock, flags); - if ((n_pending = snd_hdspm_midi_input_available (hmidi->hdspm, hmidi->id)) > 0) { + n_pending = snd_hdspm_midi_input_available (hmidi->hdspm, hmidi->id); + if (n_pending > 0) { if (hmidi->input) { - if (n_pending > (int)sizeof (buf)) { + if (n_pending > (int)sizeof (buf)) n_pending = sizeof (buf); - } - for (i = 0; i < n_pending; ++i) { - buf[i] = snd_hdspm_midi_read_byte (hmidi->hdspm, hmidi->id); - } - if (n_pending) { - snd_rawmidi_receive (hmidi->input, buf, n_pending); - } + for (i = 0; i < n_pending; ++i) + buf[i] = snd_hdspm_midi_read_byte (hmidi->hdspm, + hmidi->id); + if (n_pending) + snd_rawmidi_receive (hmidi->input, buf, + n_pending); } else { /* flush the MIDI input FIFO */ - while (n_pending--) { - snd_hdspm_midi_read_byte (hmidi->hdspm, hmidi->id); - } + while (n_pending--) + snd_hdspm_midi_read_byte (hmidi->hdspm, + hmidi->id); } } hmidi->pending = 0; - if (hmidi->id) { + if (hmidi->id) hmidi->hdspm->control_register |= HDSPM_Midi1InterruptEnable; - } else { + else hmidi->hdspm->control_register |= HDSPM_Midi0InterruptEnable; - } - hdspm_write(hmidi->hdspm, HDSPM_controlRegister, hmidi->hdspm->control_register); + hdspm_write(hmidi->hdspm, HDSPM_controlRegister, + hmidi->hdspm->control_register); spin_unlock_irqrestore (&hmidi->lock, flags); return snd_hdspm_midi_output_write (hmidi); } -static void snd_hdspm_midi_input_trigger(struct snd_rawmidi_substream *substream, int up) +static void +snd_hdspm_midi_input_trigger(struct snd_rawmidi_substream *substream, int up) { struct hdspm *hdspm; struct hdspm_midi *hmidi; unsigned long flags; u32 ie; - hmidi = (struct hdspm_midi *) substream->rmidi->private_data; + hmidi = substream->rmidi->private_data; hdspm = hmidi->hdspm; - ie = hmidi->id ? HDSPM_Midi1InterruptEnable : HDSPM_Midi0InterruptEnable; + ie = hmidi->id ? + HDSPM_Midi1InterruptEnable : HDSPM_Midi0InterruptEnable; spin_lock_irqsave (&hdspm->lock, flags); if (up) { if (!(hdspm->control_register & ie)) { @@ -1138,12 +1184,13 @@ static void snd_hdspm_midi_output_timer(unsigned long data) spin_unlock_irqrestore (&hmidi->lock, flags); } -static void snd_hdspm_midi_output_trigger(struct snd_rawmidi_substream *substream, int up) +static void +snd_hdspm_midi_output_trigger(struct snd_rawmidi_substream *substream, int up) { struct hdspm_midi *hmidi; unsigned long flags; - hmidi = (struct hdspm_midi *) substream->rmidi->private_data; + hmidi = substream->rmidi->private_data; spin_lock_irqsave (&hmidi->lock, flags); if (up) { if (!hmidi->istimer) { @@ -1155,9 +1202,8 @@ static void snd_hdspm_midi_output_trigger(struct snd_rawmidi_substream *substrea hmidi->istimer++; } } else { - if (hmidi->istimer && --hmidi->istimer <= 0) { + if (hmidi->istimer && --hmidi->istimer <= 0) del_timer (&hmidi->timer); - } } spin_unlock_irqrestore (&hmidi->lock, flags); if (up) @@ -1168,7 +1214,7 @@ static int snd_hdspm_midi_input_open(struct snd_rawmidi_substream *substream) { struct hdspm_midi *hmidi; - hmidi = (struct hdspm_midi *) substream->rmidi->private_data; + hmidi = substream->rmidi->private_data; spin_lock_irq (&hmidi->lock); snd_hdspm_flush_midi_input (hmidi->hdspm, hmidi->id); hmidi->input = substream; @@ -1181,7 +1227,7 @@ static int snd_hdspm_midi_output_open(struct snd_rawmidi_substream *substream) { struct hdspm_midi *hmidi; - hmidi = (struct hdspm_midi *) substream->rmidi->private_data; + hmidi = substream->rmidi->private_data; spin_lock_irq (&hmidi->lock); hmidi->output = substream; spin_unlock_irq (&hmidi->lock); @@ -1195,7 +1241,7 @@ static int snd_hdspm_midi_input_close(struct snd_rawmidi_substream *substream) snd_hdspm_midi_input_trigger (substream, 0); - hmidi = (struct hdspm_midi *) substream->rmidi->private_data; + hmidi = substream->rmidi->private_data; spin_lock_irq (&hmidi->lock); hmidi->input = NULL; spin_unlock_irq (&hmidi->lock); @@ -1209,7 +1255,7 @@ static int snd_hdspm_midi_output_close(struct snd_rawmidi_substream *substream) snd_hdspm_midi_output_trigger (substream, 0); - hmidi = (struct hdspm_midi *) substream->rmidi->private_data; + hmidi = substream->rmidi->private_data; spin_lock_irq (&hmidi->lock); hmidi->output = NULL; spin_unlock_irq (&hmidi->lock); @@ -1231,29 +1277,28 @@ static struct snd_rawmidi_ops snd_hdspm_midi_input = .trigger = snd_hdspm_midi_input_trigger, }; -static int __devinit snd_hdspm_create_midi (struct snd_card *card, struct hdspm *hdspm, int id) +static int __devinit snd_hdspm_create_midi (struct snd_card *card, + struct hdspm *hdspm, int id) { int err; char buf[32]; hdspm->midi[id].id = id; - hdspm->midi[id].rmidi = NULL; - hdspm->midi[id].input = NULL; - hdspm->midi[id].output = NULL; hdspm->midi[id].hdspm = hdspm; - hdspm->midi[id].istimer = 0; - hdspm->midi[id].pending = 0; spin_lock_init (&hdspm->midi[id].lock); sprintf (buf, "%s MIDI %d", card->shortname, id+1); - if ((err = snd_rawmidi_new (card, buf, id, 1, 1, &hdspm->midi[id].rmidi)) < 0) + err = snd_rawmidi_new (card, buf, id, 1, 1, &hdspm->midi[id].rmidi); + if (err < 0) return err; sprintf (hdspm->midi[id].rmidi->name, "%s MIDI %d", card->id, id+1); hdspm->midi[id].rmidi->private_data = &hdspm->midi[id]; - snd_rawmidi_set_ops (hdspm->midi[id].rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_hdspm_midi_output); - snd_rawmidi_set_ops (hdspm->midi[id].rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &snd_hdspm_midi_input); + snd_rawmidi_set_ops(hdspm->midi[id].rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, + &snd_hdspm_midi_output); + snd_rawmidi_set_ops(hdspm->midi[id].rmidi, SNDRV_RAWMIDI_STREAM_INPUT, + &snd_hdspm_midi_input); hdspm->midi[id].rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT | SNDRV_RAWMIDI_INFO_INPUT | @@ -1637,7 +1682,8 @@ static int hdspm_set_pref_sync_ref(struct hdspm * hdspm, int pref) hdspm->control_register |= HDSPM_SyncRef2+HDSPM_SyncRef1; break; case 7: - hdspm->control_register |= HDSPM_SyncRef2+HDSPM_SyncRef1+HDSPM_SyncRef0; + hdspm->control_register |= + HDSPM_SyncRef2+HDSPM_SyncRef1+HDSPM_SyncRef0; break; case 8: hdspm->control_register |= HDSPM_SyncRef3; @@ -1675,7 +1721,8 @@ static int snd_hdspm_info_pref_sync_ref(struct snd_kcontrol *kcontrol, uinfo->value.enumerated.items = 9; - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) + if (uinfo->value.enumerated.item >= + uinfo->value.enumerated.items) uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; strcpy(uinfo->value.enumerated.name, @@ -1688,7 +1735,8 @@ static int snd_hdspm_info_pref_sync_ref(struct snd_kcontrol *kcontrol, uinfo->value.enumerated.items = 2; - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) + if (uinfo->value.enumerated.item >= + uinfo->value.enumerated.items) uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; strcpy(uinfo->value.enumerated.name, @@ -1740,7 +1788,8 @@ static int hdspm_autosync_ref(struct hdspm * hdspm) { if (hdspm->is_aes32) { unsigned int status = hdspm_read(hdspm, HDSPM_statusRegister); - unsigned int syncref = (status >> HDSPM_AES32_syncref_bit) & 0xF; + unsigned int syncref = (status >> HDSPM_AES32_syncref_bit) & + 0xF; if (syncref == 0) return HDSPM_AES32_AUTOSYNC_FROM_WORD; if (syncref <= 8) @@ -1777,20 +1826,20 @@ static int snd_hdspm_info_autosync_ref(struct snd_kcontrol *kcontrol, uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; uinfo->count = 1; uinfo->value.enumerated.items = 10; - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) + 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]); - } - else - { + } else { static char *texts[] = { "WordClock", "MADI", "None" }; uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; uinfo->count = 1; uinfo->value.enumerated.items = 3; - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) + if (uinfo->value.enumerated.item >= + uinfo->value.enumerated.items) uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; strcpy(uinfo->value.enumerated.name, @@ -2416,7 +2465,7 @@ static int snd_hdspm_put_qs_wire(struct snd_kcontrol *kcontrol, if (val > 2) val = 2; spin_lock_irq(&hdspm->lock); - change = (int) val != hdspm_qs_wire(hdspm); + change = val != hdspm_qs_wire(hdspm); hdspm_set_qs_wire(hdspm, val); spin_unlock_irq(&hdspm->lock); return change; @@ -2517,8 +2566,8 @@ static int snd_hdspm_put_mixer(struct snd_kcontrol *kcontrol, source - HDSPM_MAX_CHANNELS); else - change = - gain != hdspm_read_in_gain(hdspm, destination, source); + change = gain != hdspm_read_in_gain(hdspm, destination, + source); if (change) { if (source >= HDSPM_MAX_CHANNELS) @@ -2571,7 +2620,8 @@ static int snd_hdspm_get_playback_mixer(struct snd_kcontrol *kcontrol, snd_assert(channel >= 0 || channel < HDSPM_MAX_CHANNELS, return -EINVAL); - if ((mapped_channel = hdspm->channel_map[channel]) < 0) + mapped_channel = hdspm->channel_map[channel]; + if (mapped_channel < 0) return -EINVAL; spin_lock_irq(&hdspm->lock); @@ -2579,10 +2629,12 @@ static int snd_hdspm_get_playback_mixer(struct snd_kcontrol *kcontrol, hdspm_read_pb_gain(hdspm, mapped_channel, mapped_channel); spin_unlock_irq(&hdspm->lock); - /* snd_printdd("get pb mixer index %d, channel %d, mapped_channel %d, value %d\n", - ucontrol->id.index, channel, mapped_channel, ucontrol->value.integer.value[0]); - */ - + /* + snd_printdd("get pb mixer index %d, channel %d, mapped_channel %d, " + "value %d\n", + ucontrol->id.index, channel, mapped_channel, + ucontrol->value.integer.value[0]); + */ return 0; } @@ -2603,7 +2655,8 @@ static int snd_hdspm_put_playback_mixer(struct snd_kcontrol *kcontrol, snd_assert(channel >= 0 || channel < HDSPM_MAX_CHANNELS, return -EINVAL); - if ((mapped_channel = hdspm->channel_map[channel]) < 0) + mapped_channel = hdspm->channel_map[channel]; + if (mapped_channel < 0) return -EINVAL; gain = ucontrol->value.integer.value[0]; @@ -2853,28 +2906,26 @@ static int snd_hdspm_create_controls(struct snd_card *card, struct hdspm * hdspm } /* Channel playback mixer as default control -Note: the whole matrix would be 128*HDSPM_MIXER_CHANNELS Faders, thats too big for any alsamixer -they are accesible via special IOCTL on hwdep -and the mixer 2dimensional mixer control */ + Note: the whole matrix would be 128*HDSPM_MIXER_CHANNELS Faders, + thats too * big for any alsamixer they are accesible via special + IOCTL on hwdep and the mixer 2dimensional mixer control + */ snd_hdspm_playback_mixer.name = "Chn"; limit = HDSPM_MAX_CHANNELS; - /* The index values are one greater than the channel ID so that alsamixer - will display them correctly. We want to use the index for fast lookup - of the relevant channel, but if we use it at all, most ALSA software - does the wrong thing with it ... + /* The index values are one greater than the channel ID so that + * alsamixer will display them correctly. We want to use the index + * for fast lookup of the relevant channel, but if we use it at all, + * most ALSA software does the wrong thing with it ... */ for (idx = 0; idx < limit; ++idx) { snd_hdspm_playback_mixer.index = idx + 1; - if ((err = snd_ctl_add(card, - kctl = - snd_ctl_new1 - (&snd_hdspm_playback_mixer, - hdspm)))) { + kctl = snd_ctl_new1(&snd_hdspm_playback_mixer, hdspm); + err = snd_ctl_add(card, kctl); + if (err < 0) return err; - } hdspm->playback_mixer_ctls[idx] = kctl; } @@ -2889,7 +2940,7 @@ static void snd_hdspm_proc_read_madi(struct snd_info_entry * entry, struct snd_info_buffer *buffer) { - struct hdspm *hdspm = (struct hdspm *) entry->private_data; + struct hdspm *hdspm = entry->private_data; unsigned int status; unsigned int status2; char *pref_sync_ref; @@ -2922,14 +2973,14 @@ snd_hdspm_proc_read_madi(struct snd_info_entry * entry, (status & HDSPM_midi1IRQPending) ? 1 : 0, hdspm->irq_count); snd_iprintf(buffer, - "HW pointer: id = %d, rawptr = %d (%d->%d) estimated= %ld (bytes)\n", + "HW pointer: id = %d, rawptr = %d (%d->%d) " + "estimated= %ld (bytes)\n", ((status & HDSPM_BufferID) ? 1 : 0), (status & HDSPM_BufferPositionMask), - (status & HDSPM_BufferPositionMask) % (2 * - (int)hdspm-> - period_bytes), - ((status & HDSPM_BufferPositionMask) - - 64) % (2 * (int)hdspm->period_bytes), + (status & HDSPM_BufferPositionMask) % + (2 * (int)hdspm->period_bytes), + ((status & HDSPM_BufferPositionMask) - 64) % + (2 * (int)hdspm->period_bytes), (long) hdspm_hw_pointer(hdspm) * 4); snd_iprintf(buffer, @@ -2939,24 +2990,22 @@ snd_hdspm_proc_read_madi(struct snd_info_entry * entry, hdspm_read(hdspm, HDSPM_midiStatusIn0) & 0xFF, hdspm_read(hdspm, HDSPM_midiStatusIn1) & 0xFF); snd_iprintf(buffer, - "Register: ctrl1=0x%x, ctrl2=0x%x, status1=0x%x, status2=0x%x\n", + "Register: ctrl1=0x%x, ctrl2=0x%x, status1=0x%x, " + "status2=0x%x\n", hdspm->control_register, hdspm->control2_register, status, status2); snd_iprintf(buffer, "--- Settings ---\n"); - x = 1 << (6 + - hdspm_decode_latency(hdspm-> - control_register & - HDSPM_LatencyMask)); + x = 1 << (6 + hdspm_decode_latency(hdspm->control_register & + HDSPM_LatencyMask)); snd_iprintf(buffer, "Size (Latency): %d samples (2 periods of %lu bytes)\n", x, (unsigned long) hdspm->period_bytes); snd_iprintf(buffer, "Line out: %s, Precise Pointer: %s\n", - (hdspm-> - control_register & HDSPM_LineOut) ? "on " : "off", + (hdspm->control_register & HDSPM_LineOut) ? "on " : "off", (hdspm->precise_ptr) ? "on" : "off"); switch (hdspm->control_register & HDSPM_InputMask) { @@ -2984,7 +3033,8 @@ snd_hdspm_proc_read_madi(struct snd_info_entry * entry, syncref); snd_iprintf(buffer, - "ClearTrackMarker = %s, Transmit in %s Channel Mode, Auto Input %s\n", + "ClearTrackMarker = %s, Transmit in %s Channel Mode, " + "Auto Input %s\n", (hdspm-> control_register & HDSPM_clr_tms) ? "on" : "off", (hdspm-> @@ -3085,7 +3135,7 @@ static void snd_hdspm_proc_read_aes32(struct snd_info_entry * entry, struct snd_info_buffer *buffer) { - struct hdspm *hdspm = (struct hdspm *) entry->private_data; + struct hdspm *hdspm = entry->private_data; unsigned int status; unsigned int status2; unsigned int timecode; @@ -3115,14 +3165,14 @@ snd_hdspm_proc_read_aes32(struct snd_info_entry * entry, (status & HDSPM_midi1IRQPending) ? 1 : 0, hdspm->irq_count); snd_iprintf(buffer, - "HW pointer: id = %d, rawptr = %d (%d->%d) estimated= %ld (bytes)\n", + "HW pointer: id = %d, rawptr = %d (%d->%d) " + "estimated= %ld (bytes)\n", ((status & HDSPM_BufferID) ? 1 : 0), (status & HDSPM_BufferPositionMask), - (status & HDSPM_BufferPositionMask) % (2 * - (int)hdspm-> - period_bytes), - ((status & HDSPM_BufferPositionMask) - - 64) % (2 * (int)hdspm->period_bytes), + (status & HDSPM_BufferPositionMask) % + (2 * (int)hdspm->period_bytes), + ((status & HDSPM_BufferPositionMask) - 64) % + (2 * (int)hdspm->period_bytes), (long) hdspm_hw_pointer(hdspm) * 4); snd_iprintf(buffer, @@ -3132,16 +3182,15 @@ snd_hdspm_proc_read_aes32(struct snd_info_entry * entry, hdspm_read(hdspm, HDSPM_midiStatusIn0) & 0xFF, hdspm_read(hdspm, HDSPM_midiStatusIn1) & 0xFF); snd_iprintf(buffer, - "Register: ctrl1=0x%x, status1=0x%x, status2=0x%x, timecode=0x%x\n", + "Register: ctrl1=0x%x, status1=0x%x, status2=0x%x, " + "timecode=0x%x\n", hdspm->control_register, status, status2, timecode); snd_iprintf(buffer, "--- Settings ---\n"); - x = 1 << (6 + - hdspm_decode_latency(hdspm-> - control_register & - HDSPM_LatencyMask)); + x = 1 << (6 + hdspm_decode_latency(hdspm->control_register & + HDSPM_LatencyMask)); snd_iprintf(buffer, "Size (Latency): %d samples (2 periods of %lu bytes)\n", @@ -3224,14 +3273,15 @@ snd_hdspm_proc_read_aes32(struct snd_info_entry * entry, snd_iprintf(buffer, "--- Status:\n"); snd_iprintf(buffer, "Word: %s Frequency: %d\n", - (status & HDSPM_AES32_wcLock)? "Sync " : "No Lock", - HDSPM_bit2freq((status >> HDSPM_AES32_wcFreq_bit) & 0xF)); + (status & HDSPM_AES32_wcLock)? "Sync " : "No Lock", + HDSPM_bit2freq((status >> HDSPM_AES32_wcFreq_bit) & 0xF)); for (x = 0; x < 8; x++) { snd_iprintf(buffer, "AES%d: %s Frequency: %d\n", - x+1, - (status2 & (HDSPM_LockAES >> x))? "Sync ": "No Lock", - HDSPM_bit2freq((timecode >> (4*x)) & 0xF)); + x+1, + (status2 & (HDSPM_LockAES >> x)) ? + "Sync ": "No Lock", + HDSPM_bit2freq((timecode >> (4*x)) & 0xF)); } switch (hdspm_autosync_ref(hdspm)) { @@ -3257,12 +3307,11 @@ static void snd_hdspm_proc_read_debug(struct snd_info_entry * entry, struct snd_info_buffer *buffer) { - struct hdspm *hdspm = (struct hdspm *)entry->private_data; + struct hdspm *hdspm = entry->private_data; int j,i; - for (i = 0; i < 256 /* 1024*64 */; i += j) - { + for (i = 0; i < 256 /* 1024*64 */; i += j) { snd_iprintf(buffer, "0x%08X: ", i); for (j = 0; j < 16; j += 4) snd_iprintf(buffer, "%08X ", hdspm_read(hdspm, i + j)); @@ -3305,14 +3354,20 @@ static int snd_hdspm_set_defaults(struct hdspm * hdspm) /* set defaults: */ if (hdspm->is_aes32) - hdspm->control_register = HDSPM_ClockModeMaster | /* Master Cloack Mode on */ - hdspm_encode_latency(7) | /* latency maximum = 8192 samples */ + hdspm->control_register = + HDSPM_ClockModeMaster | /* Master Cloack Mode on */ + hdspm_encode_latency(7) | /* latency maximum = + * 8192 samples + */ HDSPM_SyncRef0 | /* AES1 is syncclock */ HDSPM_LineOut | /* Analog output in */ HDSPM_Professional; /* Professional mode */ else - hdspm->control_register = HDSPM_ClockModeMaster | /* Master Cloack Mode on */ - hdspm_encode_latency(7) | /* latency maximum = 8192 samples */ + hdspm->control_register = + HDSPM_ClockModeMaster | /* Master Cloack Mode on */ + hdspm_encode_latency(7) | /* latency maximum = + * 8192 samples + */ HDSPM_InputCoaxial | /* Input Coax not Optical */ HDSPM_SyncRef_MADI | /* Madi is syncclock */ HDSPM_LineOut | /* Analog output in */ @@ -3343,7 +3398,8 @@ static int snd_hdspm_set_defaults(struct hdspm * hdspm) if (line_outs_monitor[hdspm->dev]) { - snd_printk(KERN_INFO "HDSPM: sending all playback streams to line outs.\n"); + snd_printk(KERN_INFO "HDSPM: " + "sending all playback streams to line outs.\n"); for (i = 0; i < HDSPM_MIXER_CHANNELS; i++) { if (hdspm_write_pb_gain(hdspm, i, i, UNITY_GAIN)) @@ -3392,20 +3448,16 @@ static irqreturn_t snd_hdspm_interrupt(int irq, void *dev_id) if (audio) { if (hdspm->capture_substream) - snd_pcm_period_elapsed(hdspm->pcm-> - streams - [SNDRV_PCM_STREAM_CAPTURE]. - substream); + snd_pcm_period_elapsed(hdspm->capture_substream); if (hdspm->playback_substream) - snd_pcm_period_elapsed(hdspm->pcm-> - streams - [SNDRV_PCM_STREAM_PLAYBACK]. - substream); + snd_pcm_period_elapsed(hdspm->playback_substream); } if (midi0 && midi0status) { - /* we disable interrupts for this input until processing is done */ + /* we disable interrupts for this input until processing + * is done + */ hdspm->control_register &= ~HDSPM_Midi0InterruptEnable; hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register); @@ -3413,7 +3465,9 @@ static irqreturn_t snd_hdspm_interrupt(int irq, void *dev_id) schedule = 1; } if (midi1 && midi1status) { - /* we disable interrupts for this input until processing is done */ + /* we disable interrupts for this input until processing + * is done + */ hdspm->control_register &= ~HDSPM_Midi1InterruptEnable; hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register); @@ -3445,16 +3499,16 @@ static char *hdspm_channel_buffer_location(struct hdspm * hdspm, snd_assert(channel >= 0 || channel < HDSPM_MAX_CHANNELS, return NULL); - if ((mapped_channel = hdspm->channel_map[channel]) < 0) + mapped_channel = hdspm->channel_map[channel]; + if (mapped_channel < 0) return NULL; - if (stream == SNDRV_PCM_STREAM_CAPTURE) { + if (stream == SNDRV_PCM_STREAM_CAPTURE) return hdspm->capture_buffer + mapped_channel * HDSPM_CHANNEL_BUFFER_BYTES; - } else { + else return hdspm->playback_buffer + mapped_channel * HDSPM_CHANNEL_BUFFER_BYTES; - } } @@ -3469,9 +3523,9 @@ static int snd_hdspm_playback_copy(struct snd_pcm_substream *substream, snd_assert(pos + count <= HDSPM_CHANNEL_BUFFER_BYTES / 4, return -EINVAL); - channel_buf = hdspm_channel_buffer_location(hdspm, - substream->pstr-> - stream, channel); + channel_buf = + hdspm_channel_buffer_location(hdspm, substream->pstr->stream, + channel); snd_assert(channel_buf != NULL, return -EIO); @@ -3488,9 +3542,9 @@ static int snd_hdspm_capture_copy(struct snd_pcm_substream *substream, snd_assert(pos + count <= HDSPM_CHANNEL_BUFFER_BYTES / 4, return -EINVAL); - channel_buf = hdspm_channel_buffer_location(hdspm, - substream->pstr-> - stream, channel); + channel_buf = + hdspm_channel_buffer_location(hdspm, substream->pstr->stream, + channel); snd_assert(channel_buf != NULL, return -EIO); return copy_to_user(dst, channel_buf + pos * 4, count * 4); } @@ -3503,8 +3557,8 @@ static int snd_hdspm_hw_silence(struct snd_pcm_substream *substream, char *channel_buf; channel_buf = - hdspm_channel_buffer_location(hdspm, substream->pstr->stream, - channel); + hdspm_channel_buffer_location(hdspm, substream->pstr->stream, + channel); snd_assert(channel_buf != NULL, return -EIO); memset(channel_buf + pos * 4, 0, count * 4); return 0; @@ -3560,7 +3614,7 @@ static int snd_hdspm_hw_params(struct snd_pcm_substream *substream, other_pid = hdspm->playback_pid; } - if ((other_pid > 0) && (this_pid != other_pid)) { + if (other_pid > 0 && this_pid != other_pid) { /* The other stream is open, and not by the same task as this one. Make sure that the parameters @@ -3577,7 +3631,7 @@ static int snd_hdspm_hw_params(struct snd_pcm_substream *substream, if (params_period_size(params) != hdspm->period_bytes / 4) { spin_unlock_irq(&hdspm->lock); _snd_pcm_hw_param_setempty(params, - SNDRV_PCM_HW_PARAM_PERIOD_SIZE); + SNDRV_PCM_HW_PARAM_PERIOD_SIZE); return -EBUSY; } @@ -3588,7 +3642,8 @@ static int snd_hdspm_hw_params(struct snd_pcm_substream *substream, /* how to make sure that the rate matches an externally-set one ? */ spin_lock_irq(&hdspm->lock); - if ((err = hdspm_set_rate(hdspm, params_rate(params), 0)) < 0) { + err = hdspm_set_rate(hdspm, params_rate(params), 0); + if (err < 0) { spin_unlock_irq(&hdspm->lock); _snd_pcm_hw_param_setempty(params, SNDRV_PCM_HW_PARAM_RATE); @@ -3596,16 +3651,17 @@ static int snd_hdspm_hw_params(struct snd_pcm_substream *substream, } spin_unlock_irq(&hdspm->lock); - if ((err = - hdspm_set_interrupt_interval(hdspm, - params_period_size(params))) < - 0) { + err = hdspm_set_interrupt_interval(hdspm, + params_period_size(params)); + if (err < 0) { _snd_pcm_hw_param_setempty(params, SNDRV_PCM_HW_PARAM_PERIOD_SIZE); return err; } - /* Memory allocation, takashi's method, dont know if we should spinlock */ + /* Memory allocation, takashi's method, dont know if we should + * spinlock + */ /* malloc all buffer even if not enabled to get sure */ /* Update for MADI rev 204: we need to allocate for all channels, * otherwise it doesn't work at 96kHz */ @@ -3690,7 +3746,8 @@ static int snd_hdspm_channel_info(struct snd_pcm_substream *substream, snd_assert(info->channel < HDSPM_MAX_CHANNELS, return -EINVAL); - if ((mapped_channel = hdspm->channel_map[info->channel]) < 0) + mapped_channel = hdspm->channel_map[info->channel]; + if (mapped_channel < 0) return -EINVAL; info->offset = mapped_channel * HDSPM_CHANNEL_BUFFER_BYTES; @@ -3704,15 +3761,13 @@ static int snd_hdspm_ioctl(struct snd_pcm_substream *substream, { switch (cmd) { case SNDRV_PCM_IOCTL1_RESET: - { - return snd_hdspm_reset(substream); - } + return snd_hdspm_reset(substream); case SNDRV_PCM_IOCTL1_CHANNEL_INFO: - { - struct snd_pcm_channel_info *info = arg; - return snd_hdspm_channel_info(substream, info); - } + { + struct snd_pcm_channel_info *info = arg; + return snd_hdspm_channel_info(substream, info); + } default: break; } @@ -3923,9 +3978,12 @@ static int snd_hdspm_hw_rule_channels(struct snd_pcm_hw_params *params, } -static unsigned int hdspm_aes32_sample_rates[] = { 32000, 44100, 48000, 64000, 88200, 96000, 128000, 176400, 192000 }; +static unsigned int hdspm_aes32_sample_rates[] = { + 32000, 44100, 48000, 64000, 88200, 96000, 128000, 176400, 192000 +}; -static struct snd_pcm_hw_constraint_list hdspm_hw_constraints_aes32_sample_rates = { +static struct snd_pcm_hw_constraint_list +hdspm_hw_constraints_aes32_sample_rates = { .count = ARRAY_SIZE(hdspm_aes32_sample_rates), .list = hdspm_aes32_sample_rates, .mask = 0 @@ -4051,7 +4109,7 @@ static int snd_hdspm_hwdep_dummy_op(struct snd_hwdep * hw, struct file *file) static int snd_hdspm_hwdep_ioctl(struct snd_hwdep * hw, struct file *file, unsigned int cmd, unsigned long arg) { - struct hdspm *hdspm = (struct hdspm *) hw->private_data; + struct hdspm *hdspm = hw->private_data; struct hdspm_mixer_ioctl mixer; struct hdspm_config_info info; struct hdspm_version hdspm_version; @@ -4059,11 +4117,12 @@ static int snd_hdspm_hwdep_ioctl(struct snd_hwdep * hw, struct file *file, switch (cmd) { - case SNDRV_HDSPM_IOCTL_GET_PEAK_RMS: if (copy_from_user(&rms, (void __user *)arg, sizeof(rms))) return -EFAULT; - /* maybe there is a chance to memorymap in future so dont touch just copy */ + /* maybe there is a chance to memorymap in future + * so dont touch just copy + */ if(copy_to_user_fromio((void __user *)rms.peak, hdspm->iobase+HDSPM_MADI_peakrmsbase, sizeof(struct hdspm_peak_rms)) != 0 ) @@ -4075,21 +4134,16 @@ static int snd_hdspm_hwdep_ioctl(struct snd_hwdep * hw, struct file *file, case SNDRV_HDSPM_IOCTL_GET_CONFIG_INFO: spin_lock_irq(&hdspm->lock); - info.pref_sync_ref = - (unsigned char) hdspm_pref_sync_ref(hdspm); - info.wordclock_sync_check = - (unsigned char) hdspm_wc_sync_check(hdspm); + info.pref_sync_ref = hdspm_pref_sync_ref(hdspm); + info.wordclock_sync_check = hdspm_wc_sync_check(hdspm); info.system_sample_rate = hdspm->system_sample_rate; info.autosync_sample_rate = hdspm_external_sample_rate(hdspm); - info.system_clock_mode = - (unsigned char) hdspm_system_clock_mode(hdspm); - info.clock_source = - (unsigned char) hdspm_clock_source(hdspm); - info.autosync_ref = - (unsigned char) hdspm_autosync_ref(hdspm); - info.line_out = (unsigned char) hdspm_line_out(hdspm); + info.system_clock_mode = hdspm_system_clock_mode(hdspm); + info.clock_source = hdspm_clock_source(hdspm); + info.autosync_ref = hdspm_autosync_ref(hdspm); + info.line_out = hdspm_line_out(hdspm); info.passthru = 0; spin_unlock_irq(&hdspm->lock); if (copy_to_user((void __user *) arg, &info, sizeof(info))) @@ -4106,8 +4160,8 @@ static int snd_hdspm_hwdep_ioctl(struct snd_hwdep * hw, struct file *file, case SNDRV_HDSPM_IOCTL_GET_MIXER: if (copy_from_user(&mixer, (void __user *)arg, sizeof(mixer))) return -EFAULT; - if (copy_to_user - ((void __user *)mixer.mixer, hdspm->mixer, sizeof(struct hdspm_mixer))) + if (copy_to_user((void __user *)mixer.mixer, hdspm->mixer, + sizeof(struct hdspm_mixer))) return -EFAULT; break; @@ -4150,7 +4204,8 @@ static int __devinit snd_hdspm_create_hwdep(struct snd_card *card, struct snd_hwdep *hw; int err; - if ((err = snd_hwdep_new(card, "HDSPM hwdep", 0, &hw)) < 0) + err = snd_hwdep_new(card, "HDSPM hwdep", 0, &hw); + if (err < 0) return err; hdspm->hwdep = hw; @@ -4176,15 +4231,15 @@ static int __devinit snd_hdspm_preallocate_memory(struct hdspm * hdspm) pcm = hdspm->pcm; -/* wanted = HDSPM_DMA_AREA_BYTES + 4096;*/ /* dont know why, but it works */ wanted = HDSPM_DMA_AREA_BYTES; - if ((err = + err = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG, snd_dma_pci_data(hdspm->pci), wanted, - wanted)) < 0) { + wanted); + if (err < 0) { snd_printdd("Could not preallocate %zd Bytes\n", wanted); return err; @@ -4200,8 +4255,7 @@ static void hdspm_set_sgbuf(struct hdspm * hdspm, struct snd_sg_buf *sgbuf, int i; for (i = 0; i < (channels * 16); i++) hdspm_write(hdspm, reg + 4 * i, - snd_pcm_sgbuf_get_addr(sgbuf, - (size_t) 4096 * i)); + snd_pcm_sgbuf_get_addr(sgbuf, (size_t) 4096 * i)); } /* ------------- ALSA Devices ---------------------------- */ @@ -4211,7 +4265,8 @@ static int __devinit snd_hdspm_create_pcm(struct snd_card *card, struct snd_pcm *pcm; int err; - if ((err = snd_pcm_new(card, hdspm->card_name, 0, 1, 1, &pcm)) < 0) + err = snd_pcm_new(card, hdspm->card_name, 0, 1, 1, &pcm); + if (err < 0) return err; hdspm->pcm = pcm; @@ -4225,7 +4280,8 @@ static int __devinit snd_hdspm_create_pcm(struct snd_card *card, pcm->info_flags = SNDRV_PCM_INFO_JOINT_DUPLEX; - if ((err = snd_hdspm_preallocate_memory(hdspm)) < 0) + err = snd_hdspm_preallocate_memory(hdspm); + if (err < 0) return err; return 0; @@ -4243,19 +4299,24 @@ static int __devinit snd_hdspm_create_alsa_devices(struct snd_card *card, int err; snd_printdd("Create card...\n"); - if ((err = snd_hdspm_create_pcm(card, hdspm)) < 0) + err = snd_hdspm_create_pcm(card, hdspm); + if (err < 0) return err; - if ((err = snd_hdspm_create_midi(card, hdspm, 0)) < 0) + err = snd_hdspm_create_midi(card, hdspm, 0); + if (err < 0) return err; - if ((err = snd_hdspm_create_midi(card, hdspm, 1)) < 0) + err = snd_hdspm_create_midi(card, hdspm, 1); + if (err < 0) return err; - if ((err = snd_hdspm_create_controls(card, hdspm)) < 0) + err = snd_hdspm_create_controls(card, hdspm); + if (err < 0) return err; - if ((err = snd_hdspm_create_hwdep(card, hdspm)) < 0) + err = snd_hdspm_create_hwdep(card, hdspm); + if (err < 0) return err; snd_printdd("proc init...\n"); @@ -4270,7 +4331,8 @@ static int __devinit snd_hdspm_create_alsa_devices(struct snd_card *card, hdspm->playback_substream = NULL; snd_printdd("Set defaults...\n"); - if ((err = snd_hdspm_set_defaults(hdspm)) < 0) + err = snd_hdspm_set_defaults(hdspm); + if (err < 0) return err; snd_printdd("Update mixer controls...\n"); @@ -4278,7 +4340,8 @@ static int __devinit snd_hdspm_create_alsa_devices(struct snd_card *card, snd_printdd("Initializeing complete ???\n"); - if ((err = snd_card_register(card)) < 0) { + err = snd_card_register(card); + if (err < 0) { snd_printk(KERN_ERR "HDSPM: error registering card\n"); return err; } @@ -4288,36 +4351,18 @@ static int __devinit snd_hdspm_create_alsa_devices(struct snd_card *card, return 0; } -static int __devinit snd_hdspm_create(struct snd_card *card, struct hdspm * hdspm, +static int __devinit snd_hdspm_create(struct snd_card *card, + struct hdspm *hdspm, int precise_ptr, int enable_monitor) { struct pci_dev *pci = hdspm->pci; int err; - int i; - unsigned long io_extent; hdspm->irq = -1; - hdspm->irq_count = 0; - - hdspm->midi[0].rmidi = NULL; - hdspm->midi[1].rmidi = NULL; - hdspm->midi[0].input = NULL; - hdspm->midi[1].input = NULL; - hdspm->midi[0].output = NULL; - hdspm->midi[1].output = NULL; + spin_lock_init(&hdspm->midi[0].lock); spin_lock_init(&hdspm->midi[1].lock); - hdspm->iobase = NULL; - hdspm->control_register = 0; - hdspm->control2_register = 0; - - hdspm->playback_buffer = NULL; - hdspm->capture_buffer = NULL; - - for (i = 0; i < HDSPM_MAX_CHANNELS; ++i) - hdspm->playback_mixer_ctls[i] = NULL; - hdspm->mixer = NULL; hdspm->card = card; @@ -4340,12 +4385,14 @@ static int __devinit snd_hdspm_create(struct snd_card *card, struct hdspm * hdsp hdspm->card_name = "RME HDSPM MADI"; } - if ((err = pci_enable_device(pci)) < 0) + err = pci_enable_device(pci); + if (err < 0) return err; pci_set_master(hdspm->pci); - if ((err = pci_request_regions(pci, "hdspm")) < 0) + err = pci_request_regions(pci, "hdspm"); + if (err < 0) return err; hdspm->port = pci_resource_start(pci, 0); @@ -4355,8 +4402,10 @@ static int __devinit snd_hdspm_create(struct snd_card *card, struct hdspm * hdsp hdspm->port, hdspm->port + io_extent - 1); - if ((hdspm->iobase = ioremap_nocache(hdspm->port, io_extent)) == NULL) { - snd_printk(KERN_ERR "HDSPM: unable to remap region 0x%lx-0x%lx\n", + hdspm->iobase = ioremap_nocache(hdspm->port, io_extent); + if (!hdspm->iobase) { + snd_printk(KERN_ERR "HDSPM: " + "unable to remap region 0x%lx-0x%lx\n", hdspm->port, hdspm->port + io_extent - 1); return -EBUSY; } @@ -4379,9 +4428,10 @@ static int __devinit snd_hdspm_create(struct snd_card *card, struct hdspm * hdsp snd_printdd("kmalloc Mixer memory of %zd Bytes\n", sizeof(struct hdspm_mixer)); - if ((hdspm->mixer = kmalloc(sizeof(struct hdspm_mixer), GFP_KERNEL)) - == NULL) { - snd_printk(KERN_ERR "HDSPM: unable to kmalloc Mixer memory of %d Bytes\n", + hdspm->mixer = kzalloc(sizeof(struct hdspm_mixer), GFP_KERNEL); + if (!hdspm->mixer) { + snd_printk(KERN_ERR "HDSPM: " + "unable to kmalloc Mixer memory of %d Bytes\n", (int)sizeof(struct hdspm_mixer)); return err; } @@ -4391,7 +4441,8 @@ static int __devinit snd_hdspm_create(struct snd_card *card, struct hdspm * hdsp hdspm->qs_channels = MADI_QS_CHANNELS; snd_printdd("create alsa devices.\n"); - if ((err = snd_hdspm_create_alsa_devices(card, hdspm)) < 0) + err = snd_hdspm_create_alsa_devices(card, hdspm); + if (err < 0) return err; snd_hdspm_initialize_midi_flush(hdspm); @@ -4406,9 +4457,8 @@ static int snd_hdspm_free(struct hdspm * hdspm) /* stop th audio, and cancel all interrupts */ hdspm->control_register &= - ~(HDSPM_Start | HDSPM_AudioInterruptEnable - | HDSPM_Midi0InterruptEnable | - HDSPM_Midi1InterruptEnable); + ~(HDSPM_Start | HDSPM_AudioInterruptEnable | + HDSPM_Midi0InterruptEnable | HDSPM_Midi1InterruptEnable); hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register); } @@ -4416,7 +4466,6 @@ static int snd_hdspm_free(struct hdspm * hdspm) if (hdspm->irq >= 0) free_irq(hdspm->irq, (void *) hdspm); - kfree(hdspm->mixer); if (hdspm->iobase) @@ -4431,7 +4480,7 @@ static int snd_hdspm_free(struct hdspm * hdspm) static void snd_hdspm_card_free(struct snd_card *card) { - struct hdspm *hdspm = (struct hdspm *) card->private_data; + struct hdspm *hdspm = card->private_data; if (hdspm) snd_hdspm_free(hdspm); @@ -4452,20 +4501,21 @@ static int __devinit snd_hdspm_probe(struct pci_dev *pci, return -ENOENT; } - if (!(card = snd_card_new(index[dev], id[dev], - THIS_MODULE, sizeof(struct hdspm)))) + card = snd_card_new(index[dev], id[dev], + THIS_MODULE, sizeof(struct hdspm)); + if (!card) return -ENOMEM; - hdspm = (struct hdspm *) card->private_data; + hdspm = card->private_data; card->private_free = snd_hdspm_card_free; hdspm->dev = dev; hdspm->pci = pci; snd_card_set_dev(card, &pci->dev); - if ((err = - snd_hdspm_create(card, hdspm, precise_ptr[dev], - enable_monitor[dev])) < 0) { + err = snd_hdspm_create(card, hdspm, precise_ptr[dev], + enable_monitor[dev]); + if (err < 0) { snd_card_free(card); return err; } @@ -4474,7 +4524,8 @@ static int __devinit snd_hdspm_probe(struct pci_dev *pci, sprintf(card->longname, "%s at 0x%lx, irq %d", hdspm->card_name, hdspm->port, hdspm->irq); - if ((err = snd_card_register(card)) < 0) { + err = snd_card_register(card); + if (err < 0) { snd_card_free(card); return err; } -- cgit v1.2.3 From 2807314d467e7dd929c42050031aabbd28e78f0b Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 27 Jul 2007 18:58:06 +0200 Subject: [ALSA] hda-intel - Add hwdep interface Added a hwdep interface for each codec (enabled per kconfig). This interface can be used for reading/writing HD-audio verbs and other purposes as future extensions. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/Kconfig | 9 ++++ sound/pci/hda/Makefile | 9 ++-- sound/pci/hda/hda_codec.c | 4 ++ sound/pci/hda/hda_codec.h | 3 ++ sound/pci/hda/hda_hwdep.c | 122 ++++++++++++++++++++++++++++++++++++++++++++++ sound/pci/hda/hda_local.h | 5 ++ 6 files changed, 147 insertions(+), 5 deletions(-) create mode 100644 sound/pci/hda/hda_hwdep.c (limited to 'sound/pci') diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig index c6b44102aa5..57426f6fa42 100644 --- a/sound/pci/Kconfig +++ b/sound/pci/Kconfig @@ -500,6 +500,15 @@ config SND_HDA_INTEL To compile this driver as a module, choose M here: the module will be called snd-hda-intel. +config SND_HDA_HWDEP + bool "Build hwdep interface for HD-audio driver" + depends on SND_HDA_INTEL + select SND_HWDEP + help + Say Y here to build a hwdep interface for HD-audio driver. + This interface can be used for out-of-bound communication + with codesc for debugging purposes. + config SND_HDSP tristate "RME Hammerfall DSP Audio" depends on SND diff --git a/sound/pci/hda/Makefile b/sound/pci/hda/Makefile index b2484bbdcc1..f85c34551ac 100644 --- a/sound/pci/hda/Makefile +++ b/sound/pci/hda/Makefile @@ -1,8 +1,8 @@ -snd-hda-intel-objs := hda_intel.o +snd-hda-intel-y := hda_intel.o # since snd-hda-intel is the only driver using hda-codec, # merge it into a single module although it was originally # designed to be individual modules -snd-hda-intel-objs += hda_codec.o \ +snd-hda-intel-y += hda_codec.o \ hda_generic.o \ patch_realtek.o \ patch_cmedia.o \ @@ -12,8 +12,7 @@ snd-hda-intel-objs += hda_codec.o \ patch_atihdmi.o \ patch_conexant.o \ patch_via.o -ifdef CONFIG_PROC_FS -snd-hda-intel-objs += hda_proc.o -endif +snd-hda-intel-$(CONFIG_PROC_FS) += hda_proc.o +snd-hda-intel-$(CONFIG_SND_HDA_HWDEP) += hda_hwdep.o obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-intel.o diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index a05db2f214b..e7843ffeeb2 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -31,6 +31,7 @@ #include #include #include "hda_local.h" +#include /* @@ -594,6 +595,9 @@ int __devinit snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, init_unsol_queue(bus); snd_hda_codec_proc_new(codec); +#ifdef CONFIG_SND_HDA_HWDEP + snd_hda_create_hwdep(codec); +#endif sprintf(component, "HDA:%08x", codec->vendor_id); snd_component_add(codec->bus->card, component); diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index 6809386109c..1370e346bf3 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h @@ -24,6 +24,7 @@ #include #include #include +#include /* * nodes @@ -566,6 +567,8 @@ struct hda_codec { unsigned int spdif_status; /* IEC958 status bits */ unsigned short spdif_ctls; /* SPDIF control bits */ unsigned int spdif_in_enable; /* SPDIF input enable? */ + + struct snd_hwdep *hwdep; /* assigned hwdep device */ }; /* direction */ diff --git a/sound/pci/hda/hda_hwdep.c b/sound/pci/hda/hda_hwdep.c new file mode 100644 index 00000000000..64be7b53348 --- /dev/null +++ b/sound/pci/hda/hda_hwdep.c @@ -0,0 +1,122 @@ +/* + * HWDEP Interface for HD-audio codec + * + * Copyright (c) 2007 Takashi Iwai + * + * This driver 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 driver 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 + */ + +#include +#include +#include +#include +#include +#include +#include +#include "hda_codec.h" +#include "hda_local.h" +#include + +/* + * write/read an out-of-bound verb + */ +static int verb_write_ioctl(struct hda_codec *codec, + struct hda_verb_ioctl __user *arg) +{ + u32 verb, res; + + if (get_user(verb, &arg->verb)) + return -EFAULT; + res = snd_hda_codec_read(codec, verb >> 24, 0, + (verb >> 8) & 0xffff, verb & 0xff); + if (put_user(res, &arg->res)) + return -EFAULT; + return 0; +} + +static int get_wcap_ioctl(struct hda_codec *codec, + struct hda_verb_ioctl __user *arg) +{ + u32 verb, res; + + if (get_user(verb, &arg->verb)) + return -EFAULT; + res = get_wcaps(codec, verb >> 24); + if (put_user(res, &arg->res)) + return -EFAULT; + return 0; +} + + +/* + */ +static int hda_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, + unsigned int cmd, unsigned long arg) +{ + struct hda_codec *codec = hw->private_data; + void __user *argp = (void __user *)arg; + + switch (cmd) { + case HDA_IOCTL_PVERSION: + return put_user(HDA_HWDEP_VERSION, (int __user *)argp); + case HDA_IOCTL_VERB_WRITE: + return verb_write_ioctl(codec, argp); + case HDA_IOCTL_GET_WCAP: + return get_wcap_ioctl(codec, argp); + } + return -ENOIOCTLCMD; +} + +#ifdef CONFIG_COMPAT +static int hda_hwdep_ioctl_compat(struct snd_hwdep *hw, struct file *file, + unsigned int cmd, unsigned long arg) +{ + return hda_hwdep_ioctl(hw, file, cmd, compat_ptr(arg)); +} +#endif + +static int hda_hwdep_open(struct snd_hwdep *hw, struct file *file) +{ +#ifndef CONFIG_SND_DEBUG_DETECT + if (!capable(CAP_SYS_RAWIO)) + return -EACCES; +#endif + return 0; +} + +int __devinit snd_hda_create_hwdep(struct hda_codec *codec) +{ + char hwname[16]; + struct snd_hwdep *hwdep; + int err; + + sprintf(hwname, "HDA Codec %d", codec->addr); + err = snd_hwdep_new(codec->bus->card, hwname, codec->addr, &hwdep); + if (err < 0) + return err; + codec->hwdep = hwdep; + sprintf(hwdep->name, "HDA Codec %d", codec->addr); + hwdep->iface = SNDRV_HWDEP_IFACE_HDA; + hwdep->private_data = codec; + hwdep->exclusive = 1; + + hwdep->ops.open = hda_hwdep_open; + hwdep->ops.ioctl = hda_hwdep_ioctl; +#ifdef CONFIG_COMPAT + hwdep->ops.ioctl_compat = hda_hwdep_ioctl_compat; +#endif + + return 0; +} diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h index c8d34a5b081..12428a67eb2 100644 --- a/sound/pci/hda/hda_local.h +++ b/sound/pci/hda/hda_local.h @@ -313,4 +313,9 @@ static inline u32 get_wcaps(struct hda_codec *codec, hda_nid_t nid) int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir, unsigned int caps); +/* + * hwdep interface + */ +int snd_hda_create_hwdep(struct hda_codec *codec); + #endif /* __SOUND_HDA_LOCAL_H */ -- cgit v1.2.3 From 532d5381793f3c824f8ff68d7067fab8c76bb811 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 27 Jul 2007 19:02:40 +0200 Subject: [ALSA] hda-codec - Add a generic bind-control helper Added callbacks for a generic bind-control of mixer elements. This can be used for creating a mixer element controlling multiple widgets at the same time. Two macros, HDA_BIND_VOL() and HDA_BIND_SW(), are introduced for creating bind-volume and bind-switch, respectively. It taks the mixer element name and struct hda_bind_ctls pointer, which contains the real control callbacks in ops field and long array for private_value of each bound widget. All widgets have to be the same type (i.e. the same amp capability). Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/hda_codec.c | 87 +++++++++++++++++++++ sound/pci/hda/hda_local.h | 47 +++++++++++ sound/pci/hda/patch_analog.c | 177 ++++++++++-------------------------------- sound/pci/hda/patch_realtek.c | 28 +++---- 4 files changed, 184 insertions(+), 155 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index e7843ffeeb2..36879a93eac 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -1005,6 +1005,93 @@ int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol, return err < 0 ? err : change; } +/* + * generic bound volume/swtich controls + */ +int snd_hda_mixer_bind_ctls_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + struct hda_bind_ctls *c; + int err; + + c = (struct hda_bind_ctls *)kcontrol->private_value; + mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */ + kcontrol->private_value = *c->values; + err = c->ops->info(kcontrol, uinfo); + kcontrol->private_value = (long)c; + mutex_unlock(&codec->spdif_mutex); + return err; +} + +int snd_hda_mixer_bind_ctls_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + struct hda_bind_ctls *c; + int err; + + c = (struct hda_bind_ctls *)kcontrol->private_value; + mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */ + kcontrol->private_value = *c->values; + err = c->ops->get(kcontrol, ucontrol); + kcontrol->private_value = (long)c; + mutex_unlock(&codec->spdif_mutex); + return err; +} + +int snd_hda_mixer_bind_ctls_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + struct hda_bind_ctls *c; + unsigned long *vals; + int err = 0, change = 0; + + c = (struct hda_bind_ctls *)kcontrol->private_value; + mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */ + for (vals = c->values; *vals; vals++) { + kcontrol->private_value = *vals; + err = c->ops->put(kcontrol, ucontrol); + if (err < 0) + break; + change |= err; + } + kcontrol->private_value = (long)c; + mutex_unlock(&codec->spdif_mutex); + return err < 0 ? err : change; +} + +int snd_hda_mixer_bind_tlv(struct snd_kcontrol *kcontrol, int op_flag, + unsigned int size, unsigned int __user *tlv) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + struct hda_bind_ctls *c; + int err; + + c = (struct hda_bind_ctls *)kcontrol->private_value; + mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */ + kcontrol->private_value = *c->values; + err = c->ops->tlv(kcontrol, op_flag, size, tlv); + kcontrol->private_value = (long)c; + mutex_unlock(&codec->spdif_mutex); + return err; +} + +struct hda_ctl_ops snd_hda_bind_vol = { + .info = snd_hda_mixer_amp_volume_info, + .get = snd_hda_mixer_amp_volume_get, + .put = snd_hda_mixer_amp_volume_put, + .tlv = snd_hda_mixer_amp_tlv +}; + +struct hda_ctl_ops snd_hda_bind_sw = { + .info = snd_hda_mixer_amp_switch_info, + .get = snd_hda_mixer_amp_switch_get, + .put = snd_hda_mixer_amp_switch_put, + .tlv = snd_hda_mixer_amp_tlv +}; + /* * SPDIF out controls */ diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h index 12428a67eb2..fafcffe6fc7 100644 --- a/sound/pci/hda/hda_local.h +++ b/sound/pci/hda/hda_local.h @@ -102,6 +102,53 @@ int snd_hda_mixer_bind_switch_get(struct snd_kcontrol *kcontrol, int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); +/* more generic bound controls */ +struct hda_ctl_ops { + snd_kcontrol_info_t *info; + snd_kcontrol_get_t *get; + snd_kcontrol_put_t *put; + snd_kcontrol_tlv_rw_t *tlv; +}; + +extern struct hda_ctl_ops snd_hda_bind_vol; /* for bind-volume with TLV */ +extern struct hda_ctl_ops snd_hda_bind_sw; /* for bind-switch */ + +struct hda_bind_ctls { + struct hda_ctl_ops *ops; + long values[]; +}; + +int snd_hda_mixer_bind_ctls_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo); +int snd_hda_mixer_bind_ctls_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol); +int snd_hda_mixer_bind_ctls_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol); +int snd_hda_mixer_bind_tlv(struct snd_kcontrol *kcontrol, int op_flag, + unsigned int size, unsigned int __user *tlv); + +#define HDA_BIND_VOL(xname, bindrec) \ + { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ + .name = xname, \ + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |\ + SNDRV_CTL_ELEM_ACCESS_TLV_READ |\ + SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK,\ + .info = snd_hda_mixer_bind_ctls_info,\ + .get = snd_hda_mixer_bind_ctls_get,\ + .put = snd_hda_mixer_bind_ctls_put,\ + .tlv = { .c = snd_hda_mixer_bind_tlv },\ + .private_value = (long) (bindrec) } +#define HDA_BIND_SW(xname, bindrec) \ + { .iface = SNDRV_CTL_ELEM_IFACE_MIXER,\ + .name = xname, \ + .info = snd_hda_mixer_bind_ctls_info,\ + .get = snd_hda_mixer_bind_ctls_get,\ + .put = snd_hda_mixer_bind_ctls_put,\ + .private_value = (long) (bindrec) } + +/* + * SPDIF I/O + */ int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid); int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid); diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index 488724f2e30..cc2e944cc59 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c @@ -422,94 +422,36 @@ static struct hda_input_mux ad1986a_capture_source = { }, }; -/* - * PCM control - * - * bind volumes/mutes of 3 DACs as a single PCM control for simplicity - */ - -#define ad1986a_pcm_amp_vol_info snd_hda_mixer_amp_volume_info - -static int ad1986a_pcm_amp_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - struct ad198x_spec *ad = codec->spec; - - mutex_lock(&ad->amp_mutex); - snd_hda_mixer_amp_volume_get(kcontrol, ucontrol); - mutex_unlock(&ad->amp_mutex); - return 0; -} -static int ad1986a_pcm_amp_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - struct ad198x_spec *ad = codec->spec; - int i, change = 0; - - mutex_lock(&ad->amp_mutex); - for (i = 0; i < ARRAY_SIZE(ad1986a_dac_nids); i++) { - kcontrol->private_value = HDA_COMPOSE_AMP_VAL(ad1986a_dac_nids[i], 3, 0, HDA_OUTPUT); - change |= snd_hda_mixer_amp_volume_put(kcontrol, ucontrol); - } - kcontrol->private_value = HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT); - mutex_unlock(&ad->amp_mutex); - return change; -} - -#define ad1986a_pcm_amp_sw_info snd_hda_mixer_amp_switch_info - -static int ad1986a_pcm_amp_sw_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - struct ad198x_spec *ad = codec->spec; - - mutex_lock(&ad->amp_mutex); - snd_hda_mixer_amp_switch_get(kcontrol, ucontrol); - mutex_unlock(&ad->amp_mutex); - return 0; -} - -static int ad1986a_pcm_amp_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - struct ad198x_spec *ad = codec->spec; - int i, change = 0; +static struct hda_bind_ctls ad1986a_bind_pcm_vol = { + .ops = &snd_hda_bind_vol, + .values = { + HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT), + HDA_COMPOSE_AMP_VAL(AD1986A_SURR_DAC, 3, 0, HDA_OUTPUT), + HDA_COMPOSE_AMP_VAL(AD1986A_CLFE_DAC, 3, 0, HDA_OUTPUT), + 0 + }, +}; - mutex_lock(&ad->amp_mutex); - for (i = 0; i < ARRAY_SIZE(ad1986a_dac_nids); i++) { - kcontrol->private_value = HDA_COMPOSE_AMP_VAL(ad1986a_dac_nids[i], 3, 0, HDA_OUTPUT); - change |= snd_hda_mixer_amp_switch_put(kcontrol, ucontrol); - } - kcontrol->private_value = HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT); - mutex_unlock(&ad->amp_mutex); - return change; -} +static struct hda_bind_ctls ad1986a_bind_pcm_sw = { + .ops = &snd_hda_bind_sw, + .values = { + HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT), + HDA_COMPOSE_AMP_VAL(AD1986A_SURR_DAC, 3, 0, HDA_OUTPUT), + HDA_COMPOSE_AMP_VAL(AD1986A_CLFE_DAC, 3, 0, HDA_OUTPUT), + 0 + }, +}; /* * mixers */ static struct snd_kcontrol_new ad1986a_mixers[] = { - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "PCM Playback Volume", - .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | - SNDRV_CTL_ELEM_ACCESS_TLV_READ | - SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK, - .info = ad1986a_pcm_amp_vol_info, - .get = ad1986a_pcm_amp_vol_get, - .put = ad1986a_pcm_amp_vol_put, - .tlv = { .c = snd_hda_mixer_amp_tlv }, - .private_value = HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT) - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "PCM Playback Switch", - .info = ad1986a_pcm_amp_sw_info, - .get = ad1986a_pcm_amp_sw_get, - .put = ad1986a_pcm_amp_sw_put, - .private_value = HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT) - }, + /* + * bind volumes/mutes of 3 DACs as a single PCM control for simplicity + */ + HDA_BIND_VOL("PCM Playback Volume", &ad1986a_bind_pcm_vol), + HDA_BIND_SW("PCM Playback Switch", &ad1986a_bind_pcm_sw), HDA_CODEC_VOLUME("Front Playback Volume", 0x1b, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Surround Playback Volume", 0x1c, 0x0, HDA_OUTPUT), @@ -596,41 +538,23 @@ static struct snd_kcontrol_new ad1986a_laptop_mixers[] = { /* laptop-eapd model - 2ch only */ /* master controls both pins 0x1a and 0x1b */ -static int ad1986a_laptop_master_vol_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - long *valp = ucontrol->value.integer.value; - int change; - - change = snd_hda_codec_amp_update(codec, 0x1a, 0, HDA_OUTPUT, 0, - 0x7f, valp[0] & 0x7f); - change |= snd_hda_codec_amp_update(codec, 0x1a, 1, HDA_OUTPUT, 0, - 0x7f, valp[1] & 0x7f); - snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0, - 0x7f, valp[0] & 0x7f); - snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0, - 0x7f, valp[1] & 0x7f); - return change; -} - -static int ad1986a_laptop_master_sw_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - long *valp = ucontrol->value.integer.value; - int change; +static struct hda_bind_ctls ad1986a_laptop_master_vol = { + .ops = &snd_hda_bind_vol, + .values = { + HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT), + HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT), + 0, + }, +}; - change = snd_hda_codec_amp_update(codec, 0x1a, 0, HDA_OUTPUT, 0, - 0x80, valp[0] ? 0 : 0x80); - change |= snd_hda_codec_amp_update(codec, 0x1a, 1, HDA_OUTPUT, 0, - 0x80, valp[1] ? 0 : 0x80); - snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0, - 0x80, valp[0] ? 0 : 0x80); - snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0, - 0x80, valp[1] ? 0 : 0x80); - return change; -} +static struct hda_bind_ctls ad1986a_laptop_master_sw = { + .ops = &snd_hda_bind_sw, + .values = { + HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT), + HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT), + 0, + }, +}; static struct hda_input_mux ad1986a_laptop_eapd_capture_source = { .num_items = 3, @@ -642,23 +566,8 @@ static struct hda_input_mux ad1986a_laptop_eapd_capture_source = { }; static struct snd_kcontrol_new ad1986a_laptop_eapd_mixers[] = { - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Master Playback Volume", - .info = snd_hda_mixer_amp_volume_info, - .get = snd_hda_mixer_amp_volume_get, - .put = ad1986a_laptop_master_vol_put, - .tlv = { .c = snd_hda_mixer_amp_tlv }, - .private_value = HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT), - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Master Playback Switch", - .info = snd_hda_mixer_amp_switch_info, - .get = snd_hda_mixer_amp_switch_get, - .put = ad1986a_laptop_master_sw_put, - .private_value = HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT), - }, + HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol), + HDA_BIND_SW("Master Playback Switch", &ad1986a_laptop_master_sw), HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x17, 0x0, HDA_OUTPUT), @@ -856,7 +765,6 @@ static int patch_ad1986a(struct hda_codec *codec) if (spec == NULL) return -ENOMEM; - mutex_init(&spec->amp_mutex); codec->spec = spec; spec->multiout.max_channels = 6; @@ -1064,7 +972,6 @@ static int patch_ad1983(struct hda_codec *codec) if (spec == NULL) return -ENOMEM; - mutex_init(&spec->amp_mutex); codec->spec = spec; spec->multiout.max_channels = 2; @@ -1466,7 +1373,6 @@ static int patch_ad1981(struct hda_codec *codec) if (spec == NULL) return -ENOMEM; - mutex_init(&spec->amp_mutex); codec->spec = spec; spec->multiout.max_channels = 2; @@ -2672,7 +2578,6 @@ static int patch_ad1988(struct hda_codec *codec) if (spec == NULL) return -ENOMEM; - mutex_init(&spec->amp_mutex); codec->spec = spec; if (is_rev2(codec)) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index d839d567f8e..f27e073d22b 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -7140,28 +7140,18 @@ static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = { { } /* end */ }; -static int alc262_sony_sw_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - unsigned long private_save = kcontrol->private_value; - int change; - kcontrol->private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT); - change = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol); - kcontrol->private_value = private_save; - change |= snd_hda_mixer_amp_switch_put(kcontrol, ucontrol); - return change; -} +static struct hda_bind_ctls alc262_sony_bind_sw = { + .ops = &snd_hda_bind_sw, + .values = { + HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT), + HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), + 0, + }, +}; static struct snd_kcontrol_new alc262_sony_mixer[] = { HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Front Playback Switch", - .info = snd_hda_mixer_amp_switch_info, - .get = snd_hda_mixer_amp_switch_get, - .put = alc262_sony_sw_put, - .private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT), - }, + HDA_BIND_SW("Front Playback Switch", &alc262_sony_bind_sw), HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), -- cgit v1.2.3 From 82467611ffc41fba534c95f8b4ae3887a90f5a66 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 27 Jul 2007 19:15:54 +0200 Subject: [ALSA] hda-codec - kernel config for each codec Create kernel configs to choose the codec support codes to build. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/Kconfig | 72 +++++++++++++++++++++++++++++++++++++++++++++++ sound/pci/hda/Makefile | 20 ++++++------- sound/pci/hda/hda_codec.c | 31 +++++++++++++++++--- sound/pci/hda/hda_patch.h | 16 +++++++++++ 4 files changed, 125 insertions(+), 14 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig index 57426f6fa42..b80b97f7a49 100644 --- a/sound/pci/Kconfig +++ b/sound/pci/Kconfig @@ -509,6 +509,78 @@ config SND_HDA_HWDEP This interface can be used for out-of-bound communication with codesc for debugging purposes. +config SND_HDA_CODEC_REALTEK + bool "Build Realtek HD-audio codec support" + depends on SND_HDA_INTEL + default y + help + Say Y here to include Realtek HD-audio codec support in + snd-hda-intel driver, such as ALC880. + +config SND_HDA_CODEC_ANALOG + bool "Build Analog Device HD-audio codec support" + depends on SND_HDA_INTEL + default y + help + Say Y here to include Analog Device HD-audio codec support in + snd-hda-intel driver, such as AD1986A. + +config SND_HDA_CODEC_SIGMATEL + bool "Build IDT/Sigmatel HD-audio codec support" + depends on SND_HDA_INTEL + default y + help + Say Y here to include IDT (Sigmatel) HD-audio codec support in + snd-hda-intel driver, such as STAC9200. + +config SND_HDA_CODEC_VIA + bool "Build VIA HD-audio codec support" + depends on SND_HDA_INTEL + default y + help + Say Y here to include VIA HD-audio codec support in + snd-hda-intel driver, such as VT1708. + +config SND_HDA_CODEC_ATIHDMI + bool "Build ATI HDMI HD-audio codec support" + depends on SND_HDA_INTEL + default y + help + Say Y here to include ATI HDMI HD-audio codec support in + snd-hda-intel driver, such as ATI RS600 HDMI. + +config SND_HDA_CODEC_CONEXANT + bool "Build Conexant HD-audio codec support" + depends on SND_HDA_INTEL + default y + help + Say Y here to include Conexant HD-audio codec support in + snd-hda-intel driver, such as CX20549. + +config SND_HDA_CODEC_CMEDIA + bool "Build C-Media HD-audio codec support" + depends on SND_HDA_INTEL + default y + help + Say Y here to include C-Media HD-audio codec support in + snd-hda-intel driver, such as CMI9880. + +config SND_HDA_CODEC_SI3054 + bool "Build Silicon Labs 3054 HD-modem codec support" + depends on SND_HDA_INTEL + default y + help + Say Y here to include Silicon Labs 3054 HD-modem codec + (and compatibles) support in snd-hda-intel driver. + +config SND_HDA_GENERIC + bool "Enable generic HD-audio codec parser" + depends on SND_HDA_INTEL + default y + help + Say Y here to enable the generic HD-audio codec parser + in snd-hda-intel driver. + config SND_HDSP tristate "RME Hammerfall DSP Audio" depends on SND diff --git a/sound/pci/hda/Makefile b/sound/pci/hda/Makefile index f85c34551ac..6d43e39b9d0 100644 --- a/sound/pci/hda/Makefile +++ b/sound/pci/hda/Makefile @@ -2,17 +2,17 @@ snd-hda-intel-y := hda_intel.o # since snd-hda-intel is the only driver using hda-codec, # merge it into a single module although it was originally # designed to be individual modules -snd-hda-intel-y += hda_codec.o \ - hda_generic.o \ - patch_realtek.o \ - patch_cmedia.o \ - patch_analog.o \ - patch_sigmatel.o \ - patch_si3054.o \ - patch_atihdmi.o \ - patch_conexant.o \ - patch_via.o +snd-hda-intel-y += hda_codec.o snd-hda-intel-$(CONFIG_PROC_FS) += hda_proc.o snd-hda-intel-$(CONFIG_SND_HDA_HWDEP) += hda_hwdep.o +snd-hda-intel-$(CONFIG_SND_HDA_CODEC_GENERIC) += hda_generic.o +snd-hda-intel-$(CONFIG_SND_HDA_CODEC_REALTEK) += patch_realtek.o +snd-hda-intel-$(CONFIG_SND_HDA_CODEC_CMEDIA) += patch_cmedia.o +snd-hda-intel-$(CONFIG_SND_HDA_CODEC_ANALOG) += patch_analog.o +snd-hda-intel-$(CONFIG_SND_HDA_CODEC_SIGMATEL) += patch_sigmatel.o +snd-hda-intel-$(CONFIG_SND_HDA_CODEC_SI3054) += patch_si3054.o +snd-hda-intel-$(CONFIG_SND_HDA_CODEC_ATIHDMI) += patch_atihdmi.o +snd-hda-intel-$(CONFIG_SND_HDA_CODEC_CONEXANT) += patch_conexant.o +snd-hda-intel-$(CONFIG_SND_HDA_CODEC_VIA) += patch_via.o obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-intel.o diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 36879a93eac..c4cf2c7230e 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -388,6 +388,13 @@ int __devinit snd_hda_bus_new(struct snd_card *card, return 0; } +#ifdef CONFIG_SND_HDA_GENERIC +#define is_generic_config(codec) \ + (codec->bus->modelname && !strcmp(codec->bus->modelname, "generic")) +#else +#define is_generic_config(codec) 0 +#endif + /* * find a matching codec preset */ @@ -396,7 +403,7 @@ find_codec_preset(struct hda_codec *codec) { const struct hda_codec_preset **tbl, *preset; - if (codec->bus->modelname && !strcmp(codec->bus->modelname, "generic")) + if (is_generic_config(codec)) return NULL; /* use the generic parser */ for (tbl = hda_preset_tables; *tbl; tbl++) { @@ -582,10 +589,26 @@ int __devinit snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, snd_hda_get_codec_name(codec, bus->card->mixername, sizeof(bus->card->mixername)); - if (codec->preset && codec->preset->patch) - err = codec->preset->patch(codec); - else +#ifdef CONFIG_SND_HDA_GENERIC + if (is_generic_config(codec)) { err = snd_hda_parse_generic_codec(codec); + goto patched; + } +#endif + if (codec->preset && codec->preset->patch) { + err = codec->preset->patch(codec); + goto patched; + } + + /* call the default parser */ +#ifdef CONFIG_SND_HDA_GENERIC + err = snd_hda_parse_generic_codec(codec); +#else + printk(KERN_ERR "hda-codec: No codec parser is available\n"); + err = -ENODEV; +#endif + + patched: if (err < 0) { snd_hda_codec_free(codec); return err; diff --git a/sound/pci/hda/hda_patch.h b/sound/pci/hda/hda_patch.h index 9f9e9ae44a9..f5c23bb16d7 100644 --- a/sound/pci/hda/hda_patch.h +++ b/sound/pci/hda/hda_patch.h @@ -20,13 +20,29 @@ extern struct hda_codec_preset snd_hda_preset_conexant[]; extern struct hda_codec_preset snd_hda_preset_via[]; static const struct hda_codec_preset *hda_preset_tables[] = { +#ifdef CONFIG_SND_HDA_CODEC_REALTEK snd_hda_preset_realtek, +#endif +#ifdef CONFIG_SND_HDA_CODEC_CMEDIA snd_hda_preset_cmedia, +#endif +#ifdef CONFIG_SND_HDA_CODEC_ANALOG snd_hda_preset_analog, +#endif +#ifdef CONFIG_SND_HDA_CODEC_SIGMATEL snd_hda_preset_sigmatel, +#endif +#ifdef CONFIG_SND_HDA_CODEC_SI3054 snd_hda_preset_si3054, +#endif +#ifdef CONFIG_SND_HDA_CODEC_ATIHDMI snd_hda_preset_atihdmi, +#endif +#ifdef CONFIG_SND_HDA_CODEC_CONEXANT snd_hda_preset_conexant, +#endif +#ifdef CONFIG_SND_HDA_CODEC_VIA snd_hda_preset_via, +#endif NULL }; -- cgit v1.2.3 From 29998d24ab5ec488cd127488246cc749b0ac52d6 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 30 Jul 2007 08:14:31 +0200 Subject: [ALSA] check for linked substreams of different cards It is possible to have linked substreams that belong to different cards and/or different drivers. This patch changes some drivers to make sure that they do not incorrectly try to handle substreams of a different card. Signed-off-by: Clemens Ladisch Signed-off-by: Jaroslav Kysela --- sound/pci/ca0106/ca0106_main.c | 3 +++ sound/pci/emu10k1/p16v.c | 3 +++ sound/pci/ice1712/ice1724.c | 10 ++++++---- sound/pci/pcxhr/pcxhr.c | 2 ++ 4 files changed, 14 insertions(+), 4 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c index 611fc15a054..c7f79be98d0 100644 --- a/sound/pci/ca0106/ca0106_main.c +++ b/sound/pci/ca0106/ca0106_main.c @@ -853,6 +853,9 @@ static int snd_ca0106_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 = epcm->channel_id; diff --git a/sound/pci/emu10k1/p16v.c b/sound/pci/emu10k1/p16v.c index 7ee19c63c2c..6ace1076c19 100644 --- a/sound/pci/emu10k1/p16v.c +++ b/sound/pci/emu10k1/p16v.c @@ -448,6 +448,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/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c index 32560cfb6c3..23c9383e7cc 100644 --- a/sound/pci/ice1712/ice1724.c +++ b/sound/pci/ice1712/ice1724.c @@ -341,10 +341,12 @@ static int snd_vt1724_pcm_trigger(struct snd_pcm_substream *substream, int cmd) what = 0; snd_pcm_group_for_each_entry(s, substream) { - const struct vt1724_pcm_reg *reg; - reg = s->runtime->private_data; - what |= reg->start; - snd_pcm_trigger_done(s, substream); + if (snd_pcm_substream_chip(s) == ice) { + const struct vt1724_pcm_reg *reg; + reg = s->runtime->private_data; + what |= reg->start; + snd_pcm_trigger_done(s, substream); + } } switch (cmd) { diff --git a/sound/pci/pcxhr/pcxhr.c b/sound/pci/pcxhr/pcxhr.c index f7f6a687f03..1b787f45557 100644 --- a/sound/pci/pcxhr/pcxhr.c +++ b/sound/pci/pcxhr/pcxhr.c @@ -646,6 +646,8 @@ static int pcxhr_trigger(struct snd_pcm_substream *subs, int cmd) if (snd_pcm_stream_linked(subs)) { struct snd_pcxhr *chip = snd_pcm_substream_chip(subs); snd_pcm_group_for_each_entry(s, subs) { + if (snd_pcm_substream_chip(s) != chip) + continue; stream = s->runtime->private_data; stream->status = PCXHR_STREAM_STATUS_SCHEDULE_RUN; -- cgit v1.2.3 From 6ddc9d2e82cd488aa117de8dd0a91862cb3656c1 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 30 Jul 2007 14:52:41 +0200 Subject: [ALSA] Add missing static in ac97_codec.c Added missing static to snd_ac97_restore_status() and snd_ac97_restore_iec958() functions. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/ac97/ac97_codec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c index bbed644bf9c..7b02a967c1e 100644 --- a/sound/pci/ac97/ac97_codec.c +++ b/sound/pci/ac97/ac97_codec.c @@ -2436,7 +2436,7 @@ EXPORT_SYMBOL(snd_ac97_suspend); /* * restore ac97 status */ -void snd_ac97_restore_status(struct snd_ac97 *ac97) +static void snd_ac97_restore_status(struct snd_ac97 *ac97) { int i; @@ -2457,7 +2457,7 @@ void snd_ac97_restore_status(struct snd_ac97 *ac97) /* * restore IEC958 status */ -void snd_ac97_restore_iec958(struct snd_ac97 *ac97) +static void snd_ac97_restore_iec958(struct snd_ac97 *ac97) { if (ac97->ext_id & AC97_EI_SPDIF) { if (ac97->regs[AC97_EXTENDED_STATUS] & AC97_EA_SPDIF) { -- cgit v1.2.3 From 625dc0bf4d91d379e8b4d5c3c9e05ad6fa978c51 Mon Sep 17 00:00:00 2001 From: Tobin Davis Date: Mon, 30 Jul 2007 21:42:10 +0200 Subject: [ALSA] hda-codec - Add support for the ASRock K8NF6G-VSTA motherboard This patch adds ALC861VD support for the ASRock K8NF6G-VSTA motherboard. Signed-off-by: Tobin Davis Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index f27e073d22b..db4aded9745 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -10336,6 +10336,7 @@ static struct snd_pci_quirk alc861vd_cfg_tbl[] = { SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO), SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO), SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO), + SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG), {} }; -- cgit v1.2.3 From 312d045c75fc76e7de51520c3c1b6b5bec565cc9 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 31 Jul 2007 11:08:10 +0200 Subject: [ALSA] hda-intel - Fix compile warning in snd_hwdep_ioctl_compat() Fix missing cast: sound/pci/hda/hda_hwdep.c:86: warning: passing argument 4 of 'hda_hwdep_ioctl' makes integer from pointer without a cast Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/hda_hwdep.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/hda_hwdep.c b/sound/pci/hda/hda_hwdep.c index 64be7b53348..bafb7b01f5a 100644 --- a/sound/pci/hda/hda_hwdep.c +++ b/sound/pci/hda/hda_hwdep.c @@ -83,7 +83,7 @@ static int hda_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, static int hda_hwdep_ioctl_compat(struct snd_hwdep *hw, struct file *file, unsigned int cmd, unsigned long arg) { - return hda_hwdep_ioctl(hw, file, cmd, compat_ptr(arg)); + return hda_hwdep_ioctl(hw, file, cmd, (unsigned long)compat_ptr(arg)); } #endif -- cgit v1.2.3 From d71a5c50ca9b1e24987df3cdd3a1a4fb06d265e4 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 31 Jul 2007 11:09:16 +0200 Subject: [ALSA] hda-intel - Fix a typo in Makefile Fixed a typo of CONFIG_SND_HDA_GENERIC. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/Makefile b/sound/pci/hda/Makefile index 6d43e39b9d0..ab0c726d648 100644 --- a/sound/pci/hda/Makefile +++ b/sound/pci/hda/Makefile @@ -5,7 +5,7 @@ snd-hda-intel-y := hda_intel.o snd-hda-intel-y += hda_codec.o snd-hda-intel-$(CONFIG_PROC_FS) += hda_proc.o snd-hda-intel-$(CONFIG_SND_HDA_HWDEP) += hda_hwdep.o -snd-hda-intel-$(CONFIG_SND_HDA_CODEC_GENERIC) += hda_generic.o +snd-hda-intel-$(CONFIG_SND_HDA_GENERIC) += hda_generic.o snd-hda-intel-$(CONFIG_SND_HDA_CODEC_REALTEK) += patch_realtek.o snd-hda-intel-$(CONFIG_SND_HDA_CODEC_CMEDIA) += patch_cmedia.o snd-hda-intel-$(CONFIG_SND_HDA_CODEC_ANALOG) += patch_analog.o -- cgit v1.2.3 From 8259980ebcecd8096a04cc43c1c1d72e1c0ed165 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 31 Jul 2007 15:56:24 +0200 Subject: [ALSA] hda-codec - Fix GPIO in resume Reinitialize GPIO in resume callback if necessary. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_sigmatel.c | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index d2c340e45f9..5ca430cc399 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -95,6 +95,8 @@ struct sigmatel_spec { unsigned int hp_detect: 1; unsigned int gpio_mute: 1; + unsigned int gpio_mask, gpio_data; + /* playback */ struct hda_multi_out multiout; hda_nid_t dac_nids[5]; @@ -854,20 +856,20 @@ static void stac92xx_set_config_regs(struct hda_codec *codec) spec->pin_configs[i]); } -static void stac92xx_enable_gpio_mask(struct hda_codec *codec, - int gpio_mask, int gpio_data) +static void stac92xx_enable_gpio_mask(struct hda_codec *codec) { + struct sigmatel_spec *spec = codec->spec; /* Configure GPIOx as output */ snd_hda_codec_write(codec, codec->afg, 0, - AC_VERB_SET_GPIO_DIRECTION, gpio_mask); + AC_VERB_SET_GPIO_DIRECTION, spec->gpio_mask); /* Configure GPIOx as CMOS */ snd_hda_codec_write(codec, codec->afg, 0, 0x7e7, 0x00000000); /* Assert GPIOx */ snd_hda_codec_write(codec, codec->afg, 0, - AC_VERB_SET_GPIO_DATA, gpio_data); + AC_VERB_SET_GPIO_DATA, spec->gpio_data); /* Enable GPIOx */ snd_hda_codec_write(codec, codec->afg, 0, - AC_VERB_SET_GPIO_MASK, gpio_mask); + AC_VERB_SET_GPIO_MASK, spec->gpio_mask); } /* @@ -1935,8 +1937,10 @@ static int stac92xx_resume(struct hda_codec *codec) struct sigmatel_spec *spec = codec->spec; int i; - stac92xx_init(codec); stac92xx_set_config_regs(codec); + if (spec->gpio_mask && spec->gpio_data) + stac92xx_enable_gpio_mask(codec); + stac92xx_init(codec); snd_hda_resume_ctls(codec, spec->mixer); for (i = 0; i < spec->num_mixers; i++) snd_hda_resume_ctls(codec, spec->mixers[i]); @@ -2240,7 +2244,8 @@ static int patch_stac927x(struct hda_codec *codec) spec->multiout.dac_nids = spec->dac_nids; /* GPIO0 High = Enable EAPD */ - stac92xx_enable_gpio_mask(codec, 0x00000001, 0x00000001); + spec->gpio_mask = spec->gpio_data = 0x00000001; + stac92xx_enable_gpio_mask(codec); err = stac92xx_parse_auto_config(codec, 0x1e, 0x20); if (!err) { @@ -2265,7 +2270,7 @@ static int patch_stac927x(struct hda_codec *codec) static int patch_stac9205(struct hda_codec *codec) { struct sigmatel_spec *spec; - int err, gpio_mask, gpio_data; + int err; spec = kzalloc(sizeof(*spec), GFP_KERNEL); if (spec == NULL) @@ -2308,15 +2313,16 @@ static int patch_stac9205(struct hda_codec *codec) stac92xx_set_config_reg(codec, 0x1f, 0x01441030); stac92xx_set_config_reg(codec, 0x20, 0x1c410030); - gpio_mask = 0x00000007; /* GPIO0-2 */ + spec->gpio_mask = 0x00000007; /* GPIO0-2 */ /* GPIO0 High = EAPD, GPIO1 Low = DRM, * GPIO2 High = Headphone Mute */ - gpio_data = 0x00000005; + spec->gpio_data = 0x00000005; } else - gpio_mask = gpio_data = 0x00000001; /* GPIO0 High = EAPD */ + spec->gpio_mask = spec->gpio_data = + 0x00000001; /* GPIO0 High = EAPD */ - stac92xx_enable_gpio_mask(codec, gpio_mask, gpio_data); + stac92xx_enable_gpio_mask(codec); err = stac92xx_parse_auto_config(codec, 0x1f, 0x20); if (!err) { if (spec->board_config < 0) { -- cgit v1.2.3 From c9988dce19c1ba867f58f30366466e776c51607a Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 2 Aug 2007 00:01:43 +0200 Subject: [ALSA] hda-intel - Fix a typo in Kconfig Fix a typo in Kconfig help text for CONFIG_SND_HDA_HWDEP. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound/pci') diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig index b80b97f7a49..ff7a689c229 100644 --- a/sound/pci/Kconfig +++ b/sound/pci/Kconfig @@ -507,7 +507,7 @@ config SND_HDA_HWDEP help Say Y here to build a hwdep interface for HD-audio driver. This interface can be used for out-of-bound communication - with codesc for debugging purposes. + with codecs for debugging purposes. config SND_HDA_CODEC_REALTEK bool "Build Realtek HD-audio codec support" -- cgit v1.2.3 From 609bb2ea397cd9947d8898f6077d33c1fa81b24f Mon Sep 17 00:00:00 2001 From: Michal Piotrowski Date: Thu, 2 Aug 2007 14:15:05 +0200 Subject: [ALSA] Coding style fix sound/pci/ca0106/ca_midi.h Coding style fix Signed-off-by: Michal Piotrowski Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/ca0106/ca_midi.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/ca0106/ca_midi.h b/sound/pci/ca0106/ca_midi.h index b72c0933bd2..922ed3e3731 100644 --- a/sound/pci/ca0106/ca_midi.h +++ b/sound/pci/ca0106/ca_midi.h @@ -22,9 +22,9 @@ * */ -#include -#include -#include +#include +#include +#include #define CA_MIDI_MODE_INPUT MPU401_MODE_INPUT #define CA_MIDI_MODE_OUTPUT MPU401_MODE_OUTPUT -- cgit v1.2.3 From 12f288bffeaa3196ebd5da49c5c7ac06c6188b61 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 2 Aug 2007 15:51:59 +0200 Subject: [ALSA] hda-intel - Remove invalid __devinit Some functions in hda_codec.c are called from patch ops, which are kept in the codec instance even after initialization. Thus they shouldn't be marked as __devinit. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/hda_codec.c | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index c4cf2c7230e..fc934baaae6 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -1325,8 +1325,7 @@ static struct snd_kcontrol_new dig_mixes[] = { * * Returns 0 if successful, or a negative error code. */ -int __devinit snd_hda_create_spdif_out_ctls(struct hda_codec *codec, - hda_nid_t nid) +int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid) { int err; struct snd_kcontrol *kctl; @@ -1424,8 +1423,7 @@ static struct snd_kcontrol_new dig_in_ctls[] = { * * Returns 0 if successful, or a negative error code. */ -int __devinit snd_hda_create_spdif_in_ctls(struct hda_codec *codec, - hda_nid_t nid) +int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid) { int err; struct snd_kcontrol *kctl; @@ -1895,9 +1893,9 @@ int __devinit snd_hda_build_pcms(struct hda_bus *bus) * * If no entries are matching, the function returns a negative value. */ -int __devinit snd_hda_check_board_config(struct hda_codec *codec, - int num_configs, const char **models, - const struct snd_pci_quirk *tbl) +int snd_hda_check_board_config(struct hda_codec *codec, + int num_configs, const char **models, + const struct snd_pci_quirk *tbl) { if (codec->bus->modelname && models) { int i; @@ -1947,8 +1945,7 @@ int __devinit snd_hda_check_board_config(struct hda_codec *codec, * * Returns 0 if successful, or a negative error code. */ -int __devinit snd_hda_add_new_ctls(struct hda_codec *codec, - struct snd_kcontrol_new *knew) +int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew) { int err; @@ -2224,7 +2221,7 @@ int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec, * Helper for automatic ping configuration */ -static int __devinit is_in_nid_list(hda_nid_t nid, hda_nid_t *list) +static int is_in_nid_list(hda_nid_t nid, hda_nid_t *list) { for (; *list; list++) if (*list == nid) @@ -2275,9 +2272,9 @@ static void sort_pins_by_sequence(hda_nid_t * pins, short * sequences, * The digital input/output pins are assigned to dig_in_pin and dig_out_pin, * respectively. */ -int __devinit snd_hda_parse_pin_def_config(struct hda_codec *codec, - struct auto_pin_cfg *cfg, - hda_nid_t *ignore_nids) +int snd_hda_parse_pin_def_config(struct hda_codec *codec, + struct auto_pin_cfg *cfg, + hda_nid_t *ignore_nids) { hda_nid_t nid, nid_start; int nodes; -- cgit v1.2.3 From 6ed44ad3ebec52059f6f534deeb08f1d701852c5 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Mon, 6 Aug 2007 14:05:27 +0200 Subject: [ALSA] au88x0: mem leak fix in snd_vortex_create() In sound/pci/au88x0/au88x0.c::snd_vortex_create() : The Coverity checker found that if we allocate storage for 'chip' but then leave via the regions_out: label, then we end up leaking the storage allocated for 'chip'. I believe simply freeing 'chip' before the 'return err;' line is all we need to fix this, but please double-check me :) Signed-off-by: Jesper Juhl Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/au88x0/au88x0.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sound/pci') diff --git a/sound/pci/au88x0/au88x0.c b/sound/pci/au88x0/au88x0.c index 5ec1b6fcd54..f70286a7364 100644 --- a/sound/pci/au88x0/au88x0.c +++ b/sound/pci/au88x0/au88x0.c @@ -232,6 +232,7 @@ snd_vortex_create(struct snd_card *card, struct pci_dev *pci, vortex_t ** rchip) pci_disable_device(chip->pci_dev); //FIXME: this not the right place to unregister the gameport vortex_gameport_unregister(chip); + kfree(chip); return err; } -- cgit v1.2.3 From 4ff076e5d925d8f714b88a1d3992796f89b45450 Mon Sep 17 00:00:00 2001 From: Tobin Davis Date: Tue, 7 Aug 2007 11:48:12 +0200 Subject: [ALSA] hda-codec - Add more Dell systems This patch adds support for Dell E520 and a couple of other 965 based systems. Signed-off-by: Tobin Davis Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_sigmatel.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 5ca430cc399..87a36e9d654 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -80,6 +80,7 @@ enum { STAC_D965_REF, STAC_D965_3ST, STAC_D965_5ST, + STAC_DELL_3ST, STAC_927X_MODELS }; @@ -719,16 +720,25 @@ static unsigned int d965_5st_pin_configs[14] = { 0x40000100, 0x40000100 }; +static unsigned int dell_3st_pin_configs[14] = { + 0x02211230, 0x02a11220, 0x01a19040, 0x01114210, + 0x01111212, 0x01116211, 0x01813050, 0x01112214, + 0x403003fa, 0x40000100, 0x40000100, 0x404003fb, + 0x40c003fc, 0x40000100 +}; + static unsigned int *stac927x_brd_tbl[STAC_927X_MODELS] = { [STAC_D965_REF] = ref927x_pin_configs, [STAC_D965_3ST] = d965_3st_pin_configs, [STAC_D965_5ST] = d965_5st_pin_configs, + [STAC_DELL_3ST] = dell_3st_pin_configs, }; static const char *stac927x_models[STAC_927X_MODELS] = { [STAC_D965_REF] = "ref", [STAC_D965_3ST] = "3stack", [STAC_D965_5ST] = "5stack", + [STAC_DELL_3ST] = "dell-3stack", }; static struct snd_pci_quirk stac927x_cfg_tbl[] = { @@ -755,6 +765,10 @@ static struct snd_pci_quirk stac927x_cfg_tbl[] = { SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2003, "Intel D965", STAC_D965_3ST), SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2002, "Intel D965", STAC_D965_3ST), SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2001, "Intel D965", STAC_D965_3ST), + /* Dell 3 stack systems */ + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01dd, "Dell E520", STAC_DELL_3ST), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ed, "Dell ", STAC_DELL_3ST), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f4, "Dell ", STAC_DELL_3ST), /* 965 based 5 stack systems */ SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2301, "Intel D965", STAC_D965_5ST), SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2302, "Intel D965", STAC_D965_5ST), -- cgit v1.2.3 From 2880a8670d45f66bbdd3c5dd8f4ba46fe1ce9329 Mon Sep 17 00:00:00 2001 From: Tobin Davis Date: Tue, 7 Aug 2007 11:50:26 +0200 Subject: [ALSA] hda-codec - Add support for Acer Aspire laptops This patch adds support for some Acer Aspire systems. Signed-off-by: Tobin Davis Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_realtek.c | 56 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index db4aded9745..39c08bb670d 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -167,6 +167,7 @@ enum { ALC883_TARGA_DIG, ALC883_TARGA_2ch_DIG, ALC883_ACER, + ALC883_ACER_ASPIRE, ALC883_MEDION, ALC883_MEDION_MD2, ALC883_LAPTOP_EAPD, @@ -6219,6 +6220,33 @@ static struct snd_kcontrol_new alc888_3st_hp_mixer[] = { { } /* end */ }; +static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = { + HDA_CODEC_VOLUME("Front Playback Volume", 0x0d, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), + HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), + HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), + HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), + HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + /* .name = "Capture Source", */ + .name = "Input Source", + .count = 2, + .info = alc883_mux_enum_info, + .get = alc883_mux_enum_get, + .put = alc883_mux_enum_put, + }, + { } /* end */ +}; + static struct snd_kcontrol_new alc883_chmode_mixer[] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, @@ -6436,6 +6464,18 @@ static struct hda_verb alc883_medion_md2_verbs[] = { { } /* end */ }; +static struct hda_verb alc883_acer_aspire_verbs[] = { + {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, + {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, + + {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, + + {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, + { } /* end */ +}; + /* toggle speaker-output according to the hp-jack state */ static void alc883_medion_md2_automute(struct hda_codec *codec) { @@ -6622,6 +6662,7 @@ static const char *alc883_models[ALC883_MODEL_LAST] = { [ALC883_TARGA_DIG] = "targa-dig", [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig", [ALC883_ACER] = "acer", + [ALC883_ACER_ASPIRE] = "acer-aspire", [ALC883_MEDION] = "medion", [ALC883_MEDION_MD2] = "medion-md2", [ALC883_LAPTOP_EAPD] = "laptop-eapd", @@ -6657,6 +6698,7 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = { SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG), SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG), SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG), + SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE), SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER), SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch), SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION), @@ -6771,6 +6813,20 @@ static struct alc_config_preset alc883_presets[] = { .channel_mode = alc883_3ST_2ch_modes, .input_mux = &alc883_capture_source, }, + [ALC883_ACER_ASPIRE] = { + .mixers = { alc883_acer_aspire_mixer}, + .init_verbs = { alc883_init_verbs, alc883_acer_aspire_verbs}, + .num_dacs = ARRAY_SIZE(alc883_dac_nids), + .dac_nids = alc883_dac_nids, + .dig_out_nid = ALC883_DIGOUT_NID, + .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), + .adc_nids = alc883_adc_nids, + .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), + .channel_mode = alc883_3ST_2ch_modes, + .input_mux = &alc883_capture_source, + .unsol_event = alc883_medion_md2_unsol_event, + .init_hook = alc883_medion_md2_automute, + }, [ALC883_MEDION] = { .mixers = { alc883_fivestack_mixer, alc883_chmode_mixer }, -- cgit v1.2.3 From 45cffef1ff4679f5961146101ea1b8235bdd25b5 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 10 Aug 2007 16:50:37 +0200 Subject: [ALSA] Use msecs_to_jiffies() in ac97_codec.c Replace the direct calculation of jiffies with msecs_to_jiffies(). Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/ac97/ac97_codec.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c index 7b02a967c1e..df1333332a5 100644 --- a/sound/pci/ac97/ac97_codec.c +++ b/sound/pci/ac97/ac97_codec.c @@ -2036,11 +2036,12 @@ int snd_ac97_mixer(struct snd_ac97_bus *bus, struct snd_ac97_template *template, else { udelay(50); if (ac97->scaps & AC97_SCAP_SKIP_AUDIO) - err = ac97_reset_wait(ac97, HZ/2, 1); + err = ac97_reset_wait(ac97, msecs_to_jiffies(500), 1); else { - err = ac97_reset_wait(ac97, HZ/2, 0); + err = ac97_reset_wait(ac97, msecs_to_jiffies(500), 0); if (err < 0) - err = ac97_reset_wait(ac97, HZ/2, 1); + err = ac97_reset_wait(ac97, + msecs_to_jiffies(500), 1); } if (err < 0) { snd_printk(KERN_WARNING "AC'97 %d does not respond - RESET\n", ac97->num); @@ -2104,7 +2105,7 @@ int snd_ac97_mixer(struct snd_ac97_bus *bus, struct snd_ac97_template *template, } /* nothing should be in powerdown mode */ snd_ac97_write_cache(ac97, AC97_GENERAL_PURPOSE, 0); - end_time = jiffies + (HZ / 10); + end_time = jiffies + msecs_to_jiffies(100); do { if ((snd_ac97_read(ac97, AC97_POWERDOWN) & 0x0f) == 0x0f) goto __ready_ok; @@ -2136,7 +2137,7 @@ int snd_ac97_mixer(struct snd_ac97_bus *bus, struct snd_ac97_template *template, udelay(100); /* nothing should be in powerdown mode */ snd_ac97_write_cache(ac97, AC97_EXTENDED_MSTATUS, 0); - end_time = jiffies + (HZ / 10); + end_time = jiffies + msecs_to_jiffies(100); do { if ((snd_ac97_read(ac97, AC97_EXTENDED_MSTATUS) & tmp) == tmp) goto __ready_ok; @@ -2354,7 +2355,8 @@ int snd_ac97_update_power(struct snd_ac97 *ac97, int reg, int powerup) * (for avoiding loud click noises for many (OSS) apps * that open/close frequently) */ - schedule_delayed_work(&ac97->power_work, HZ*2); + schedule_delayed_work(&ac97->power_work, + msecs_to_jiffies(2000)); else { cancel_delayed_work(&ac97->power_work); update_power_regs(ac97); -- cgit v1.2.3 From 01751f54ff23b9d59e07f9c9ef189d4733525463 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 10 Aug 2007 16:59:39 +0200 Subject: [ALSA] hda-codec - rewrite amp cache more generic Rewrite the code to handle amp cache and hash tables to be more generic. This routine will be used by the register caches in the next patch. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/hda_codec.c | 89 +++++++++++++++++++++++++++-------------------- sound/pci/hda/hda_codec.h | 24 ++++++++----- 2 files changed, 68 insertions(+), 45 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index fc934baaae6..46f8ab1df87 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -494,6 +494,10 @@ static int read_widget_caps(struct hda_codec *codec, hda_nid_t fg_node) } +static void init_hda_cache(struct hda_cache_rec *cache, + unsigned int record_size); +static inline void free_hda_cache(struct hda_cache_rec *cache); + /* * codec destructor */ @@ -505,13 +509,11 @@ static void snd_hda_codec_free(struct hda_codec *codec) codec->bus->caddr_tbl[codec->addr] = NULL; if (codec->patch_ops.free) codec->patch_ops.free(codec); - kfree(codec->amp_info); + free_hda_cache(&codec->amp_cache); kfree(codec->wcaps); kfree(codec); } -static void init_amp_hash(struct hda_codec *codec); - /** * snd_hda_codec_new - create a HDA codec * @bus: the bus to assign @@ -545,7 +547,7 @@ int __devinit snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, codec->bus = bus; codec->addr = codec_addr; mutex_init(&codec->spdif_mutex); - init_amp_hash(codec); + init_hda_cache(&codec->amp_cache, sizeof(struct hda_amp_info)); list_add_tail(&codec->list, &bus->codec_list); bus->caddr_tbl[codec_addr] = codec; @@ -664,59 +666,72 @@ void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid, #define INFO_AMP_VOL(ch) (1 << (1 + (ch))) /* initialize the hash table */ -static void __devinit init_amp_hash(struct hda_codec *codec) +static void __devinit init_hda_cache(struct hda_cache_rec *cache, + unsigned int record_size) +{ + memset(cache, 0, sizeof(*cache)); + memset(cache->hash, 0xff, sizeof(cache->hash)); + cache->record_size = record_size; +} + +static inline void free_hda_cache(struct hda_cache_rec *cache) { - memset(codec->amp_hash, 0xff, sizeof(codec->amp_hash)); - codec->num_amp_entries = 0; - codec->amp_info_size = 0; - codec->amp_info = NULL; + kfree(cache->buffer); } /* query the hash. allocate an entry if not found. */ -static struct hda_amp_info *get_alloc_amp_hash(struct hda_codec *codec, u32 key) +static struct hda_cache_head *get_alloc_hash(struct hda_cache_rec *cache, + u32 key) { - u16 idx = key % (u16)ARRAY_SIZE(codec->amp_hash); - u16 cur = codec->amp_hash[idx]; - struct hda_amp_info *info; + u16 idx = key % (u16)ARRAY_SIZE(cache->hash); + u16 cur = cache->hash[idx]; + struct hda_cache_head *info; while (cur != 0xffff) { - info = &codec->amp_info[cur]; + info = (struct hda_cache_head *)(cache->buffer + + cur * cache->record_size); if (info->key == key) return info; cur = info->next; } /* add a new hash entry */ - if (codec->num_amp_entries >= codec->amp_info_size) { + if (cache->num_entries >= cache->size) { /* reallocate the array */ - int new_size = codec->amp_info_size + 64; - struct hda_amp_info *new_info; - new_info = kcalloc(new_size, sizeof(struct hda_amp_info), - GFP_KERNEL); - if (!new_info) { + unsigned int new_size = cache->size + 64; + void *new_buffer; + new_buffer = kcalloc(new_size, cache->record_size, GFP_KERNEL); + if (!new_buffer) { snd_printk(KERN_ERR "hda_codec: " "can't malloc amp_info\n"); return NULL; } - if (codec->amp_info) { - memcpy(new_info, codec->amp_info, - codec->amp_info_size * - sizeof(struct hda_amp_info)); - kfree(codec->amp_info); + if (cache->buffer) { + memcpy(new_buffer, cache->buffer, + cache->size * cache->record_size); + kfree(cache->buffer); } - codec->amp_info_size = new_size; - codec->amp_info = new_info; + cache->size = new_size; + cache->buffer = new_buffer; } - cur = codec->num_amp_entries++; - info = &codec->amp_info[cur]; + cur = cache->num_entries++; + info = (struct hda_cache_head *)(cache->buffer + + cur * cache->record_size); info->key = key; - info->status = 0; /* not initialized yet */ - info->next = codec->amp_hash[idx]; - codec->amp_hash[idx] = cur; + info->val = 0; + info->next = cache->hash[idx]; + cache->hash[idx] = cur; return info; } +/* query and allocate an amp hash entry */ +static inline struct hda_amp_info * +get_alloc_amp_hash(struct hda_codec *codec, u32 key) +{ + return (struct hda_amp_info *)get_alloc_hash(&codec->amp_cache, key); +} + /* * query AMP capabilities for the given widget and direction */ @@ -727,7 +742,7 @@ static u32 query_amp_caps(struct hda_codec *codec, hda_nid_t nid, int direction) info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, direction, 0)); if (!info) return 0; - if (!(info->status & INFO_AMP_CAPS)) { + if (!(info->head.val & INFO_AMP_CAPS)) { if (!(get_wcaps(codec, nid) & AC_WCAP_AMP_OVRD)) nid = codec->afg; info->amp_caps = snd_hda_param_read(codec, nid, @@ -735,7 +750,7 @@ static u32 query_amp_caps(struct hda_codec *codec, hda_nid_t nid, int direction) AC_PAR_AMP_OUT_CAP : AC_PAR_AMP_IN_CAP); if (info->amp_caps) - info->status |= INFO_AMP_CAPS; + info->head.val |= INFO_AMP_CAPS; } return info->amp_caps; } @@ -749,7 +764,7 @@ int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir, if (!info) return -EINVAL; info->amp_caps = caps; - info->status |= INFO_AMP_CAPS; + info->head.val |= INFO_AMP_CAPS; return 0; } @@ -763,7 +778,7 @@ static unsigned int get_vol_mute(struct hda_codec *codec, { u32 val, parm; - if (info->status & INFO_AMP_VOL(ch)) + if (info->head.val & INFO_AMP_VOL(ch)) return info->vol[ch]; parm = ch ? AC_AMP_GET_RIGHT : AC_AMP_GET_LEFT; @@ -772,7 +787,7 @@ static unsigned int get_vol_mute(struct hda_codec *codec, val = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_AMP_GAIN_MUTE, parm); info->vol[ch] = val & 0xff; - info->status |= INFO_AMP_VOL(ch); + info->head.val |= INFO_AMP_VOL(ch); return info->vol[ch]; } diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index 1370e346bf3..1a69743160c 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h @@ -480,12 +480,24 @@ struct hda_codec_ops { }; /* record for amp information cache */ -struct hda_amp_info { +struct hda_cache_head { u32 key; /* hash key */ + u16 val; /* assigned value */ + u16 next; /* next link; -1 = terminal */ +}; + +struct hda_amp_info { + struct hda_cache_head head; u32 amp_caps; /* amp capabilities */ u16 vol[2]; /* current volume & mute */ - u16 status; /* update flag */ - u16 next; /* next link */ +}; + +struct hda_cache_rec { + u16 hash[64]; /* hash table for index */ + unsigned int num_entries; /* number of assigned entries */ + unsigned int size; /* allocated size */ + unsigned int record_size; /* record size (including header) */ + void *buffer; /* hash table entries */ }; /* PCM callbacks */ @@ -557,11 +569,7 @@ struct hda_codec { hda_nid_t start_nid; u32 *wcaps; - /* hash for amp access */ - u16 amp_hash[32]; - int num_amp_entries; - int amp_info_size; - struct hda_amp_info *amp_info; + struct hda_cache_rec amp_cache; /* cache for amp access */ struct mutex spdif_mutex; unsigned int spdif_status; /* IEC958 status bits */ -- cgit v1.2.3 From b3ac56364126f78cae94eb2a75b72d9ea85aca9d Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 10 Aug 2007 17:03:40 +0200 Subject: [ALSA] hda-codec - introduce command register cache This patch adds the cache for codec command registers. snd_hda_codec_write_cache() and snd_hda_sequence_write_cache() do the write operations with caching, which values can be resumed via snd_hda_codec_resume_cache(). The patch introduces only the framework, and no codec code is using this cache yet. It'll be implemented in the following patch. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/hda_codec.c | 91 +++++++++++++++++++++++++++++++++++++++++++++++ sound/pci/hda/hda_codec.h | 8 +++++ sound/pci/hda/hda_local.h | 1 + 3 files changed, 100 insertions(+) (limited to 'sound/pci') diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 46f8ab1df87..6652a531980 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -510,6 +510,7 @@ static void snd_hda_codec_free(struct hda_codec *codec) if (codec->patch_ops.free) codec->patch_ops.free(codec); free_hda_cache(&codec->amp_cache); + free_hda_cache(&codec->cmd_cache); kfree(codec->wcaps); kfree(codec); } @@ -548,6 +549,7 @@ int __devinit snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, codec->addr = codec_addr; mutex_init(&codec->spdif_mutex); init_hda_cache(&codec->amp_cache, sizeof(struct hda_amp_info)); + init_hda_cache(&codec->cmd_cache, sizeof(struct hda_cache_head)); list_add_tail(&codec->list, &bus->codec_list); bus->caddr_tbl[codec_addr] = codec; @@ -840,6 +842,29 @@ int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch, return 1; } +/* resume the all amp commands from the cache */ +void snd_hda_codec_resume_amp(struct hda_codec *codec) +{ + struct hda_amp_info *buffer = codec->amp_cache.buffer; + int i; + + for (i = 0; i < codec->amp_cache.size; i++, buffer++) { + u32 key = buffer->head.key; + hda_nid_t nid; + unsigned int idx, dir, ch; + if (!key) + continue; + nid = key & 0xff; + idx = (key >> 16) & 0xff; + dir = (key >> 24) & 0xff; + for (ch = 0; ch < 2; ch++) { + if (!(buffer->head.val & INFO_AMP_VOL(ch))) + continue; + put_vol_mute(codec, buffer, nid, ch, dir, idx, + buffer->vol[ch]); + } + } +} /* * AMP control callbacks @@ -1458,6 +1483,72 @@ int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid) } +/* build a 32bit cache key with the widget id and the command parameter */ +#define build_cmd_cache_key(nid, verb) ((verb << 8) | nid) +#define get_cmd_cache_nid(key) ((key) & 0xff) +#define get_cmd_cache_cmd(key) (((key) >> 8) & 0xffff) + +/** + * snd_hda_codec_write_cache - send a single command with caching + * @codec: the HDA codec + * @nid: NID to send the command + * @direct: direct flag + * @verb: the verb to send + * @parm: the parameter for the verb + * + * Send a single command without waiting for response. + * + * Returns 0 if successful, or a negative error code. + */ +int snd_hda_codec_write_cache(struct hda_codec *codec, hda_nid_t nid, + int direct, unsigned int verb, unsigned int parm) +{ + int err; + mutex_lock(&codec->bus->cmd_mutex); + err = codec->bus->ops.command(codec, nid, direct, verb, parm); + if (!err) { + struct hda_cache_head *c; + u32 key = build_cmd_cache_key(nid, verb); + c = get_alloc_hash(&codec->cmd_cache, key); + if (c) + c->val = parm; + } + mutex_unlock(&codec->bus->cmd_mutex); + return err; +} + +/* resume the all commands from the cache */ +void snd_hda_codec_resume_cache(struct hda_codec *codec) +{ + struct hda_cache_head *buffer = codec->cmd_cache.buffer; + int i; + + for (i = 0; i < codec->cmd_cache.size; i++, buffer++) { + u32 key = buffer->key; + if (!key) + continue; + snd_hda_codec_write(codec, get_cmd_cache_nid(key), 0, + get_cmd_cache_cmd(key), buffer->val); + } +} + +/** + * snd_hda_sequence_write_cache - sequence writes with caching + * @codec: the HDA codec + * @seq: VERB array to send + * + * Send the commands sequentially from the given array. + * Thte commands are recorded on cache for power-save and resume. + * The array must be terminated with NID=0. + */ +void snd_hda_sequence_write_cache(struct hda_codec *codec, + const struct hda_verb *seq) +{ + for (; seq->nid; seq++) + snd_hda_codec_write_cache(codec, seq->nid, 0, seq->verb, + seq->param); +} + /* * set power state of the codec */ diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index 1a69743160c..ef94c9122c6 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h @@ -570,6 +570,7 @@ struct hda_codec { u32 *wcaps; struct hda_cache_rec amp_cache; /* cache for amp access */ + struct hda_cache_rec cmd_cache; /* cache for other commands */ struct mutex spdif_mutex; unsigned int spdif_status; /* IEC958 status bits */ @@ -620,6 +621,13 @@ void snd_hda_sequence_write(struct hda_codec *codec, /* unsolicited event */ int snd_hda_queue_unsol_event(struct hda_bus *bus, u32 res, u32 res_ex); +/* cached write */ +int snd_hda_codec_write_cache(struct hda_codec *codec, hda_nid_t nid, + int direct, unsigned int verb, unsigned int parm); +void snd_hda_sequence_write_cache(struct hda_codec *codec, + const struct hda_verb *seq); +void snd_hda_codec_resume_cache(struct hda_codec *codec); + /* * Mixer */ diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h index fafcffe6fc7..51208974c2d 100644 --- a/sound/pci/hda/hda_local.h +++ b/sound/pci/hda/hda_local.h @@ -84,6 +84,7 @@ int snd_hda_codec_amp_read(struct hda_codec *codec, hda_nid_t nid, int ch, int direction, int index); int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch, int direction, int idx, int mask, int val); +void snd_hda_codec_resume_amp(struct hda_codec *codec); /* mono switch binding multiple inputs */ #define HDA_BIND_MUTE_MONO(xname, nid, channel, indices, direction) \ -- cgit v1.2.3 From 82beb8fd365afe3891b277c46425083f13e23c56 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 10 Aug 2007 17:09:26 +0200 Subject: [ALSA] hda-codec - optimize resume using caches So far, the driver looked the table of snd_kcontrol_new used for creating mixer elements and forces to call each of its put callbacks in PM resume code. This is too ugly and hackish. Now, the resume is simplified using the codec amp and command register caches. The driver simply restores the values that have been written in the cache table. With this simplification, most codec support codes don't require any special resume callback. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/hda_codec.c | 115 +++++++++------------------- sound/pci/hda/hda_codec.h | 10 +-- sound/pci/hda/hda_generic.c | 24 +++--- sound/pci/hda/hda_local.h | 11 +-- sound/pci/hda/patch_analog.c | 68 ++++++----------- sound/pci/hda/patch_atihdmi.c | 16 ---- sound/pci/hda/patch_cmedia.c | 24 ------ sound/pci/hda/patch_conexant.c | 28 +------ sound/pci/hda/patch_realtek.c | 167 +++++++++++++++++++++-------------------- sound/pci/hda/patch_si3054.c | 10 +-- sound/pci/hda/patch_sigmatel.c | 46 +++++------- sound/pci/hda/patch_via.c | 24 ------ 12 files changed, 195 insertions(+), 348 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 6652a531980..1d31da47bc9 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -836,12 +836,13 @@ int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch, return 0; val &= mask; val |= get_vol_mute(codec, info, nid, ch, direction, idx) & ~mask; - if (info->vol[ch] == val && !codec->in_resume) + if (info->vol[ch] == val) return 0; put_vol_mute(codec, info, nid, ch, direction, idx, val); return 1; } +#ifdef CONFIG_PM /* resume the all amp commands from the cache */ void snd_hda_codec_resume_amp(struct hda_codec *codec) { @@ -865,6 +866,7 @@ void snd_hda_codec_resume_amp(struct hda_codec *codec) } } } +#endif /* CONFIG_PM */ /* * AMP control callbacks @@ -1272,11 +1274,13 @@ static int snd_hda_spdif_default_put(struct snd_kcontrol *kcontrol, change = codec->spdif_ctls != val; codec->spdif_ctls = val; - if (change || codec->in_resume) { - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, - val & 0xff); - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_2, - val >> 8); + if (change) { + snd_hda_codec_write_cache(codec, nid, 0, + AC_VERB_SET_DIGI_CONVERT_1, + val & 0xff); + snd_hda_codec_write_cache(codec, nid, 0, + AC_VERB_SET_DIGI_CONVERT_2, + val >> 8); } mutex_unlock(&codec->spdif_mutex); @@ -1307,17 +1311,19 @@ static int snd_hda_spdif_out_switch_put(struct snd_kcontrol *kcontrol, if (ucontrol->value.integer.value[0]) val |= AC_DIG1_ENABLE; change = codec->spdif_ctls != val; - if (change || codec->in_resume) { + if (change) { codec->spdif_ctls = val; - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, - val & 0xff); + snd_hda_codec_write_cache(codec, nid, 0, + AC_VERB_SET_DIGI_CONVERT_1, + val & 0xff); /* unmute amp switch (if any) */ if ((get_wcaps(codec, nid) & AC_WCAP_OUT_AMP) && - (val & AC_DIG1_ENABLE)) - snd_hda_codec_write(codec, nid, 0, - AC_VERB_SET_AMP_GAIN_MUTE, - AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT | - AC_AMP_SET_OUTPUT); + (val & AC_DIG1_ENABLE)) { + snd_hda_codec_amp_update(codec, nid, 0, HDA_OUTPUT, 0, + 0x80, 0x00); + snd_hda_codec_amp_update(codec, nid, 1, HDA_OUTPUT, 0, + 0x80, 0x00); + } } mutex_unlock(&codec->spdif_mutex); return change; @@ -1409,10 +1415,10 @@ static int snd_hda_spdif_in_switch_put(struct snd_kcontrol *kcontrol, mutex_lock(&codec->spdif_mutex); change = codec->spdif_in_enable != val; - if (change || codec->in_resume) { + if (change) { codec->spdif_in_enable = val; - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, - val); + snd_hda_codec_write_cache(codec, nid, 0, + AC_VERB_SET_DIGI_CONVERT_1, val); } mutex_unlock(&codec->spdif_mutex); return change; @@ -1482,6 +1488,10 @@ int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid) return 0; } +#ifdef CONFIG_PM +/* + * command cache + */ /* build a 32bit cache key with the widget id and the command parameter */ #define build_cmd_cache_key(nid, verb) ((verb << 8) | nid) @@ -1548,6 +1558,7 @@ void snd_hda_sequence_write_cache(struct hda_codec *codec, snd_hda_codec_write_cache(codec, seq->nid, 0, seq->verb, seq->param); } +#endif /* CONFIG_PM */ /* * set power state of the codec @@ -2122,12 +2133,12 @@ int snd_hda_ch_mode_put(struct hda_codec *codec, mode = ucontrol->value.enumerated.item[0]; snd_assert(mode < num_chmodes, return -EINVAL); - if (*max_channelsp == chmode[mode].channels && !codec->in_resume) + if (*max_channelsp == chmode[mode].channels) return 0; /* change the current channel setting */ *max_channelsp = chmode[mode].channels; if (chmode[mode].sequence) - snd_hda_sequence_write(codec, chmode[mode].sequence); + snd_hda_sequence_write_cache(codec, chmode[mode].sequence); return 1; } @@ -2160,10 +2171,10 @@ int snd_hda_input_mux_put(struct hda_codec *codec, idx = ucontrol->value.enumerated.item[0]; if (idx >= imux->num_items) idx = imux->num_items - 1; - if (*cur_val == idx && !codec->in_resume) + if (*cur_val == idx) return 0; - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, - imux->items[idx].index); + snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, + imux->items[idx].index); *cur_val = idx; return 1; } @@ -2608,65 +2619,13 @@ int snd_hda_resume(struct hda_bus *bus) AC_PWRST_D0); if (codec->patch_ops.resume) codec->patch_ops.resume(codec); - } - return 0; -} - -/** - * snd_hda_resume_ctls - resume controls in the new control list - * @codec: the HDA codec - * @knew: the array of struct snd_kcontrol_new - * - * This function resumes the mixer controls in the struct snd_kcontrol_new array, - * originally for snd_hda_add_new_ctls(). - * The array must be terminated with an empty entry as terminator. - */ -int snd_hda_resume_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew) -{ - struct snd_ctl_elem_value *val; - - val = kmalloc(sizeof(*val), GFP_KERNEL); - if (!val) - return -ENOMEM; - codec->in_resume = 1; - for (; knew->name; knew++) { - int i, count; - count = knew->count ? knew->count : 1; - for (i = 0; i < count; i++) { - memset(val, 0, sizeof(*val)); - val->id.iface = knew->iface; - val->id.device = knew->device; - val->id.subdevice = knew->subdevice; - strcpy(val->id.name, knew->name); - val->id.index = knew->index ? knew->index : i; - /* Assume that get callback reads only from cache, - * not accessing to the real hardware - */ - if (snd_ctl_elem_read(codec->bus->card, val) < 0) - continue; - snd_ctl_elem_write(codec->bus->card, NULL, val); + else { + codec->patch_ops.init(codec); + snd_hda_codec_resume_amp(codec); + snd_hda_codec_resume_cache(codec); } } - codec->in_resume = 0; - kfree(val); return 0; } -/** - * snd_hda_resume_spdif_out - resume the digital out - * @codec: the HDA codec - */ -int snd_hda_resume_spdif_out(struct hda_codec *codec) -{ - return snd_hda_resume_ctls(codec, dig_mixes); -} - -/** - * snd_hda_resume_spdif_in - resume the digital in - * @codec: the HDA codec - */ -int snd_hda_resume_spdif_in(struct hda_codec *codec) -{ - return snd_hda_resume_ctls(codec, dig_in_ctls); -} #endif diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index ef94c9122c6..92938d2a52e 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h @@ -552,11 +552,6 @@ struct hda_codec { /* set by patch */ struct hda_codec_ops patch_ops; - /* resume phase - all controls should update even if - * the values are not changed - */ - unsigned int in_resume; - /* PCM to create, set by patch_ops.build_pcms callback */ unsigned int num_pcms; struct hda_pcm *pcm_info; @@ -622,11 +617,16 @@ void snd_hda_sequence_write(struct hda_codec *codec, int snd_hda_queue_unsol_event(struct hda_bus *bus, u32 res, u32 res_ex); /* cached write */ +#ifdef CONFIG_PM int snd_hda_codec_write_cache(struct hda_codec *codec, hda_nid_t nid, int direct, unsigned int verb, unsigned int parm); void snd_hda_sequence_write_cache(struct hda_codec *codec, const struct hda_verb *seq); void snd_hda_codec_resume_cache(struct hda_codec *codec); +#else +#define snd_hda_codec_write_cache snd_hda_codec_write +#define snd_hda_sequence_write_cache snd_hda_sequence_write +#endif /* * Mixer diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c index 000287f7da4..d5f1180115c 100644 --- a/sound/pci/hda/hda_generic.c +++ b/sound/pci/hda/hda_generic.c @@ -218,9 +218,9 @@ static int unmute_output(struct hda_codec *codec, struct hda_gnode *node) ofs = (node->amp_out_caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT; if (val >= ofs) val -= ofs; - val |= AC_AMP_SET_LEFT | AC_AMP_SET_RIGHT; - val |= AC_AMP_SET_OUTPUT; - return snd_hda_codec_write(codec, node->nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, val); + snd_hda_codec_amp_update(codec, node->nid, 0, HDA_OUTPUT, 0, 0xff, val); + snd_hda_codec_amp_update(codec, node->nid, 0, HDA_OUTPUT, 1, 0xff, val); + return 0; } /* @@ -234,11 +234,11 @@ static int unmute_input(struct hda_codec *codec, struct hda_gnode *node, unsigne ofs = (node->amp_in_caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT; if (val >= ofs) val -= ofs; - val |= AC_AMP_SET_LEFT | AC_AMP_SET_RIGHT; - val |= AC_AMP_SET_INPUT; - // awk added - fixed to allow unmuting of indexed amps - val |= index << AC_AMP_SET_INDEX_SHIFT; - return snd_hda_codec_write(codec, node->nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, val); + snd_hda_codec_amp_update(codec, node->nid, 0, HDA_INPUT, index, + 0xff, val); + snd_hda_codec_amp_update(codec, node->nid, 1, HDA_INPUT, index, + 0xff, val); + return 0; } /* @@ -248,7 +248,8 @@ static int select_input_connection(struct hda_codec *codec, struct hda_gnode *no unsigned int index) { snd_printdd("CONNECT: NID=0x%x IDX=0x%x\n", node->nid, index); - return snd_hda_codec_write(codec, node->nid, 0, AC_VERB_SET_CONNECT_SEL, index); + return snd_hda_codec_write_cache(codec, node->nid, 0, + AC_VERB_SET_CONNECT_SEL, index); } /* @@ -379,7 +380,7 @@ static struct hda_gnode *parse_output_jack(struct hda_codec *codec, /* unmute the PIN output */ unmute_output(codec, node); /* set PIN-Out enable */ - snd_hda_codec_write(codec, node->nid, 0, + snd_hda_codec_write_cache(codec, node->nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_OUT_EN | ((node->pin_caps & AC_PINCAP_HP_DRV) ? @@ -570,7 +571,8 @@ static int parse_adc_sub_nodes(struct hda_codec *codec, struct hda_gspec *spec, /* unmute the PIN external input */ unmute_input(codec, node, 0); /* index = 0? */ /* set PIN-In enable */ - snd_hda_codec_write(codec, node->nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pinctl); + snd_hda_codec_write_cache(codec, node->nid, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, pinctl); return 1; /* found */ } diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h index 51208974c2d..8dec32cfdf5 100644 --- a/sound/pci/hda/hda_local.h +++ b/sound/pci/hda/hda_local.h @@ -84,7 +84,9 @@ int snd_hda_codec_amp_read(struct hda_codec *codec, hda_nid_t nid, int ch, int direction, int index); int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch, int direction, int idx, int mask, int val); +#ifdef CONFIG_PM void snd_hda_codec_resume_amp(struct hda_codec *codec); +#endif /* mono switch binding multiple inputs */ #define HDA_BIND_MUTE_MONO(xname, nid, channel, indices, direction) \ @@ -256,15 +258,6 @@ int snd_hda_check_board_config(struct hda_codec *codec, int num_configs, int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew); -/* - * power management - */ -#ifdef CONFIG_PM -int snd_hda_resume_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew); -int snd_hda_resume_spdif_out(struct hda_codec *codec); -int snd_hda_resume_spdif_in(struct hda_codec *codec); -#endif - /* * unsolicited event handler */ diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index cc2e944cc59..f20ddd85db2 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c @@ -318,31 +318,11 @@ static void ad198x_free(struct hda_codec *codec) kfree(codec->spec); } -#ifdef CONFIG_PM -static int ad198x_resume(struct hda_codec *codec) -{ - struct ad198x_spec *spec = codec->spec; - int i; - - codec->patch_ops.init(codec); - for (i = 0; i < spec->num_mixers; i++) - snd_hda_resume_ctls(codec, spec->mixers[i]); - if (spec->multiout.dig_out_nid) - snd_hda_resume_spdif_out(codec); - if (spec->dig_in_nid) - snd_hda_resume_spdif_in(codec); - return 0; -} -#endif - static struct hda_codec_ops ad198x_patch_ops = { .build_controls = ad198x_build_controls, .build_pcms = ad198x_build_pcms, .init = ad198x_init, .free = ad198x_free, -#ifdef CONFIG_PM - .resume = ad198x_resume, -#endif }; @@ -376,12 +356,12 @@ static int ad198x_eapd_put(struct snd_kcontrol *kcontrol, eapd = ucontrol->value.integer.value[0]; if (invert) eapd = !eapd; - if (eapd == spec->cur_eapd && ! codec->in_resume) + if (eapd == spec->cur_eapd) return 0; spec->cur_eapd = eapd; - snd_hda_codec_write(codec, nid, - 0, AC_VERB_SET_EAPD_BTLENABLE, - eapd ? 0x02 : 0x00); + snd_hda_codec_write_cache(codec, nid, + 0, AC_VERB_SET_EAPD_BTLENABLE, + eapd ? 0x02 : 0x00); return 1; } @@ -882,8 +862,9 @@ static int ad1983_spdif_route_put(struct snd_kcontrol *kcontrol, struct snd_ctl_ if (spec->spdif_route != ucontrol->value.enumerated.item[0]) { spec->spdif_route = ucontrol->value.enumerated.item[0]; - snd_hda_codec_write(codec, spec->multiout.dig_out_nid, 0, - AC_VERB_SET_CONNECT_SEL, spec->spdif_route); + snd_hda_codec_write_cache(codec, spec->multiout.dig_out_nid, 0, + AC_VERB_SET_CONNECT_SEL, + spec->spdif_route); return 1; } return 0; @@ -1824,33 +1805,34 @@ static int ad1988_spdif_playback_source_put(struct snd_kcontrol *kcontrol, AC_VERB_GET_AMP_GAIN_MUTE, AC_AMP_GET_INPUT); change = sel & 0x80; - if (change || codec->in_resume) { - snd_hda_codec_write(codec, 0x1d, 0, - AC_VERB_SET_AMP_GAIN_MUTE, - AMP_IN_UNMUTE(0)); - snd_hda_codec_write(codec, 0x1d, 0, - AC_VERB_SET_AMP_GAIN_MUTE, - AMP_IN_MUTE(1)); + if (change) { + snd_hda_codec_write_cache(codec, 0x1d, 0, + AC_VERB_SET_AMP_GAIN_MUTE, + AMP_IN_UNMUTE(0)); + snd_hda_codec_write_cache(codec, 0x1d, 0, + AC_VERB_SET_AMP_GAIN_MUTE, + AMP_IN_MUTE(1)); } } else { sel = snd_hda_codec_read(codec, 0x1d, 0, AC_VERB_GET_AMP_GAIN_MUTE, AC_AMP_GET_INPUT | 0x01); change = sel & 0x80; - if (change || codec->in_resume) { - snd_hda_codec_write(codec, 0x1d, 0, - AC_VERB_SET_AMP_GAIN_MUTE, - AMP_IN_MUTE(0)); - snd_hda_codec_write(codec, 0x1d, 0, - AC_VERB_SET_AMP_GAIN_MUTE, - AMP_IN_UNMUTE(1)); + if (change) { + snd_hda_codec_write_cache(codec, 0x1d, 0, + AC_VERB_SET_AMP_GAIN_MUTE, + AMP_IN_MUTE(0)); + snd_hda_codec_write_cache(codec, 0x1d, 0, + AC_VERB_SET_AMP_GAIN_MUTE, + AMP_IN_UNMUTE(1)); } sel = snd_hda_codec_read(codec, 0x0b, 0, AC_VERB_GET_CONNECT_SEL, 0) + 1; change |= sel != val; - if (change || codec->in_resume) - snd_hda_codec_write(codec, 0x0b, 0, - AC_VERB_SET_CONNECT_SEL, val - 1); + if (change) + snd_hda_codec_write_cache(codec, 0x0b, 0, + AC_VERB_SET_CONNECT_SEL, + val - 1); } return change; } diff --git a/sound/pci/hda/patch_atihdmi.c b/sound/pci/hda/patch_atihdmi.c index 72d3ab9751a..fbb8969dc55 100644 --- a/sound/pci/hda/patch_atihdmi.c +++ b/sound/pci/hda/patch_atihdmi.c @@ -62,19 +62,6 @@ static int atihdmi_init(struct hda_codec *codec) return 0; } -#ifdef CONFIG_PM -/* - * resume - */ -static int atihdmi_resume(struct hda_codec *codec) -{ - atihdmi_init(codec); - snd_hda_resume_spdif_out(codec); - - return 0; -} -#endif - /* * Digital out */ @@ -141,9 +128,6 @@ static struct hda_codec_ops atihdmi_patch_ops = { .build_pcms = atihdmi_build_pcms, .init = atihdmi_init, .free = atihdmi_free, -#ifdef CONFIG_PM - .resume = atihdmi_resume, -#endif }; static int patch_atihdmi(struct hda_codec *codec) diff --git a/sound/pci/hda/patch_cmedia.c b/sound/pci/hda/patch_cmedia.c index 3c722e667bc..2468f317122 100644 --- a/sound/pci/hda/patch_cmedia.c +++ b/sound/pci/hda/patch_cmedia.c @@ -427,27 +427,6 @@ static int cmi9880_init(struct hda_codec *codec) return 0; } -#ifdef CONFIG_PM -/* - * resume - */ -static int cmi9880_resume(struct hda_codec *codec) -{ - struct cmi_spec *spec = codec->spec; - - cmi9880_init(codec); - snd_hda_resume_ctls(codec, cmi9880_basic_mixer); - if (spec->channel_modes) - snd_hda_resume_ctls(codec, cmi9880_ch_mode_mixer); - if (spec->multiout.dig_out_nid) - snd_hda_resume_spdif_out(codec); - if (spec->dig_in_nid) - snd_hda_resume_spdif_in(codec); - - return 0; -} -#endif - /* * Analog playback callbacks */ @@ -635,9 +614,6 @@ static struct hda_codec_ops cmi9880_patch_ops = { .build_pcms = cmi9880_build_pcms, .init = cmi9880_init, .free = cmi9880_free, -#ifdef CONFIG_PM - .resume = cmi9880_resume, -#endif }; static int patch_cmi9880(struct hda_codec *codec) diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 26034315197..f1b6d0eda14 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -311,23 +311,6 @@ static void conexant_free(struct hda_codec *codec) kfree(codec->spec); } -#ifdef CONFIG_PM -static int conexant_resume(struct hda_codec *codec) -{ - struct conexant_spec *spec = codec->spec; - int i; - - codec->patch_ops.init(codec); - for (i = 0; i < spec->num_mixers; i++) - snd_hda_resume_ctls(codec, spec->mixers[i]); - if (spec->multiout.dig_out_nid) - snd_hda_resume_spdif_out(codec); - if (spec->dig_in_nid) - snd_hda_resume_spdif_in(codec); - return 0; -} -#endif - static int conexant_build_controls(struct hda_codec *codec) { struct conexant_spec *spec = codec->spec; @@ -358,9 +341,6 @@ static struct hda_codec_ops conexant_patch_ops = { .build_pcms = conexant_build_pcms, .init = conexant_init, .free = conexant_free, -#ifdef CONFIG_PM - .resume = conexant_resume, -#endif }; /* @@ -396,13 +376,13 @@ static int cxt_eapd_put(struct snd_kcontrol *kcontrol, eapd = ucontrol->value.integer.value[0]; if (invert) eapd = !eapd; - if (eapd == spec->cur_eapd && !codec->in_resume) + if (eapd == spec->cur_eapd) return 0; spec->cur_eapd = eapd; - snd_hda_codec_write(codec, nid, - 0, AC_VERB_SET_EAPD_BTLENABLE, - eapd ? 0x02 : 0x00); + snd_hda_codec_write_cache(codec, nid, + 0, AC_VERB_SET_EAPD_BTLENABLE, + eapd ? 0x02 : 0x00); return 1; } diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 39c08bb670d..63011133e3f 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -442,8 +442,9 @@ static int alc_pin_mode_put(struct snd_kcontrol *kcontrol, change = pinctl != alc_pin_mode_values[val]; if (change) { /* Set pin mode to that requested */ - snd_hda_codec_write(codec,nid,0,AC_VERB_SET_PIN_WIDGET_CONTROL, - alc_pin_mode_values[val]); + snd_hda_codec_write_cache(codec, nid, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, + alc_pin_mode_values[val]); /* Also enable the retasking pin's input/output as required * for the requested pin mode. Enum values of 2 or less are @@ -456,19 +457,23 @@ static int alc_pin_mode_put(struct snd_kcontrol *kcontrol, * this turns out to be necessary in the future. */ if (val <= 2) { - snd_hda_codec_write(codec, nid, 0, - AC_VERB_SET_AMP_GAIN_MUTE, - AMP_OUT_MUTE); - snd_hda_codec_write(codec, nid, 0, - AC_VERB_SET_AMP_GAIN_MUTE, - AMP_IN_UNMUTE(0)); + snd_hda_codec_amp_update(codec, nid, 0, HDA_OUTPUT, 0, + 0x80, 0x80); + snd_hda_codec_amp_update(codec, nid, 1, HDA_OUTPUT, 0, + 0x80, 0x80); + snd_hda_codec_amp_update(codec, nid, 0, HDA_INPUT, 0, + 0x80, 0x00); + snd_hda_codec_amp_update(codec, nid, 1, HDA_INPUT, 0, + 0x80, 0x00); } else { - snd_hda_codec_write(codec, nid, 0, - AC_VERB_SET_AMP_GAIN_MUTE, - AMP_IN_MUTE(0)); - snd_hda_codec_write(codec, nid, 0, - AC_VERB_SET_AMP_GAIN_MUTE, - AMP_OUT_UNMUTE); + snd_hda_codec_amp_update(codec, nid, 0, HDA_INPUT, 0, + 0x80, 0x80); + snd_hda_codec_amp_update(codec, nid, 1, HDA_INPUT, 0, + 0x80, 0x80); + snd_hda_codec_amp_update(codec, nid, 0, HDA_OUTPUT, 0, + 0x80, 0x00); + snd_hda_codec_amp_update(codec, nid, 1, HDA_OUTPUT, 0, + 0x80, 0x00); } } return change; @@ -520,7 +525,8 @@ static int alc_gpio_data_put(struct snd_kcontrol *kcontrol, gpio_data &= ~mask; else gpio_data |= mask; - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_GPIO_DATA, gpio_data); + snd_hda_codec_write_cache(codec, nid, 0, + AC_VERB_SET_GPIO_DATA, gpio_data); return change; } @@ -573,8 +579,8 @@ static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol, ctrl_data &= ~mask; else ctrl_data |= mask; - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, - ctrl_data); + snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, + ctrl_data); return change; } @@ -2026,27 +2032,6 @@ static void alc_unsol_event(struct hda_codec *codec, unsigned int res) spec->unsol_event(codec, res); } -#ifdef CONFIG_PM -/* - * resume - */ -static int alc_resume(struct hda_codec *codec) -{ - struct alc_spec *spec = codec->spec; - int i; - - alc_init(codec); - for (i = 0; i < spec->num_mixers; i++) - snd_hda_resume_ctls(codec, spec->mixers[i]); - if (spec->multiout.dig_out_nid) - snd_hda_resume_spdif_out(codec); - if (spec->dig_in_nid) - snd_hda_resume_spdif_in(codec); - - return 0; -} -#endif - /* * Analog playback callbacks */ @@ -2278,9 +2263,6 @@ static struct hda_codec_ops alc_patch_ops = { .init = alc_init, .free = alc_free, .unsol_event = alc_unsol_event, -#ifdef CONFIG_PM - .resume = alc_resume, -#endif }; @@ -2377,11 +2359,15 @@ static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol, AC_VERB_GET_PIN_WIDGET_CONTROL, 0); new_ctl = ctls[ucontrol->value.enumerated.item[0]]; if (old_ctl != new_ctl) { - snd_hda_codec_write(codec, nid, 0, - AC_VERB_SET_PIN_WIDGET_CONTROL, new_ctl); - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, - (ucontrol->value.enumerated.item[0] >= 3 ? - 0xb080 : 0xb000)); + int val; + snd_hda_codec_write_cache(codec, nid, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, + new_ctl); + val = ucontrol->value.enumerated.item[0] >= 3 ? 0x80 : 0x00; + snd_hda_codec_amp_update(codec, nid, 0, HDA_OUTPUT, 0, + 0x80, val); + snd_hda_codec_amp_update(codec, nid, 1, HDA_OUTPUT, 0, + 0x80, val); return 1; } return 0; @@ -2424,7 +2410,8 @@ static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol, sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3; if (ucontrol->value.enumerated.item[0] != sel) { sel = ucontrol->value.enumerated.item[0] & 3; - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, sel); + snd_hda_codec_write_cache(codec, nid, 0, + AC_VERB_SET_CONNECT_SEL, sel); return 1; } return 0; @@ -4054,13 +4041,17 @@ static void alc260_replacer_672v_automute(struct hda_codec *codec) present = snd_hda_codec_read(codec, 0x0f, 0, AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; if (present) { - snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 1); - snd_hda_codec_write(codec, 0x0f, 0, - AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP); + snd_hda_codec_write_cache(codec, 0x01, 0, + AC_VERB_SET_GPIO_DATA, 1); + snd_hda_codec_write_cache(codec, 0x0f, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, + PIN_HP); } else { - snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0); - snd_hda_codec_write(codec, 0x0f, 0, - AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); + snd_hda_codec_write_cache(codec, 0x01, 0, + AC_VERB_SET_GPIO_DATA, 0); + snd_hda_codec_write_cache(codec, 0x0f, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, + PIN_OUT); } } @@ -4797,12 +4788,16 @@ static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol, idx = ucontrol->value.enumerated.item[0]; if (idx >= imux->num_items) idx = imux->num_items - 1; - if (*cur_val == idx && !codec->in_resume) + if (*cur_val == idx) return 0; for (i = 0; i < imux->num_items; i++) { - unsigned int v = (i == idx) ? 0x7000 : 0x7080; - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, - v | (imux->items[i].index << 8)); + unsigned int v = (i == idx) ? 0x00 : 0x80; + snd_hda_codec_amp_update(codec, nid, 0, HDA_INPUT, + imux->items[i].index, + 0x80, v); + snd_hda_codec_amp_update(codec, nid, 1, HDA_INPUT, + imux->items[i].index, + 0x80, v); } *cur_val = idx; return 1; @@ -5187,7 +5182,8 @@ static void alc882_targa_automute(struct hda_codec *codec) 0x80, present ? 0x80 : 0); snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0, 0x80, present ? 0x80 : 0); - snd_hda_codec_write(codec, 1, 0, AC_VERB_SET_GPIO_DATA, present ? 1 : 3); + snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA, + present ? 1 : 3); } static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res) @@ -5777,12 +5773,16 @@ static int alc883_mux_enum_put(struct snd_kcontrol *kcontrol, idx = ucontrol->value.enumerated.item[0]; if (idx >= imux->num_items) idx = imux->num_items - 1; - if (*cur_val == idx && !codec->in_resume) + if (*cur_val == idx) return 0; for (i = 0; i < imux->num_items; i++) { - unsigned int v = (i == idx) ? 0x7000 : 0x7080; - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, - v | (imux->items[i].index << 8)); + unsigned int v = (i == idx) ? 0x00 : 0x80; + snd_hda_codec_amp_update(codec, nid, 0, HDA_INPUT, + imux->items[i].index, + 0x80, v); + snd_hda_codec_amp_update(codec, nid, 1, HDA_INPUT, + imux->items[i].index, + 0x80, v); } *cur_val = idx; return 1; @@ -6509,8 +6509,8 @@ static void alc883_tagra_automute(struct hda_codec *codec) 0x80, bits); snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0, 0x80, bits); - snd_hda_codec_write(codec, 1, 0, AC_VERB_SET_GPIO_DATA, - present ? 1 : 3); + snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA, + present ? 1 : 3); } static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res) @@ -7510,8 +7510,8 @@ static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol, 0x80, valp[0] ? 0 : 0x80); change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0, 0x80, valp[1] ? 0 : 0x80); - if (change || codec->in_resume) - alc262_fujitsu_automute(codec, codec->in_resume); + if (change) + alc262_fujitsu_automute(codec, 0); return change; } @@ -8328,14 +8328,17 @@ static int alc268_mux_enum_put(struct snd_kcontrol *kcontrol, idx = ucontrol->value.enumerated.item[0]; if (idx >= imux->num_items) idx = imux->num_items - 1; - if (*cur_val == idx && !codec->in_resume) + if (*cur_val == idx) return 0; for (i = 0; i < imux->num_items; i++) { - unsigned int v = (i == idx) ? 0x7000 : 0x7080; - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, - v | (imux->items[i].index << 8)); - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, - idx ); + unsigned int v = (i == idx) ? 0x00 : 0x80; + snd_hda_codec_amp_update(codec, nid, 0, HDA_INPUT, + imux->items[i].index, 0x80, v); + snd_hda_codec_amp_update(codec, nid, 1, HDA_INPUT, + imux->items[i].index, 0x80, v); + snd_hda_codec_write_cache(codec, nid, 0, + AC_VERB_SET_CONNECT_SEL, + idx ); } *cur_val = idx; return 1; @@ -9916,12 +9919,14 @@ static int alc861vd_mux_enum_put(struct snd_kcontrol *kcontrol, idx = ucontrol->value.enumerated.item[0]; if (idx >= imux->num_items) idx = imux->num_items - 1; - if (*cur_val == idx && !codec->in_resume) + if (*cur_val == idx) return 0; for (i = 0; i < imux->num_items; i++) { - unsigned int v = (i == idx) ? 0x7000 : 0x7080; - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, - v | (imux->items[i].index << 8)); + unsigned int v = (i == idx) ? 0x00 : 0x80; + snd_hda_codec_amp_update(codec, nid, 0, HDA_INPUT, + imux->items[i].index, 0x80, v); + snd_hda_codec_amp_update(codec, nid, 1, HDA_INPUT, + imux->items[i].index, 0x80, v); } *cur_val = idx; return 1; @@ -10847,12 +10852,14 @@ static int alc662_mux_enum_put(struct snd_kcontrol *kcontrol, idx = ucontrol->value.enumerated.item[0]; if (idx >= imux->num_items) idx = imux->num_items - 1; - if (*cur_val == idx && !codec->in_resume) + if (*cur_val == idx) return 0; for (i = 0; i < imux->num_items; i++) { - unsigned int v = (i == idx) ? 0x7000 : 0x7080; - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, - v | (imux->items[i].index << 8)); + unsigned int v = (i == idx) ? 0x00 : 0x80; + snd_hda_codec_amp_update(codec, nid, 0, HDA_INPUT, + imux->items[i].index, 0x80, v); + snd_hda_codec_amp_update(codec, nid, 1, HDA_INPUT, + imux->items[i].index, 0x80, v); } *cur_val = idx; return 1; diff --git a/sound/pci/hda/patch_si3054.c b/sound/pci/hda/patch_si3054.c index 9838eac9ab5..2a4b9609aa5 100644 --- a/sound/pci/hda/patch_si3054.c +++ b/sound/pci/hda/patch_si3054.c @@ -78,6 +78,8 @@ /* si3054 codec registers (nodes) access macros */ #define GET_REG(codec,reg) (snd_hda_codec_read(codec,reg,0,SI3054_VERB_READ_NODE,0)) #define SET_REG(codec,reg,val) (snd_hda_codec_write(codec,reg,0,SI3054_VERB_WRITE_NODE,val)) +#define SET_REG_CACHE(codec,reg,val) \ + snd_hda_codec_write_cache(codec,reg,0,SI3054_VERB_WRITE_NODE,val) struct si3054_spec { @@ -113,9 +115,9 @@ static int si3054_switch_put(struct snd_kcontrol *kcontrol, u16 reg = PRIVATE_REG(kcontrol->private_value); u16 mask = PRIVATE_MASK(kcontrol->private_value); if (uvalue->value.integer.value[0]) - SET_REG(codec, reg, (GET_REG(codec, reg)) | mask); + SET_REG_CACHE(codec, reg, (GET_REG(codec, reg)) | mask); else - SET_REG(codec, reg, (GET_REG(codec, reg)) & ~mask); + SET_REG_CACHE(codec, reg, (GET_REG(codec, reg)) & ~mask); return 0; } @@ -267,10 +269,6 @@ static struct hda_codec_ops si3054_patch_ops = { .build_pcms = si3054_build_pcms, .init = si3054_init, .free = si3054_free, -#ifdef CONFIG_PM - //.suspend = si3054_suspend, - .resume = si3054_init, -#endif }; static int patch_si3054(struct hda_codec *codec) diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 87a36e9d654..145a5f3c063 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -874,16 +874,16 @@ static void stac92xx_enable_gpio_mask(struct hda_codec *codec) { struct sigmatel_spec *spec = codec->spec; /* Configure GPIOx as output */ - snd_hda_codec_write(codec, codec->afg, 0, - AC_VERB_SET_GPIO_DIRECTION, spec->gpio_mask); + snd_hda_codec_write_cache(codec, codec->afg, 0, + AC_VERB_SET_GPIO_DIRECTION, spec->gpio_mask); /* Configure GPIOx as CMOS */ - snd_hda_codec_write(codec, codec->afg, 0, 0x7e7, 0x00000000); + snd_hda_codec_write_cache(codec, codec->afg, 0, 0x7e7, 0x00000000); /* Assert GPIOx */ - snd_hda_codec_write(codec, codec->afg, 0, - AC_VERB_SET_GPIO_DATA, spec->gpio_data); + snd_hda_codec_write_cache(codec, codec->afg, 0, + AC_VERB_SET_GPIO_DATA, spec->gpio_data); /* Enable GPIOx */ - snd_hda_codec_write(codec, codec->afg, 0, - AC_VERB_SET_GPIO_MASK, spec->gpio_mask); + snd_hda_codec_write_cache(codec, codec->afg, 0, + AC_VERB_SET_GPIO_MASK, spec->gpio_mask); } /* @@ -1082,7 +1082,8 @@ static unsigned int stac92xx_get_vref(struct hda_codec *codec, hda_nid_t nid) static void stac92xx_auto_set_pinctl(struct hda_codec *codec, hda_nid_t nid, int pin_type) { - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type); + snd_hda_codec_write_cache(codec, nid, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type); } #define stac92xx_io_switch_info snd_ctl_boolean_mono_info @@ -1291,8 +1292,8 @@ static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec, spec->multiout.num_dacs++; if (conn_len > 1) { /* select this DAC in the pin's input mux */ - snd_hda_codec_write(codec, nid, 0, - AC_VERB_SET_CONNECT_SEL, j); + snd_hda_codec_write_cache(codec, nid, 0, + AC_VERB_SET_CONNECT_SEL, j); } } @@ -1545,9 +1546,9 @@ static int stac92xx_auto_create_analog_input_ctls(struct hda_codec *codec, const * NID lists. Hopefully this won't get confused. */ for (i = 0; i < spec->num_muxes; i++) { - snd_hda_codec_write(codec, spec->mux_nids[i], 0, - AC_VERB_SET_CONNECT_SEL, - imux->items[0].index); + snd_hda_codec_write_cache(codec, spec->mux_nids[i], 0, + AC_VERB_SET_CONNECT_SEL, + imux->items[0].index); } } @@ -1879,7 +1880,7 @@ static void stac92xx_set_pinctl(struct hda_codec *codec, hda_nid_t nid, if (flag & (AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN)) pin_ctl &= ~(AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN); - snd_hda_codec_write(codec, nid, 0, + snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_ctl | flag); } @@ -1889,7 +1890,7 @@ static void stac92xx_reset_pinctl(struct hda_codec *codec, hda_nid_t nid, { unsigned int pin_ctl = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00); - snd_hda_codec_write(codec, nid, 0, + snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_ctl & ~flag); } @@ -1948,21 +1949,10 @@ static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res) #ifdef CONFIG_PM static int stac92xx_resume(struct hda_codec *codec) { - struct sigmatel_spec *spec = codec->spec; - int i; - stac92xx_set_config_regs(codec); - if (spec->gpio_mask && spec->gpio_data) - stac92xx_enable_gpio_mask(codec); stac92xx_init(codec); - snd_hda_resume_ctls(codec, spec->mixer); - for (i = 0; i < spec->num_mixers; i++) - snd_hda_resume_ctls(codec, spec->mixers[i]); - if (spec->multiout.dig_out_nid) - snd_hda_resume_spdif_out(codec); - if (spec->dig_in_nid) - snd_hda_resume_spdif_in(codec); - + snd_hda_codec_resume_amp(codec); + snd_hda_codec_resume_cache(codec); return 0; } #endif diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index ba32d1e52cb..6c734f07e5b 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c @@ -543,27 +543,6 @@ static int via_init(struct hda_codec *codec) return 0; } -#ifdef CONFIG_PM -/* - * resume - */ -static int via_resume(struct hda_codec *codec) -{ - struct via_spec *spec = codec->spec; - int i; - - via_init(codec); - for (i = 0; i < spec->num_mixers; i++) - snd_hda_resume_ctls(codec, spec->mixers[i]); - if (spec->multiout.dig_out_nid) - snd_hda_resume_spdif_out(codec); - if (spec->dig_in_nid) - snd_hda_resume_spdif_in(codec); - - return 0; -} -#endif - /* */ static struct hda_codec_ops via_patch_ops = { @@ -571,9 +550,6 @@ static struct hda_codec_ops via_patch_ops = { .build_pcms = via_build_pcms, .init = via_init, .free = via_free, -#ifdef CONFIG_PM - .resume = via_resume, -#endif }; /* fill in the dac_nids table from the parsed pin configuration */ -- cgit v1.2.3 From 47fd830acf0b6b5bc75db55d0f2cc64f59a23b5f Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 10 Aug 2007 17:11:07 +0200 Subject: [ALSA] hda-codec - add snd_hda_codec_stereo() function Added snd_hda_codec_amp_stereo() function that changes both of stereo channels with the same mask and value bits. It simplifies most of amp-handling codes. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/hda_codec.c | 38 +++-- sound/pci/hda/hda_generic.c | 8 +- sound/pci/hda/hda_local.h | 7 + sound/pci/hda/patch_analog.c | 21 ++- sound/pci/hda/patch_conexant.c | 66 ++++----- sound/pci/hda/patch_realtek.c | 325 +++++++++++++++-------------------------- sound/pci/hda/patch_sigmatel.c | 18 ++- 7 files changed, 205 insertions(+), 278 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 1d31da47bc9..04352930867 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -842,6 +842,19 @@ int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch, return 1; } +/* + * update the AMP stereo with the same mask and value + */ +int snd_hda_codec_amp_stereo(struct hda_codec *codec, hda_nid_t nid, + int direction, int idx, int mask, int val) +{ + int ch, ret = 0; + for (ch = 0; ch < 2; ch++) + ret |= snd_hda_codec_amp_update(codec, nid, ch, direction, + idx, mask, val); + return ret; +} + #ifdef CONFIG_PM /* resume the all amp commands from the cache */ void snd_hda_codec_resume_amp(struct hda_codec *codec) @@ -913,9 +926,11 @@ int snd_hda_mixer_amp_volume_get(struct snd_kcontrol *kcontrol, long *valp = ucontrol->value.integer.value; if (chs & 1) - *valp++ = snd_hda_codec_amp_read(codec, nid, 0, dir, idx) & 0x7f; + *valp++ = snd_hda_codec_amp_read(codec, nid, 0, dir, idx) + & HDA_AMP_VOLMASK; if (chs & 2) - *valp = snd_hda_codec_amp_read(codec, nid, 1, dir, idx) & 0x7f; + *valp = snd_hda_codec_amp_read(codec, nid, 1, dir, idx) + & HDA_AMP_VOLMASK; return 0; } @@ -992,10 +1007,10 @@ int snd_hda_mixer_amp_switch_get(struct snd_kcontrol *kcontrol, if (chs & 1) *valp++ = (snd_hda_codec_amp_read(codec, nid, 0, dir, idx) & - 0x80) ? 0 : 1; + HDA_AMP_MUTE) ? 0 : 1; if (chs & 2) *valp = (snd_hda_codec_amp_read(codec, nid, 1, dir, idx) & - 0x80) ? 0 : 1; + HDA_AMP_MUTE) ? 0 : 1; return 0; } @@ -1012,12 +1027,14 @@ int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol, if (chs & 1) { change = snd_hda_codec_amp_update(codec, nid, 0, dir, idx, - 0x80, *valp ? 0 : 0x80); + HDA_AMP_MUTE, + *valp ? 0 : HDA_AMP_MUTE); valp++; } if (chs & 2) change |= snd_hda_codec_amp_update(codec, nid, 1, dir, idx, - 0x80, *valp ? 0 : 0x80); + HDA_AMP_MUTE, + *valp ? 0 : HDA_AMP_MUTE); return change; } @@ -1318,12 +1335,9 @@ static int snd_hda_spdif_out_switch_put(struct snd_kcontrol *kcontrol, val & 0xff); /* unmute amp switch (if any) */ if ((get_wcaps(codec, nid) & AC_WCAP_OUT_AMP) && - (val & AC_DIG1_ENABLE)) { - snd_hda_codec_amp_update(codec, nid, 0, HDA_OUTPUT, 0, - 0x80, 0x00); - snd_hda_codec_amp_update(codec, nid, 1, HDA_OUTPUT, 0, - 0x80, 0x00); - } + (val & AC_DIG1_ENABLE)) + snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, + HDA_AMP_MUTE, 0); } mutex_unlock(&codec->spdif_mutex); return change; diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c index d5f1180115c..91cd9b9ea5d 100644 --- a/sound/pci/hda/hda_generic.c +++ b/sound/pci/hda/hda_generic.c @@ -218,8 +218,7 @@ static int unmute_output(struct hda_codec *codec, struct hda_gnode *node) ofs = (node->amp_out_caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT; if (val >= ofs) val -= ofs; - snd_hda_codec_amp_update(codec, node->nid, 0, HDA_OUTPUT, 0, 0xff, val); - snd_hda_codec_amp_update(codec, node->nid, 0, HDA_OUTPUT, 1, 0xff, val); + snd_hda_codec_amp_stereo(codec, node->nid, HDA_OUTPUT, 0, 0xff, val); return 0; } @@ -234,10 +233,7 @@ static int unmute_input(struct hda_codec *codec, struct hda_gnode *node, unsigne ofs = (node->amp_in_caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT; if (val >= ofs) val -= ofs; - snd_hda_codec_amp_update(codec, node->nid, 0, HDA_INPUT, index, - 0xff, val); - snd_hda_codec_amp_update(codec, node->nid, 1, HDA_INPUT, index, - 0xff, val); + snd_hda_codec_amp_stereo(codec, node->nid, HDA_INPUT, index, 0xff, val); return 0; } diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h index 8dec32cfdf5..35ea0cf37a2 100644 --- a/sound/pci/hda/hda_local.h +++ b/sound/pci/hda/hda_local.h @@ -84,10 +84,17 @@ int snd_hda_codec_amp_read(struct hda_codec *codec, hda_nid_t nid, int ch, int direction, int index); int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch, int direction, int idx, int mask, int val); +int snd_hda_codec_amp_stereo(struct hda_codec *codec, hda_nid_t nid, + int dir, int idx, int mask, int val); #ifdef CONFIG_PM void snd_hda_codec_resume_amp(struct hda_codec *codec); #endif +/* amp value bits */ +#define HDA_AMP_MUTE 0x80 +#define HDA_AMP_UNMUTE 0x00 +#define HDA_AMP_VOLMASK 0x7f + /* mono switch binding multiple inputs */ #define HDA_BIND_MUTE_MONO(xname, nid, channel, indices, direction) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index f20ddd85db2..febc2053f08 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c @@ -1120,10 +1120,9 @@ static int ad1981_hp_master_sw_put(struct snd_kcontrol *kcontrol, return 0; /* toggle HP mute appropriately */ - snd_hda_codec_amp_update(codec, 0x06, 0, HDA_OUTPUT, 0, - 0x80, spec->cur_eapd ? 0 : 0x80); - snd_hda_codec_amp_update(codec, 0x06, 1, HDA_OUTPUT, 0, - 0x80, spec->cur_eapd ? 0 : 0x80); + snd_hda_codec_amp_stereo(codec, 0x06, HDA_OUTPUT, 0, + HDA_AMP_MUTE, + spec->cur_eapd ? 0 : HDA_AMP_MUTE); return 1; } @@ -1136,13 +1135,13 @@ static int ad1981_hp_master_vol_put(struct snd_kcontrol *kcontrol, int change; change = snd_hda_codec_amp_update(codec, 0x05, 0, HDA_OUTPUT, 0, - 0x7f, valp[0] & 0x7f); + HDA_AMP_VOLMASK, valp[0]); change |= snd_hda_codec_amp_update(codec, 0x05, 1, HDA_OUTPUT, 0, - 0x7f, valp[1] & 0x7f); + HDA_AMP_VOLMASK, valp[1]); snd_hda_codec_amp_update(codec, 0x06, 0, HDA_OUTPUT, 0, - 0x7f, valp[0] & 0x7f); + HDA_AMP_VOLMASK, valp[0]); snd_hda_codec_amp_update(codec, 0x06, 1, HDA_OUTPUT, 0, - 0x7f, valp[1] & 0x7f); + HDA_AMP_VOLMASK, valp[1]); return change; } @@ -1153,10 +1152,8 @@ static void ad1981_hp_automute(struct hda_codec *codec) present = snd_hda_codec_read(codec, 0x06, 0, AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; - snd_hda_codec_amp_update(codec, 0x05, 0, HDA_OUTPUT, 0, - 0x80, present ? 0x80 : 0); - snd_hda_codec_amp_update(codec, 0x05, 1, HDA_OUTPUT, 0, - 0x80, present ? 0x80 : 0); + snd_hda_codec_amp_stereo(codec, 0x05, HDA_OUTPUT, 0, + HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); } /* toggle input of built-in and mic jack appropriately */ diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index f1b6d0eda14..ebf83275756 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -472,13 +472,13 @@ static int cxt5045_hp_master_sw_put(struct snd_kcontrol *kcontrol, /* toggle internal speakers mute depending of presence of * the headphone jack */ - bits = (!spec->hp_present && spec->cur_eapd) ? 0 : 0x80; - snd_hda_codec_amp_update(codec, 0x10, 0, HDA_OUTPUT, 0, 0x80, bits); - snd_hda_codec_amp_update(codec, 0x10, 1, HDA_OUTPUT, 0, 0x80, bits); + bits = (!spec->hp_present && spec->cur_eapd) ? 0 : HDA_AMP_MUTE; + snd_hda_codec_amp_stereo(codec, 0x10, HDA_OUTPUT, 0, + HDA_AMP_MUTE, bits); - bits = spec->cur_eapd ? 0 : 0x80; - snd_hda_codec_amp_update(codec, 0x11, 0, HDA_OUTPUT, 0, 0x80, bits); - snd_hda_codec_amp_update(codec, 0x11, 1, HDA_OUTPUT, 0, 0x80, bits); + bits = spec->cur_eapd ? 0 : HDA_AMP_MUTE; + snd_hda_codec_amp_stereo(codec, 0x11, HDA_OUTPUT, 0, + HDA_AMP_MUTE, bits); return 1; } @@ -491,13 +491,13 @@ static int cxt5045_hp_master_vol_put(struct snd_kcontrol *kcontrol, int change; change = snd_hda_codec_amp_update(codec, 0x10, 0, HDA_OUTPUT, 0, - 0x7f, valp[0] & 0x7f); + HDA_AMP_VOLMASK, valp[0]); change |= snd_hda_codec_amp_update(codec, 0x10, 1, HDA_OUTPUT, 0, - 0x7f, valp[1] & 0x7f); + HDA_AMP_VOLMASK, valp[1]); snd_hda_codec_amp_update(codec, 0x11, 0, HDA_OUTPUT, 0, - 0x7f, valp[0] & 0x7f); + HDA_AMP_VOLMASK, valp[0]); snd_hda_codec_amp_update(codec, 0x11, 1, HDA_OUTPUT, 0, - 0x7f, valp[1] & 0x7f); + HDA_AMP_VOLMASK, valp[1]); return change; } @@ -534,9 +534,9 @@ static void cxt5045_hp_automute(struct hda_codec *codec) spec->hp_present = snd_hda_codec_read(codec, 0x11, 0, AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; - bits = (spec->hp_present || !spec->cur_eapd) ? 0x80 : 0; - snd_hda_codec_amp_update(codec, 0x10, 0, HDA_OUTPUT, 0, 0x80, bits); - snd_hda_codec_amp_update(codec, 0x10, 1, HDA_OUTPUT, 0, 0x80, bits); + bits = (spec->hp_present || !spec->cur_eapd) ? HDA_AMP_MUTE : 0; + snd_hda_codec_amp_stereo(codec, 0x10, HDA_OUTPUT, 0, + HDA_AMP_MUTE, bits); } /* unsolicited event for HP jack sensing */ @@ -887,12 +887,12 @@ static int cxt5047_hp_master_sw_put(struct snd_kcontrol *kcontrol, /* toggle internal speakers mute depending of presence of * the headphone jack */ - bits = (!spec->hp_present && spec->cur_eapd) ? 0 : 0x80; - snd_hda_codec_amp_update(codec, 0x1d, 0, HDA_OUTPUT, 0, 0x80, bits); - snd_hda_codec_amp_update(codec, 0x1d, 1, HDA_OUTPUT, 0, 0x80, bits); - bits = spec->cur_eapd ? 0 : 0x80; - snd_hda_codec_amp_update(codec, 0x13, 0, HDA_OUTPUT, 0, 0x80, bits); - snd_hda_codec_amp_update(codec, 0x13, 1, HDA_OUTPUT, 0, 0x80, bits); + bits = (!spec->hp_present && spec->cur_eapd) ? 0 : HDA_AMP_MUTE; + snd_hda_codec_amp_stereo(codec, 0x1d, HDA_OUTPUT, 0, + HDA_AMP_MUTE, bits); + bits = spec->cur_eapd ? 0 : HDA_AMP_MUTE; + snd_hda_codec_amp_stereo(codec, 0x13, HDA_OUTPUT, 0, + HDA_AMP_MUTE, bits); return 1; } @@ -905,13 +905,13 @@ static int cxt5047_hp_master_vol_put(struct snd_kcontrol *kcontrol, int change; change = snd_hda_codec_amp_update(codec, 0x1d, 0, HDA_OUTPUT, 0, - 0x7f, valp[0] & 0x7f); + HDA_AMP_VOLMASK, valp[0]); change |= snd_hda_codec_amp_update(codec, 0x1d, 1, HDA_OUTPUT, 0, - 0x7f, valp[1] & 0x7f); + HDA_AMP_VOLMASK, valp[1]); snd_hda_codec_amp_update(codec, 0x13, 0, HDA_OUTPUT, 0, - 0x7f, valp[0] & 0x7f); + HDA_AMP_VOLMASK, valp[0]); snd_hda_codec_amp_update(codec, 0x13, 1, HDA_OUTPUT, 0, - 0x7f, valp[1] & 0x7f); + HDA_AMP_VOLMASK, valp[1]); return change; } @@ -924,12 +924,12 @@ static void cxt5047_hp_automute(struct hda_codec *codec) spec->hp_present = snd_hda_codec_read(codec, 0x13, 0, AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; - bits = (spec->hp_present || !spec->cur_eapd) ? 0x80 : 0; - snd_hda_codec_amp_update(codec, 0x1d, 0, HDA_OUTPUT, 0, 0x80, bits); - snd_hda_codec_amp_update(codec, 0x1d, 1, HDA_OUTPUT, 0, 0x80, bits); + bits = (spec->hp_present || !spec->cur_eapd) ? HDA_AMP_MUTE : 0; + snd_hda_codec_amp_stereo(codec, 0x1d, HDA_OUTPUT, 0, + HDA_AMP_MUTE, bits); /* Mute/Unmute PCM 2 for good measure - some systems need this */ - snd_hda_codec_amp_update(codec, 0x1c, 0, HDA_OUTPUT, 0, 0x80, bits); - snd_hda_codec_amp_update(codec, 0x1c, 1, HDA_OUTPUT, 0, 0x80, bits); + snd_hda_codec_amp_stereo(codec, 0x1c, HDA_OUTPUT, 0, + HDA_AMP_MUTE, bits); } /* mute internal speaker if HP is plugged */ @@ -941,12 +941,12 @@ static void cxt5047_hp2_automute(struct hda_codec *codec) spec->hp_present = snd_hda_codec_read(codec, 0x13, 0, AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; - bits = spec->hp_present ? 0x80 : 0; - snd_hda_codec_amp_update(codec, 0x1d, 0, HDA_OUTPUT, 0, 0x80, bits); - snd_hda_codec_amp_update(codec, 0x1d, 1, HDA_OUTPUT, 0, 0x80, bits); + bits = spec->hp_present ? HDA_AMP_MUTE : 0; + snd_hda_codec_amp_stereo(codec, 0x1d, HDA_OUTPUT, 0, + HDA_AMP_MUTE, bits); /* Mute/Unmute PCM 2 for good measure - some systems need this */ - snd_hda_codec_amp_update(codec, 0x1c, 0, HDA_OUTPUT, 0, 0x80, bits); - snd_hda_codec_amp_update(codec, 0x1c, 1, HDA_OUTPUT, 0, 0x80, bits); + snd_hda_codec_amp_stereo(codec, 0x1c, HDA_OUTPUT, 0, + HDA_AMP_MUTE, bits); } /* toggle input of built-in and mic jack appropriately */ diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 63011133e3f..29119fd4017 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -457,23 +457,15 @@ static int alc_pin_mode_put(struct snd_kcontrol *kcontrol, * this turns out to be necessary in the future. */ if (val <= 2) { - snd_hda_codec_amp_update(codec, nid, 0, HDA_OUTPUT, 0, - 0x80, 0x80); - snd_hda_codec_amp_update(codec, nid, 1, HDA_OUTPUT, 0, - 0x80, 0x80); - snd_hda_codec_amp_update(codec, nid, 0, HDA_INPUT, 0, - 0x80, 0x00); - snd_hda_codec_amp_update(codec, nid, 1, HDA_INPUT, 0, - 0x80, 0x00); + snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, + HDA_AMP_MUTE, HDA_AMP_MUTE); + snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0, + HDA_AMP_MUTE, 0); } else { - snd_hda_codec_amp_update(codec, nid, 0, HDA_INPUT, 0, - 0x80, 0x80); - snd_hda_codec_amp_update(codec, nid, 1, HDA_INPUT, 0, - 0x80, 0x80); - snd_hda_codec_amp_update(codec, nid, 0, HDA_OUTPUT, 0, - 0x80, 0x00); - snd_hda_codec_amp_update(codec, nid, 1, HDA_OUTPUT, 0, - 0x80, 0x00); + snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0, + HDA_AMP_MUTE, HDA_AMP_MUTE); + snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, + HDA_AMP_MUTE, 0); } } return change; @@ -1559,15 +1551,11 @@ static void alc880_uniwill_hp_automute(struct hda_codec *codec) present = snd_hda_codec_read(codec, 0x14, 0, AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; - bits = present ? 0x80 : 0; - snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0, - 0x80, bits); - snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0, - 0x80, bits); - snd_hda_codec_amp_update(codec, 0x16, 0, HDA_OUTPUT, 0, - 0x80, bits); - snd_hda_codec_amp_update(codec, 0x16, 1, HDA_OUTPUT, 0, - 0x80, bits); + bits = present ? HDA_AMP_MUTE : 0; + snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, + HDA_AMP_MUTE, bits); + snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0, + HDA_AMP_MUTE, bits); } /* auto-toggle front mic */ @@ -1578,11 +1566,8 @@ static void alc880_uniwill_mic_automute(struct hda_codec *codec) present = snd_hda_codec_read(codec, 0x18, 0, AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; - bits = present ? 0x80 : 0; - snd_hda_codec_amp_update(codec, 0x0b, 0, HDA_INPUT, 1, - 0x80, bits); - snd_hda_codec_amp_update(codec, 0x0b, 1, HDA_INPUT, 1, - 0x80, bits); + bits = present ? HDA_AMP_MUTE : 0; + snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits); } static void alc880_uniwill_automute(struct hda_codec *codec) @@ -1614,11 +1599,8 @@ static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec) present = snd_hda_codec_read(codec, 0x14, 0, AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; - bits = present ? 0x80 : 0; - snd_hda_codec_amp_update(codec, 0x15, 0, HDA_INPUT, 0, - 0x80, bits); - snd_hda_codec_amp_update(codec, 0x15, 1, HDA_INPUT, 0, - 0x80, bits); + bits = present ? HDA_AMP_MUTE : 0; + snd_hda_codec_amp_stereo(codec, 0x15, HDA_INPUT, 0, HDA_AMP_MUTE, bits); } static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec) @@ -1626,19 +1608,14 @@ static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec) unsigned int present; present = snd_hda_codec_read(codec, 0x21, 0, - AC_VERB_GET_VOLUME_KNOB_CONTROL, 0) & 0x7f; - - snd_hda_codec_amp_update(codec, 0x0c, 0, HDA_OUTPUT, 0, - 0x7f, present); - snd_hda_codec_amp_update(codec, 0x0c, 1, HDA_OUTPUT, 0, - 0x7f, present); - - snd_hda_codec_amp_update(codec, 0x0d, 0, HDA_OUTPUT, 0, - 0x7f, present); - snd_hda_codec_amp_update(codec, 0x0d, 1, HDA_OUTPUT, 0, - 0x7f, present); - + AC_VERB_GET_VOLUME_KNOB_CONTROL, 0); + present &= HDA_AMP_VOLMASK; + snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0, + HDA_AMP_VOLMASK, present); + snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0, + HDA_AMP_VOLMASK, present); } + static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec, unsigned int res) { @@ -1891,11 +1868,9 @@ static void alc880_lg_automute(struct hda_codec *codec) present = snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; - bits = present ? 0x80 : 0; - snd_hda_codec_amp_update(codec, 0x17, 0, HDA_OUTPUT, 0, - 0x80, bits); - snd_hda_codec_amp_update(codec, 0x17, 1, HDA_OUTPUT, 0, - 0x80, bits); + bits = present ? HDA_AMP_MUTE : 0; + snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0, + HDA_AMP_MUTE, bits); } static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res) @@ -1990,11 +1965,9 @@ static void alc880_lg_lw_automute(struct hda_codec *codec) present = snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; - bits = present ? 0x80 : 0; - snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0, - 0x80, bits); - snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0, - 0x80, bits); + bits = present ? HDA_AMP_MUTE : 0; + snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, + HDA_AMP_MUTE, bits); } static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res) @@ -2363,11 +2336,10 @@ static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol, snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, new_ctl); - val = ucontrol->value.enumerated.item[0] >= 3 ? 0x80 : 0x00; - snd_hda_codec_amp_update(codec, nid, 0, HDA_OUTPUT, 0, - 0x80, val); - snd_hda_codec_amp_update(codec, nid, 1, HDA_OUTPUT, 0, - 0x80, val); + val = ucontrol->value.enumerated.item[0] >= 3 ? + HDA_AMP_MUTE : 0; + snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, + HDA_AMP_MUTE, val); return 1; } return 0; @@ -4791,13 +4763,10 @@ static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol, if (*cur_val == idx) return 0; for (i = 0; i < imux->num_items; i++) { - unsigned int v = (i == idx) ? 0x00 : 0x80; - snd_hda_codec_amp_update(codec, nid, 0, HDA_INPUT, - imux->items[i].index, - 0x80, v); - snd_hda_codec_amp_update(codec, nid, 1, HDA_INPUT, + unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE; + snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, imux->items[i].index, - 0x80, v); + HDA_AMP_MUTE, v); } *cur_val = idx; return 1; @@ -5134,14 +5103,10 @@ static void alc885_imac24_automute(struct hda_codec *codec) present = snd_hda_codec_read(codec, 0x14, 0, AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; - snd_hda_codec_amp_update(codec, 0x18, 0, HDA_OUTPUT, 0, - 0x80, present ? 0x80 : 0); - snd_hda_codec_amp_update(codec, 0x18, 1, HDA_OUTPUT, 0, - 0x80, present ? 0x80 : 0); - snd_hda_codec_amp_update(codec, 0x1a, 0, HDA_OUTPUT, 0, - 0x80, present ? 0x80 : 0); - snd_hda_codec_amp_update(codec, 0x1a, 1, HDA_OUTPUT, 0, - 0x80, present ? 0x80 : 0); + snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0, + HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); + snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0, + HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); } /* Processes unsolicited events. */ @@ -5178,10 +5143,8 @@ static void alc882_targa_automute(struct hda_codec *codec) present = snd_hda_codec_read(codec, 0x14, 0, AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; - snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0, - 0x80, present ? 0x80 : 0); - snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0, - 0x80, present ? 0x80 : 0); + snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0, + HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA, present ? 1 : 3); } @@ -5776,13 +5739,10 @@ static int alc883_mux_enum_put(struct snd_kcontrol *kcontrol, if (*cur_val == idx) return 0; for (i = 0; i < imux->num_items; i++) { - unsigned int v = (i == idx) ? 0x00 : 0x80; - snd_hda_codec_amp_update(codec, nid, 0, HDA_INPUT, + unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE; + snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, imux->items[i].index, - 0x80, v); - snd_hda_codec_amp_update(codec, nid, 1, HDA_INPUT, - imux->items[i].index, - 0x80, v); + HDA_AMP_MUTE, v); } *cur_val = idx; return 1; @@ -6421,15 +6381,10 @@ static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec) present = snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; - snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0, - 0x80, present ? 0x80 : 0); - snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0, - 0x80, present ? 0x80 : 0); - snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0, - 0x80, present ? 0x80 : 0); - snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0, - 0x80, present ? 0x80 : 0); - + snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, + HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); + snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, + HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); } /* toggle RCA according to the front-jack state */ @@ -6439,12 +6394,10 @@ static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec) present = snd_hda_codec_read(codec, 0x14, 0, AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; - snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0, - 0x80, present ? 0x80 : 0); - snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0, - 0x80, present ? 0x80 : 0); - + snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, + HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); } + static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec, unsigned int res) { @@ -6483,10 +6436,8 @@ static void alc883_medion_md2_automute(struct hda_codec *codec) present = snd_hda_codec_read(codec, 0x14, 0, AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; - snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0, - 0x80, present ? 0x80 : 0); - snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0, - 0x80, present ? 0x80 : 0); + snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, + HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); } static void alc883_medion_md2_unsol_event(struct hda_codec *codec, @@ -6504,11 +6455,9 @@ static void alc883_tagra_automute(struct hda_codec *codec) present = snd_hda_codec_read(codec, 0x14, 0, AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; - bits = present ? 0x80 : 0; - snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0, - 0x80, bits); - snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0, - 0x80, bits); + bits = present ? HDA_AMP_MUTE : 0; + snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0, + HDA_AMP_MUTE, bits); snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA, present ? 1 : 3); } @@ -6526,11 +6475,9 @@ static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec) present = snd_hda_codec_read(codec, 0x14, 0, AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; - bits = present ? 0x80 : 0; - snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0, - 0x80, bits); - snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0, - 0x80, bits); + bits = present ? HDA_AMP_MUTE : 0; + snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, + HDA_AMP_MUTE, bits); } static void alc883_lenovo_101e_all_automute(struct hda_codec *codec) @@ -6540,15 +6487,11 @@ static void alc883_lenovo_101e_all_automute(struct hda_codec *codec) present = snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; - bits = present ? 0x80 : 0; - snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0, - 0x80, bits); - snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0, - 0x80, bits); - snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0, - 0x80, bits); - snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0, - 0x80, bits); + bits = present ? HDA_AMP_MUTE : 0; + snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, + HDA_AMP_MUTE, bits); + snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, + HDA_AMP_MUTE, bits); } static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec, @@ -7347,18 +7290,13 @@ static void alc262_hippo_automute(struct hda_codec *codec) spec->jack_present = (present & 0x80000000) != 0; if (spec->jack_present) { /* mute internal speaker */ - snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0, - 0x80, 0x80); - snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0, - 0x80, 0x80); + snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, + HDA_AMP_MUTE, HDA_AMP_MUTE); } else { /* unmute internal speaker if necessary */ mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0); - snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0, - 0x80, mute & 0x80); - mute = snd_hda_codec_amp_read(codec, 0x15, 1, HDA_OUTPUT, 0); - snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0, - 0x80, mute & 0x80); + snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, + HDA_AMP_MUTE, mute); } } @@ -7382,18 +7320,13 @@ static void alc262_hippo1_automute(struct hda_codec *codec) present = (present & 0x80000000) != 0; if (present) { /* mute internal speaker */ - snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0, - 0x80, 0x80); - snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0, - 0x80, 0x80); + snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, + HDA_AMP_MUTE, HDA_AMP_MUTE); } else { /* unmute internal speaker if necessary */ mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0); - snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0, - 0x80, mute & 0x80); - mute = snd_hda_codec_amp_read(codec, 0x1b, 1, HDA_OUTPUT, 0); - snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0, - 0x80, mute & 0x80); + snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, + HDA_AMP_MUTE, mute); } } @@ -7455,18 +7388,13 @@ static void alc262_fujitsu_automute(struct hda_codec *codec, int force) } if (spec->jack_present) { /* mute internal speaker */ - snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0, - 0x80, 0x80); - snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0, - 0x80, 0x80); + snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, + HDA_AMP_MUTE, HDA_AMP_MUTE); } else { /* unmute internal speaker if necessary */ mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0); - snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0, - 0x80, mute & 0x80); - mute = snd_hda_codec_amp_read(codec, 0x14, 1, HDA_OUTPUT, 0); - snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0, - 0x80, mute & 0x80); + snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, + HDA_AMP_MUTE, mute); } } @@ -7488,13 +7416,13 @@ static int alc262_fujitsu_master_vol_put(struct snd_kcontrol *kcontrol, int change; change = snd_hda_codec_amp_update(codec, 0x0c, 0, HDA_OUTPUT, 0, - 0x7f, valp[0] & 0x7f); + HDA_AMP_VOLMASK, valp[0]); change |= snd_hda_codec_amp_update(codec, 0x0c, 1, HDA_OUTPUT, 0, - 0x7f, valp[1] & 0x7f); + HDA_AMP_VOLMASK, valp[1]); snd_hda_codec_amp_update(codec, 0x0d, 0, HDA_OUTPUT, 0, - 0x7f, valp[0] & 0x7f); + HDA_AMP_VOLMASK, valp[0]); snd_hda_codec_amp_update(codec, 0x0d, 1, HDA_OUTPUT, 0, - 0x7f, valp[1] & 0x7f); + HDA_AMP_VOLMASK, valp[1]); return change; } @@ -7507,9 +7435,11 @@ static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol, int change; change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0, - 0x80, valp[0] ? 0 : 0x80); + HDA_AMP_MUTE, + valp[0] ? 0 : HDA_AMP_MUTE); change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0, - 0x80, valp[1] ? 0 : 0x80); + HDA_AMP_MUTE, + valp[1] ? 0 : HDA_AMP_MUTE); if (change) alc262_fujitsu_automute(codec, 0); return change; @@ -8331,11 +8261,10 @@ static int alc268_mux_enum_put(struct snd_kcontrol *kcontrol, if (*cur_val == idx) return 0; for (i = 0; i < imux->num_items; i++) { - unsigned int v = (i == idx) ? 0x00 : 0x80; - snd_hda_codec_amp_update(codec, nid, 0, HDA_INPUT, - imux->items[i].index, 0x80, v); - snd_hda_codec_amp_update(codec, nid, 1, HDA_INPUT, - imux->items[i].index, 0x80, v); + unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE; + snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, + imux->items[i].index, + HDA_AMP_MUTE, v); snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx ); @@ -9328,14 +9257,10 @@ static void alc861_toshiba_automute(struct hda_codec *codec) present = snd_hda_codec_read(codec, 0x0f, 0, AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; - snd_hda_codec_amp_update(codec, 0x16, 0, HDA_INPUT, 0, - 0x80, present ? 0x80 : 0); - snd_hda_codec_amp_update(codec, 0x16, 1, HDA_INPUT, 0, - 0x80, present ? 0x80 : 0); - snd_hda_codec_amp_update(codec, 0x1a, 0, HDA_INPUT, 3, - 0x80, present ? 0 : 0x80); - snd_hda_codec_amp_update(codec, 0x1a, 1, HDA_INPUT, 3, - 0x80, present ? 0 : 0x80); + snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0, + HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); + snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3, + HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE); } static void alc861_toshiba_unsol_event(struct hda_codec *codec, @@ -9922,11 +9847,10 @@ static int alc861vd_mux_enum_put(struct snd_kcontrol *kcontrol, if (*cur_val == idx) return 0; for (i = 0; i < imux->num_items; i++) { - unsigned int v = (i == idx) ? 0x00 : 0x80; - snd_hda_codec_amp_update(codec, nid, 0, HDA_INPUT, - imux->items[i].index, 0x80, v); - snd_hda_codec_amp_update(codec, nid, 1, HDA_INPUT, - imux->items[i].index, 0x80, v); + unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE; + snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, + imux->items[i].index, + HDA_AMP_MUTE, v); } *cur_val = idx; return 1; @@ -10261,11 +10185,9 @@ static void alc861vd_lenovo_hp_automute(struct hda_codec *codec) present = snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; - bits = present ? 0x80 : 0; - snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0, - 0x80, bits); - snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0, - 0x80, bits); + bits = present ? HDA_AMP_MUTE : 0; + snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, + HDA_AMP_MUTE, bits); } static void alc861vd_lenovo_mic_automute(struct hda_codec *codec) @@ -10275,11 +10197,9 @@ static void alc861vd_lenovo_mic_automute(struct hda_codec *codec) present = snd_hda_codec_read(codec, 0x18, 0, AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; - bits = present ? 0x80 : 0; - snd_hda_codec_amp_update(codec, 0x0b, 0, HDA_INPUT, 1, - 0x80, bits); - snd_hda_codec_amp_update(codec, 0x0b, 1, HDA_INPUT, 1, - 0x80, bits); + bits = present ? HDA_AMP_MUTE : 0; + snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, + HDA_AMP_MUTE, bits); } static void alc861vd_lenovo_automute(struct hda_codec *codec) @@ -10353,10 +10273,8 @@ static void alc861vd_dallas_automute(struct hda_codec *codec) present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; - snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0, - 0x80, present ? 0x80 : 0); - snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0, - 0x80, present ? 0x80 : 0); + snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, + HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); } static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int res) @@ -10855,11 +10773,10 @@ static int alc662_mux_enum_put(struct snd_kcontrol *kcontrol, if (*cur_val == idx) return 0; for (i = 0; i < imux->num_items; i++) { - unsigned int v = (i == idx) ? 0x00 : 0x80; - snd_hda_codec_amp_update(codec, nid, 0, HDA_INPUT, - imux->items[i].index, 0x80, v); - snd_hda_codec_amp_update(codec, nid, 1, HDA_INPUT, - imux->items[i].index, 0x80, v); + unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE; + snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, + imux->items[i].index, + HDA_AMP_MUTE, v); } *cur_val = idx; return 1; @@ -11204,11 +11121,9 @@ static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec) present = snd_hda_codec_read(codec, 0x14, 0, AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; - bits = present ? 0x80 : 0; - snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0, - 0x80, bits); - snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0, - 0x80, bits); + bits = present ? HDA_AMP_MUTE : 0; + snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, + HDA_AMP_MUTE, bits); } static void alc662_lenovo_101e_all_automute(struct hda_codec *codec) @@ -11218,15 +11133,11 @@ static void alc662_lenovo_101e_all_automute(struct hda_codec *codec) present = snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; - bits = present ? 0x80 : 0; - snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0, - 0x80, bits); - snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0, - 0x80, bits); - snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0, - 0x80, bits); - snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0, - 0x80, bits); + bits = present ? HDA_AMP_MUTE : 0; + snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, + HDA_AMP_MUTE, bits); + snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, + HDA_AMP_MUTE, bits); } static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec, diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 145a5f3c063..1690726c1e1 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -2408,13 +2408,13 @@ static int vaio_master_vol_put(struct snd_kcontrol *kcontrol, int change; change = snd_hda_codec_amp_update(codec, 0x02, 0, HDA_OUTPUT, 0, - 0x7f, valp[0] & 0x7f); + HDA_AMP_VOLMASK, valp[0]); change |= snd_hda_codec_amp_update(codec, 0x02, 1, HDA_OUTPUT, 0, - 0x7f, valp[1] & 0x7f); + HDA_AMP_VOLMASK, valp[1]); snd_hda_codec_amp_update(codec, 0x05, 0, HDA_OUTPUT, 0, - 0x7f, valp[0] & 0x7f); + HDA_AMP_VOLMASK, valp[0]); snd_hda_codec_amp_update(codec, 0x05, 1, HDA_OUTPUT, 0, - 0x7f, valp[1] & 0x7f); + HDA_AMP_VOLMASK, valp[1]); return change; } @@ -2427,13 +2427,15 @@ static int vaio_master_sw_put(struct snd_kcontrol *kcontrol, int change; change = snd_hda_codec_amp_update(codec, 0x02, 0, HDA_OUTPUT, 0, - 0x80, (valp[0] ? 0 : 0x80)); + HDA_AMP_MUTE, + (valp[0] ? 0 : HDA_AMP_MUTE)); change |= snd_hda_codec_amp_update(codec, 0x02, 1, HDA_OUTPUT, 0, - 0x80, (valp[1] ? 0 : 0x80)); + HDA_AMP_MUTE, + (valp[1] ? 0 : HDA_AMP_MUTE)); snd_hda_codec_amp_update(codec, 0x05, 0, HDA_OUTPUT, 0, - 0x80, (valp[0] ? 0 : 0x80)); + HDA_AMP_MUTE, (valp[0] ? 0 : HDA_AMP_MUTE)); snd_hda_codec_amp_update(codec, 0x05, 1, HDA_OUTPUT, 0, - 0x80, (valp[1] ? 0 : 0x80)); + HDA_AMP_MUTE, (valp[1] ? 0 : HDA_AMP_MUTE)); return change; } -- cgit v1.2.3 From cca3b3718ca96dca51daf1129ac03003bcede751 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 10 Aug 2007 17:12:15 +0200 Subject: [ALSA] hda-codec - Clean up bind-controls We have already a generic bind-control helper, so let's clean up the codes using it. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_analog.c | 34 +++++----------- sound/pci/hda/patch_conexant.c | 68 +++++++++----------------------- sound/pci/hda/patch_realtek.c | 35 +++++------------ sound/pci/hda/patch_sigmatel.c | 89 ++++++++++-------------------------------- 4 files changed, 56 insertions(+), 170 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index febc2053f08..f9390a544ea 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c @@ -1127,23 +1127,14 @@ static int ad1981_hp_master_sw_put(struct snd_kcontrol *kcontrol, } /* bind volumes of both NID 0x05 and 0x06 */ -static int ad1981_hp_master_vol_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - long *valp = ucontrol->value.integer.value; - int change; - - change = snd_hda_codec_amp_update(codec, 0x05, 0, HDA_OUTPUT, 0, - HDA_AMP_VOLMASK, valp[0]); - change |= snd_hda_codec_amp_update(codec, 0x05, 1, HDA_OUTPUT, 0, - HDA_AMP_VOLMASK, valp[1]); - snd_hda_codec_amp_update(codec, 0x06, 0, HDA_OUTPUT, 0, - HDA_AMP_VOLMASK, valp[0]); - snd_hda_codec_amp_update(codec, 0x06, 1, HDA_OUTPUT, 0, - HDA_AMP_VOLMASK, valp[1]); - return change; -} +static struct hda_bind_ctls ad1981_hp_bind_master_vol = { + .ops = &snd_hda_bind_vol, + .values = { + HDA_COMPOSE_AMP_VAL(0x05, 3, 0, HDA_OUTPUT), + HDA_COMPOSE_AMP_VAL(0x06, 3, 0, HDA_OUTPUT), + 0 + }, +}; /* mute internal speaker if HP is plugged */ static void ad1981_hp_automute(struct hda_codec *codec) @@ -1204,14 +1195,7 @@ static struct hda_input_mux ad1981_hp_capture_source = { }; static struct snd_kcontrol_new ad1981_hp_mixers[] = { - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Master Playback Volume", - .info = snd_hda_mixer_amp_volume_info, - .get = snd_hda_mixer_amp_volume_get, - .put = ad1981_hp_master_vol_put, - .private_value = HDA_COMPOSE_AMP_VAL(0x05, 3, 0, HDA_OUTPUT), - }, + HDA_BIND_VOL("Master Playback Volume", &ad1981_hp_bind_master_vol), { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Master Playback Switch", diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index ebf83275756..080e3001d9c 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -483,23 +483,14 @@ static int cxt5045_hp_master_sw_put(struct snd_kcontrol *kcontrol, } /* bind volumes of both NID 0x10 and 0x11 */ -static int cxt5045_hp_master_vol_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - long *valp = ucontrol->value.integer.value; - int change; - - change = snd_hda_codec_amp_update(codec, 0x10, 0, HDA_OUTPUT, 0, - HDA_AMP_VOLMASK, valp[0]); - change |= snd_hda_codec_amp_update(codec, 0x10, 1, HDA_OUTPUT, 0, - HDA_AMP_VOLMASK, valp[1]); - snd_hda_codec_amp_update(codec, 0x11, 0, HDA_OUTPUT, 0, - HDA_AMP_VOLMASK, valp[0]); - snd_hda_codec_amp_update(codec, 0x11, 1, HDA_OUTPUT, 0, - HDA_AMP_VOLMASK, valp[1]); - return change; -} +static struct hda_bind_ctls cxt5045_hp_bind_master_vol = { + .ops = &snd_hda_bind_vol, + .values = { + HDA_COMPOSE_AMP_VAL(0x10, 3, 0, HDA_OUTPUT), + HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT), + 0 + }, +}; /* toggle input of built-in and mic jack appropriately */ static void cxt5045_hp_automic(struct hda_codec *codec) @@ -567,14 +558,7 @@ static struct snd_kcontrol_new cxt5045_mixers[] = { HDA_CODEC_MUTE("Int Mic Switch", 0x1a, 0x01, HDA_INPUT), HDA_CODEC_VOLUME("Ext Mic Volume", 0x1a, 0x02, HDA_INPUT), HDA_CODEC_MUTE("Ext Mic Switch", 0x1a, 0x02, HDA_INPUT), - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Master Playback Volume", - .info = snd_hda_mixer_amp_volume_info, - .get = snd_hda_mixer_amp_volume_get, - .put = cxt5045_hp_master_vol_put, - .private_value = HDA_COMPOSE_AMP_VAL(0x10, 3, 0, HDA_OUTPUT), - }, + HDA_BIND_VOL("Master Playback Volume", &cxt5045_hp_bind_master_vol), { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Master Playback Switch", @@ -897,23 +881,14 @@ static int cxt5047_hp_master_sw_put(struct snd_kcontrol *kcontrol, } /* bind volumes of both NID 0x13 (Headphones) and 0x1d (Speakers) */ -static int cxt5047_hp_master_vol_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - long *valp = ucontrol->value.integer.value; - int change; - - change = snd_hda_codec_amp_update(codec, 0x1d, 0, HDA_OUTPUT, 0, - HDA_AMP_VOLMASK, valp[0]); - change |= snd_hda_codec_amp_update(codec, 0x1d, 1, HDA_OUTPUT, 0, - HDA_AMP_VOLMASK, valp[1]); - snd_hda_codec_amp_update(codec, 0x13, 0, HDA_OUTPUT, 0, - HDA_AMP_VOLMASK, valp[0]); - snd_hda_codec_amp_update(codec, 0x13, 1, HDA_OUTPUT, 0, - HDA_AMP_VOLMASK, valp[1]); - return change; -} +static struct hda_bind_ctls cxt5047_bind_master_vol = { + .ops = &snd_hda_bind_vol, + .values = { + HDA_COMPOSE_AMP_VAL(0x13, 3, 0, HDA_OUTPUT), + HDA_COMPOSE_AMP_VAL(0x1d, 3, 0, HDA_OUTPUT), + 0 + }, +}; /* mute internal speaker if HP is plugged */ static void cxt5047_hp_automute(struct hda_codec *codec) @@ -1035,14 +1010,7 @@ static struct snd_kcontrol_new cxt5047_toshiba_mixers[] = { HDA_CODEC_MUTE("Capture Switch", 0x12, 0x03, HDA_INPUT), HDA_CODEC_VOLUME("PCM Volume", 0x10, 0x00, HDA_OUTPUT), HDA_CODEC_MUTE("PCM Switch", 0x10, 0x00, HDA_OUTPUT), - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Master Playback Volume", - .info = snd_hda_mixer_amp_volume_info, - .get = snd_hda_mixer_amp_volume_get, - .put = cxt5047_hp_master_vol_put, - .private_value = HDA_COMPOSE_AMP_VAL(0x13, 3, 0, HDA_OUTPUT), - }, + HDA_BIND_VOL("Master Playback Volume", &cxt5047_bind_master_vol), { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Master Playback Switch", diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 29119fd4017..ebbabeb3293 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -7408,23 +7408,14 @@ static void alc262_fujitsu_unsol_event(struct hda_codec *codec, } /* bind volumes of both NID 0x0c and 0x0d */ -static int alc262_fujitsu_master_vol_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - long *valp = ucontrol->value.integer.value; - int change; - - change = snd_hda_codec_amp_update(codec, 0x0c, 0, HDA_OUTPUT, 0, - HDA_AMP_VOLMASK, valp[0]); - change |= snd_hda_codec_amp_update(codec, 0x0c, 1, HDA_OUTPUT, 0, - HDA_AMP_VOLMASK, valp[1]); - snd_hda_codec_amp_update(codec, 0x0d, 0, HDA_OUTPUT, 0, - HDA_AMP_VOLMASK, valp[0]); - snd_hda_codec_amp_update(codec, 0x0d, 1, HDA_OUTPUT, 0, - HDA_AMP_VOLMASK, valp[1]); - return change; -} +static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = { + .ops = &snd_hda_bind_vol, + .values = { + HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT), + HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT), + 0 + }, +}; /* bind hp and internal speaker mute (with plug check) */ static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol, @@ -7446,15 +7437,7 @@ static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol, } static struct snd_kcontrol_new alc262_fujitsu_mixer[] = { - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Master Playback Volume", - .info = snd_hda_mixer_amp_volume_info, - .get = snd_hda_mixer_amp_volume_get, - .put = alc262_fujitsu_master_vol_put, - .tlv = { .c = snd_hda_mixer_amp_tlv }, - .private_value = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT), - }, + HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol), { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Master Playback Switch", diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 1690726c1e1..bf5d91b63d1 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -2400,63 +2400,28 @@ static struct hda_verb vaio_ar_init[] = { }; /* bind volumes of both NID 0x02 and 0x05 */ -static int vaio_master_vol_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - long *valp = ucontrol->value.integer.value; - int change; - - change = snd_hda_codec_amp_update(codec, 0x02, 0, HDA_OUTPUT, 0, - HDA_AMP_VOLMASK, valp[0]); - change |= snd_hda_codec_amp_update(codec, 0x02, 1, HDA_OUTPUT, 0, - HDA_AMP_VOLMASK, valp[1]); - snd_hda_codec_amp_update(codec, 0x05, 0, HDA_OUTPUT, 0, - HDA_AMP_VOLMASK, valp[0]); - snd_hda_codec_amp_update(codec, 0x05, 1, HDA_OUTPUT, 0, - HDA_AMP_VOLMASK, valp[1]); - return change; -} +static struct hda_bind_ctls vaio_bind_master_vol = { + .ops = &snd_hda_bind_vol, + .values = { + HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT), + HDA_COMPOSE_AMP_VAL(0x05, 3, 0, HDA_OUTPUT), + 0 + }, +}; /* bind volumes of both NID 0x02 and 0x05 */ -static int vaio_master_sw_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - long *valp = ucontrol->value.integer.value; - int change; - - change = snd_hda_codec_amp_update(codec, 0x02, 0, HDA_OUTPUT, 0, - HDA_AMP_MUTE, - (valp[0] ? 0 : HDA_AMP_MUTE)); - change |= snd_hda_codec_amp_update(codec, 0x02, 1, HDA_OUTPUT, 0, - HDA_AMP_MUTE, - (valp[1] ? 0 : HDA_AMP_MUTE)); - snd_hda_codec_amp_update(codec, 0x05, 0, HDA_OUTPUT, 0, - HDA_AMP_MUTE, (valp[0] ? 0 : HDA_AMP_MUTE)); - snd_hda_codec_amp_update(codec, 0x05, 1, HDA_OUTPUT, 0, - HDA_AMP_MUTE, (valp[1] ? 0 : HDA_AMP_MUTE)); - return change; -} +static struct hda_bind_ctls vaio_bind_master_sw = { + .ops = &snd_hda_bind_sw, + .values = { + HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT), + HDA_COMPOSE_AMP_VAL(0x05, 3, 0, HDA_OUTPUT), + 0, + }, +}; static struct snd_kcontrol_new vaio_mixer[] = { - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Master Playback Volume", - .info = snd_hda_mixer_amp_volume_info, - .get = snd_hda_mixer_amp_volume_get, - .put = vaio_master_vol_put, - .tlv = { .c = snd_hda_mixer_amp_tlv }, - .private_value = HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT), - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Master Playback Switch", - .info = snd_hda_mixer_amp_switch_info, - .get = snd_hda_mixer_amp_switch_get, - .put = vaio_master_sw_put, - .private_value = HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT), - }, + HDA_BIND_VOL("Master Playback Volume", &vaio_bind_master_vol), + HDA_BIND_SW("Master Playback Switch", &vaio_bind_master_sw), /* HDA_CODEC_VOLUME("CD Capture Volume", 0x07, 0, HDA_INPUT), */ HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_INPUT), HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_INPUT), @@ -2472,22 +2437,8 @@ static struct snd_kcontrol_new vaio_mixer[] = { }; static struct snd_kcontrol_new vaio_ar_mixer[] = { - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Master Playback Volume", - .info = snd_hda_mixer_amp_volume_info, - .get = snd_hda_mixer_amp_volume_get, - .put = vaio_master_vol_put, - .private_value = HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT), - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Master Playback Switch", - .info = snd_hda_mixer_amp_switch_info, - .get = snd_hda_mixer_amp_switch_get, - .put = vaio_master_sw_put, - .private_value = HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT), - }, + HDA_BIND_VOL("Master Playback Volume", &vaio_bind_master_vol), + HDA_BIND_SW("Master Playback Switch", &vaio_bind_master_sw), /* HDA_CODEC_VOLUME("CD Capture Volume", 0x07, 0, HDA_INPUT), */ HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_INPUT), HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_INPUT), -- cgit v1.2.3 From cb53c626e1145edf1d619bc4953f6293d3a77ace Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 10 Aug 2007 17:21:45 +0200 Subject: [ALSA] hda-intel - Add POWER_SAVE option Added CONFIG_SND_HDA_POWER_SAVE kconfig. It's an experimental option to achieve an aggressive power-saving. With this option, the driver will turn on/off the power of each codec and controller chip dynamically on demand. The patch introduces a new module option 'power_save'. It specifies the second of time-out for automatic power-down. As default, it's 10 seconds. Setting 0 means to suppress the power-saving feature. The codec may have analog-input loopbacks, which are usually represented by mixer elements such as 'Mic Playback Switch' or 'CD Playback Switch'. When these are on, we cannot turn off the mixer and the codec chip has to be kept on. For bookkeeping these states, a new codec-callback is introduced. For the bus-controller side, a new callback pm_notify is introduced, which can be used to turn on/off the contoller appropriately. Note that this power-saving might cause slight click-noise at power-on/off. Also, it might take some time to wake up the codec, and might even drop some tones at the very beginning. This seems to be the side-effect of turning off the controller chip. This turn-off of the controller can be disabled by undefining HDA_POWER_SAVE_RESET_CONTOLLER in hda_intel.c. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/Kconfig | 8 ++ sound/pci/hda/hda_codec.c | 239 ++++++++++++++++++++++++++------ sound/pci/hda/hda_codec.h | 32 ++++- sound/pci/hda/hda_generic.c | 55 +++++++- sound/pci/hda/hda_intel.c | 158 ++++++++++++++++----- sound/pci/hda/hda_local.h | 25 +++- sound/pci/hda/hda_proc.c | 3 + sound/pci/hda/patch_analog.c | 91 ++++++++++++ sound/pci/hda/patch_realtek.c | 307 +++++++++++++++++++++++++++++------------ sound/pci/hda/patch_sigmatel.c | 6 +- sound/pci/hda/patch_via.c | 68 +++++++-- 11 files changed, 800 insertions(+), 192 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig index ff7a689c229..9554140f0b0 100644 --- a/sound/pci/Kconfig +++ b/sound/pci/Kconfig @@ -581,6 +581,14 @@ config SND_HDA_GENERIC Say Y here to enable the generic HD-audio codec parser in snd-hda-intel driver. +config SND_HDA_POWER_SAVE + bool "Aggressive power-saving on HD-audio" + depends on SND_HDA_INTEL && EXPERIMENTAL + help + Say Y here to enable more aggressive power-saving mode on + HD-audio driver. The power-saving timeout can be configured + via power_save option or over sysfs on-the-fly. + config SND_HDSP tristate "RME Hammerfall DSP Audio" depends on SND diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 04352930867..9a3b72824f8 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -33,6 +33,13 @@ #include "hda_local.h" #include +#ifdef CONFIG_SND_HDA_POWER_SAVE +/* define this option here to hide as static */ +static int power_save = 10; +module_param(power_save, int, 0644); +MODULE_PARM_DESC(power_save, "Automatic power-saving timeout " + "(in second, 0 = disable)."); +#endif /* * vendor / preset table @@ -60,6 +67,13 @@ static struct hda_vendor_id hda_vendor_ids[] = { #include "hda_patch.h" +#ifdef CONFIG_SND_HDA_POWER_SAVE +static void hda_power_work(struct work_struct *work); +static void hda_keep_power_on(struct hda_codec *codec); +#else +static inline void hda_keep_power_on(struct hda_codec *codec) {} +#endif + /** * snd_hda_codec_read - send a command and get the response * @codec: the HDA codec @@ -77,12 +91,14 @@ unsigned int snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid, unsigned int verb, unsigned int parm) { unsigned int res; + snd_hda_power_up(codec); mutex_lock(&codec->bus->cmd_mutex); if (!codec->bus->ops.command(codec, nid, direct, verb, parm)) res = codec->bus->ops.get_response(codec); else res = (unsigned int)-1; mutex_unlock(&codec->bus->cmd_mutex); + snd_hda_power_down(codec); return res; } @@ -102,9 +118,11 @@ int snd_hda_codec_write(struct hda_codec *codec, hda_nid_t nid, int direct, unsigned int verb, unsigned int parm) { int err; + snd_hda_power_up(codec); mutex_lock(&codec->bus->cmd_mutex); err = codec->bus->ops.command(codec, nid, direct, verb, parm); mutex_unlock(&codec->bus->cmd_mutex); + snd_hda_power_down(codec); return err; } @@ -505,6 +523,9 @@ static void snd_hda_codec_free(struct hda_codec *codec) { if (!codec) return; +#ifdef CONFIG_SND_HDA_POWER_SAVE + cancel_delayed_work(&codec->power_work); +#endif list_del(&codec->list); codec->bus->caddr_tbl[codec->addr] = NULL; if (codec->patch_ops.free) @@ -551,6 +572,15 @@ int __devinit snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, init_hda_cache(&codec->amp_cache, sizeof(struct hda_amp_info)); init_hda_cache(&codec->cmd_cache, sizeof(struct hda_cache_head)); +#ifdef CONFIG_SND_HDA_POWER_SAVE + INIT_DELAYED_WORK(&codec->power_work, hda_power_work); + /* snd_hda_codec_new() marks the codec as power-up, and leave it as is. + * the caller has to power down appropriatley after initialization + * phase. + */ + hda_keep_power_on(codec); +#endif + list_add_tail(&codec->list, &bus->codec_list); bus->caddr_tbl[codec_addr] = codec; @@ -855,7 +885,7 @@ int snd_hda_codec_amp_stereo(struct hda_codec *codec, hda_nid_t nid, return ret; } -#ifdef CONFIG_PM +#ifdef SND_HDA_NEEDS_RESUME /* resume the all amp commands from the cache */ void snd_hda_codec_resume_amp(struct hda_codec *codec) { @@ -879,7 +909,7 @@ void snd_hda_codec_resume_amp(struct hda_codec *codec) } } } -#endif /* CONFIG_PM */ +#endif /* SND_HDA_NEEDS_RESUME */ /* * AMP control callbacks @@ -945,6 +975,7 @@ int snd_hda_mixer_amp_volume_put(struct snd_kcontrol *kcontrol, long *valp = ucontrol->value.integer.value; int change = 0; + snd_hda_power_up(codec); if (chs & 1) { change = snd_hda_codec_amp_update(codec, nid, 0, dir, idx, 0x7f, *valp); @@ -953,6 +984,7 @@ int snd_hda_mixer_amp_volume_put(struct snd_kcontrol *kcontrol, if (chs & 2) change |= snd_hda_codec_amp_update(codec, nid, 1, dir, idx, 0x7f, *valp); + snd_hda_power_down(codec); return change; } @@ -1025,6 +1057,7 @@ int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol, long *valp = ucontrol->value.integer.value; int change = 0; + snd_hda_power_up(codec); if (chs & 1) { change = snd_hda_codec_amp_update(codec, nid, 0, dir, idx, HDA_AMP_MUTE, @@ -1035,7 +1068,11 @@ int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol, change |= snd_hda_codec_amp_update(codec, nid, 1, dir, idx, HDA_AMP_MUTE, *valp ? 0 : HDA_AMP_MUTE); - +#ifdef CONFIG_SND_HDA_POWER_SAVE + if (codec->patch_ops.check_power_status) + codec->patch_ops.check_power_status(codec, nid); +#endif + snd_hda_power_down(codec); return change; } @@ -1502,7 +1539,7 @@ int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid) return 0; } -#ifdef CONFIG_PM +#ifdef SND_HDA_NEEDS_RESUME /* * command cache */ @@ -1528,6 +1565,7 @@ int snd_hda_codec_write_cache(struct hda_codec *codec, hda_nid_t nid, int direct, unsigned int verb, unsigned int parm) { int err; + snd_hda_power_up(codec); mutex_lock(&codec->bus->cmd_mutex); err = codec->bus->ops.command(codec, nid, direct, verb, parm); if (!err) { @@ -1538,6 +1576,7 @@ int snd_hda_codec_write_cache(struct hda_codec *codec, hda_nid_t nid, c->val = parm; } mutex_unlock(&codec->bus->cmd_mutex); + snd_hda_power_down(codec); return err; } @@ -1572,7 +1611,7 @@ void snd_hda_sequence_write_cache(struct hda_codec *codec, snd_hda_codec_write_cache(codec, seq->nid, 0, seq->verb, seq->param); } -#endif /* CONFIG_PM */ +#endif /* SND_HDA_NEEDS_RESUME */ /* * set power state of the codec @@ -1580,24 +1619,70 @@ void snd_hda_sequence_write_cache(struct hda_codec *codec, static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg, unsigned int power_state) { - hda_nid_t nid, nid_start; - int nodes; + hda_nid_t nid; + int i; snd_hda_codec_write(codec, fg, 0, AC_VERB_SET_POWER_STATE, power_state); - nodes = snd_hda_get_sub_nodes(codec, fg, &nid_start); - for (nid = nid_start; nid < nodes + nid_start; nid++) { + nid = codec->start_nid; + for (i = 0; i < codec->num_nodes; i++, nid++) { if (get_wcaps(codec, nid) & AC_WCAP_POWER) snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_POWER_STATE, power_state); } - if (power_state == AC_PWRST_D0) + if (power_state == AC_PWRST_D0) { + unsigned long end_time; + int state; msleep(10); + /* wait until the codec reachs to D0 */ + end_time = jiffies + msecs_to_jiffies(500); + do { + state = snd_hda_codec_read(codec, fg, 0, + AC_VERB_GET_POWER_STATE, 0); + if (state == power_state) + break; + msleep(1); + } while (time_after_eq(end_time, jiffies)); + } +} + +#ifdef SND_HDA_NEEDS_RESUME +/* + * call suspend and power-down; used both from PM and power-save + */ +static void hda_call_codec_suspend(struct hda_codec *codec) +{ + if (codec->patch_ops.suspend) + codec->patch_ops.suspend(codec, PMSG_SUSPEND); + hda_set_power_state(codec, + codec->afg ? codec->afg : codec->mfg, + AC_PWRST_D3); +#ifdef CONFIG_SND_HDA_POWER_SAVE + cancel_delayed_work(&codec->power_work); +#endif } +/* + * kick up codec; used both from PM and power-save + */ +static void hda_call_codec_resume(struct hda_codec *codec) +{ + hda_set_power_state(codec, + codec->afg ? codec->afg : codec->mfg, + AC_PWRST_D0); + if (codec->patch_ops.resume) + codec->patch_ops.resume(codec); + else { + codec->patch_ops.init(codec); + snd_hda_codec_resume_amp(codec); + snd_hda_codec_resume_cache(codec); + } +} +#endif /* SND_HDA_NEEDS_RESUME */ + /** * snd_hda_build_controls - build mixer controls @@ -1611,28 +1696,24 @@ int __devinit snd_hda_build_controls(struct hda_bus *bus) { struct hda_codec *codec; - /* build controls */ list_for_each_entry(codec, &bus->codec_list, list) { - int err; - if (!codec->patch_ops.build_controls) - continue; - err = codec->patch_ops.build_controls(codec); - if (err < 0) - return err; - } - - /* initialize */ - list_for_each_entry(codec, &bus->codec_list, list) { - int err; + int err = 0; + /* fake as if already powered-on */ + hda_keep_power_on(codec); + /* then fire up */ hda_set_power_state(codec, codec->afg ? codec->afg : codec->mfg, AC_PWRST_D0); - if (!codec->patch_ops.init) - continue; - err = codec->patch_ops.init(codec); + /* continue to initialize... */ + if (codec->patch_ops.init) + err = codec->patch_ops.init(codec); + if (!err && codec->patch_ops.build_controls) + err = codec->patch_ops.build_controls(codec); + snd_hda_power_down(codec); if (err < 0) return err; } + return 0; } @@ -2078,7 +2159,7 @@ int snd_hda_check_board_config(struct hda_codec *codec, */ int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew) { - int err; + int err; for (; knew->name; knew++) { struct snd_kcontrol *kctl; @@ -2101,6 +2182,89 @@ int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew) return 0; } +#ifdef CONFIG_SND_HDA_POWER_SAVE +static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg, + unsigned int power_state); + +static void hda_power_work(struct work_struct *work) +{ + struct hda_codec *codec = + container_of(work, struct hda_codec, power_work.work); + + if (!codec->power_on || codec->power_count) + return; + + hda_call_codec_suspend(codec); + codec->power_on = 0; + if (codec->bus->ops.pm_notify) + codec->bus->ops.pm_notify(codec); +} + +static void hda_keep_power_on(struct hda_codec *codec) +{ + codec->power_count++; + codec->power_on = 1; +} + +void snd_hda_power_up(struct hda_codec *codec) +{ + codec->power_count++; + if (codec->power_on) + return; + + codec->power_on = 1; + if (codec->bus->ops.pm_notify) + codec->bus->ops.pm_notify(codec); + hda_call_codec_resume(codec); + cancel_delayed_work(&codec->power_work); +} + +void snd_hda_power_down(struct hda_codec *codec) +{ + --codec->power_count; + if (!codec->power_on) + return; + if (power_save) + schedule_delayed_work(&codec->power_work, + msecs_to_jiffies(power_save * 1000)); +} + +int snd_hda_check_amp_list_power(struct hda_codec *codec, + struct hda_loopback_check *check, + hda_nid_t nid) +{ + struct hda_amp_list *p; + int ch, v; + + if (!check->amplist) + return 0; + for (p = check->amplist; p->nid; p++) { + if (p->nid == nid) + break; + } + if (!p->nid) + return 0; /* nothing changed */ + + for (p = check->amplist; p->nid; p++) { + for (ch = 0; ch < 2; ch++) { + v = snd_hda_codec_amp_read(codec, p->nid, ch, p->dir, + p->idx); + if (!(v & HDA_AMP_MUTE) && v > 0) { + if (!check->power_on) { + check->power_on = 1; + snd_hda_power_up(codec); + } + return 1; + } + } + } + if (check->power_on) { + check->power_on = 0; + snd_hda_power_down(codec); + } + return 0; +} +#endif /* * Channel mode helper @@ -2605,41 +2769,32 @@ int snd_hda_suspend(struct hda_bus *bus, pm_message_t state) { struct hda_codec *codec; - /* FIXME: should handle power widget capabilities */ list_for_each_entry(codec, &bus->codec_list, list) { - if (codec->patch_ops.suspend) - codec->patch_ops.suspend(codec, state); - hda_set_power_state(codec, - codec->afg ? codec->afg : codec->mfg, - AC_PWRST_D3); + hda_call_codec_suspend(codec); } return 0; } +#ifndef CONFIG_SND_HDA_POWER_SAVE /** * snd_hda_resume - resume the codecs * @bus: the HDA bus * @state: resume state * * Returns 0 if successful. + * + * This fucntion is defined only when POWER_SAVE isn't set. + * In the power-save mode, the codec is resumed dynamically. */ int snd_hda_resume(struct hda_bus *bus) { struct hda_codec *codec; list_for_each_entry(codec, &bus->codec_list, list) { - hda_set_power_state(codec, - codec->afg ? codec->afg : codec->mfg, - AC_PWRST_D0); - if (codec->patch_ops.resume) - codec->patch_ops.resume(codec); - else { - codec->patch_ops.init(codec); - snd_hda_codec_resume_amp(codec); - snd_hda_codec_resume_cache(codec); - } + hda_call_codec_resume(codec); } return 0; } +#endif /* !CONFIG_SND_HDA_POWER_SAVE */ #endif diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index 92938d2a52e..1ffffaa3a30 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h @@ -26,6 +26,10 @@ #include #include +#if defined(CONFIG_PM) || defined(CONFIG_SND_HDA_POWER_SAVE) +#define SND_HDA_NEEDS_RESUME /* resume control code is required */ +#endif + /* * nodes */ @@ -412,6 +416,10 @@ struct hda_bus_ops { unsigned int (*get_response)(struct hda_codec *codec); /* free the private data */ void (*private_free)(struct hda_bus *); +#ifdef CONFIG_SND_HDA_POWER_SAVE + /* notify power-up/down from codec to contoller */ + void (*pm_notify)(struct hda_codec *codec); +#endif }; /* template to pass to the bus constructor */ @@ -473,10 +481,13 @@ struct hda_codec_ops { int (*init)(struct hda_codec *codec); void (*free)(struct hda_codec *codec); void (*unsol_event)(struct hda_codec *codec, unsigned int res); -#ifdef CONFIG_PM +#ifdef SND_HDA_NEEDS_RESUME int (*suspend)(struct hda_codec *codec, pm_message_t state); int (*resume)(struct hda_codec *codec); #endif +#ifdef CONFIG_SND_HDA_POWER_SAVE + int (*check_power_status)(struct hda_codec *codec, hda_nid_t nid); +#endif }; /* record for amp information cache */ @@ -573,6 +584,12 @@ struct hda_codec { unsigned int spdif_in_enable; /* SPDIF input enable? */ struct snd_hwdep *hwdep; /* assigned hwdep device */ + +#ifdef CONFIG_SND_HDA_POWER_SAVE + int power_on; /* current (global) power-state */ + int power_count; /* current (global) power refcount */ + struct delayed_work power_work; /* delayed task for powerdown */ +#endif }; /* direction */ @@ -617,7 +634,7 @@ void snd_hda_sequence_write(struct hda_codec *codec, int snd_hda_queue_unsol_event(struct hda_bus *bus, u32 res, u32 res_ex); /* cached write */ -#ifdef CONFIG_PM +#ifdef SND_HDA_NEEDS_RESUME int snd_hda_codec_write_cache(struct hda_codec *codec, hda_nid_t nid, int direct, unsigned int verb, unsigned int parm); void snd_hda_sequence_write_cache(struct hda_codec *codec, @@ -662,4 +679,15 @@ int snd_hda_suspend(struct hda_bus *bus, pm_message_t state); int snd_hda_resume(struct hda_bus *bus); #endif +/* + * power saving + */ +#ifdef CONFIG_SND_HDA_POWER_SAVE +void snd_hda_power_up(struct hda_codec *codec); +void snd_hda_power_down(struct hda_codec *codec); +#else +static inline void snd_hda_power_up(struct hda_codec *codec) {} +static inline void snd_hda_power_down(struct hda_codec *codec) {} +#endif + #endif /* __SOUND_HDA_CODEC_H */ diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c index 91cd9b9ea5d..819c804a579 100644 --- a/sound/pci/hda/hda_generic.c +++ b/sound/pci/hda/hda_generic.c @@ -70,6 +70,13 @@ struct hda_gspec { struct hda_pcm pcm_rec; /* PCM information */ struct list_head nid_list; /* list of widgets */ + +#ifdef CONFIG_SND_HDA_POWER_SAVE +#define MAX_LOOPBACK_AMPS 7 + struct hda_loopback_check loopback; + int num_loopbacks; + struct hda_amp_list loopback_list[MAX_LOOPBACK_AMPS + 1]; +#endif }; /* @@ -682,11 +689,33 @@ static int parse_input(struct hda_codec *codec) return 0; } +#ifdef CONFIG_SND_HDA_POWER_SAVE +static void add_input_loopback(struct hda_codec *codec, hda_nid_t nid, + int dir, int idx) +{ + struct hda_gspec *spec = codec->spec; + struct hda_amp_list *p; + + if (spec->num_loopbacks >= MAX_LOOPBACK_AMPS) { + snd_printk(KERN_ERR "hda_generic: Too many loopback ctls\n"); + return; + } + p = &spec->loopback_list[spec->num_loopbacks++]; + p->nid = nid; + p->dir = dir; + p->idx = idx; + spec->loopback.amplist = spec->loopback_list; +} +#else +#define add_input_loopback(codec,nid,dir,idx) +#endif + /* * create mixer controls if possible */ static int create_mixer(struct hda_codec *codec, struct hda_gnode *node, - unsigned int index, const char *type, const char *dir_sfx) + unsigned int index, const char *type, + const char *dir_sfx, int is_loopback) { char name[32]; int err; @@ -700,6 +729,8 @@ static int create_mixer(struct hda_codec *codec, struct hda_gnode *node, if ((node->wid_caps & AC_WCAP_IN_AMP) && (node->amp_in_caps & AC_AMPCAP_MUTE)) { knew = (struct snd_kcontrol_new)HDA_CODEC_MUTE(name, node->nid, index, HDA_INPUT); + if (is_loopback) + add_input_loopback(codec, node->nid, HDA_INPUT, index); snd_printdd("[%s] NID=0x%x, DIR=IN, IDX=0x%x\n", name, node->nid, index); if ((err = snd_ctl_add(codec->bus->card, snd_ctl_new1(&knew, codec))) < 0) return err; @@ -707,6 +738,8 @@ static int create_mixer(struct hda_codec *codec, struct hda_gnode *node, } else if ((node->wid_caps & AC_WCAP_OUT_AMP) && (node->amp_out_caps & AC_AMPCAP_MUTE)) { knew = (struct snd_kcontrol_new)HDA_CODEC_MUTE(name, node->nid, 0, HDA_OUTPUT); + if (is_loopback) + add_input_loopback(codec, node->nid, HDA_OUTPUT, 0); snd_printdd("[%s] NID=0x%x, DIR=OUT\n", name, node->nid); if ((err = snd_ctl_add(codec->bus->card, snd_ctl_new1(&knew, codec))) < 0) return err; @@ -765,7 +798,7 @@ static int create_output_mixers(struct hda_codec *codec, const char **names) for (i = 0; i < spec->pcm_vol_nodes; i++) { err = create_mixer(codec, spec->pcm_vol[i].node, spec->pcm_vol[i].index, - names[i], "Playback"); + names[i], "Playback", 0); if (err < 0) return err; } @@ -782,7 +815,7 @@ static int build_output_controls(struct hda_codec *codec) case 1: return create_mixer(codec, spec->pcm_vol[0].node, spec->pcm_vol[0].index, - "Master", "Playback"); + "Master", "Playback", 0); case 2: if (defcfg_type(spec->out_pin_node[0]) == AC_JACK_SPEAKER) return create_output_mixers(codec, types_speaker); @@ -818,7 +851,7 @@ static int build_input_controls(struct hda_codec *codec) if (spec->input_mux.num_items == 1) { err = create_mixer(codec, adc_node, spec->input_mux.items[0].index, - NULL, "Capture"); + NULL, "Capture", 0); if (err < 0) return err; return 0; @@ -884,7 +917,8 @@ static int parse_loopback_path(struct hda_codec *codec, struct hda_gspec *spec, return err; else if (err >= 1) { if (err == 1) { - err = create_mixer(codec, node, i, type, "Playback"); + err = create_mixer(codec, node, i, type, + "Playback", 1); if (err < 0) return err; if (err > 0) @@ -1020,6 +1054,14 @@ static int build_generic_pcms(struct hda_codec *codec) return 0; } +#ifdef CONFIG_SND_HDA_POWER_SAVE +static int generic_check_power_status(struct hda_codec *codec, hda_nid_t nid) +{ + struct hda_gspec *spec = codec->spec; + return snd_hda_check_amp_list_power(codec, &spec->loopback, nid); +} +#endif + /* */ @@ -1027,6 +1069,9 @@ static struct hda_codec_ops generic_patch_ops = { .build_controls = build_generic_controls, .build_pcms = build_generic_pcms, .free = snd_hda_generic_free, +#ifdef CONFIG_SND_HDA_POWER_SAVE + .check_power_status = generic_check_power_status, +#endif }; /* diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index ebb442dcc02..7be3a9b5533 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -75,6 +75,7 @@ MODULE_PARM_DESC(single_cmd, "Use single command to communicate with codecs " module_param(enable_msi, int, 0); MODULE_PARM_DESC(enable_msi, "Enable Message Signaled Interrupt (MSI)"); +/* power_save option is defined in hda_codec.c */ /* just for backward compatibility */ static int enable; @@ -101,6 +102,18 @@ MODULE_DESCRIPTION("Intel HDA driver"); #define SFX "hda-intel: " +/* + * build flags + */ + +/* + * reset the HD-audio controller in power save mode. + * this may give more power-saving, but will take longer time to + * wake up. + */ +#define HDA_POWER_SAVE_RESET_CONTROLLER + + /* * registers */ @@ -345,6 +358,7 @@ struct azx { /* flags */ int position_fix; + unsigned int running :1; unsigned int initialized :1; unsigned int single_cmd :1; unsigned int polling_mode :1; @@ -665,6 +679,9 @@ static unsigned int azx_get_response(struct hda_codec *codec) return azx_rirb_get_response(codec); } +#ifdef CONFIG_SND_HDA_POWER_SAVE +static void azx_power_notify(struct hda_codec *codec); +#endif /* reset codec link */ static int azx_reset(struct azx *chip) @@ -790,19 +807,12 @@ static void azx_stream_stop(struct azx *chip, struct azx_dev *azx_dev) /* - * initialize the chip + * reset and start the controller registers */ static void azx_init_chip(struct azx *chip) { - unsigned char reg; - - /* Clear bits 0-2 of PCI register TCSEL (at offset 0x44) - * TCSEL == Traffic Class Select Register, which sets PCI express QOS - * Ensuring these bits are 0 clears playback static on some HD Audio - * codecs - */ - pci_read_config_byte (chip->pci, ICH6_PCIREG_TCSEL, ®); - pci_write_config_byte(chip->pci, ICH6_PCIREG_TCSEL, reg & 0xf8); + if (chip->initialized) + return; /* reset controller */ azx_reset(chip); @@ -819,22 +829,45 @@ static void azx_init_chip(struct azx *chip) azx_writel(chip, DPLBASE, (u32)chip->posbuf.addr); azx_writel(chip, DPUBASE, upper_32bit(chip->posbuf.addr)); + chip->initialized = 1; +} + +/* + * initialize the PCI registers + */ +/* update bits in a PCI register byte */ +static void update_pci_byte(struct pci_dev *pci, unsigned int reg, + unsigned char mask, unsigned char val) +{ + unsigned char data; + + pci_read_config_byte(pci, reg, &data); + data &= ~mask; + data |= (val & mask); + pci_write_config_byte(pci, reg, data); +} + +static void azx_init_pci(struct azx *chip) +{ + /* Clear bits 0-2 of PCI register TCSEL (at offset 0x44) + * TCSEL == Traffic Class Select Register, which sets PCI express QOS + * Ensuring these bits are 0 clears playback static on some HD Audio + * codecs + */ + update_pci_byte(chip->pci, ICH6_PCIREG_TCSEL, 0x07, 0); + switch (chip->driver_type) { case AZX_DRIVER_ATI: /* For ATI SB450 azalia HD audio, we need to enable snoop */ - pci_read_config_byte(chip->pci, - ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR, - ®); - pci_write_config_byte(chip->pci, - ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR, - (reg & 0xf8) | - ATI_SB450_HDAUDIO_ENABLE_SNOOP); + update_pci_byte(chip->pci, + ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR, + 0x07, ATI_SB450_HDAUDIO_ENABLE_SNOOP); break; case AZX_DRIVER_NVIDIA: /* For NVIDIA HDA, enable snoop */ - pci_read_config_byte(chip->pci,NVIDIA_HDA_TRANSREG_ADDR, ®); - pci_write_config_byte(chip->pci,NVIDIA_HDA_TRANSREG_ADDR, - (reg & 0xf0) | NVIDIA_HDA_ENABLE_COHBITS); + update_pci_byte(chip->pci, + NVIDIA_HDA_TRANSREG_ADDR, + 0x0f, NVIDIA_HDA_ENABLE_COHBITS); break; } } @@ -1007,6 +1040,9 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model) bus_temp.pci = chip->pci; bus_temp.ops.command = azx_send_cmd; bus_temp.ops.get_response = azx_get_response; +#ifdef CONFIG_SND_HDA_POWER_SAVE + bus_temp.ops.pm_notify = azx_power_notify; +#endif err = snd_hda_bus_new(chip->card, &bus_temp, &chip->bus); if (err < 0) @@ -1128,9 +1164,11 @@ static int azx_pcm_open(struct snd_pcm_substream *substream) 128); snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 128); + snd_hda_power_up(apcm->codec); err = hinfo->ops.open(hinfo, apcm->codec, substream); if (err < 0) { azx_release_device(azx_dev); + snd_hda_power_down(apcm->codec); mutex_unlock(&chip->open_mutex); return err; } @@ -1159,6 +1197,7 @@ static int azx_pcm_close(struct snd_pcm_substream *substream) spin_unlock_irqrestore(&chip->reg_lock, flags); azx_release_device(azx_dev); hinfo->ops.close(hinfo, apcm->codec, substream); + snd_hda_power_down(apcm->codec); mutex_unlock(&chip->open_mutex); return 0; } @@ -1459,6 +1498,48 @@ static int azx_acquire_irq(struct azx *chip, int do_disconnect) } +static void azx_stop_chip(struct azx *chip) +{ + if (chip->initialized) + return; + + /* disable interrupts */ + azx_int_disable(chip); + azx_int_clear(chip); + + /* disable CORB/RIRB */ + azx_free_cmd_io(chip); + + /* disable position buffer */ + azx_writel(chip, DPLBASE, 0); + azx_writel(chip, DPUBASE, 0); + + chip->initialized = 0; +} + +#ifdef CONFIG_SND_HDA_POWER_SAVE +/* power-up/down the controller */ +static void azx_power_notify(struct hda_codec *codec) +{ + struct azx *chip = codec->bus->private_data; + struct hda_codec *c; + int power_on = 0; + + list_for_each_entry(c, &codec->bus->codec_list, list) { + if (c->power_on) { + power_on = 1; + break; + } + } + if (power_on) + azx_init_chip(chip); +#ifdef HDA_POWER_SAVE_RESET_CONTROLLER + else if (chip->running) + azx_stop_chip(chip); +#endif +} +#endif /* CONFIG_SND_HDA_POWER_SAVE */ + #ifdef CONFIG_PM /* * power management @@ -1473,7 +1554,7 @@ static int azx_suspend(struct pci_dev *pci, pm_message_t state) for (i = 0; i < chip->pcm_devs; i++) snd_pcm_suspend_all(chip->pcm[i]); snd_hda_suspend(chip->bus, state); - azx_free_cmd_io(chip); + azx_stop_chip(chip); if (chip->irq >= 0) { synchronize_irq(chip->irq); free_irq(chip->irq, chip); @@ -1506,8 +1587,12 @@ static int azx_resume(struct pci_dev *pci) chip->msi = 0; if (azx_acquire_irq(chip, 1) < 0) return -EIO; + azx_init_pci(chip); +#ifndef CONFIG_SND_HDA_POWER_SAVE + /* the explicit resume is needed only when POWER_SAVE isn't set */ azx_init_chip(chip); snd_hda_resume(chip->bus); +#endif snd_power_change_state(card, SNDRV_CTL_POWER_D0); return 0; } @@ -1521,20 +1606,9 @@ static int azx_free(struct azx *chip) { if (chip->initialized) { int i; - for (i = 0; i < chip->num_streams; i++) azx_stream_stop(chip, &chip->azx_dev[i]); - - /* disable interrupts */ - azx_int_disable(chip); - azx_int_clear(chip); - - /* disable CORB/RIRB */ - azx_free_cmd_io(chip); - - /* disable position buffer */ - azx_writel(chip, DPLBASE, 0); - azx_writel(chip, DPUBASE, 0); + azx_stop_chip(chip); } if (chip->irq >= 0) { @@ -1720,10 +1794,9 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, azx_init_stream(chip); /* initialize chip */ + azx_init_pci(chip); azx_init_chip(chip); - chip->initialized = 1; - /* codec detection */ if (!chip->codec_mask) { snd_printk(KERN_ERR SFX "no codecs found!\n"); @@ -1750,6 +1823,19 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, return err; } +static void power_down_all_codecs(struct azx *chip) +{ +#ifdef CONFIG_SND_HDA_POWER_SAVE + /* The codecs were powered up in snd_hda_codec_new(). + * Now all initialization done, so turn them down if possible + */ + struct hda_codec *codec; + list_for_each_entry(codec, &chip->bus->codec_list, list) { + snd_hda_power_down(codec); + } +#endif +} + static int __devinit azx_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) { @@ -1800,6 +1886,8 @@ static int __devinit azx_probe(struct pci_dev *pci, } pci_set_drvdata(pci, card); + chip->running = 1; + power_down_all_codecs(chip); return err; } diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h index 35ea0cf37a2..a79d0ed5469 100644 --- a/sound/pci/hda/hda_local.h +++ b/sound/pci/hda/hda_local.h @@ -86,7 +86,7 @@ int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch, int direction, int idx, int mask, int val); int snd_hda_codec_amp_stereo(struct hda_codec *codec, hda_nid_t nid, int dir, int idx, int mask, int val); -#ifdef CONFIG_PM +#ifdef SND_HDA_NEEDS_RESUME void snd_hda_codec_resume_amp(struct hda_codec *codec); #endif @@ -366,4 +366,27 @@ int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir, */ int snd_hda_create_hwdep(struct hda_codec *codec); +/* + * power-management + */ + +#ifdef CONFIG_SND_HDA_POWER_SAVE +void snd_hda_schedule_power_save(struct hda_codec *codec); + +struct hda_amp_list { + hda_nid_t nid; + unsigned char dir; + unsigned char idx; +}; + +struct hda_loopback_check { + struct hda_amp_list *amplist; + int power_on; +}; + +int snd_hda_check_amp_list_power(struct hda_codec *codec, + struct hda_loopback_check *check, + hda_nid_t nid); +#endif /* CONFIG_SND_HDA_POWER_SAVE */ + #endif /* __SOUND_HDA_LOCAL_H */ diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c index ccd19180e54..e94944f34ff 100644 --- a/sound/pci/hda/hda_proc.c +++ b/sound/pci/hda/hda_proc.c @@ -262,6 +262,7 @@ static void print_codec_info(struct snd_info_entry *entry, if (! codec->afg) return; + snd_hda_power_up(codec); snd_iprintf(buffer, "Default PCM:\n"); print_pcm_caps(buffer, codec, codec->afg); snd_iprintf(buffer, "Default Amp-In caps: "); @@ -272,6 +273,7 @@ static void print_codec_info(struct snd_info_entry *entry, nodes = snd_hda_get_sub_nodes(codec, codec->afg, &nid); if (! nid || nodes < 0) { snd_iprintf(buffer, "Invalid AFG subtree\n"); + snd_hda_power_down(codec); return; } for (i = 0; i < nodes; i++, nid++) { @@ -359,6 +361,7 @@ static void print_codec_info(struct snd_info_entry *entry, snd_iprintf(buffer, "\n"); } } + snd_hda_power_down(codec); } /* diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index f9390a544ea..53cfa0da496 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c @@ -73,6 +73,10 @@ struct ad198x_spec { struct snd_kcontrol_new *kctl_alloc; struct hda_input_mux private_imux; hda_nid_t private_dac_nids[4]; + +#ifdef CONFIG_SND_HDA_POWER_SAVE + struct hda_loopback_check loopback; +#endif }; /* @@ -144,6 +148,14 @@ static int ad198x_build_controls(struct hda_codec *codec) return 0; } +#ifdef CONFIG_SND_HDA_POWER_SAVE +static int ad198x_check_power_status(struct hda_codec *codec, hda_nid_t nid) +{ + struct ad198x_spec *spec = codec->spec; + return snd_hda_check_amp_list_power(codec, &spec->loopback, nid); +} +#endif + /* * Analog playback callbacks */ @@ -323,6 +335,9 @@ static struct hda_codec_ops ad198x_patch_ops = { .build_pcms = ad198x_build_pcms, .init = ad198x_init, .free = ad198x_free, +#ifdef CONFIG_SND_HDA_POWER_SAVE + .check_power_status = ad198x_check_power_status, +#endif }; @@ -736,6 +751,17 @@ static struct snd_pci_quirk ad1986a_cfg_tbl[] = { {} }; +#ifdef CONFIG_SND_HDA_POWER_SAVE +static struct hda_amp_list ad1986a_loopbacks[] = { + { 0x13, HDA_OUTPUT, 0 }, /* Mic */ + { 0x14, HDA_OUTPUT, 0 }, /* Phone */ + { 0x15, HDA_OUTPUT, 0 }, /* CD */ + { 0x16, HDA_OUTPUT, 0 }, /* Aux */ + { 0x17, HDA_OUTPUT, 0 }, /* Line */ + { } /* end */ +}; +#endif + static int patch_ad1986a(struct hda_codec *codec) { struct ad198x_spec *spec; @@ -759,6 +785,9 @@ static int patch_ad1986a(struct hda_codec *codec) spec->mixers[0] = ad1986a_mixers; spec->num_init_verbs = 1; spec->init_verbs[0] = ad1986a_init_verbs; +#ifdef CONFIG_SND_HDA_POWER_SAVE + spec->loopback.amplist = ad1986a_loopbacks; +#endif codec->patch_ops = ad198x_patch_ops; @@ -944,6 +973,13 @@ static struct hda_verb ad1983_init_verbs[] = { { } /* end */ }; +#ifdef CONFIG_SND_HDA_POWER_SAVE +static struct hda_amp_list ad1983_loopbacks[] = { + { 0x12, HDA_OUTPUT, 0 }, /* Mic */ + { 0x13, HDA_OUTPUT, 0 }, /* Line */ + { } /* end */ +}; +#endif static int patch_ad1983(struct hda_codec *codec) { @@ -968,6 +1004,9 @@ static int patch_ad1983(struct hda_codec *codec) spec->num_init_verbs = 1; spec->init_verbs[0] = ad1983_init_verbs; spec->spdif_route = 0; +#ifdef CONFIG_SND_HDA_POWER_SAVE + spec->loopback.amplist = ad1983_loopbacks; +#endif codec->patch_ops = ad198x_patch_ops; @@ -1091,6 +1130,17 @@ static struct hda_verb ad1981_init_verbs[] = { { } /* end */ }; +#ifdef CONFIG_SND_HDA_POWER_SAVE +static struct hda_amp_list ad1981_loopbacks[] = { + { 0x12, HDA_OUTPUT, 0 }, /* Front Mic */ + { 0x13, HDA_OUTPUT, 0 }, /* Line */ + { 0x1b, HDA_OUTPUT, 0 }, /* Aux */ + { 0x1c, HDA_OUTPUT, 0 }, /* Mic */ + { 0x1d, HDA_OUTPUT, 0 }, /* CD */ + { } /* end */ +}; +#endif + /* * Patch for HP nx6320 * @@ -1350,6 +1400,9 @@ static int patch_ad1981(struct hda_codec *codec) spec->num_init_verbs = 1; spec->init_verbs[0] = ad1981_init_verbs; spec->spdif_route = 0; +#ifdef CONFIG_SND_HDA_POWER_SAVE + spec->loopback.amplist = ad1981_loopbacks; +#endif codec->patch_ops = ad198x_patch_ops; @@ -2103,6 +2156,15 @@ static void ad1988_laptop_unsol_event(struct hda_codec *codec, unsigned int res) snd_hda_sequence_write(codec, ad1988_laptop_hp_off); } +#ifdef CONFIG_SND_HDA_POWER_SAVE +static struct hda_amp_list ad1988_loopbacks[] = { + { 0x20, HDA_INPUT, 0 }, /* Front Mic */ + { 0x20, HDA_INPUT, 1 }, /* Line */ + { 0x20, HDA_INPUT, 4 }, /* Mic */ + { 0x20, HDA_INPUT, 6 }, /* CD */ + { } /* end */ +}; +#endif /* * Automatic parse of I/O pins from the BIOS configuration @@ -2647,6 +2709,9 @@ static int patch_ad1988(struct hda_codec *codec) codec->patch_ops.unsol_event = ad1988_laptop_unsol_event; break; } +#ifdef CONFIG_SND_HDA_POWER_SAVE + spec->loopback.amplist = ad1988_loopbacks; +#endif return 0; } @@ -2803,6 +2868,16 @@ static struct hda_verb ad1884_init_verbs[] = { { } /* end */ }; +#ifdef CONFIG_SND_HDA_POWER_SAVE +static struct hda_amp_list ad1884_loopbacks[] = { + { 0x20, HDA_INPUT, 0 }, /* Front Mic */ + { 0x20, HDA_INPUT, 1 }, /* Mic */ + { 0x20, HDA_INPUT, 2 }, /* CD */ + { 0x20, HDA_INPUT, 4 }, /* Docking */ + { } /* end */ +}; +#endif + static int patch_ad1884(struct hda_codec *codec) { struct ad198x_spec *spec; @@ -2827,6 +2902,9 @@ static int patch_ad1884(struct hda_codec *codec) spec->num_init_verbs = 1; spec->init_verbs[0] = ad1884_init_verbs; spec->spdif_route = 0; +#ifdef CONFIG_SND_HDA_POWER_SAVE + spec->loopback.amplist = ad1884_loopbacks; +#endif codec->patch_ops = ad198x_patch_ops; @@ -3208,6 +3286,16 @@ static struct hda_verb ad1882_init_verbs[] = { { } /* end */ }; +#ifdef CONFIG_SND_HDA_POWER_SAVE +static struct hda_amp_list ad1882_loopbacks[] = { + { 0x20, HDA_INPUT, 0 }, /* Front Mic */ + { 0x20, HDA_INPUT, 1 }, /* Mic */ + { 0x20, HDA_INPUT, 4 }, /* Line */ + { 0x20, HDA_INPUT, 6 }, /* CD */ + { } /* end */ +}; +#endif + /* models */ enum { AD1882_3STACK, @@ -3246,6 +3334,9 @@ static int patch_ad1882(struct hda_codec *codec) spec->num_init_verbs = 1; spec->init_verbs[0] = ad1882_init_verbs; spec->spdif_route = 0; +#ifdef CONFIG_SND_HDA_POWER_SAVE + spec->loopback.amplist = ad1882_loopbacks; +#endif codec->patch_ops = ad198x_patch_ops; diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index ebbabeb3293..b3d3916c8ec 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -240,6 +240,10 @@ struct alc_spec { /* for pin sensing */ unsigned int sense_updated: 1; unsigned int jack_present: 1; + +#ifdef CONFIG_SND_HDA_POWER_SAVE + struct hda_loopback_check loopback; +#endif }; /* @@ -264,6 +268,9 @@ struct alc_config_preset { const struct hda_input_mux *input_mux; void (*unsol_event)(struct hda_codec *, unsigned int); void (*init_hook)(struct hda_codec *); +#ifdef CONFIG_SND_HDA_POWER_SAVE + struct hda_amp_list *loopbacks; +#endif }; @@ -621,6 +628,9 @@ static void setup_preset(struct alc_spec *spec, spec->unsol_event = preset->unsol_event; spec->init_hook = preset->init_hook; +#ifdef CONFIG_SND_HDA_POWER_SAVE + spec->loopback.amplist = preset->loopbacks; +#endif } /* Enable GPIO mask and set output */ @@ -1287,11 +1297,13 @@ static struct hda_verb alc880_volume_init_verbs[] = { * panel mic (mic 2) */ /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* * Set up output mixers (0x0c - 0x0f) @@ -1836,8 +1848,8 @@ static struct hda_verb alc880_lg_init_verbs[] = { {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, /* mute all amp mixer inputs */ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)}, - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(6)}, - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(7)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* line-in to input */ {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, @@ -1939,7 +1951,7 @@ static struct hda_verb alc880_lg_lw_init_verbs[] = { {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(7)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* speaker-out */ {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, @@ -1979,6 +1991,24 @@ static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res) alc880_lg_lw_automute(codec); } +#ifdef CONFIG_SND_HDA_POWER_SAVE +static struct hda_amp_list alc880_loopbacks[] = { + { 0x0b, HDA_INPUT, 0 }, + { 0x0b, HDA_INPUT, 1 }, + { 0x0b, HDA_INPUT, 2 }, + { 0x0b, HDA_INPUT, 3 }, + { 0x0b, HDA_INPUT, 4 }, + { } /* end */ +}; + +static struct hda_amp_list alc880_lg_loopbacks[] = { + { 0x0b, HDA_INPUT, 1 }, + { 0x0b, HDA_INPUT, 6 }, + { 0x0b, HDA_INPUT, 7 }, + { } /* end */ +}; +#endif + /* * Common callbacks */ @@ -2005,6 +2035,14 @@ static void alc_unsol_event(struct hda_codec *codec, unsigned int res) spec->unsol_event(codec, res); } +#ifdef CONFIG_SND_HDA_POWER_SAVE +static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid) +{ + struct alc_spec *spec = codec->spec; + return snd_hda_check_amp_list_power(codec, &spec->loopback, nid); +} +#endif + /* * Analog playback callbacks */ @@ -2236,6 +2274,9 @@ static struct hda_codec_ops alc_patch_ops = { .init = alc_init, .free = alc_free, .unsol_event = alc_unsol_event, +#ifdef CONFIG_SND_HDA_POWER_SAVE + .check_power_status = alc_check_power_status, +#endif }; @@ -2860,6 +2901,9 @@ static struct alc_config_preset alc880_presets[] = { .input_mux = &alc880_lg_capture_source, .unsol_event = alc880_lg_unsol_event, .init_hook = alc880_lg_automute, +#ifdef CONFIG_SND_HDA_POWER_SAVE + .loopbacks = alc880_lg_loopbacks, +#endif }, [ALC880_LG_LW] = { .mixers = { alc880_lg_lw_mixer }, @@ -3343,6 +3387,10 @@ static int patch_alc880(struct hda_codec *codec) codec->patch_ops = alc_patch_ops; if (board_config == ALC880_AUTO) spec->init_hook = alc880_auto_init; +#ifdef CONFIG_SND_HDA_POWER_SAVE + if (!spec->loopback.amplist) + spec->loopback.amplist = alc880_loopbacks; +#endif return 0; } @@ -3691,12 +3739,12 @@ static struct hda_verb alc260_init_verbs[] = { /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & * Line In 2 = 0x03 */ - /* mute CD */ - {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, - /* mute Line In */ - {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, - /* mute Mic */ - {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + /* mute analog inputs */ + {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, + {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, + {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, + {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, + {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */ /* mute Front out path */ {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, @@ -3741,12 +3789,12 @@ static struct hda_verb alc260_hp_init_verbs[] = { /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & * Line In 2 = 0x03 */ - /* unmute CD */ - {0x07, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, - /* unmute Line In */ - {0x07, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, - /* unmute Mic */ - {0x07, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, + /* mute analog inputs */ + {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, + {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, + {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, + {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, + {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */ /* Unmute Front out path */ {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, @@ -3791,12 +3839,12 @@ static struct hda_verb alc260_hp_3013_init_verbs[] = { /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & * Line In 2 = 0x03 */ - /* unmute CD */ - {0x07, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, - /* unmute Line In */ - {0x07, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, - /* unmute Mic */ - {0x07, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, + /* mute analog inputs */ + {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, + {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, + {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, + {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, + {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */ /* Unmute Front out path */ {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, @@ -4418,11 +4466,12 @@ static struct hda_verb alc260_volume_init_verbs[] = { * front panel mic (mic 2) */ /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ - {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, - {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, - {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, + /* mute analog inputs */ + {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, + {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, + {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, + {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, + {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* * Set up output mixers (0x08 - 0x0a) @@ -4499,6 +4548,17 @@ static void alc260_auto_init(struct hda_codec *codec) alc260_auto_init_analog_input(codec); } +#ifdef CONFIG_SND_HDA_POWER_SAVE +static struct hda_amp_list alc260_loopbacks[] = { + { 0x07, HDA_INPUT, 0 }, + { 0x07, HDA_INPUT, 1 }, + { 0x07, HDA_INPUT, 2 }, + { 0x07, HDA_INPUT, 3 }, + { 0x07, HDA_INPUT, 4 }, + { } /* end */ +}; +#endif + /* * ALC260 configurations */ @@ -4698,6 +4758,10 @@ static int patch_alc260(struct hda_codec *codec) codec->patch_ops = alc_patch_ops; if (board_config == ALC260_AUTO) spec->init_hook = alc260_auto_init; +#ifdef CONFIG_SND_HDA_POWER_SAVE + if (!spec->loopback.amplist) + spec->loopback.amplist = alc260_loopbacks; +#endif return 0; } @@ -5223,17 +5287,17 @@ static struct hda_verb alc882_auto_init_verbs[] = { {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback + /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback * mixer widget * Note: PASD motherboards uses the Line In 2 as the input for * front panel mic (mic 2) */ /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* * Set up output mixers (0x0c - 0x0f) @@ -5322,6 +5386,10 @@ static struct snd_kcontrol_new alc882_capture_mixer[] = { { } /* end */ }; +#ifdef CONFIG_SND_HDA_POWER_SAVE +#define alc882_loopbacks alc880_loopbacks +#endif + /* pcm configuration: identiacal with ALC880 */ #define alc882_pcm_analog_playback alc880_pcm_analog_playback #define alc882_pcm_analog_capture alc880_pcm_analog_capture @@ -5659,6 +5727,10 @@ static int patch_alc882(struct hda_codec *codec) codec->patch_ops = alc_patch_ops; if (board_config == ALC882_AUTO) spec->init_hook = alc882_auto_init; +#ifdef CONFIG_SND_HDA_POWER_SAVE + if (!spec->loopback.amplist) + spec->loopback.amplist = alc882_loopbacks; +#endif return 0; } @@ -6242,11 +6314,12 @@ static struct hda_verb alc883_init_verbs[] = { {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, + /* mute analog input loopbacks */ + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* Front Pin: output 0 (0x0c) */ {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, @@ -6515,17 +6588,17 @@ static struct hda_verb alc883_auto_init_verbs[] = { {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback + /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback * mixer widget * Note: PASD motherboards uses the Line In 2 as the input for * front panel mic (mic 2) */ /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* * Set up output mixers (0x0c - 0x0f) @@ -6588,6 +6661,10 @@ static struct snd_kcontrol_new alc883_capture_mixer[] = { { } /* end */ }; +#ifdef CONFIG_SND_HDA_POWER_SAVE +#define alc883_loopbacks alc880_loopbacks +#endif + /* pcm configuration: identiacal with ALC880 */ #define alc883_pcm_analog_playback alc880_pcm_analog_playback #define alc883_pcm_analog_capture alc880_pcm_analog_capture @@ -7029,6 +7106,10 @@ static int patch_alc883(struct hda_codec *codec) codec->patch_ops = alc_patch_ops; if (board_config == ALC883_AUTO) spec->init_hook = alc883_auto_init; +#ifdef CONFIG_SND_HDA_POWER_SAVE + if (!spec->loopback.amplist) + spec->loopback.amplist = alc883_loopbacks; +#endif return 0; } @@ -7186,17 +7267,17 @@ static struct hda_verb alc262_init_verbs[] = { {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback + /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback * mixer widget * Note: PASD motherboards uses the Line In 2 as the input for * front panel mic (mic 2) */ /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* * Set up output mixers (0x0c - 0x0e) @@ -7565,17 +7646,17 @@ static struct hda_verb alc262_volume_init_verbs[] = { {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback + /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback * mixer widget * Note: PASD motherboards uses the Line In 2 as the input for * front panel mic (mic 2) */ /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* * Set up output mixers (0x0c - 0x0f) @@ -7626,19 +7707,19 @@ static struct hda_verb alc262_HP_BPC_init_verbs[] = { {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback + /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback * mixer widget * Note: PASD motherboards uses the Line In 2 as the input for * front panel mic (mic 2) */ /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)}, - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(6)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* * Set up output mixers (0x0c - 0x0e) @@ -7713,20 +7794,20 @@ static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = { {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback + /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback * mixer widget * Note: PASD motherboards uses the Line In 2 as the input for front * panel mic (mic 2) */ /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)}, - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(6)}, - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(7)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* * Set up output mixers (0x0c - 0x0e) */ @@ -7796,6 +7877,10 @@ static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = { { } }; +#ifdef CONFIG_SND_HDA_POWER_SAVE +#define alc262_loopbacks alc880_loopbacks +#endif + /* pcm configuration: identiacal with ALC880 */ #define alc262_pcm_analog_playback alc880_pcm_analog_playback #define alc262_pcm_analog_capture alc880_pcm_analog_capture @@ -8098,6 +8183,10 @@ static int patch_alc262(struct hda_codec *codec) codec->patch_ops = alc_patch_ops; if (board_config == ALC262_AUTO) spec->init_hook = alc262_auto_init; +#ifdef CONFIG_SND_HDA_POWER_SAVE + if (!spec->loopback.amplist) + spec->loopback.amplist = alc262_loopbacks; +#endif return 0; } @@ -8507,6 +8596,10 @@ static void alc268_auto_init(struct hda_codec *codec) alc268_auto_init_analog_input(codec); } +#ifdef CONFIG_SND_HDA_POWER_SAVE +#define alc883_loopbacks alc880_loopbacks +#endif + /* * configuration and preset */ @@ -9556,6 +9649,16 @@ static void alc861_auto_init(struct hda_codec *codec) alc861_auto_init_analog_input(codec); } +#ifdef CONFIG_SND_HDA_POWER_SAVE +static struct hda_amp_list alc861_loopbacks[] = { + { 0x15, HDA_INPUT, 0 }, + { 0x15, HDA_INPUT, 1 }, + { 0x15, HDA_INPUT, 2 }, + { 0x15, HDA_INPUT, 3 }, + { } /* end */ +}; +#endif + /* * configuration and preset @@ -9753,6 +9856,10 @@ static int patch_alc861(struct hda_codec *codec) codec->patch_ops = alc_patch_ops; if (board_config == ALC861_AUTO) spec->init_hook = alc861_auto_init; +#ifdef CONFIG_SND_HDA_POWER_SAVE + if (!spec->loopback.amplist) + spec->loopback.amplist = alc861_loopbacks; +#endif return 0; } @@ -10035,11 +10142,11 @@ static struct hda_verb alc861vd_volume_init_verbs[] = { * the analog-loopback mixer widget */ /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */ {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, @@ -10266,6 +10373,10 @@ static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int re alc861vd_dallas_automute(codec); } +#ifdef CONFIG_SND_HDA_POWER_SAVE +#define alc861vd_loopbacks alc880_loopbacks +#endif + /* pcm configuration: identiacal with ALC880 */ #define alc861vd_pcm_analog_playback alc880_pcm_analog_playback #define alc861vd_pcm_analog_capture alc880_pcm_analog_capture @@ -10688,6 +10799,10 @@ static int patch_alc861vd(struct hda_codec *codec) if (board_config == ALC861VD_AUTO) spec->init_hook = alc861vd_auto_init; +#ifdef CONFIG_SND_HDA_POWER_SAVE + if (!spec->loopback.amplist) + spec->loopback.amplist = alc861vd_loopbacks; +#endif return 0; } @@ -10968,11 +11083,11 @@ static struct hda_verb alc662_init_verbs[] = { {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front mixer: unmute input/output amp left and right (volume = 0) */ - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, @@ -11041,11 +11156,11 @@ static struct hda_verb alc662_auto_init_verbs[] = { * panel mic (mic 2) */ /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* * Set up output mixers (0x0c - 0x0f) @@ -11132,6 +11247,10 @@ static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec, alc662_lenovo_101e_ispeaker_automute(codec); } +#ifdef CONFIG_SND_HDA_POWER_SAVE +#define alc662_loopbacks alc880_loopbacks +#endif + /* pcm configuration: identiacal with ALC880 */ #define alc662_pcm_analog_playback alc880_pcm_analog_playback @@ -11534,6 +11653,10 @@ static int patch_alc662(struct hda_codec *codec) codec->patch_ops = alc_patch_ops; if (board_config == ALC662_AUTO) spec->init_hook = alc662_auto_init; +#ifdef CONFIG_SND_HDA_POWER_SAVE + if (!spec->loopback.amplist) + spec->loopback.amplist = alc662_loopbacks; +#endif return 0; } diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index bf5d91b63d1..4a981399abd 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -1946,7 +1946,7 @@ static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res) } } -#ifdef CONFIG_PM +#ifdef SND_HDA_NEEDS_RESUME static int stac92xx_resume(struct hda_codec *codec) { stac92xx_set_config_regs(codec); @@ -1963,7 +1963,7 @@ static struct hda_codec_ops stac92xx_patch_ops = { .init = stac92xx_init, .free = stac92xx_free, .unsol_event = stac92xx_unsol_event, -#ifdef CONFIG_PM +#ifdef SND_HDA_NEEDS_RESUME .resume = stac92xx_resume, #endif }; @@ -2460,7 +2460,7 @@ static struct hda_codec_ops stac9872_patch_ops = { .build_pcms = stac92xx_build_pcms, .init = stac92xx_init, .free = stac92xx_free, -#ifdef CONFIG_PM +#ifdef SND_HDA_NEEDS_RESUME .resume = stac92xx_resume, #endif }; diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index 6c734f07e5b..33b5e1ffa81 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c @@ -115,6 +115,10 @@ struct via_spec { struct snd_kcontrol_new *kctl_alloc; struct hda_input_mux private_imux; hda_nid_t private_dac_nids[4]; + +#ifdef CONFIG_SND_HDA_POWER_SAVE + struct hda_loopback_check loopback; +#endif }; static hda_nid_t vt1708_adc_nids[2] = { @@ -305,15 +309,15 @@ static struct hda_verb vt1708_volume_init_verbs[] = { {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback + /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback * mixer widget */ /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */ - {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, - {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, - {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, + {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, /* master */ + {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, + {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, + {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, + {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* * Set up output mixers (0x19 - 0x1b) @@ -543,6 +547,14 @@ static int via_init(struct hda_codec *codec) return 0; } +#ifdef CONFIG_SND_HDA_POWER_SAVE +static int via_check_power_status(struct hda_codec *codec, hda_nid_t nid) +{ + struct via_spec *spec = codec->spec; + return snd_hda_check_amp_list_power(codec, &spec->loopback, nid); +} +#endif + /* */ static struct hda_codec_ops via_patch_ops = { @@ -550,6 +562,9 @@ static struct hda_codec_ops via_patch_ops = { .build_pcms = via_build_pcms, .init = via_init, .free = via_free, +#ifdef CONFIG_SND_HDA_POWER_SAVE + .check_power_status = via_check_power_status, +#endif }; /* fill in the dac_nids table from the parsed pin configuration */ @@ -738,6 +753,16 @@ static int vt1708_auto_create_analog_input_ctls(struct via_spec *spec, return 0; } +#ifdef CONFIG_SND_HDA_POWER_SAVE +static struct hda_amp_list vt1708_loopbacks[] = { + { 0x17, HDA_INPUT, 1 }, + { 0x17, HDA_INPUT, 2 }, + { 0x17, HDA_INPUT, 3 }, + { 0x17, HDA_INPUT, 4 }, + { } /* end */ +}; +#endif + static int vt1708_parse_auto_config(struct hda_codec *codec) { struct via_spec *spec = codec->spec; @@ -831,6 +856,9 @@ static int patch_vt1708(struct hda_codec *codec) codec->patch_ops = via_patch_ops; codec->patch_ops.init = via_auto_init; +#ifdef CONFIG_SND_HDA_POWER_SAVE + spec->loopback.amplist = vt1708_loopbacks; +#endif return 0; } @@ -871,15 +899,15 @@ static struct hda_verb vt1709_10ch_volume_init_verbs[] = { {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback + /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback * mixer widget */ /* Amp Indices: AOW0=0, CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */ - {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, - {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, - {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, + {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, /* unmute master */ + {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, + {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, + {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, + {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* * Set up output selector (0x1a, 0x1b, 0x29) @@ -1227,6 +1255,16 @@ static int vt1709_parse_auto_config(struct hda_codec *codec) return 1; } +#ifdef CONFIG_SND_HDA_POWER_SAVE +static struct hda_amp_list vt1709_loopbacks[] = { + { 0x18, HDA_INPUT, 1 }, + { 0x18, HDA_INPUT, 2 }, + { 0x18, HDA_INPUT, 3 }, + { 0x18, HDA_INPUT, 4 }, + { } /* end */ +}; +#endif + static int patch_vt1709_10ch(struct hda_codec *codec) { struct via_spec *spec; @@ -1269,6 +1307,9 @@ static int patch_vt1709_10ch(struct hda_codec *codec) codec->patch_ops = via_patch_ops; codec->patch_ops.init = via_auto_init; +#ifdef CONFIG_SND_HDA_POWER_SAVE + spec->loopback.amplist = vt1709_loopbacks; +#endif return 0; } @@ -1359,6 +1400,9 @@ static int patch_vt1709_6ch(struct hda_codec *codec) codec->patch_ops = via_patch_ops; codec->patch_ops.init = via_auto_init; +#ifdef CONFIG_SND_HDA_POWER_SAVE + spec->loopback.amplist = vt1709_loopbacks; +#endif return 0; } -- cgit v1.2.3 From 51882453a729675aa7266aa87d99f33eca310c86 Mon Sep 17 00:00:00 2001 From: Mariusz Kozlowski Date: Sat, 11 Aug 2007 11:06:09 +0200 Subject: [ALSA] This patch removes memset() from snd_emu10k1_fx8010_info() which apparently isn't needed there. Upatched code uses: memset(info, 0, sizeof(info)); where 'info' is a pointer and therefore only first 4 bytes of 'info' gets cleared on a 32bit machine. Anyway looking at the code zeoring this memory region isn't needed at all because the snd_emu10k1_fx8010_info() function initializes all the 'info' fields on its own. So that's why this code works at all in its original form. This patch removes this redundant code. Also snd_emu10k1_fx8010_info() can't fail so lets save some bytes and change its return type to void. Signed-off-by: Mariusz Kozlowski Signed-off-by: Andrew Morton Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/emu10k1/emufx.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/emu10k1/emufx.c b/sound/pci/emu10k1/emufx.c index febdd130a20..5967e60119f 100644 --- a/sound/pci/emu10k1/emufx.c +++ b/sound/pci/emu10k1/emufx.c @@ -2440,14 +2440,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; @@ -2464,7 +2463,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) @@ -2485,10 +2483,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; -- cgit v1.2.3 From 95e99fdadb34debebd8dd35bb5a18b253dece22d Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 13 Aug 2007 15:29:04 +0200 Subject: [ALSA] hda-intel - Fix resume with power save The controller power wasn't turned on properly at resume due to the power-saving patch. Now fixed. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/hda_codec.c | 2 +- sound/pci/hda/hda_intel.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 9a3b72824f8..efd56a3396b 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -1662,6 +1662,7 @@ static void hda_call_codec_suspend(struct hda_codec *codec) AC_PWRST_D3); #ifdef CONFIG_SND_HDA_POWER_SAVE cancel_delayed_work(&codec->power_work); + codec->power_on = 0; #endif } @@ -2195,7 +2196,6 @@ static void hda_power_work(struct work_struct *work) return; hda_call_codec_suspend(codec); - codec->power_on = 0; if (codec->bus->ops.pm_notify) codec->bus->ops.pm_notify(codec); } diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 7be3a9b5533..f9c7c2e4f92 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -1500,7 +1500,7 @@ static int azx_acquire_irq(struct azx *chip, int do_disconnect) static void azx_stop_chip(struct azx *chip) { - if (chip->initialized) + if (!chip->initialized) return; /* disable interrupts */ -- cgit v1.2.3 From ae0a8ed8bf9c2edee4b831dee91ae914b9641fdd Mon Sep 17 00:00:00 2001 From: Tobin Davis Date: Mon, 13 Aug 2007 15:50:29 +0200 Subject: [ALSA] This patch adds more support for Dell systems with Stac9205 codecs. Tested against a couple of different systems (with different pin configs), but the others should also work. Also cleaned up some of the 9205 patch code. Signed-off-by: Tobin Davis Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_sigmatel.c | 64 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 53 insertions(+), 11 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 4a981399abd..e096a48899c 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -44,7 +44,9 @@ enum { enum { STAC_9205_REF, - STAC_M43xx, + STAC_9205_DELL_M43, + STAC_9205_DELL_M44, + STAC_9205_M43xx, STAC_9205_MODELS }; @@ -788,23 +790,58 @@ static unsigned int ref9205_pin_configs[12] = { 0x90a000f0, 0x90a000f0, 0x01441030, 0x01c41030 }; +static unsigned int dell_m43_9205_pin_configs[12] = { + 0x0321101f, 0x03a11020, 0x90a70330, 0x90170310, + 0x400000fe, 0x400000ff, 0x400000fd, 0x40f000f9, + 0x400000fa, 0x400000fc, 0x0144131f, 0x40c003f8, +}; + +static unsigned int dell_m44_9205_pin_configs[12] = { + 0x0421101f, 0x04a11020, 0x400003fa, 0x90170310, + 0x400003fb, 0x400003fc, 0x400003fd, 0x400003f9, + 0x90a60330, 0x400003ff, 0x01441340, 0x40c003fe, +}; + + static unsigned int *stac9205_brd_tbl[STAC_9205_MODELS] = { - [STAC_REF] = ref9205_pin_configs, - [STAC_M43xx] = NULL, + [STAC_9205_REF] = ref9205_pin_configs, + [STAC_9205_DELL_M43] = dell_m43_9205_pin_configs, + [STAC_9205_DELL_M44] = dell_m44_9205_pin_configs, + [STAC_9205_M43xx] = NULL, }; static const char *stac9205_models[STAC_9205_MODELS] = { [STAC_9205_REF] = "ref", + [STAC_9205_DELL_M43] = "dell-m43", + [STAC_9205_DELL_M44] = "dell-m44", }; static struct snd_pci_quirk stac9205_cfg_tbl[] = { /* SigmaTel reference board */ SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, "DFI LanParty", STAC_9205_REF), - SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x01f8, - "Dell Precision", STAC_M43xx), - SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x01ff, - "Dell Precision", STAC_M43xx), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f8, + "Dell Precision", STAC_9205_M43xx), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f9, + "Dell Precision", STAC_9205_DELL_M43), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fa, + "Dell Precision", STAC_9205_DELL_M43), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fe, + "Dell Precision", STAC_9205_DELL_M43), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ff, + "Dell Precision", STAC_9205_DELL_M43), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0206, + "Dell Precision", STAC_9205_DELL_M43), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f1, + "Dell Inspiron", STAC_9205_DELL_M44), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f2, + "Dell Inspiron", STAC_9205_DELL_M44), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fc, + "Dell Inspiron", STAC_9205_DELL_M44), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fd, + "Dell Inspiron", STAC_9205_DELL_M44), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021f, + "Dell Inspiron", STAC_9205_DELL_M44), {} /* terminator */ }; @@ -2312,7 +2349,9 @@ static int patch_stac9205(struct hda_codec *codec) spec->multiout.dac_nids = spec->dac_nids; - if (spec->board_config == STAC_M43xx) { + switch (spec->board_config){ + case STAC_9205_M43xx: + case STAC_9205_DELL_M43: /* Enable SPDIF in/out */ stac92xx_set_config_reg(codec, 0x1f, 0x01441030); stac92xx_set_config_reg(codec, 0x20, 0x1c410030); @@ -2322,9 +2361,12 @@ static int patch_stac9205(struct hda_codec *codec) * GPIO2 High = Headphone Mute */ spec->gpio_data = 0x00000005; - } else - spec->gpio_mask = spec->gpio_data = - 0x00000001; /* GPIO0 High = EAPD */ + break; + default: + /* GPIO0 High = EAPD */ + spec->gpio_mask = spec->gpio_data = 0x00000001; + break; + } stac92xx_enable_gpio_mask(codec); err = stac92xx_parse_auto_config(codec, 0x1f, 0x20); -- cgit v1.2.3 From dee1b66ce4f406d36fef70d1dd4360c5f1d26218 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 13 Aug 2007 16:10:30 +0200 Subject: [ALSA] hda-intel - Add power_save_controller module option Add power_save_controller module option instead of define flag. Also, added descriptions of new module options in ALSA-Configuration.txt. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/hda_intel.c | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index f9c7c2e4f92..e20629a2d7d 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -75,8 +75,18 @@ MODULE_PARM_DESC(single_cmd, "Use single command to communicate with codecs " module_param(enable_msi, int, 0); MODULE_PARM_DESC(enable_msi, "Enable Message Signaled Interrupt (MSI)"); +#ifdef CONFIG_SND_HDA_POWER_SAVE /* power_save option is defined in hda_codec.c */ +/* reset the HD-audio controller in power save mode. + * this may give more power-saving, but will take longer time to + * wake up. + */ +static int power_save_controller = 1; +module_param(power_save_controller, bool, 0644); +MODULE_PARM_DESC(power_save_controller, "Reset controller in power save mode."); +#endif + /* just for backward compatibility */ static int enable; module_param(enable, bool, 0444); @@ -102,17 +112,6 @@ MODULE_DESCRIPTION("Intel HDA driver"); #define SFX "hda-intel: " -/* - * build flags - */ - -/* - * reset the HD-audio controller in power save mode. - * this may give more power-saving, but will take longer time to - * wake up. - */ -#define HDA_POWER_SAVE_RESET_CONTROLLER - /* * registers @@ -1533,10 +1532,8 @@ static void azx_power_notify(struct hda_codec *codec) } if (power_on) azx_init_chip(chip); -#ifdef HDA_POWER_SAVE_RESET_CONTROLLER - else if (chip->running) + else if (chip->running && power_save_controller) azx_stop_chip(chip); -#endif } #endif /* CONFIG_SND_HDA_POWER_SAVE */ -- cgit v1.2.3 From f9ff161a14baca1a4ead5f12377ab25b9dd332e1 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 13 Aug 2007 16:16:53 +0200 Subject: [ALSA] mixart - Check ioremap error Check ioremap error and handle properly at initialization. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/mixart/mixart.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'sound/pci') diff --git a/sound/pci/mixart/mixart.c b/sound/pci/mixart/mixart.c index ac007cec087..c5109547f43 100644 --- a/sound/pci/mixart/mixart.c +++ b/sound/pci/mixart/mixart.c @@ -1317,6 +1317,12 @@ static int __devinit snd_mixart_probe(struct pci_dev *pci, mgr->mem[i].phys = pci_resource_start(pci, i); mgr->mem[i].virt = ioremap_nocache(mgr->mem[i].phys, pci_resource_len(pci, i)); + if (!mgr->mem[i].virt) { + printk(KERN_ERR "unable to remap resource 0x%lx\n", + mgr->mem[i].phys); + snd_mixart_free(mgr); + return -EBUSY; + } } if (request_irq(pci->irq, snd_mixart_interrupt, IRQF_SHARED, -- cgit v1.2.3 From b83f346bc4d6ab358fd0da85b7eab08bf0234c0b Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 13 Aug 2007 17:37:55 +0200 Subject: [ALSA] remove incorrect usage of SNDRV_PCM_INFO_SYNC_START and snd_pcm_set_sync() Set the SNDRV_PCM_INFO_SYNC_START flag and the substream's sync ID (only) if the substream actually can be linked to another one. Signed-off-by: Clemens Ladisch Signed-off-by: Jaroslav Kysela --- sound/pci/ca0106/ca0106_main.c | 10 ++++++---- sound/pci/cs4281.c | 24 ++++++++++-------------- sound/pci/cs5535audio/cs5535audio_pcm.c | 6 +----- sound/pci/emu10k1/p16v.c | 16 +++++++++++----- sound/pci/korg1212/korg1212.c | 4 ---- sound/pci/maestro3.c | 2 -- sound/pci/mixart/mixart.c | 4 ++-- sound/pci/nm256/nm256.c | 1 - sound/pci/pcxhr/pcxhr.c | 2 ++ sound/pci/rme96.c | 8 -------- 10 files changed, 32 insertions(+), 45 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c index c7f79be98d0..31d8db9f7a4 100644 --- a/sound/pci/ca0106/ca0106_main.c +++ b/sound/pci/ca0106/ca0106_main.c @@ -274,10 +274,11 @@ static struct snd_ca0106_details ca0106_chip_details[] = { /* hardware definition */ static struct snd_pcm_hardware snd_ca0106_playback_hw = { - .info = (SNDRV_PCM_INFO_MMAP | - SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_BLOCK_TRANSFER | - SNDRV_PCM_INFO_MMAP_VALID), + .info = SNDRV_PCM_INFO_MMAP | + SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_BLOCK_TRANSFER | + SNDRV_PCM_INFO_MMAP_VALID | + SNDRV_PCM_INFO_SYNC_START, .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE, .rates = (SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000), @@ -507,6 +508,7 @@ static int snd_ca0106_pcm_open_playback_channel(struct snd_pcm_substream *substr return err; if ((err = snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 64)) < 0) return err; + snd_pcm_set_sync(substream); if (chip->details->spi_dac && channel_id != PCM_FRONT_CHANNEL) { const int reg = spi_dacd_reg[channel_id]; diff --git a/sound/pci/cs4281.c b/sound/pci/cs4281.c index 44cf5460764..1fca49a1641 100644 --- a/sound/pci/cs4281.c +++ b/sound/pci/cs4281.c @@ -842,12 +842,11 @@ static snd_pcm_uframes_t snd_cs4281_pointer(struct snd_pcm_substream *substream) static struct snd_pcm_hardware snd_cs4281_playback = { - .info = (SNDRV_PCM_INFO_MMAP | - SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_MMAP_VALID | - SNDRV_PCM_INFO_PAUSE | - SNDRV_PCM_INFO_RESUME | - SNDRV_PCM_INFO_SYNC_START), + .info = SNDRV_PCM_INFO_MMAP | + SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_MMAP_VALID | + SNDRV_PCM_INFO_PAUSE | + SNDRV_PCM_INFO_RESUME, .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U16_LE | SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_BE | SNDRV_PCM_FMTBIT_S16_BE | @@ -868,12 +867,11 @@ static struct snd_pcm_hardware snd_cs4281_playback = static struct snd_pcm_hardware snd_cs4281_capture = { - .info = (SNDRV_PCM_INFO_MMAP | - SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_MMAP_VALID | - SNDRV_PCM_INFO_PAUSE | - SNDRV_PCM_INFO_RESUME | - SNDRV_PCM_INFO_SYNC_START), + .info = SNDRV_PCM_INFO_MMAP | + SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_MMAP_VALID | + SNDRV_PCM_INFO_PAUSE | + SNDRV_PCM_INFO_RESUME, .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U16_LE | SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_BE | SNDRV_PCM_FMTBIT_S16_BE | @@ -904,7 +902,6 @@ static int snd_cs4281_playback_open(struct snd_pcm_substream *substream) dma->right_slot = 1; runtime->private_data = dma; runtime->hw = snd_cs4281_playback; - snd_pcm_set_sync(substream); /* should be detected from the AC'97 layer, but it seems that although CS4297A rev B reports 18-bit ADC resolution, samples are 20-bit */ @@ -924,7 +921,6 @@ static int snd_cs4281_capture_open(struct snd_pcm_substream *substream) dma->right_slot = 11; runtime->private_data = dma; runtime->hw = snd_cs4281_capture; - snd_pcm_set_sync(substream); /* should be detected from the AC'97 layer, but it seems that although CS4297A rev B reports 18-bit ADC resolution, samples are 20-bit */ diff --git a/sound/pci/cs5535audio/cs5535audio_pcm.c b/sound/pci/cs5535audio/cs5535audio_pcm.c index 5450a9e8f13..ec920cbb2a7 100644 --- a/sound/pci/cs5535audio/cs5535audio_pcm.c +++ b/sound/pci/cs5535audio/cs5535audio_pcm.c @@ -43,7 +43,6 @@ static struct snd_pcm_hardware snd_cs5535audio_playback = SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_PAUSE | - SNDRV_PCM_INFO_SYNC_START | SNDRV_PCM_INFO_RESUME ), .formats = ( @@ -71,8 +70,7 @@ static struct snd_pcm_hardware snd_cs5535audio_capture = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | - SNDRV_PCM_INFO_MMAP_VALID | - SNDRV_PCM_INFO_SYNC_START + SNDRV_PCM_INFO_MMAP_VALID ), .formats = ( SNDRV_PCM_FMTBIT_S16_LE @@ -102,7 +100,6 @@ static int snd_cs5535audio_playback_open(struct snd_pcm_substream *substream) runtime->hw = snd_cs5535audio_playback; cs5535au->playback_substream = substream; runtime->private_data = &(cs5535au->dmas[CS5535AUDIO_DMA_PLAYBACK]); - snd_pcm_set_sync(substream); if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0) return err; @@ -348,7 +345,6 @@ static int snd_cs5535audio_capture_open(struct snd_pcm_substream *substream) runtime->hw = snd_cs5535audio_capture; cs5535au->capture_substream = substream; runtime->private_data = &(cs5535au->dmas[CS5535AUDIO_DMA_CAPTURE]); - snd_pcm_set_sync(substream); if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0) return err; diff --git a/sound/pci/emu10k1/p16v.c b/sound/pci/emu10k1/p16v.c index 6ace1076c19..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 */ diff --git a/sound/pci/korg1212/korg1212.c b/sound/pci/korg1212/korg1212.c index 5338243fb03..c4af57fb5af 100644 --- a/sound/pci/korg1212/korg1212.c +++ b/sound/pci/korg1212/korg1212.c @@ -1391,8 +1391,6 @@ static int snd_korg1212_playback_open(struct snd_pcm_substream *substream) K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_playback_open [%s]\n", stateName[korg1212->cardState]); - snd_pcm_set_sync(substream); // ??? - snd_korg1212_OpenCard(korg1212); runtime->hw = snd_korg1212_playback_info; @@ -1422,8 +1420,6 @@ static int snd_korg1212_capture_open(struct snd_pcm_substream *substream) K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_capture_open [%s]\n", stateName[korg1212->cardState]); - snd_pcm_set_sync(substream); - snd_korg1212_OpenCard(korg1212); runtime->hw = snd_korg1212_capture_info; diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c index 8a5ff1cb536..32245770595 100644 --- a/sound/pci/maestro3.c +++ b/sound/pci/maestro3.c @@ -1821,7 +1821,6 @@ snd_m3_playback_open(struct snd_pcm_substream *subs) return err; runtime->hw = snd_m3_playback; - snd_pcm_set_sync(subs); return 0; } @@ -1846,7 +1845,6 @@ snd_m3_capture_open(struct snd_pcm_substream *subs) return err; runtime->hw = snd_m3_capture; - snd_pcm_set_sync(subs); return 0; } diff --git a/sound/pci/mixart/mixart.c b/sound/pci/mixart/mixart.c index c5109547f43..880b824e24c 100644 --- a/sound/pci/mixart/mixart.c +++ b/sound/pci/mixart/mixart.c @@ -652,7 +652,7 @@ static int snd_mixart_hw_free(struct snd_pcm_substream *subs) static struct snd_pcm_hardware snd_mixart_analog_caps = { .info = ( SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START | + SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_PAUSE), .formats = ( SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE | @@ -673,7 +673,7 @@ static struct snd_pcm_hardware snd_mixart_analog_caps = static struct snd_pcm_hardware snd_mixart_digital_caps = { .info = ( SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START | + SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_PAUSE), .formats = ( SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE | diff --git a/sound/pci/nm256/nm256.c b/sound/pci/nm256/nm256.c index c7621bd770a..276c5763f0e 100644 --- a/sound/pci/nm256/nm256.c +++ b/sound/pci/nm256/nm256.c @@ -842,7 +842,6 @@ static void snd_nm256_setup_stream(struct nm256 *chip, struct nm256_stream *s, runtime->private_data = s; s->substream = substream; - snd_pcm_set_sync(substream); snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &constraints_rates); } diff --git a/sound/pci/pcxhr/pcxhr.c b/sound/pci/pcxhr/pcxhr.c index 1b787f45557..cd4613a97bd 100644 --- a/sound/pci/pcxhr/pcxhr.c +++ b/sound/pci/pcxhr/pcxhr.c @@ -904,6 +904,8 @@ static int pcxhr_open(struct snd_pcm_substream *subs) snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 4); snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 4); + snd_pcm_set_sync(subs); + mgr->ref_count_rate++; mutex_unlock(&mgr->setup_mutex); diff --git a/sound/pci/rme96.c b/sound/pci/rme96.c index 9a4596f879e..ba4a34bae48 100644 --- a/sound/pci/rme96.c +++ b/sound/pci/rme96.c @@ -1176,8 +1176,6 @@ snd_rme96_playback_spdif_open(struct snd_pcm_substream *substream) struct rme96 *rme96 = snd_pcm_substream_chip(substream); struct snd_pcm_runtime *runtime = substream->runtime; - snd_pcm_set_sync(substream); - spin_lock_irq(&rme96->lock); if (rme96->playback_substream != NULL) { spin_unlock_irq(&rme96->lock); @@ -1214,8 +1212,6 @@ snd_rme96_capture_spdif_open(struct snd_pcm_substream *substream) struct rme96 *rme96 = snd_pcm_substream_chip(substream); struct snd_pcm_runtime *runtime = substream->runtime; - snd_pcm_set_sync(substream); - runtime->hw = snd_rme96_capture_spdif_info; if (snd_rme96_getinputtype(rme96) != RME96_INPUT_ANALOG && (rate = snd_rme96_capture_getrate(rme96, &isadat)) > 0) @@ -1247,8 +1243,6 @@ snd_rme96_playback_adat_open(struct snd_pcm_substream *substream) struct rme96 *rme96 = snd_pcm_substream_chip(substream); struct snd_pcm_runtime *runtime = substream->runtime; - snd_pcm_set_sync(substream); - spin_lock_irq(&rme96->lock); if (rme96->playback_substream != NULL) { spin_unlock_irq(&rme96->lock); @@ -1280,8 +1274,6 @@ snd_rme96_capture_adat_open(struct snd_pcm_substream *substream) struct rme96 *rme96 = snd_pcm_substream_chip(substream); struct snd_pcm_runtime *runtime = substream->runtime; - snd_pcm_set_sync(substream); - runtime->hw = snd_rme96_capture_adat_info; if (snd_rme96_getinputtype(rme96) == RME96_INPUT_ANALOG) { /* makes no sense to use analog input. Note that analog -- cgit v1.2.3 From 918f3a0e8cf67b5db966516f255eaf24d814fac0 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 13 Aug 2007 17:40:54 +0200 Subject: [ALSA] pcm: add snd_pcm_rate_to_rate_bit() helper Add a snd_pcm_rate_to_rate_bit() function to factor out common code used by several drivers. Signed-off-by: Clemens Ladisch Signed-off-by: Jaroslav Kysela --- sound/pci/bt87x.c | 21 +-------------------- sound/pci/rme32.c | 21 ++++----------------- sound/pci/rme96.c | 22 ++++------------------ 3 files changed, 9 insertions(+), 55 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c index f0e12985dc2..85d50b64d2b 100644 --- a/sound/pci/bt87x.c +++ b/sound/pci/bt87x.c @@ -340,28 +340,9 @@ static struct snd_pcm_hardware snd_bt87x_analog_hw = { static int snd_bt87x_set_digital_hw(struct snd_bt87x *chip, struct snd_pcm_runtime *runtime) { - static struct { - int rate; - unsigned int bit; - } ratebits[] = { - {8000, SNDRV_PCM_RATE_8000}, - {11025, SNDRV_PCM_RATE_11025}, - {16000, SNDRV_PCM_RATE_16000}, - {22050, SNDRV_PCM_RATE_22050}, - {32000, SNDRV_PCM_RATE_32000}, - {44100, SNDRV_PCM_RATE_44100}, - {48000, SNDRV_PCM_RATE_48000} - }; - int i; - chip->reg_control |= CTL_DA_IOM_DA; runtime->hw = snd_bt87x_digital_hw; - runtime->hw.rates = SNDRV_PCM_RATE_KNOT; - for (i = 0; i < ARRAY_SIZE(ratebits); ++i) - if (chip->dig_rate == ratebits[i].rate) { - runtime->hw.rates = ratebits[i].bit; - break; - } + runtime->hw.rates = snd_pcm_rate_to_rate_bit(chip->dig_rate); runtime->hw.rate_min = chip->dig_rate; runtime->hw.rate_max = chip->dig_rate; return 0; diff --git a/sound/pci/rme32.c b/sound/pci/rme32.c index ee0189b756d..1475912588e 100644 --- a/sound/pci/rme32.c +++ b/sound/pci/rme32.c @@ -258,19 +258,6 @@ static inline unsigned int snd_rme32_pcm_byteptr(struct rme32 * rme32) & RME32_RCR_AUDIO_ADDR_MASK); } -static int snd_rme32_ratecode(int rate) -{ - switch (rate) { - case 32000: return SNDRV_PCM_RATE_32000; - case 44100: return SNDRV_PCM_RATE_44100; - case 48000: return SNDRV_PCM_RATE_48000; - case 64000: return SNDRV_PCM_RATE_64000; - case 88200: return SNDRV_PCM_RATE_88200; - case 96000: return SNDRV_PCM_RATE_96000; - } - return 0; -} - /* silence callback for halfduplex mode */ static int snd_rme32_playback_silence(struct snd_pcm_substream *substream, int channel, /* not used (interleaved data) */ snd_pcm_uframes_t pos, @@ -887,7 +874,7 @@ static int snd_rme32_playback_spdif_open(struct snd_pcm_substream *substream) if ((rme32->rcreg & RME32_RCR_KMODE) && (rate = snd_rme32_capture_getrate(rme32, &dummy)) > 0) { /* AutoSync */ - runtime->hw.rates = snd_rme32_ratecode(rate); + runtime->hw.rates = snd_pcm_rate_to_rate_bit(rate); runtime->hw.rate_min = rate; runtime->hw.rate_max = rate; } @@ -929,7 +916,7 @@ static int snd_rme32_capture_spdif_open(struct snd_pcm_substream *substream) if (isadat) { return -EIO; } - runtime->hw.rates = snd_rme32_ratecode(rate); + runtime->hw.rates = snd_pcm_rate_to_rate_bit(rate); runtime->hw.rate_min = rate; runtime->hw.rate_max = rate; } @@ -965,7 +952,7 @@ snd_rme32_playback_adat_open(struct snd_pcm_substream *substream) if ((rme32->rcreg & RME32_RCR_KMODE) && (rate = snd_rme32_capture_getrate(rme32, &dummy)) > 0) { /* AutoSync */ - runtime->hw.rates = snd_rme32_ratecode(rate); + runtime->hw.rates = snd_pcm_rate_to_rate_bit(rate); runtime->hw.rate_min = rate; runtime->hw.rate_max = rate; } @@ -989,7 +976,7 @@ snd_rme32_capture_adat_open(struct snd_pcm_substream *substream) if (!isadat) { return -EIO; } - runtime->hw.rates = snd_rme32_ratecode(rate); + runtime->hw.rates = snd_pcm_rate_to_rate_bit(rate); runtime->hw.rate_min = rate; runtime->hw.rate_max = rate; } diff --git a/sound/pci/rme96.c b/sound/pci/rme96.c index ba4a34bae48..0b3c532c401 100644 --- a/sound/pci/rme96.c +++ b/sound/pci/rme96.c @@ -300,20 +300,6 @@ snd_rme96_capture_ptr(struct rme96 *rme96) & RME96_RCR_AUDIO_ADDR_MASK) >> rme96->capture_frlog; } -static int -snd_rme96_ratecode(int rate) -{ - switch (rate) { - case 32000: return SNDRV_PCM_RATE_32000; - case 44100: return SNDRV_PCM_RATE_44100; - case 48000: return SNDRV_PCM_RATE_48000; - case 64000: return SNDRV_PCM_RATE_64000; - case 88200: return SNDRV_PCM_RATE_88200; - case 96000: return SNDRV_PCM_RATE_96000; - } - return 0; -} - static int snd_rme96_playback_silence(struct snd_pcm_substream *substream, int channel, /* not used (interleaved data) */ @@ -1192,7 +1178,7 @@ snd_rme96_playback_spdif_open(struct snd_pcm_substream *substream) (rate = snd_rme96_capture_getrate(rme96, &dummy)) > 0) { /* slave clock */ - runtime->hw.rates = snd_rme96_ratecode(rate); + runtime->hw.rates = snd_pcm_rate_to_rate_bit(rate); runtime->hw.rate_min = rate; runtime->hw.rate_max = rate; } @@ -1219,7 +1205,7 @@ snd_rme96_capture_spdif_open(struct snd_pcm_substream *substream) if (isadat) { return -EIO; } - runtime->hw.rates = snd_rme96_ratecode(rate); + runtime->hw.rates = snd_pcm_rate_to_rate_bit(rate); runtime->hw.rate_min = rate; runtime->hw.rate_max = rate; } @@ -1259,7 +1245,7 @@ snd_rme96_playback_adat_open(struct snd_pcm_substream *substream) (rate = snd_rme96_capture_getrate(rme96, &dummy)) > 0) { /* slave clock */ - runtime->hw.rates = snd_rme96_ratecode(rate); + runtime->hw.rates = snd_pcm_rate_to_rate_bit(rate); runtime->hw.rate_min = rate; runtime->hw.rate_max = rate; } @@ -1284,7 +1270,7 @@ snd_rme96_capture_adat_open(struct snd_pcm_substream *substream) if (!isadat) { return -EIO; } - runtime->hw.rates = snd_rme96_ratecode(rate); + runtime->hw.rates = snd_pcm_rate_to_rate_bit(rate); runtime->hw.rate_min = rate; runtime->hw.rate_max = rate; } -- cgit v1.2.3 From 9d99f312629802f4c45306ee07618ee4978b4adc Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 14 Aug 2007 15:15:52 +0200 Subject: [ALSA] hda-intel - Fix NULL dereference in resume codec->patch_ops.init can be NULL. Check before calling it. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/hda_codec.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index efd56a3396b..fc1ddf408b9 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -1677,7 +1677,8 @@ static void hda_call_codec_resume(struct hda_codec *codec) if (codec->patch_ops.resume) codec->patch_ops.resume(codec); else { - codec->patch_ops.init(codec); + if (codec->patch_ops.init) + codec->patch_ops.init(codec); snd_hda_codec_resume_amp(codec); snd_hda_codec_resume_cache(codec); } -- cgit v1.2.3 From 0b7a2e9cefd7614e68520127751f76583498df6c Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 14 Aug 2007 15:18:26 +0200 Subject: [ALSA] hda-intel - Don't do suspend if already powered down In the power-saving mode, the suspend is done dynamically at power-down. So we don't have to call suspend stuff explicitly if it's already powered down. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/hda_codec.c | 4 ++++ sound/pci/hda/hda_intel.c | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index fc1ddf408b9..0e923f3f0a8 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -2771,6 +2771,10 @@ int snd_hda_suspend(struct hda_bus *bus, pm_message_t state) struct hda_codec *codec; list_for_each_entry(codec, &bus->codec_list, list) { +#ifdef CONFIG_SND_HDA_POWER_SAVE + if (!codec->power_on) + continue; +#endif hda_call_codec_suspend(codec); } return 0; diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index e20629a2d7d..ab698336563 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -1550,7 +1550,8 @@ static int azx_suspend(struct pci_dev *pci, pm_message_t state) snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); for (i = 0; i < chip->pcm_devs; i++) snd_pcm_suspend_all(chip->pcm[i]); - snd_hda_suspend(chip->bus, state); + if (chip->initialized) + snd_hda_suspend(chip->bus, state); azx_stop_chip(chip); if (chip->irq >= 0) { synchronize_irq(chip->irq); -- cgit v1.2.3 From 765c24efa55752b715d9122f36eee485d4903839 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 15 Aug 2007 15:43:06 +0200 Subject: [ALSA] hda-codec - Remove conflicting capture mixers for ALC861VD Removed conflicting capture mixers for ALC861VD model=dallas. It fixes the ALSA bug#3236. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_realtek.c | 11 ----------- 1 file changed, 11 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index b3d3916c8ec..171f64192dc 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -10114,17 +10114,6 @@ static struct snd_kcontrol_new alc861vd_dallas_mixer[] = { HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x05, HDA_INPUT), HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x05, HDA_INPUT), - HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), - HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - /* .name = "Capture Source", */ - .name = "Input Source", - .count = 1, - .info = alc882_mux_enum_info, - .get = alc882_mux_enum_get, - .put = alc882_mux_enum_put, - }, { } /* end */ }; -- cgit v1.2.3 From d1a991a682f6718db6c611ccfd36d903732d946c Mon Sep 17 00:00:00 2001 From: Kailang Yang Date: Wed, 15 Aug 2007 16:21:59 +0200 Subject: [ALSA] hda-codec - Update realtek codec support 1. Support Acer Aspire 9810 2. Support TOSHIBA A205 3. Support HP TX1000 Signed-off-by: Kailang Yang Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_realtek.c | 125 +++++++++++++++++++++++++++++++----------- 1 file changed, 93 insertions(+), 32 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 171f64192dc..778853c0de8 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -102,6 +102,7 @@ enum { /* ALC268 models */ enum { ALC268_3ST, + ALC268_TOSHIBA, ALC268_AUTO, ALC268_MODEL_LAST /* last tag */ }; @@ -129,6 +130,7 @@ enum { ALC861VD_6ST_DIG, ALC861VD_LENOVO, ALC861VD_DALLAS, + ALC861VD_HP, ALC861VD_AUTO, ALC861VD_MODEL_LAST, }; @@ -6253,16 +6255,14 @@ static struct snd_kcontrol_new alc888_3st_hp_mixer[] = { }; static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = { - HDA_CODEC_VOLUME("Front Playback Volume", 0x0d, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), + HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), - HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), + HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), @@ -6277,7 +6277,7 @@ static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = { .put = alc883_mux_enum_put, }, { } /* end */ -}; +}; static struct snd_kcontrol_new alc883_chmode_mixer[] = { { @@ -6490,18 +6490,6 @@ static struct hda_verb alc883_medion_md2_verbs[] = { { } /* end */ }; -static struct hda_verb alc883_acer_aspire_verbs[] = { - {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - - {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, - - {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, - { } /* end */ -}; - /* toggle speaker-output according to the hp-jack state */ static void alc883_medion_md2_automute(struct hda_codec *codec) { @@ -6576,6 +6564,21 @@ static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec, alc883_lenovo_101e_ispeaker_automute(codec); } +static struct hda_verb alc883_acer_eapd_verbs[] = { + /* HP Pin: output 0 (0x0c) */ + {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, + {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, + {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, + /* Front Pin: output 0 (0x0c) */ + {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, + {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, + {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, + /* eanable EAPD on medion laptop */ + {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, + {0x20, AC_VERB_SET_PROC_COEF, 0x3050}, + { } +}; + /* * generic initialization of ADC, input mixers and output mixers */ @@ -6718,6 +6721,7 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = { SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG), SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG), SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG), + SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE), SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE), SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER), SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch), @@ -6834,8 +6838,13 @@ static struct alc_config_preset alc883_presets[] = { .input_mux = &alc883_capture_source, }, [ALC883_ACER_ASPIRE] = { - .mixers = { alc883_acer_aspire_mixer}, - .init_verbs = { alc883_init_verbs, alc883_acer_aspire_verbs}, + .mixers = { alc883_acer_aspire_mixer, alc883_chmode_mixer }, + /* On TravelMate laptops, GPIO 0 enables the internal speaker + * and the headphone jack. Turn this on and rely on the + * standard mute methods whenever the user wants to turn + * these outputs off. + */ + .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs }, .num_dacs = ARRAY_SIZE(alc883_dac_nids), .dac_nids = alc883_dac_nids, .dig_out_nid = ALC883_DIGOUT_NID, @@ -6844,9 +6853,7 @@ static struct alc_config_preset alc883_presets[] = { .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), .channel_mode = alc883_3ST_2ch_modes, .input_mux = &alc883_capture_source, - .unsol_event = alc883_medion_md2_unsol_event, - .init_hook = alc883_medion_md2_automute, - }, + }, [ALC883_MEDION] = { .mixers = { alc883_fivestack_mixer, alc883_chmode_mixer }, @@ -8221,6 +8228,12 @@ static struct snd_kcontrol_new alc268_base_mixer[] = { { } }; +static struct hda_verb alc268_eapd_verbs[] = { + {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, + {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, + { } +}; + /* * generic initialization of ADC, input mixers and output mixers */ @@ -8610,6 +8623,7 @@ static const char *alc268_models[ALC268_MODEL_LAST] = { static struct snd_pci_quirk alc268_cfg_tbl[] = { SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST), + SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA), {} }; @@ -8627,6 +8641,18 @@ static struct alc_config_preset alc268_presets[] = { .channel_mode = alc268_modes, .input_mux = &alc268_capture_source, }, + [ALC268_TOSHIBA] = { + .mixers = { alc268_base_mixer, alc268_capture_alt_mixer }, + .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs }, + .num_dacs = ARRAY_SIZE(alc268_dac_nids), + .dac_nids = alc268_dac_nids, + .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), + .adc_nids = alc268_adc_nids_alt, + .hp_nid = 0x03, + .num_channel_mode = ARRAY_SIZE(alc268_modes), + .channel_mode = alc268_modes, + .input_mux = &alc268_capture_source, + }, }; static int patch_alc268(struct hda_codec *codec) @@ -9916,6 +9942,14 @@ static struct hda_input_mux alc861vd_dallas_capture_source = { }, }; +static struct hda_input_mux alc861vd_hp_capture_source = { + .num_items = 2, + .items = { + { "Front Mic", 0x0 }, + { "ATAPI Mic", 0x1 }, + }, +}; + #define alc861vd_mux_enum_info alc_mux_enum_info #define alc861vd_mux_enum_get alc_mux_enum_get @@ -10117,6 +10151,22 @@ static struct snd_kcontrol_new alc861vd_dallas_mixer[] = { { } /* end */ }; +/* Pin assignment: Speaker=0x14, Line-out = 0x15, + * Front Mic=0x18, ATAPI Mic = 0x19, + */ +static struct snd_kcontrol_new alc861vd_hp_mixer[] = { + HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), + HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), + HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), + HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT), + HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), + + { } /* end */ +}; + /* * generic initialization of ADC, input mixers and output mixers */ @@ -10399,6 +10449,7 @@ static struct snd_pci_quirk alc861vd_cfg_tbl[] = { SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO), SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO), SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG), + SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP), {} }; @@ -10488,7 +10539,21 @@ static struct alc_config_preset alc861vd_presets[] = { .input_mux = &alc861vd_dallas_capture_source, .unsol_event = alc861vd_dallas_unsol_event, .init_hook = alc861vd_dallas_automute, - }, + }, + [ALC861VD_HP] = { + .mixers = { alc861vd_hp_mixer }, + .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs }, + .num_dacs = ARRAY_SIZE(alc861vd_dac_nids), + .dac_nids = alc861vd_dac_nids, + .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids), + .dig_out_nid = ALC861VD_DIGOUT_NID, + .adc_nids = alc861vd_adc_nids, + .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), + .channel_mode = alc861vd_3stack_2ch_modes, + .input_mux = &alc861vd_hp_capture_source, + .unsol_event = alc861vd_dallas_unsol_event, + .init_hook = alc861vd_dallas_automute, + }, }; /* @@ -10849,7 +10914,7 @@ static int alc662_mux_enum_put(struct snd_kcontrol *kcontrol, struct alc_spec *spec = codec->spec; const struct hda_input_mux *imux = spec->input_mux; unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); - static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 }; + static hda_nid_t capture_mixers[2] = { 0x23, 0x22 }; hda_nid_t nid = capture_mixers[adc_idx]; unsigned int *cur_val = &spec->cur_mux[adc_idx]; unsigned int i, idx; @@ -11173,11 +11238,7 @@ static struct hda_verb alc662_auto_init_verbs[] = { /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ /* Input mixer */ {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, - /*{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},*/ - {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, - + {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, { } }; -- cgit v1.2.3 From 39c5d41ffef0e176968079f2f84f657e8511cdf9 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 15 Aug 2007 16:24:17 +0200 Subject: [ALSA] hda-codec - Add support for Biostar NF61S SE mobo Added the support for Biostar NF61S SE mobo with ALC861VD codec, model=6stack-digout (ALSA bug#3190). Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 778853c0de8..3a028814310 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -10448,6 +10448,7 @@ static struct snd_pci_quirk alc861vd_cfg_tbl[] = { SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO), SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO), SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO), + SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG), SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG), SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP), {} -- cgit v1.2.3 From 983f8ae4067cf0731f19fc6bda3bc3ef200c32e7 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 15 Aug 2007 16:44:04 +0200 Subject: [ALSA] hda-codec - Add option texts and descriptions for new Realtek models Added the missing text entries and descriptions for the newly added model values for Realtek codec chips. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_realtek.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 3a028814310..a6fcfbce0c0 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -8618,6 +8618,7 @@ static void alc268_auto_init(struct hda_codec *codec) */ static const char *alc268_models[ALC268_MODEL_LAST] = { [ALC268_3ST] = "3stack", + [ALC268_TOSHIBA] = "toshiba", [ALC268_AUTO] = "auto", }; @@ -10427,12 +10428,13 @@ static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int re */ static const char *alc861vd_models[ALC861VD_MODEL_LAST] = { [ALC660VD_3ST] = "3stack-660", - [ALC660VD_3ST_DIG]= "3stack-660-digout", + [ALC660VD_3ST_DIG] = "3stack-660-digout", [ALC861VD_3ST] = "3stack", [ALC861VD_3ST_DIG] = "3stack-digout", [ALC861VD_6ST_DIG] = "6stack-digout", [ALC861VD_LENOVO] = "lenovo", [ALC861VD_DALLAS] = "dallas", + [ALC861VD_HP] = "hp", [ALC861VD_AUTO] = "auto", }; -- cgit v1.2.3 From 2525fdc42fdc4bb943ec2fa5a37e2ae139e1b6d3 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 15 Aug 2007 22:18:22 +0200 Subject: [ALSA] hda-intel - Add flush_scheduled_work() in snd_hda_codec_free() Added flush_scheduled_work() in snd_hda_codec_free() to make sure that the all work is gone. Also, optimized the condition to schedule the delayed work in snd_hda_power_down(). Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/hda_codec.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 0e923f3f0a8..0b9029436bb 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -525,6 +525,7 @@ static void snd_hda_codec_free(struct hda_codec *codec) return; #ifdef CONFIG_SND_HDA_POWER_SAVE cancel_delayed_work(&codec->power_work); + flush_scheduled_work(); #endif list_del(&codec->list); codec->bus->caddr_tbl[codec->addr] = NULL; @@ -2223,7 +2224,7 @@ void snd_hda_power_up(struct hda_codec *codec) void snd_hda_power_down(struct hda_codec *codec) { --codec->power_count; - if (!codec->power_on) + if (!codec->power_on || codec->power_count) return; if (power_save) schedule_delayed_work(&codec->power_work, -- cgit v1.2.3 From 20a45e8644ef4f5e7dfd727859301c4c581e9489 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 15 Aug 2007 22:20:45 +0200 Subject: [ALSA] hda-codec - Fix Master volume with AD1986A laptop model Use the bind-control for NID 0x1a and 0x1b as Master volume control on AD1986 model=laptop as well as model=laptop-eapd. This will fix the missing output on some devices. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_analog.c | 44 +++++++++++++++++++++----------------------- 1 file changed, 21 insertions(+), 23 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index 53cfa0da496..bc4b797aa97 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c @@ -498,13 +498,30 @@ static struct snd_kcontrol_new ad1986a_3st_mixers[] = { /* laptop model - 2ch only */ static hda_nid_t ad1986a_laptop_dac_nids[1] = { AD1986A_FRONT_DAC }; +/* master controls both pins 0x1a and 0x1b */ +static struct hda_bind_ctls ad1986a_laptop_master_vol = { + .ops = &snd_hda_bind_vol, + .values = { + HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT), + HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT), + 0, + }, +}; + +static struct hda_bind_ctls ad1986a_laptop_master_sw = { + .ops = &snd_hda_bind_sw, + .values = { + HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT), + HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT), + 0, + }, +}; + static struct snd_kcontrol_new ad1986a_laptop_mixers[] = { HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Master Playback Volume", 0x1b, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Master Playback Switch", 0x1b, 0x0, HDA_OUTPUT), - /* HDA_CODEC_VOLUME("Headphone Playback Volume", 0x1a, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT), */ + HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol), + HDA_BIND_SW("Master Playback Switch", &ad1986a_laptop_master_sw), HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Line Playback Volume", 0x17, 0x0, HDA_OUTPUT), @@ -532,25 +549,6 @@ static struct snd_kcontrol_new ad1986a_laptop_mixers[] = { /* laptop-eapd model - 2ch only */ -/* master controls both pins 0x1a and 0x1b */ -static struct hda_bind_ctls ad1986a_laptop_master_vol = { - .ops = &snd_hda_bind_vol, - .values = { - HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT), - HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT), - 0, - }, -}; - -static struct hda_bind_ctls ad1986a_laptop_master_sw = { - .ops = &snd_hda_bind_sw, - .values = { - HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT), - HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT), - 0, - }, -}; - static struct hda_input_mux ad1986a_laptop_eapd_capture_source = { .num_items = 3, .items = { -- cgit v1.2.3 From 0cb65f2262776e07c2b8ec1121738b97f8941dae Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 16 Aug 2007 12:32:45 +0200 Subject: [ALSA] hda-intel - Add position_fix quirk for Dell Precision 390 Dell Precision 390 needs position_fix=1 as default (ALSA bug#3295). Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/hda_intel.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sound/pci') diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index ab698336563..14bcc108e77 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -1642,6 +1642,7 @@ static int azx_dev_free(struct snd_device *device) */ static struct snd_pci_quirk position_fix_list[] __devinitdata = { SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_NONE), + SND_PCI_QUIRK(0x1028, 0x01de, "Dell Precision 390", POS_FIX_NONE), {} }; -- cgit v1.2.3 From d273809e2e512d0638d443dce408ac0342ab73cf Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 16 Aug 2007 14:59:45 +0200 Subject: [ALSA] hda-codec - Add ALC268 acer model Added model=acer for ALC268 codec support. The configuration is: headphone = 0x14, speaker = 0x15 needs hp-jack auto-detection. The same routine as alc262-fujitsu model is used. Also, added the auto-muting routine for ALC268 model=toshiba. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_realtek.c | 76 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 75 insertions(+), 1 deletion(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index a6fcfbce0c0..b47934f87f8 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -103,6 +103,7 @@ enum { enum { ALC268_3ST, ALC268_TOSHIBA, + ALC268_ACER, ALC268_AUTO, ALC268_MODEL_LAST /* last tag */ }; @@ -8234,6 +8235,58 @@ static struct hda_verb alc268_eapd_verbs[] = { { } }; +/* Toshiba specific */ +#define alc268_toshiba_automute alc262_hippo_automute + +static struct hda_verb alc268_toshiba_verbs[] = { + {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, + { } /* end */ +}; + +/* Acer specific */ +#define alc268_acer_bind_master_vol alc262_fujitsu_bind_master_vol +#define alc268_acer_master_sw_put alc262_fujitsu_master_sw_put +#define alc268_acer_automute alc262_fujitsu_automute + +static struct snd_kcontrol_new alc268_acer_mixer[] = { + /* output mixer control */ + HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol), + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Master Playback Switch", + .info = snd_hda_mixer_amp_switch_info, + .get = snd_hda_mixer_amp_switch_get, + .put = alc268_acer_master_sw_put, + .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), + }, + { } +}; + +static struct hda_verb alc268_acer_verbs[] = { + {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, + {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, + + {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, + { } +}; + +/* unsolicited event for HP jack sensing */ +static void alc268_toshiba_unsol_event(struct hda_codec *codec, + unsigned int res) +{ + if ((res >> 28) != ALC880_HP_EVENT) + return; + alc268_toshiba_automute(codec); +} + +static void alc268_acer_unsol_event(struct hda_codec *codec, + unsigned int res) +{ + if ((res >> 28) != ALC880_HP_EVENT) + return; + alc268_acer_automute(codec, 1); +} + /* * generic initialization of ADC, input mixers and output mixers */ @@ -8619,12 +8672,15 @@ static void alc268_auto_init(struct hda_codec *codec) static const char *alc268_models[ALC268_MODEL_LAST] = { [ALC268_3ST] = "3stack", [ALC268_TOSHIBA] = "toshiba", + [ALC268_ACER] = "acer", [ALC268_AUTO] = "auto", }; static struct snd_pci_quirk alc268_cfg_tbl[] = { SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST), SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA), + SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA), + SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER), {} }; @@ -8644,7 +8700,8 @@ static struct alc_config_preset alc268_presets[] = { }, [ALC268_TOSHIBA] = { .mixers = { alc268_base_mixer, alc268_capture_alt_mixer }, - .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs }, + .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, + alc268_toshiba_verbs }, .num_dacs = ARRAY_SIZE(alc268_dac_nids), .dac_nids = alc268_dac_nids, .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), @@ -8653,6 +8710,23 @@ static struct alc_config_preset alc268_presets[] = { .num_channel_mode = ARRAY_SIZE(alc268_modes), .channel_mode = alc268_modes, .input_mux = &alc268_capture_source, + .input_mux = &alc268_capture_source, + .unsol_event = alc268_toshiba_unsol_event, + .init_hook = alc268_toshiba_automute, + }, + [ALC268_ACER] = { + .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer }, + .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, + alc268_acer_verbs }, + .num_dacs = ARRAY_SIZE(alc268_dac_nids), + .dac_nids = alc268_dac_nids, + .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), + .adc_nids = alc268_adc_nids_alt, + .hp_nid = 0x02, + .num_channel_mode = ARRAY_SIZE(alc268_modes), + .channel_mode = alc268_modes, + .input_mux = &alc268_capture_source, + .unsol_event = alc268_acer_unsol_event, }, }; -- cgit v1.2.3 From 7debbe51cc001a6deb549999f9d8f53d99c6fd9e Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 16 Aug 2007 15:01:03 +0200 Subject: [ALSA] hda-codec - Fix PM on ALC885 Intel Macs Fix power-management on ALC885 Intel Macs. It fixes the problem with power-saving mode, too. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_realtek.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index b47934f87f8..b63d185433f 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -5276,6 +5276,20 @@ static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted) AC_VERB_SET_GPIO_DATA, gpiostate); } +/* set up GPIO at initialization */ +static void alc885_macpro_init_hook(struct hda_codec *codec) +{ + alc882_gpio_mute(codec, 0, 0); + alc882_gpio_mute(codec, 1, 0); +} + +/* set up GPIO and update auto-muting at initialization */ +static void alc885_imac24_init_hook(struct hda_codec *codec) +{ + alc885_macpro_init_hook(codec); + alc885_imac24_automute(codec); +} + /* * generic initialization of ADC, input mixers and output mixers */ @@ -5480,6 +5494,7 @@ static struct alc_config_preset alc882_presets[] = { .num_channel_mode = ARRAY_SIZE(alc882_ch_modes), .channel_mode = alc882_ch_modes, .input_mux = &alc882_capture_source, + .init_hook = alc885_macpro_init_hook, }, [ALC885_IMAC24] = { .mixers = { alc885_imac24_mixer }, @@ -5492,7 +5507,7 @@ static struct alc_config_preset alc882_presets[] = { .channel_mode = alc882_ch_modes, .input_mux = &alc882_capture_source, .unsol_event = alc885_imac24_unsol_event, - .init_hook = alc885_imac24_automute, + .init_hook = alc885_imac24_init_hook, }, [ALC882_TARGA] = { .mixers = { alc882_targa_mixer, alc882_chmode_mixer, @@ -5695,11 +5710,6 @@ static int patch_alc882(struct hda_codec *codec) if (board_config != ALC882_AUTO) setup_preset(spec, &alc882_presets[board_config]); - if (board_config == ALC885_MACPRO || board_config == ALC885_IMAC24) { - alc882_gpio_mute(codec, 0, 0); - alc882_gpio_mute(codec, 1, 0); - } - spec->stream_name_analog = "ALC882 Analog"; spec->stream_analog_playback = &alc882_pcm_analog_playback; spec->stream_analog_capture = &alc882_pcm_analog_capture; -- cgit v1.2.3 From 6c726dc672d82749e09345a79350838d4558fae4 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 16 Aug 2007 15:02:16 +0200 Subject: [ALSA] hda-codec - Remove superfluous code Remove the superfluous code that's actually not used at all. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_realtek.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index b63d185433f..31ff11721b7 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -8672,10 +8672,6 @@ static void alc268_auto_init(struct hda_codec *codec) alc268_auto_init_analog_input(codec); } -#ifdef CONFIG_SND_HDA_POWER_SAVE -#define alc883_loopbacks alc880_loopbacks -#endif - /* * configuration and preset */ -- cgit v1.2.3 From 676a9b53dcb0843a98f7339a492e42baf4b9a734 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 16 Aug 2007 15:23:35 +0200 Subject: [ALSA] hda-codec - Add unsol_event to ALC883 Acer Aspire Added unsol_event handling to ALC883 Acer Aspire codes. Also, removed unneeded channel-mode mixer control from 2-ch only presets. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_realtek.c | 40 +++++++++++++++++++++++++++++----------- 1 file changed, 29 insertions(+), 11 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 31ff11721b7..eec1a784386 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -6575,18 +6575,41 @@ static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec, alc883_lenovo_101e_ispeaker_automute(codec); } +/* toggle speaker-output according to the hp-jack state */ +static void alc883_acer_aspire_automute(struct hda_codec *codec) +{ + unsigned int present; + + present = snd_hda_codec_read(codec, 0x14, 0, + AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; + snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, + HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); + snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0, + HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); +} + +static void alc883_acer_aspire_unsol_event(struct hda_codec *codec, + unsigned int res) +{ + if ((res >> 26) == ALC880_HP_EVENT) + alc883_acer_aspire_automute(codec); +} + static struct hda_verb alc883_acer_eapd_verbs[] = { /* HP Pin: output 0 (0x0c) */ {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front Pin: output 0 (0x0c) */ + {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, + {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* eanable EAPD on medion laptop */ {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, {0x20, AC_VERB_SET_PROC_COEF, 0x3050}, + /* enable unsolicited event */ + {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, { } }; @@ -6832,8 +6855,7 @@ static struct alc_config_preset alc883_presets[] = { .init_hook = alc883_tagra_automute, }, [ALC883_ACER] = { - .mixers = { alc883_base_mixer, - alc883_chmode_mixer }, + .mixers = { alc883_base_mixer }, /* On TravelMate laptops, GPIO 0 enables the internal speaker * and the headphone jack. Turn this on and rely on the * standard mute methods whenever the user wants to turn @@ -6849,12 +6871,7 @@ static struct alc_config_preset alc883_presets[] = { .input_mux = &alc883_capture_source, }, [ALC883_ACER_ASPIRE] = { - .mixers = { alc883_acer_aspire_mixer, alc883_chmode_mixer }, - /* On TravelMate laptops, GPIO 0 enables the internal speaker - * and the headphone jack. Turn this on and rely on the - * standard mute methods whenever the user wants to turn - * these outputs off. - */ + .mixers = { alc883_acer_aspire_mixer }, .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs }, .num_dacs = ARRAY_SIZE(alc883_dac_nids), .dac_nids = alc883_dac_nids, @@ -6864,6 +6881,8 @@ static struct alc_config_preset alc883_presets[] = { .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), .channel_mode = alc883_3ST_2ch_modes, .input_mux = &alc883_capture_source, + .unsol_event = alc883_acer_aspire_unsol_event, + .init_hook = alc883_acer_aspire_automute, }, [ALC883_MEDION] = { .mixers = { alc883_fivestack_mixer, @@ -6893,8 +6912,7 @@ static struct alc_config_preset alc883_presets[] = { .init_hook = alc883_medion_md2_automute, }, [ALC883_LAPTOP_EAPD] = { - .mixers = { alc883_base_mixer, - alc883_chmode_mixer }, + .mixers = { alc883_base_mixer }, .init_verbs = { alc883_init_verbs, alc882_eapd_verbs }, .num_dacs = ARRAY_SIZE(alc883_dac_nids), .dac_nids = alc883_dac_nids, -- cgit v1.2.3 From a221e287ab39a0d169809cb79536abd75392c3c1 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 16 Aug 2007 16:35:33 +0200 Subject: [ALSA] hda-intel - Avoid unnecessary work scheduling Avoid unnecessary work scheduling for power-off. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/hda_codec.c | 10 +++++++--- sound/pci/hda/hda_codec.h | 3 ++- 2 files changed, 9 insertions(+), 4 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 0b9029436bb..b1eee9a044f 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -1664,6 +1664,7 @@ static void hda_call_codec_suspend(struct hda_codec *codec) #ifdef CONFIG_SND_HDA_POWER_SAVE cancel_delayed_work(&codec->power_work); codec->power_on = 0; + codec->power_transition = 0; #endif } @@ -2211,7 +2212,7 @@ static void hda_keep_power_on(struct hda_codec *codec) void snd_hda_power_up(struct hda_codec *codec) { codec->power_count++; - if (codec->power_on) + if (codec->power_on || codec->power_transition) return; codec->power_on = 1; @@ -2219,16 +2220,19 @@ void snd_hda_power_up(struct hda_codec *codec) codec->bus->ops.pm_notify(codec); hda_call_codec_resume(codec); cancel_delayed_work(&codec->power_work); + codec->power_transition = 0; } void snd_hda_power_down(struct hda_codec *codec) { --codec->power_count; - if (!codec->power_on || codec->power_count) + if (!codec->power_on || codec->power_count || codec->power_transition) return; - if (power_save) + if (power_save) { + codec->power_transition = 1; /* avoid reentrance */ schedule_delayed_work(&codec->power_work, msecs_to_jiffies(power_save * 1000)); + } } int snd_hda_check_amp_list_power(struct hda_codec *codec, diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index 1ffffaa3a30..ca157e5100c 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h @@ -586,7 +586,8 @@ struct hda_codec { struct snd_hwdep *hwdep; /* assigned hwdep device */ #ifdef CONFIG_SND_HDA_POWER_SAVE - int power_on; /* current (global) power-state */ + unsigned int power_on :1; /* current (global) power-state */ + unsigned int power_transition :1; /* power-state in transition */ int power_count; /* current (global) power refcount */ struct delayed_work power_work; /* delayed task for powerdown */ #endif -- cgit v1.2.3 From 64ca1c294c94579af68197d5f4af6911236b5a51 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 16 Aug 2007 17:23:32 +0200 Subject: [ALSA] hda-codec - Add model for MSI m673x Added model=targa-dig for MSI m673x with ALC883 codec. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index eec1a784386..7466df4767e 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -6751,6 +6751,7 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = { SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG), SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG), SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG), + SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG), SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG), SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG), SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG), -- cgit v1.2.3 From 72e7b0ddf52d334939778fc71e9d013519a3ee8c Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 16 Aug 2007 17:33:55 +0200 Subject: [ALSA] hda-codec - Add auto-mute function to Sony VAIO with STAC9872 Added auto-mute function with HP jack to Sony VAIO laptop with STAC9872 codec. The patch taken from ALSA bug#3275. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_sigmatel.c | 47 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index e096a48899c..76ec32a375c 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -2411,6 +2411,7 @@ static struct hda_input_mux vaio_mux = { static struct hda_verb vaio_init[] = { {0x0a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP <- 0x2 */ + {0x0a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | STAC_HP_EVENT}, {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Speaker <- 0x5 */ {0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? (<- 0x2) */ {0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD */ @@ -2507,6 +2508,49 @@ static struct hda_codec_ops stac9872_patch_ops = { #endif }; +static int stac9872_vaio_init(struct hda_codec *codec) +{ + int err; + + err = stac92xx_init(codec); + if (err < 0) + return err; + if (codec->patch_ops.unsol_event) + codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26); + return 0; +} + +static void stac9872_vaio_hp_detect(struct hda_codec *codec, unsigned int res) +{ + if (get_pin_presence(codec, 0x0a)) { + stac92xx_reset_pinctl(codec, 0x0f, AC_PINCTL_OUT_EN); + stac92xx_set_pinctl(codec, 0x0a, AC_PINCTL_OUT_EN); + } else { + stac92xx_reset_pinctl(codec, 0x0a, AC_PINCTL_OUT_EN); + stac92xx_set_pinctl(codec, 0x0f, AC_PINCTL_OUT_EN); + } +} + +static void stac9872_vaio_unsol_event(struct hda_codec *codec, unsigned int res) +{ + switch (res >> 26) { + case STAC_HP_EVENT: + stac9872_vaio_hp_detect(codec, res); + break; + } +} + +static struct hda_codec_ops stac9872_vaio_patch_ops = { + .build_controls = stac92xx_build_controls, + .build_pcms = stac92xx_build_pcms, + .init = stac9872_vaio_init, + .free = stac92xx_free, + .unsol_event = stac9872_vaio_unsol_event, +#ifdef CONFIG_PM + .resume = stac92xx_resume, +#endif +}; + enum { /* FE and SZ series. id=0x83847661 and subsys=0x104D0700 or 104D1000. */ CXD9872RD_VAIO, /* Unknown. id=0x83847662 and subsys=0x104D1200 or 104D1000. */ @@ -2562,6 +2606,7 @@ static int patch_stac9872(struct hda_codec *codec) spec->adc_nids = vaio_adcs; spec->input_mux = &vaio_mux; spec->mux_nids = vaio_mux_nids; + codec->patch_ops = stac9872_vaio_patch_ops; break; case CXD9872AKD_VAIO: @@ -2575,10 +2620,10 @@ static int patch_stac9872(struct hda_codec *codec) spec->adc_nids = vaio_adcs; spec->input_mux = &vaio_mux; spec->mux_nids = vaio_mux_nids; + codec->patch_ops = stac9872_patch_ops; break; } - codec->patch_ops = stac9872_patch_ops; return 0; } -- cgit v1.2.3 From 38baf5ad8b7d24be16a2cf0e4c1d7429aeb4aa45 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 16 Aug 2007 17:52:43 +0200 Subject: [ALSA] hda-codec - Fix Toshiba A135 model selection Fixed the double entries in the model presets. Toshib A135 prefers model=lenovo rather than dallas. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_realtek.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 7466df4767e..e4064f997e8 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -10544,7 +10544,7 @@ static struct snd_pci_quirk alc861vd_cfg_tbl[] = { SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST), SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST), - SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS), + /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/ SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS), SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO), SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO), -- cgit v1.2.3 From 87350ad0cf05d734309ca40e1524a07cf12190aa Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 16 Aug 2007 18:19:38 +0200 Subject: [ALSA] hda-codec - Add support for Macbook Pro rev3 Added the support for Macbook Pro rev3 with ALC885 codec chip. The patch taken from ALSA bug#3242. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_realtek.c | 145 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 145 insertions(+) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index e4064f997e8..0473f2a9c18 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -156,6 +156,7 @@ enum { ALC882_TARGA, ALC882_ASUS_A7J, ALC885_MACPRO, + ALC885_MBP3, ALC885_IMAC24, ALC882_AUTO, ALC882_MODEL_LAST, @@ -4895,6 +4896,38 @@ static struct hda_channel_mode alc882_sixstack_modes[2] = { { 8, alc882_sixstack_ch8_init }, }; +/* + * macbook pro ALC885 can switch LineIn to LineOut without loosing Mic + */ + +/* + * 2ch mode + */ +static struct hda_verb alc885_mbp_ch2_init[] = { + { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, + { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, + { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, + { } /* end */ +}; + +/* + * 6ch mode + */ +static struct hda_verb alc885_mbp_ch6_init[] = { + { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, + { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, + { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, + { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, + { } /* end */ +}; + +static struct hda_channel_mode alc885_mbp_6ch_modes[2] = { + { 2, alc885_mbp_ch2_init }, + { 6, alc885_mbp_ch6_init }, +}; + + /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b */ @@ -4925,6 +4958,19 @@ static struct snd_kcontrol_new alc882_base_mixer[] = { { } /* end */ }; +static struct snd_kcontrol_new alc885_mbp3_mixer[] = { + HDA_CODEC_VOLUME("Master Volume", 0x0c, 0x00, HDA_OUTPUT), + HDA_BIND_MUTE ("Master Switch", 0x0c, 0x02, HDA_INPUT), + HDA_CODEC_MUTE ("Speaker Switch", 0x14, 0x00, HDA_OUTPUT), + HDA_CODEC_VOLUME("Line Out Volume", 0x0d,0x00, HDA_OUTPUT), + HDA_CODEC_VOLUME("Line In Playback Volume", 0x0b, 0x02, HDA_INPUT), + HDA_CODEC_MUTE ("Line In Playback Switch", 0x0b, 0x02, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT), + HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT), + HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0x00, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT), + { } /* end */ +}; static struct snd_kcontrol_new alc882_w2jc_mixer[] = { HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), @@ -5135,6 +5181,66 @@ static struct hda_verb alc882_macpro_init_verbs[] = { { } }; +/* Macbook Pro rev3 */ +static struct hda_verb alc885_mbp3_init_verbs[] = { + /* Front mixer: unmute input/output amp left and right (volume = 0) */ + {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, + {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, + {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, + /* Rear mixer */ + {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, + {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, + {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, + /* Front Pin: output 0 (0x0c) */ + {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, + {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, + {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, + /* HP Pin: output 0 (0x0d) */ + {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, + {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, + {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, + {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, + /* Mic (rear) pin: input vref at 80% */ + {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, + {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, + /* Front Mic pin: input vref at 80% */ + {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, + {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, + /* Line In pin: use output 1 when in LineOut mode */ + {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, + {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, + {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, + + /* FIXME: use matrix-type input source selection */ + /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ + /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ + {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, + {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, + {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, + /* Input mixer2 */ + {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, + {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, + {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, + /* Input mixer3 */ + {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, + {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, + {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, + /* ADC1: mute amp left and right */ + {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, + {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, + /* ADC2: mute amp left and right */ + {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, + {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, + /* ADC3: mute amp left and right */ + {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, + {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, + + { } +}; + /* iMac 24 mixer. */ static struct snd_kcontrol_new alc885_imac24_mixer[] = { HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT), @@ -5185,6 +5291,27 @@ static void alc885_imac24_unsol_event(struct hda_codec *codec, alc885_imac24_automute(codec); } +static void alc885_mbp3_automute(struct hda_codec *codec) +{ + unsigned int present; + + present = snd_hda_codec_read(codec, 0x15, 0, + AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; + snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, + HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); + snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, + HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE); + +} +static void alc885_mbp3_unsol_event(struct hda_codec *codec, + unsigned int res) +{ + /* Headphone insertion or removal. */ + if ((res >> 26) == ALC880_HP_EVENT) + alc885_mbp3_automute(codec); +} + + static struct hda_verb alc882_targa_verbs[] = { {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, @@ -5422,6 +5549,7 @@ static const char *alc882_models[ALC882_MODEL_LAST] = { [ALC882_ARIMA] = "arima", [ALC882_W2JC] = "w2jc", [ALC885_MACPRO] = "macpro", + [ALC885_MBP3] = "mbp3", [ALC885_IMAC24] = "imac24", [ALC882_AUTO] = "auto", }; @@ -5484,6 +5612,20 @@ static struct alc_config_preset alc882_presets[] = { .input_mux = &alc882_capture_source, .dig_out_nid = ALC882_DIGOUT_NID, }, + [ALC885_MBP3] = { + .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer }, + .init_verbs = { alc885_mbp3_init_verbs, + alc880_gpio1_init_verbs }, + .num_dacs = ARRAY_SIZE(alc882_dac_nids), + .dac_nids = alc882_dac_nids, + .channel_mode = alc885_mbp_6ch_modes, + .num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes), + .input_mux = &alc882_capture_source, + .dig_out_nid = ALC882_DIGOUT_NID, + .dig_in_nid = ALC882_DIGIN_NID, + .unsol_event = alc885_mbp3_unsol_event, + .init_hook = alc885_mbp3_automute, + }, [ALC885_MACPRO] = { .mixers = { alc882_macpro_mixer }, .init_verbs = { alc882_macpro_init_verbs }, @@ -5684,6 +5826,9 @@ static int patch_alc882(struct hda_codec *codec) case 0x106b1000: /* iMac 24 */ board_config = ALC885_IMAC24; break; + case 0x106b2c00: /* Macbook Pro rev3 */ + board_config = ALC885_MBP3; + break; default: printk(KERN_INFO "hda_codec: Unknown model for ALC882, " "trying auto-probe from BIOS...\n"); -- cgit v1.2.3 From 542d7c66201439f98dd44e62a8186ec33a15b1a7 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 16 Aug 2007 18:57:30 +0200 Subject: [ALSA] hda-codec - Add support for Toshiba Satellite P205 Add model=lenovo for Toshiba Satellite P205 with ALC861VD codec chip. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 0473f2a9c18..e82b03a5979 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -10694,6 +10694,7 @@ static struct snd_pci_quirk alc861vd_cfg_tbl[] = { SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO), SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO), SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO), + SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO), SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG), SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG), SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP), -- cgit v1.2.3 From 7583cb51a1e276591f57a2fae05489c878f8ef54 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 16 Aug 2007 19:32:16 +0200 Subject: [ALSA] emu10k1 - Fix memory corruption The number of mixer elements for SPDIF control don't match with the actual array size (3). This may result in a memory corruption that overwrites the i2c_capture_source field (ALSA bug#3095). Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/emu10k1/emumixer.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/emu10k1/emumixer.c b/sound/pci/emu10k1/emumixer.c index 692b871bff5..71ad5a038e8 100644 --- a/sound/pci/emu10k1/emumixer.c +++ b/sound/pci/emu10k1/emumixer.c @@ -896,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 }; @@ -905,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 -- cgit v1.2.3 From 6bc9685796529754acd819d9c979227d823c408d Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 17 Aug 2007 09:02:12 +0200 Subject: [ALSA] hda-codec - Fix ALC268 acer model ALC268 has different NIDs from ALC262. Acer model should use NID 0x02 and 0x03 instead of 0x0c and 0x0d for the master volume. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_realtek.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index e82b03a5979..4a40a056a8c 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -8418,7 +8418,16 @@ static struct hda_verb alc268_toshiba_verbs[] = { }; /* Acer specific */ -#define alc268_acer_bind_master_vol alc262_fujitsu_bind_master_vol +/* bind volumes of both NID 0x0c and 0x0d */ +static struct hda_bind_ctls alc268_acer_bind_master_vol = { + .ops = &snd_hda_bind_vol, + .values = { + HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT), + HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT), + 0 + }, +}; + #define alc268_acer_master_sw_put alc262_fujitsu_master_sw_put #define alc268_acer_automute alc262_fujitsu_automute -- cgit v1.2.3 From 669ba27a6e25251427bde8f4980f62733a8f0c7e Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 17 Aug 2007 09:17:36 +0200 Subject: [ALSA] hda-intel - Add probe_mask blacklist Added the black-list of probe_mask option to set the default value for known non-working devices. Currently, Thinkpad *60 and *61 series are set. I'm afraid more will be added to the list in near future... Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/hda_intel.c | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 14bcc108e77..3d06eccc9b9 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -1653,7 +1653,7 @@ static int __devinit check_position_fix(struct azx *chip, int fix) if (fix == POS_FIX_AUTO) { q = snd_pci_quirk_lookup(chip->pci, position_fix_list); if (q) { - snd_printdd(KERN_INFO + printk(KERN_INFO "hda_intel: position_fix set to %d " "for device %04x:%04x\n", q->value, q->subvendor, q->subdevice); @@ -1663,6 +1663,36 @@ static int __devinit check_position_fix(struct azx *chip, int fix) return fix; } +/* + * black-lists for probe_mask + */ +static struct snd_pci_quirk probe_mask_list[] __devinitdata = { + /* Thinkpad often breaks the controller communication when accessing + * to the non-working (or non-existing) modem codec slot. + */ + SND_PCI_QUIRK(0x1014, 0x05b7, "Thinkpad Z60", 0x01), + SND_PCI_QUIRK(0x17aa, 0x2010, "Thinkpad X/T/R60", 0x01), + SND_PCI_QUIRK(0x17aa, 0x20ac, "Thinkpad X/T/R61", 0x01), + {} +}; + +static void __devinit check_probe_mask(struct azx *chip) +{ + const struct snd_pci_quirk *q; + + if (probe_mask == -1) { + q = snd_pci_quirk_lookup(chip->pci, probe_mask_list); + if (q) { + printk(KERN_INFO + "hda_intel: probe_mask set to 0x%x " + "for device %04x:%04x\n", + q->value, q->subvendor, q->subdevice); + probe_mask = q->value; + } + } +} + + /* * constructor */ @@ -1698,6 +1728,7 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, chip->msi = enable_msi; chip->position_fix = check_position_fix(chip, position_fix); + check_probe_mask(chip); chip->single_cmd = single_cmd; -- cgit v1.2.3 From 189609ae1e4db898d9a933753348ca19544c5903 Mon Sep 17 00:00:00 2001 From: Kailang Yang Date: Mon, 20 Aug 2007 11:31:23 +0200 Subject: [ALSA] hda-codec - Add support for Haier W66 1. Support Lenovo 420A (PCI SSID: 0x17aa 0x3bfc) 2. Support Haier W66 (PCI SSID: 0x1991 0x5625) Signed-off-by: Kailang Yang Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_realtek.c | 52 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 4a40a056a8c..f558b801c82 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -177,7 +177,8 @@ enum { ALC883_LAPTOP_EAPD, ALC883_LENOVO_101E_2ch, ALC883_LENOVO_NB0763, - ALC888_LENOVO_MS7195_DIG, + ALC888_LENOVO_MS7195_DIG, + ALC883_HAIER_W66, ALC888_6ST_HP, ALC888_3ST_HP, ALC883_AUTO, @@ -6567,6 +6568,19 @@ static struct hda_verb alc888_lenovo_ms7195_verbs[] = { { } /* end */ }; +static struct hda_verb alc883_haier_w66_verbs[] = { + {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, + + {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, + + {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, + {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, + {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, + {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, + { } /* end */ +}; + static struct hda_verb alc888_6st_hp_verbs[] = { {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */ {0x15, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Rear : output 2 (0x0e) */ @@ -6685,6 +6699,25 @@ static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res) alc883_tagra_automute(codec); } +static void alc883_haier_w66_automute(struct hda_codec *codec) +{ + unsigned int present; + unsigned char bits; + + present = snd_hda_codec_read(codec, 0x1b, 0, + AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; + bits = present ? 0x80 : 0; + snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, + 0x80, bits); +} + +static void alc883_haier_w66_unsol_event(struct hda_codec *codec, + unsigned int res) +{ + if ((res >> 26) == ALC880_HP_EVENT) + alc883_haier_w66_automute(codec); +} + static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec) { unsigned int present; @@ -6871,6 +6904,7 @@ static const char *alc883_models[ALC883_MODEL_LAST] = { [ALC883_LENOVO_101E_2ch] = "lenovo-101e", [ALC883_LENOVO_NB0763] = "lenovo-nb0763", [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig", + [ALC883_HAIER_W66] = "haier-w66", [ALC888_6ST_HP] = "6stack-hp", [ALC888_3ST_HP] = "3stack-hp", [ALC883_AUTO] = "auto", @@ -6915,6 +6949,8 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = { SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP), SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP), SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2), + SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66), + SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763), {} }; @@ -7109,6 +7145,20 @@ static struct alc_config_preset alc883_presets[] = { .input_mux = &alc883_capture_source, .unsol_event = alc883_lenovo_ms7195_unsol_event, .init_hook = alc888_lenovo_ms7195_front_automute, + }, + [ALC883_HAIER_W66] = { + .mixers = { alc883_tagra_2ch_mixer}, + .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs}, + .num_dacs = ARRAY_SIZE(alc883_dac_nids), + .dac_nids = alc883_dac_nids, + .dig_out_nid = ALC883_DIGOUT_NID, + .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), + .adc_nids = alc883_adc_nids, + .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), + .channel_mode = alc883_3ST_2ch_modes, + .input_mux = &alc883_capture_source, + .unsol_event = alc883_haier_w66_unsol_event, + .init_hook = alc883_haier_w66_automute, }, [ALC888_6ST_HP] = { .mixers = { alc888_6st_hp_mixer, alc883_chmode_mixer }, -- cgit v1.2.3 From d53d7d9e5e6bce747e8b8b2f825db1b32d8f6647 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 20 Aug 2007 15:20:02 +0200 Subject: [ALSA] hda-codec - Add SPDIF support on ALC880 fujitsu model Some Fujitsu laptops have SPDIF output jack (ALSA bug#3009). Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index f558b801c82..e67f586ebfb 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -2875,6 +2875,7 @@ static struct alc_config_preset alc880_presets[] = { alc880_beep_init_verbs }, .num_dacs = ARRAY_SIZE(alc880_dac_nids), .dac_nids = alc880_dac_nids, + .dig_out_nid = ALC880_DIGOUT_NID, .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), .channel_mode = alc880_2_jack_modes, .input_mux = &alc880_capture_source, -- cgit v1.2.3 From 1e02d6ea85e5ca3a8c49a7e2ef1656bfba902fc9 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Tue, 21 Aug 2007 08:58:35 +0200 Subject: [ALSA] cmipci: fix MIDI device name Initialize card->shortname early enough so that the MIDI device can pick it up and does not need to have a generic name. Signed-off-by: Clemens Ladisch Signed-off-by: Jaroslav Kysela --- sound/pci/cmipci.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c index f38054ead17..c42c51647df 100644 --- a/sound/pci/cmipci.c +++ b/sound/pci/cmipci.c @@ -2923,6 +2923,13 @@ static int __devinit snd_cmipci_create(struct snd_card *card, struct pci_dev *pc break; } + sprintf(card->shortname, "C-Media PCI %s", card->driver); + sprintf(card->longname, "%s (model %d) at 0x%lx, irq %i", + card->shortname, + cm->chip_version, + cm->iobase, + cm->irq); + if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, cm, &ops)) < 0) { snd_cmipci_free(cm); return err; @@ -3049,15 +3056,6 @@ static int __devinit snd_cmipci_probe(struct pci_dev *pci, } card->private_data = cm; - sprintf(card->shortname, "C-Media PCI %s", card->driver); - sprintf(card->longname, "%s (model %d) at 0x%lx, irq %i", - card->shortname, - cm->chip_version, - cm->iobase, - cm->irq); - - //snd_printd("%s is detected\n", card->longname); - if ((err = snd_card_register(card)) < 0) { snd_card_free(card); return err; -- cgit v1.2.3 From 33bf17abf98087d7a6eec9476cd767c6e998fc05 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 21 Aug 2007 11:51:42 +0200 Subject: [ALSA] hda-codec - Add missing capture boost for ALC268 Added missing capture boost controls for ALC268 codec. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_realtek.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index e67f586ebfb..db29ebea20b 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -8451,6 +8451,9 @@ static struct snd_kcontrol_new alc268_base_mixer[] = { HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT), { } }; @@ -8493,6 +8496,9 @@ static struct snd_kcontrol_new alc268_acer_mixer[] = { .put = alc268_acer_master_sw_put, .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), }, + HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT), { } }; -- cgit v1.2.3 From 45c41b4868c9dbec5d43a4023e77994afa94470f Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Wed, 22 Aug 2007 09:45:03 +0200 Subject: [ALSA] cmipci: fix handling of FM/MIDI port addresses Make sure that the MPU-401 MIDI and OPL-3 FM devices are used only on those chips where they are supported, and that the correct port addresses are used. Signed-off-by: Clemens Ladisch Signed-off-by: Jaroslav Kysela --- sound/pci/Kconfig | 6 +++--- sound/pci/cmipci.c | 22 +++++++++++++++------- 2 files changed, 18 insertions(+), 10 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig index 9554140f0b0..5d0732c09f2 100644 --- a/sound/pci/Kconfig +++ b/sound/pci/Kconfig @@ -170,14 +170,14 @@ config SND_CA0106 will be called snd-ca0106. config SND_CMIPCI - tristate "C-Media 8738, 8338" + tristate "C-Media 8338, 8738, 8768, 8770" depends on SND select SND_OPL3_LIB select SND_MPU401_UART select SND_PCM help - If you want to use soundcards based on C-Media CMI8338 or CMI8738 - chips, say Y here and read + If you want to use soundcards based on C-Media CMI8338, CMI8738, + CMI8768 or CMI8770 chips, say Y here and read . To compile this driver as a module, choose M here: the module diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c index c42c51647df..9d394c7c221 100644 --- a/sound/pci/cmipci.c +++ b/sound/pci/cmipci.c @@ -2774,10 +2774,14 @@ static int __devinit snd_cmipci_create_fm(struct cmipci *cm, long fm_port) if (!fm_port) goto disable_fm; - /* first try FM regs in PCI port range */ - iosynth = cm->iobase + CM_REG_FM_PCI; - err = snd_opl3_create(cm->card, iosynth, iosynth + 2, - OPL3_HW_OPL3, 1, &opl3); + if (cm->chip_version > 33) { + /* first try FM regs in PCI port range */ + iosynth = cm->iobase + CM_REG_FM_PCI; + err = snd_opl3_create(cm->card, iosynth, iosynth + 2, + OPL3_HW_OPL3, 1, &opl3); + } else { + err = -EIO; + } if (err < 0) { /* then try legacy ports */ val = snd_cmipci_read(cm, CM_REG_LEGACY_CTRL) & ~CM_FMSEL_MASK; @@ -2935,7 +2939,8 @@ static int __devinit snd_cmipci_create(struct snd_card *card, struct pci_dev *pc return err; } - integrated_midi = snd_cmipci_read_b(cm, CM_REG_MPU_PCI) != 0xff; + integrated_midi = cm->chip_version > 33 && + snd_cmipci_read_b(cm, CM_REG_MPU_PCI + 1) != 0xff; if (integrated_midi && mpu_port[dev] == 1) iomidi = cm->iobase + CM_REG_MPU_PCI; else { @@ -2955,8 +2960,11 @@ static int __devinit snd_cmipci_create(struct snd_card *card, struct pci_dev *pc } } - if ((err = snd_cmipci_create_fm(cm, fm_port[dev])) < 0) - return err; + if (cm->chip_version < 68) { + err = snd_cmipci_create_fm(cm, fm_port[dev]); + if (err < 0) + return err; + } /* reset mixer */ snd_cmipci_mixer_write(cm, 0, 0); -- cgit v1.2.3 From abaeeb59c94b6efc368f5058009c1d82ce031abd Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 22 Aug 2007 14:19:45 +0200 Subject: [ALSA] bt87x - Add known PCI ID entries Added the PCI ID entries for known working devices - Prolink PixelView PV-M4900 - Pinnacle Studio PCTV rave Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/bt87x.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'sound/pci') diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c index 85d50b64d2b..d87d6a3298a 100644 --- a/sound/pci/bt87x.c +++ b/sound/pci/bt87x.c @@ -764,6 +764,10 @@ static struct pci_device_id snd_bt87x_ids[] = { BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x121a, 0x3000, 32000), /* AVerMedia Studio No. 103, 203, ...? */ BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x1461, 0x0003, 48000), + /* Prolink PixelView PV-M4900 */ + BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x1554, 0x4011, 32000), + /* Pinnacle Studio PCTV rave */ + BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0xbd11, 0x1200, 32000), { } }; MODULE_DEVICE_TABLE(pci, snd_bt87x_ids); -- cgit v1.2.3 From 1fcaee6ee212fc214c1327d788afa10899c22e3a Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 23 Aug 2007 00:01:09 +0200 Subject: [ALSA] hda-intel - Fix compile with gcc-3.x gcc-3.x doesn't like forward inlining: CC [M] sound/pci/hda/hda_codec.o sound/pci/hda/hda_codec.c: In function 'snd_hda_codec_free': sound/pci/hda/hda_codec.c:517: sorry, unimplemented: inlining failed in call to 'free_hda_cache': function body not available sound/pci/hda/hda_codec.c:534: sorry, unimplemented: called from here sound/pci/hda/hda_codec.c:517: sorry, unimplemented: inlining failed in call to 'free_hda_cache': function body not available sound/pci/hda/hda_codec.c:535: sorry, unimplemented: called from here Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/hda_codec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index b1eee9a044f..46d4253642d 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -514,7 +514,7 @@ static int read_widget_caps(struct hda_codec *codec, hda_nid_t fg_node) static void init_hda_cache(struct hda_cache_rec *cache, unsigned int record_size); -static inline void free_hda_cache(struct hda_cache_rec *cache); +static void free_hda_cache(struct hda_cache_rec *cache); /* * codec destructor @@ -707,7 +707,7 @@ static void __devinit init_hda_cache(struct hda_cache_rec *cache, cache->record_size = record_size; } -static inline void free_hda_cache(struct hda_cache_rec *cache) +static void free_hda_cache(struct hda_cache_rec *cache) { kfree(cache->buffer); } -- cgit v1.2.3 From 0724ea2a85a804e151d960359b599ae8a7c1cad1 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 23 Aug 2007 00:31:43 +0200 Subject: [ALSA] hda-codec - Fix mater mixer switch of ALC262 sony-amd model Fixed the master mixer switch of ALC272 sony-amd model. It used a simple bind-control, but it resulted in unexpected unmute of speaker output. Now the control checks the HP jack state apropriately, just like fujitsu model. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_realtek.c | 48 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 38 insertions(+), 10 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index db29ebea20b..4cbd0e6e849 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -7453,18 +7453,46 @@ static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = { { } /* end */ }; -static struct hda_bind_ctls alc262_sony_bind_sw = { - .ops = &snd_hda_bind_sw, - .values = { - HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT), - HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), - 0, - }, -}; +/* bind hp and internal speaker mute (with plug check) */ +static int alc262_sony_master_sw_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + long *valp = ucontrol->value.integer.value; + int change; + + /* change hp mute */ + change = snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0, + HDA_AMP_MUTE, + valp[0] ? 0 : HDA_AMP_MUTE); + change |= snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0, + HDA_AMP_MUTE, + valp[1] ? 0 : HDA_AMP_MUTE); + if (change) { + /* change speaker according to HP jack state */ + struct alc_spec *spec = codec->spec; + unsigned int mute; + if (spec->jack_present) + mute = HDA_AMP_MUTE; + else + mute = snd_hda_codec_amp_read(codec, 0x15, 0, + HDA_OUTPUT, 0); + snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, + HDA_AMP_MUTE, mute); + } + return change; +} static struct snd_kcontrol_new alc262_sony_mixer[] = { - HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), - HDA_BIND_SW("Front Playback Switch", &alc262_sony_bind_sw), + HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Master Playback Switch", + .info = snd_hda_mixer_amp_switch_info, + .get = snd_hda_mixer_amp_switch_get, + .put = alc262_sony_master_sw_put, + .private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT), + }, HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), -- cgit v1.2.3 From 889c43955115ea7412d71335e3ceff6bad118dce Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 23 Aug 2007 18:56:52 +0200 Subject: [ALSA] hda-codec - Fix ALC268 unsol event The unsol event of ALC268 is in the standard bit 26. Also, fixed the Acer master controls, and added Extensa 5210 to the quirk list. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_realtek.c | 55 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 50 insertions(+), 5 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 4cbd0e6e849..b108ea3d99b 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -8500,7 +8500,7 @@ static struct hda_verb alc268_toshiba_verbs[] = { }; /* Acer specific */ -/* bind volumes of both NID 0x0c and 0x0d */ +/* bind volumes of both NID 0x02 and 0x03 */ static struct hda_bind_ctls alc268_acer_bind_master_vol = { .ops = &snd_hda_bind_vol, .values = { @@ -8510,8 +8510,46 @@ static struct hda_bind_ctls alc268_acer_bind_master_vol = { }, }; -#define alc268_acer_master_sw_put alc262_fujitsu_master_sw_put -#define alc268_acer_automute alc262_fujitsu_automute +/* mute/unmute internal speaker according to the hp jack and mute state */ +static void alc268_acer_automute(struct hda_codec *codec, int force) +{ + struct alc_spec *spec = codec->spec; + unsigned int mute; + + if (force || !spec->sense_updated) { + unsigned int present; + present = snd_hda_codec_read(codec, 0x14, 0, + AC_VERB_GET_PIN_SENSE, 0); + spec->jack_present = (present & 0x80000000) != 0; + spec->sense_updated = 1; + } + if (spec->jack_present) + mute = HDA_AMP_MUTE; /* mute internal speaker */ + else /* unmute internal speaker if necessary */ + mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0); + snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, + HDA_AMP_MUTE, mute); +} + + +/* bind hp and internal speaker mute (with plug check) */ +static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + long *valp = ucontrol->value.integer.value; + int change; + + change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0, + HDA_AMP_MUTE, + valp[0] ? 0 : HDA_AMP_MUTE); + change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0, + HDA_AMP_MUTE, + valp[1] ? 0 : HDA_AMP_MUTE); + if (change) + alc268_acer_automute(codec, 0); + return change; +} static struct snd_kcontrol_new alc268_acer_mixer[] = { /* output mixer control */ @@ -8542,7 +8580,7 @@ static struct hda_verb alc268_acer_verbs[] = { static void alc268_toshiba_unsol_event(struct hda_codec *codec, unsigned int res) { - if ((res >> 28) != ALC880_HP_EVENT) + if ((res >> 26) != ALC880_HP_EVENT) return; alc268_toshiba_automute(codec); } @@ -8550,11 +8588,16 @@ static void alc268_toshiba_unsol_event(struct hda_codec *codec, static void alc268_acer_unsol_event(struct hda_codec *codec, unsigned int res) { - if ((res >> 28) != ALC880_HP_EVENT) + if ((res >> 26) != ALC880_HP_EVENT) return; alc268_acer_automute(codec, 1); } +static void alc268_acer_init_hook(struct hda_codec *codec) +{ + alc268_acer_automute(codec, 1); +} + /* * generic initialization of ADC, input mixers and output mixers */ @@ -8945,6 +8988,7 @@ static struct snd_pci_quirk alc268_cfg_tbl[] = { SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA), SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA), SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER), + SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER), {} }; @@ -8991,6 +9035,7 @@ static struct alc_config_preset alc268_presets[] = { .channel_mode = alc268_modes, .input_mux = &alc268_capture_source, .unsol_event = alc268_acer_unsol_event, + .init_hook = alc268_acer_init_hook, }, }; -- cgit v1.2.3 From dfe495d0a51e20325b51760f34a2f53bfe1f3b52 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 23 Aug 2007 19:04:28 +0200 Subject: [ALSA] hda-codec - Fix Dell laptops support with STAC codecs Fixed Dell laptops support with STAC92xx codecs. Many pin-config models are introduced. See ALSA-Configuration.txt for details. The patch taken from ALSA bug#3319, originally by Jorg Prante: https://bugtrack.alsa-project.org/alsa-bug/view.php?id=3319 Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_sigmatel.c | 345 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 313 insertions(+), 32 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 76ec32a375c..adca2854e50 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -39,11 +39,22 @@ enum { STAC_REF, + STAC_9200_DELL_D21, + STAC_9200_DELL_D22, + STAC_9200_DELL_D23, + STAC_9200_DELL_M21, + STAC_9200_DELL_M22, + STAC_9200_DELL_M23, + STAC_9200_DELL_M24, + STAC_9200_DELL_M25, + STAC_9200_DELL_M26, + STAC_9200_DELL_M27, STAC_9200_MODELS }; enum { STAC_9205_REF, + STAC_9205_DELL_M42, STAC_9205_DELL_M43, STAC_9205_DELL_M44, STAC_9205_M43xx, @@ -62,19 +73,22 @@ enum { STAC_D945_REF, STAC_D945GTP3, STAC_D945GTP5, - STAC_922X_DELL, STAC_INTEL_MAC_V1, STAC_INTEL_MAC_V2, STAC_INTEL_MAC_V3, STAC_INTEL_MAC_V4, STAC_INTEL_MAC_V5, - /* for backward compitability */ + /* for backward compatibility */ STAC_MACMINI, STAC_MACBOOK, STAC_MACBOOK_PRO_V1, STAC_MACBOOK_PRO_V2, STAC_IMAC_INTEL, STAC_IMAC_INTEL_20, + STAC_922X_DELL_D81, + STAC_922X_DELL_D82, + STAC_922X_DELL_M81, + STAC_922X_DELL_M82, STAC_922X_MODELS }; @@ -456,12 +470,144 @@ static unsigned int ref9200_pin_configs[8] = { 0x02a19020, 0x01a19021, 0x90100140, 0x01813122, }; +/* + STAC 9200 pin configs for + 102801A8 + 102801DE + 102801E8 +*/ +static unsigned int dell9200_d21_pin_configs[8] = { + 0x400001f0, 0x400001f1, 0x01a19021, 0x90100140, + 0x01813122, 0x02214030, 0x01014010, 0x02a19020, +}; + +/* + STAC 9200 pin configs for + 102801C0 + 102801C1 +*/ +static unsigned int dell9200_d22_pin_configs[8] = { + 0x400001f0, 0x400001f1, 0x02a19021, 0x90100140, + 0x400001f2, 0x0221401f, 0x01014010, 0x01813020, +}; + +/* + STAC 9200 pin configs for + 102801C4 (Dell Dimension E310) + 102801C5 + 102801C7 + 102801D9 + 102801DA + 102801E3 +*/ +static unsigned int dell9200_d23_pin_configs[8] = { + 0x400001f0, 0x400001f1, 0x01a19021, 0x90100140, + 0x400001f2, 0x0221401f, 0x01014010, 0x01813020, +}; + + +/* + STAC 9200-32 pin configs for + 102801B5 (Dell Inspiron 630m) + 102801D8 (Dell Inspiron 640m) +*/ +static unsigned int dell9200_m21_pin_configs[8] = { + 0x40c003fa, 0x03441340, 0x03a11020, 0x401003fc, + 0x403003fd, 0x0321121f, 0x0321121f, 0x408003fb, +}; + +/* + STAC 9200-32 pin configs for + 102801C2 (Dell Latitude D620) + 102801C8 + 102801CC (Dell Latitude D820) + 102801D4 + 102801D6 +*/ +static unsigned int dell9200_m22_pin_configs[8] = { + 0x40c003fa, 0x0144131f, 0x03A11020, 0x401003fb, + 0x40f000fc, 0x0321121f, 0x90170310, 0x90a70321, +}; + +/* + STAC 9200-32 pin configs for + 102801CE (Dell XPS M1710) + 102801CF (Dell Precision M90) +*/ +static unsigned int dell9200_m23_pin_configs[8] = { + 0x40c003fa, 0x01441340, 0x0421421f, 0x90170310, + 0x408003fb, 0x04a1102e, 0x90170311, 0x403003fc, +}; + +/* + STAC 9200-32 pin configs for + 102801C9 + 102801CA + 102801CB (Dell Latitude 120L) + 102801D3 +*/ +static unsigned int dell9200_m24_pin_configs[8] = { + 0x40c003fa, 0x404003fb, 0x03a11020, 0x401003fd, + 0x403003fe, 0x0321121f, 0x90170310, 0x408003fc, +}; + +/* + STAC 9200-32 pin configs for + 102801BD (Dell Inspiron E1505n) + 102801EE + 102801EF +*/ +static unsigned int dell9200_m25_pin_configs[8] = { + 0x40c003fa, 0x01441340, 0x04a11020, 0x401003fc, + 0x403003fd, 0x0421121f, 0x90170310, 0x408003fb, +}; + +/* + STAC 9200-32 pin configs for + 102801F5 (Dell Inspiron 1501) + 102801F6 +*/ +static unsigned int dell9200_m26_pin_configs[8] = { + 0x40c003fa, 0x404003fb, 0x04a11020, 0x401003fd, + 0x403003fe, 0x0421121f, 0x90170310, 0x408003fc, +}; + +/* + STAC 9200-32 + 102801CD (Dell Inspiron E1705/9400) +*/ +static unsigned int dell9200_m27_pin_configs[8] = { + 0x40c003fa, 0x01441340, 0x04a11020, 0x90170310, + 0x40f003fc, 0x0421121f, 0x90170310, 0x408003fb, +}; + + static unsigned int *stac9200_brd_tbl[STAC_9200_MODELS] = { [STAC_REF] = ref9200_pin_configs, + [STAC_9200_DELL_D21] = dell9200_d21_pin_configs, + [STAC_9200_DELL_D22] = dell9200_d22_pin_configs, + [STAC_9200_DELL_D23] = dell9200_d23_pin_configs, + [STAC_9200_DELL_M21] = dell9200_m21_pin_configs, + [STAC_9200_DELL_M22] = dell9200_m22_pin_configs, + [STAC_9200_DELL_M23] = dell9200_m23_pin_configs, + [STAC_9200_DELL_M24] = dell9200_m24_pin_configs, + [STAC_9200_DELL_M25] = dell9200_m25_pin_configs, + [STAC_9200_DELL_M26] = dell9200_m26_pin_configs, + [STAC_9200_DELL_M27] = dell9200_m27_pin_configs, }; static const char *stac9200_models[STAC_9200_MODELS] = { [STAC_REF] = "ref", + [STAC_9200_DELL_D21] = "dell-d21", + [STAC_9200_DELL_D22] = "dell-d22", + [STAC_9200_DELL_D23] = "dell-d23", + [STAC_9200_DELL_M21] = "dell-m21", + [STAC_9200_DELL_M22] = "dell-m22", + [STAC_9200_DELL_M23] = "dell-m23", + [STAC_9200_DELL_M24] = "dell-m24", + [STAC_9200_DELL_M25] = "dell-m25", + [STAC_9200_DELL_M26] = "dell-m26", + [STAC_9200_DELL_M27] = "dell-m27", }; static struct snd_pci_quirk stac9200_cfg_tbl[] = { @@ -469,27 +615,64 @@ static struct snd_pci_quirk stac9200_cfg_tbl[] = { SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, "DFI LanParty", STAC_REF), /* Dell laptops have BIOS problem */ + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a8, + "unknown Dell", STAC_9200_DELL_D21), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01b5, - "Dell Inspiron 630m", STAC_REF), + "Dell Inspiron 630m", STAC_9200_DELL_M21), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01bd, + "Dell Inspiron E1505n", STAC_9200_DELL_M25), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c0, + "unknown Dell", STAC_9200_DELL_D22), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c1, + "unknown Dell", STAC_9200_DELL_D22), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c2, - "Dell Latitude D620", STAC_REF), + "Dell Latitude D620", STAC_9200_DELL_M22), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c5, + "unknown Dell", STAC_9200_DELL_D23), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c7, + "unknown Dell", STAC_9200_DELL_D23), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c8, + "unknown Dell", STAC_9200_DELL_M22), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c9, + "unknown Dell", STAC_9200_DELL_M24), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ca, + "unknown Dell", STAC_9200_DELL_M24), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cb, - "Dell Latitude 120L", STAC_REF), + "Dell Latitude 120L", STAC_9200_DELL_M24), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cc, - "Dell Latitude D820", STAC_REF), + "Dell Latitude D820", STAC_9200_DELL_M22), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cd, - "Dell Inspiron E1705/9400", STAC_REF), + "Dell Inspiron E1705/9400", STAC_9200_DELL_M27), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ce, - "Dell XPS M1710", STAC_REF), + "Dell XPS M1710", STAC_9200_DELL_M23), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cf, - "Dell Precision M90", STAC_REF), + "Dell Precision M90", STAC_9200_DELL_M23), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d3, + "unknown Dell", STAC_9200_DELL_M22), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d4, + "unknown Dell", STAC_9200_DELL_M22), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d6, - "unknown Dell", STAC_REF), + "unknown Dell", STAC_9200_DELL_M22), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d8, - "Dell Inspiron 640m", STAC_REF), + "Dell Inspiron 640m", STAC_9200_DELL_M21), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d9, + "unknown Dell", STAC_9200_DELL_D23), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01da, + "unknown Dell", STAC_9200_DELL_D23), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01de, + "unknown Dell", STAC_9200_DELL_D21), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01e3, + "unknown Dell", STAC_9200_DELL_D23), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01e8, + "unknown Dell", STAC_9200_DELL_D21), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ee, + "unknown Dell", STAC_9200_DELL_M25), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ef, + "unknown Dell", STAC_9200_DELL_M25), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f5, - "Dell Inspiron 1501", STAC_REF), - + "Dell Inspiron 1501", STAC_9200_DELL_M26), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f6, + "unknown Dell", STAC_9200_DELL_M26), /* Panasonic */ SND_PCI_QUIRK(0x10f7, 0x8338, "Panasonic CF-74", STAC_REF), @@ -548,6 +731,51 @@ static unsigned int ref922x_pin_configs[10] = { 0x40000100, 0x40000100, }; +/* + STAC 922X pin configs for + 102801A7 + 102801AB + 102801A9 + 102801D1 + 102801D2 +*/ +static unsigned int dell_922x_d81_pin_configs[10] = { + 0x02214030, 0x01a19021, 0x01111012, 0x01114010, + 0x02a19020, 0x01117011, 0x400001f0, 0x400001f1, + 0x01813122, 0x400001f2, +}; + +/* + STAC 922X pin configs for + 102801AC + 102801D0 +*/ +static unsigned int dell_922x_d82_pin_configs[10] = { + 0x02214030, 0x01a19021, 0x01111012, 0x01114010, + 0x02a19020, 0x01117011, 0x01451140, 0x400001f0, + 0x01813122, 0x400001f1, +}; + +/* + STAC 922X pin configs for + 102801BF +*/ +static unsigned int dell_922x_m81_pin_configs[10] = { + 0x0321101f, 0x01112024, 0x01111222, 0x91174220, + 0x03a11050, 0x01116221, 0x90a70330, 0x01452340, + 0x40C003f1, 0x405003f0, +}; + +/* + STAC 9221 A1 pin configs for + 102801D7 (Dell XPS M1210) +*/ +static unsigned int dell_922x_m82_pin_configs[10] = { + 0x0221121f, 0x408103ff, 0x02111212, 0x90100310, + 0x408003f1, 0x02111211, 0x03451340, 0x40c003f2, + 0x508003f3, 0x405003f4, +}; + static unsigned int d945gtp3_pin_configs[10] = { 0x0221401f, 0x01a19022, 0x01813021, 0x01014010, 0x40000100, 0x40000100, 0x40000100, 0x40000100, @@ -590,48 +818,49 @@ static unsigned int intel_mac_v5_pin_configs[10] = { 0x400000fc, 0x400000fb, }; -static unsigned int stac922x_dell_pin_configs[10] = { - 0x0221121e, 0x408103ff, 0x02a1123e, 0x90100310, - 0x408003f1, 0x0221122f, 0x03451340, 0x40c003f2, - 0x50a003f3, 0x405003f4 -}; static unsigned int *stac922x_brd_tbl[STAC_922X_MODELS] = { [STAC_D945_REF] = ref922x_pin_configs, [STAC_D945GTP3] = d945gtp3_pin_configs, [STAC_D945GTP5] = d945gtp5_pin_configs, - [STAC_922X_DELL] = stac922x_dell_pin_configs, [STAC_INTEL_MAC_V1] = intel_mac_v1_pin_configs, [STAC_INTEL_MAC_V2] = intel_mac_v2_pin_configs, [STAC_INTEL_MAC_V3] = intel_mac_v3_pin_configs, [STAC_INTEL_MAC_V4] = intel_mac_v4_pin_configs, [STAC_INTEL_MAC_V5] = intel_mac_v5_pin_configs, - /* for backward compitability */ + /* for backward compatibility */ [STAC_MACMINI] = intel_mac_v3_pin_configs, [STAC_MACBOOK] = intel_mac_v5_pin_configs, [STAC_MACBOOK_PRO_V1] = intel_mac_v3_pin_configs, [STAC_MACBOOK_PRO_V2] = intel_mac_v3_pin_configs, [STAC_IMAC_INTEL] = intel_mac_v2_pin_configs, [STAC_IMAC_INTEL_20] = intel_mac_v3_pin_configs, + [STAC_922X_DELL_D81] = dell_922x_d81_pin_configs, + [STAC_922X_DELL_D82] = dell_922x_d82_pin_configs, + [STAC_922X_DELL_M81] = dell_922x_m81_pin_configs, + [STAC_922X_DELL_M82] = dell_922x_m82_pin_configs, }; static const char *stac922x_models[STAC_922X_MODELS] = { [STAC_D945_REF] = "ref", [STAC_D945GTP5] = "5stack", [STAC_D945GTP3] = "3stack", - [STAC_922X_DELL] = "dell", [STAC_INTEL_MAC_V1] = "intel-mac-v1", [STAC_INTEL_MAC_V2] = "intel-mac-v2", [STAC_INTEL_MAC_V3] = "intel-mac-v3", [STAC_INTEL_MAC_V4] = "intel-mac-v4", [STAC_INTEL_MAC_V5] = "intel-mac-v5", - /* for backward compitability */ + /* for backward compatibility */ [STAC_MACMINI] = "macmini", [STAC_MACBOOK] = "macbook", [STAC_MACBOOK_PRO_V1] = "macbook-pro-v1", [STAC_MACBOOK_PRO_V2] = "macbook-pro", [STAC_IMAC_INTEL] = "imac-intel", [STAC_IMAC_INTEL_20] = "imac-intel-20", + [STAC_922X_DELL_D81] = "dell-d81", + [STAC_922X_DELL_D82] = "dell-d82", + [STAC_922X_DELL_M81] = "dell-m81", + [STAC_922X_DELL_M82] = "dell-m82", }; static struct snd_pci_quirk stac922x_cfg_tbl[] = { @@ -695,9 +924,25 @@ static struct snd_pci_quirk stac922x_cfg_tbl[] = { /* Apple Mac Mini (early 2006) */ SND_PCI_QUIRK(0x8384, 0x7680, "Mac Mini", STAC_INTEL_MAC_V3), - /* Dell */ - SND_PCI_QUIRK(0x1028, 0x01d7, "Dell XPS M1210", STAC_922X_DELL), - + /* Dell systems */ + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a7, + "unknown Dell", STAC_922X_DELL_D81), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a9, + "unknown Dell", STAC_922X_DELL_D81), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ab, + "unknown Dell", STAC_922X_DELL_D81), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ac, + "unknown Dell", STAC_922X_DELL_D82), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01bf, + "unknown Dell", STAC_922X_DELL_M81), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d0, + "unknown Dell", STAC_922X_DELL_D82), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d1, + "unknown Dell", STAC_922X_DELL_D81), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d2, + "unknown Dell", STAC_922X_DELL_D81), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d7, + "Dell XPS M1210", STAC_922X_DELL_M82), {} /* terminator */ }; @@ -768,7 +1013,7 @@ static struct snd_pci_quirk stac927x_cfg_tbl[] = { SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2002, "Intel D965", STAC_D965_3ST), SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2001, "Intel D965", STAC_D965_3ST), /* Dell 3 stack systems */ - SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01dd, "Dell E520", STAC_DELL_3ST), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01dd, "Dell Dimension E520", STAC_DELL_3ST), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ed, "Dell ", STAC_DELL_3ST), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f4, "Dell ", STAC_DELL_3ST), /* 965 based 5 stack systems */ @@ -790,28 +1035,54 @@ static unsigned int ref9205_pin_configs[12] = { 0x90a000f0, 0x90a000f0, 0x01441030, 0x01c41030 }; -static unsigned int dell_m43_9205_pin_configs[12] = { +/* + STAC 9205 pin configs for + 102801F1 + 102801F2 + 102801FC + 102801FD + 10280204 + 1028021F +*/ +static unsigned int dell_9205_m42_pin_configs[12] = { + 0x0321101F, 0x03A11020, 0x400003FA, 0x90170310, + 0x400003FB, 0x400003FC, 0x400003FD, 0x40F000F9, + 0x90A60330, 0x400003FF, 0x0144131F, 0x40C003FE, +}; + +/* + STAC 9205 pin configs for + 102801F9 + 102801FA + 102801FE + 102801FF (Dell Precision M4300) + 10280206 + 10280200 + 10280201 +*/ +static unsigned int dell_9205_m43_pin_configs[12] = { 0x0321101f, 0x03a11020, 0x90a70330, 0x90170310, 0x400000fe, 0x400000ff, 0x400000fd, 0x40f000f9, 0x400000fa, 0x400000fc, 0x0144131f, 0x40c003f8, }; -static unsigned int dell_m44_9205_pin_configs[12] = { +static unsigned int dell_9205_m44_pin_configs[12] = { 0x0421101f, 0x04a11020, 0x400003fa, 0x90170310, 0x400003fb, 0x400003fc, 0x400003fd, 0x400003f9, 0x90a60330, 0x400003ff, 0x01441340, 0x40c003fe, }; - static unsigned int *stac9205_brd_tbl[STAC_9205_MODELS] = { [STAC_9205_REF] = ref9205_pin_configs, - [STAC_9205_DELL_M43] = dell_m43_9205_pin_configs, - [STAC_9205_DELL_M44] = dell_m44_9205_pin_configs, + [STAC_9205_DELL_M42] = dell_9205_m42_pin_configs, + [STAC_9205_DELL_M43] = dell_9205_m43_pin_configs, + [STAC_9205_DELL_M44] = dell_9205_m44_pin_configs, [STAC_9205_M43xx] = NULL, }; static const char *stac9205_models[STAC_9205_MODELS] = { [STAC_9205_REF] = "ref", + [STAC_9205_DELL_M42] = "dell-m42", [STAC_9205_DELL_M43] = "dell-m43", [STAC_9205_DELL_M44] = "dell-m44", }; @@ -820,16 +1091,24 @@ static struct snd_pci_quirk stac9205_cfg_tbl[] = { /* SigmaTel reference board */ SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, "DFI LanParty", STAC_9205_REF), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f1, + "unknown Dell", STAC_9205_DELL_M42), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f2, + "unknown Dell", STAC_9205_DELL_M42), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f8, "Dell Precision", STAC_9205_M43xx), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f9, "Dell Precision", STAC_9205_DELL_M43), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fa, "Dell Precision", STAC_9205_DELL_M43), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fc, + "unknown Dell", STAC_9205_DELL_M42), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fd, + "unknown Dell", STAC_9205_DELL_M42), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fe, "Dell Precision", STAC_9205_DELL_M43), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ff, - "Dell Precision", STAC_9205_DELL_M43), + "Dell Precision M4300", STAC_9205_DELL_M43), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0206, "Dell Precision", STAC_9205_DELL_M43), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f1, @@ -840,6 +1119,8 @@ static struct snd_pci_quirk stac9205_cfg_tbl[] = { "Dell Inspiron", STAC_9205_DELL_M44), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fd, "Dell Inspiron", STAC_9205_DELL_M44), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0204, + "unknown Dell", STAC_9205_DELL_M42), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021f, "Dell Inspiron", STAC_9205_DELL_M44), {} /* terminator */ -- cgit v1.2.3 From c9116ae45bd10eabe1e5cf88798092e184d8dbc2 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Fri, 24 Aug 2007 09:18:04 +0200 Subject: [ALSA] cmipci: make the test for integrated MIDI port address more robust Unused bytes in the I/O register range are likely to have the value 0x00 instead of 0xff, so test against both values when checking for the presence of the integrated MIDI port. Signed-off-by: Clemens Ladisch Signed-off-by: Jaroslav Kysela --- sound/pci/cmipci.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c index 9d394c7c221..6021e5c402e 100644 --- a/sound/pci/cmipci.c +++ b/sound/pci/cmipci.c @@ -2827,7 +2827,7 @@ static int __devinit snd_cmipci_create(struct snd_card *card, struct pci_dev *pc }; unsigned int val = 0; long iomidi; - int integrated_midi; + int integrated_midi = 0; int pcm_index, pcm_spdif_index; static struct pci_device_id intel_82437vx[] = { { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82437VX) }, @@ -2939,11 +2939,14 @@ static int __devinit snd_cmipci_create(struct snd_card *card, struct pci_dev *pc return err; } - integrated_midi = cm->chip_version > 33 && - snd_cmipci_read_b(cm, CM_REG_MPU_PCI + 1) != 0xff; - if (integrated_midi && mpu_port[dev] == 1) - iomidi = cm->iobase + CM_REG_MPU_PCI; - else { + if (cm->chip_version > 33 && mpu_port[dev] == 1) { + val = snd_cmipci_read_b(cm, CM_REG_MPU_PCI + 1); + if (val != 0x00 && val != 0xff) { + iomidi = cm->iobase + CM_REG_MPU_PCI; + integrated_midi = 1; + } + } + if (!integrated_midi) { iomidi = mpu_port[dev]; switch (iomidi) { case 0x320: val = CM_VMPU_320; break; -- cgit v1.2.3 From 133271fef52c06de52ea9a8ee27899f18dae9af2 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 27 Aug 2007 09:20:31 +0200 Subject: [ALSA] cmipci: reorganize chip version detection Add a case for chip version 39 where no bit is set in register 0Ch, and move the detection of version 39 before that of 8768. This makes the logic more compatible with the driver on that other OS. Signed-off-by: Clemens Ladisch Signed-off-by: Jaroslav Kysela --- sound/pci/cmipci.c | 44 ++++++++++++++++++++------------------------ 1 file changed, 20 insertions(+), 24 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c index 6021e5c402e..cc0977a8a3d 100644 --- a/sound/pci/cmipci.c +++ b/sound/pci/cmipci.c @@ -2625,46 +2625,42 @@ static void __devinit query_chip(struct cmipci *cm) if (! detect) { /* check reg 08h, bit 24-28 */ detect = snd_cmipci_read(cm, CM_REG_CHFORMAT) & CM_CHIP_MASK1; - if (! detect) { + switch (detect) { + case 0: cm->chip_version = 33; - cm->max_channels = 2; if (cm->do_soft_ac3) cm->can_ac3_sw = 1; else cm->can_ac3_hw = 1; - cm->has_dual_dac = 1; - } else { + break; + case 1: cm->chip_version = 37; - cm->max_channels = 2; cm->can_ac3_hw = 1; - cm->has_dual_dac = 1; + break; + default: + cm->chip_version = 39; + cm->can_ac3_hw = 1; + break; } + cm->max_channels = 2; + cm->has_dual_dac = 1; } else { - /* check reg 0Ch, bit 26 */ - if (detect & CM_CHIP_8768) { - cm->chip_version = 68; - cm->max_channels = 8; - cm->can_ac3_hw = 1; - cm->has_dual_dac = 1; - cm->can_multi_ch = 1; - } else if (detect & CM_CHIP_055) { - cm->chip_version = 55; - cm->max_channels = 6; - cm->can_ac3_hw = 1; - cm->has_dual_dac = 1; - cm->can_multi_ch = 1; - } else if (detect & CM_CHIP_039) { + if (detect & CM_CHIP_039) { cm->chip_version = 39; if (detect & CM_CHIP_039_6CH) /* 4 or 6 channels */ cm->max_channels = 6; else cm->max_channels = 4; - cm->can_ac3_hw = 1; - cm->has_dual_dac = 1; - cm->can_multi_ch = 1; + } else if (detect & CM_CHIP_8768) { + cm->chip_version = 68; + cm->max_channels = 8; } else { - printk(KERN_ERR "chip %x version not supported\n", detect); + cm->chip_version = 55; + cm->max_channels = 6; } + cm->can_ac3_hw = 1; + cm->has_dual_dac = 1; + cm->can_multi_ch = 1; } } -- cgit v1.2.3 From b080ebbf92f8d98a048b100e0b0c4aa7e6354ab9 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 27 Aug 2007 09:21:02 +0200 Subject: [ALSA] cmipci: remove has_dual_dac Remove the has_dual_dac variable because it was always set. Signed-off-by: Clemens Ladisch Signed-off-by: Jaroslav Kysela --- sound/pci/cmipci.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c index cc0977a8a3d..42227012c0b 100644 --- a/sound/pci/cmipci.c +++ b/sound/pci/cmipci.c @@ -424,7 +424,6 @@ struct cmipci { int chip_version; int max_channels; - unsigned int has_dual_dac: 1; unsigned int can_ac3_sw: 1; unsigned int can_ac3_hw: 1; unsigned int can_multi_ch: 1; @@ -2643,7 +2642,6 @@ static void __devinit query_chip(struct cmipci *cm) break; } cm->max_channels = 2; - cm->has_dual_dac = 1; } else { if (detect & CM_CHIP_039) { cm->chip_version = 39; @@ -2659,7 +2657,6 @@ static void __devinit query_chip(struct cmipci *cm) cm->max_channels = 6; } cm->can_ac3_hw = 1; - cm->has_dual_dac = 1; cm->can_multi_ch = 1; } } @@ -2975,11 +2972,9 @@ static int __devinit snd_cmipci_create(struct snd_card *card, struct pci_dev *pc if ((err = snd_cmipci_pcm_new(cm, pcm_index)) < 0) return err; pcm_index++; - if (cm->has_dual_dac) { - if ((err = snd_cmipci_pcm2_new(cm, pcm_index)) < 0) - return err; - pcm_index++; - } + if ((err = snd_cmipci_pcm2_new(cm, pcm_index)) < 0) + return err; + pcm_index++; if (cm->can_ac3_hw || cm->can_ac3_sw) { pcm_spdif_index = pcm_index; if ((err = snd_cmipci_pcm_spdif_new(cm, pcm_index)) < 0) -- cgit v1.2.3 From d6426257d2c960399ff675b7807cde54b769e543 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 27 Aug 2007 09:22:31 +0200 Subject: [ALSA] cmipci: show actual chip name in card longname Show the actual name of CMI8762/CMI8768/CMI8769/CMI8770 chips in the card longname instead of just using 'CMI8738' for all of them. Signed-off-by: Clemens Ladisch Signed-off-by: Jaroslav Kysela --- sound/pci/cmipci.c | 42 +++++++++++++++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 7 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c index 42227012c0b..315ba26bbd8 100644 --- a/sound/pci/cmipci.c +++ b/sound/pci/cmipci.c @@ -2818,7 +2818,7 @@ static int __devinit snd_cmipci_create(struct snd_card *card, struct pci_dev *pc static struct snd_device_ops ops = { .dev_free = snd_cmipci_dev_free, }; - unsigned int val = 0; + unsigned int val; long iomidi; int integrated_midi = 0; int pcm_index, pcm_spdif_index; @@ -2920,18 +2920,46 @@ static int __devinit snd_cmipci_create(struct snd_card *card, struct pci_dev *pc break; } - sprintf(card->shortname, "C-Media PCI %s", card->driver); - sprintf(card->longname, "%s (model %d) at 0x%lx, irq %i", - card->shortname, - cm->chip_version, - cm->iobase, - cm->irq); + sprintf(card->shortname, "C-Media %s", card->driver); + if (cm->chip_version < 68) { + val = pci->device < 0x110 ? 8338 : 8738; + sprintf(card->longname, + "C-Media CMI%d (model %d) at 0x%lx, irq %i", + val, cm->chip_version, cm->iobase, cm->irq); + } else { + switch (snd_cmipci_read_b(cm, CM_REG_INT_HLDCLR + 3) & 0x03) { + case 0: + val = 8769; + break; + case 2: + val = 8762; + break; + default: + switch ((pci->subsystem_vendor << 16) | + pci->subsystem_device) { + case 0x13f69761: + case 0x584d3741: + case 0x584d3751: + case 0x584d3761: + case 0x584d3771: + case 0x72848384: + val = 8770; + break; + default: + val = 8768; + break; + } + } + sprintf(card->longname, "C-Media CMI%d at 0x%lx, irq %i", + val, cm->iobase, cm->irq); + } if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, cm, &ops)) < 0) { snd_cmipci_free(cm); return err; } + val = 0; if (cm->chip_version > 33 && mpu_port[dev] == 1) { val = snd_cmipci_read_b(cm, CM_REG_MPU_PCI + 1); if (val != 0x00 && val != 0xff) { -- cgit v1.2.3 From 36726d9df7746efc2f71bb63f39f8ac7f7951a26 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Tue, 28 Aug 2007 15:21:33 +0200 Subject: [ALSA] emu10k1: There's no need to cast vmalloc() return value in snd_emu10k1_create() vmalloc() returns void *. no need to cast. Signed-off-by: Jesper Juhl Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/emu10k1/emu10k1_main.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c index f55395bc911..b112b295e9c 100644 --- a/sound/pci/emu10k1/emu10k1_main.c +++ b/sound/pci/emu10k1/emu10k1_main.c @@ -1755,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; -- cgit v1.2.3 From 776e184e8082a4ec9bf4fe18b11dae6dc4e43d1f Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 29 Aug 2007 15:07:11 +0200 Subject: [ALSA] hda-codec - Add Mic Boost control with auto-configuration Some codecs need Mic Boost mixer controls for obtaining a proper recording level, but the auto-configuration doesn't create them. This patch adds the creation of mic-boost controls on corresponding codecs. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_realtek.c | 68 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 60 insertions(+), 8 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index b108ea3d99b..b3062afc481 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -5782,6 +5782,32 @@ static void alc882_auto_init_analog_input(struct hda_codec *codec) } } +/* add mic boosts if needed */ +static int alc_auto_add_mic_boost(struct hda_codec *codec) +{ + struct alc_spec *spec = codec->spec; + int err; + hda_nid_t nid; + + nid = spec->autocfg.input_pins[AUTO_PIN_MIC]; + if (nid) { + err = add_control(spec, ALC_CTL_WIDGET_VOL, + "Mic Boost", + HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT)); + if (err < 0) + return err; + } + nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC]; + if (nid) { + err = add_control(spec, ALC_CTL_WIDGET_VOL, + "Front Mic Boost", + HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT)); + if (err < 0) + return err; + } + return 0; +} + /* almost identical with ALC880 parser... */ static int alc882_parse_auto_config(struct hda_codec *codec) { @@ -5790,10 +5816,17 @@ static int alc882_parse_auto_config(struct hda_codec *codec) if (err < 0) return err; - else if (err > 0) - /* hack - override the init verbs */ - spec->init_verbs[0] = alc882_auto_init_verbs; - return err; + else if (!err) + return 0; /* no config found */ + + err = alc_auto_add_mic_boost(codec); + if (err < 0) + return err; + + /* hack - override the init verbs */ + spec->init_verbs[0] = alc882_auto_init_verbs; + + return 1; /* config found */ } /* additional initialization for auto-configuration model */ @@ -7270,12 +7303,19 @@ static int alc883_parse_auto_config(struct hda_codec *codec) if (err < 0) return err; - else if (err > 0) - /* hack - override the init verbs */ - spec->init_verbs[0] = alc883_auto_init_verbs; + else if (!err) + return 0; /* no config found */ + + err = alc_auto_add_mic_boost(codec); + if (err < 0) + return err; + + /* hack - override the init verbs */ + spec->init_verbs[0] = alc883_auto_init_verbs; spec->mixers[spec->num_mixers] = alc883_capture_mixer; spec->num_mixers++; - return err; + + return 1; /* config found */ } /* additional initialization for auto-configuration model */ @@ -8184,6 +8224,10 @@ static int alc262_parse_auto_config(struct hda_codec *codec) spec->num_mux_defs = 1; spec->input_mux = &spec->private_imux; + err = alc_auto_add_mic_boost(codec); + if (err < 0) + return err; + return 1; } @@ -8957,6 +9001,10 @@ static int alc268_parse_auto_config(struct hda_codec *codec) spec->num_mux_defs = 1; spec->input_mux = &spec->private_imux; + err = alc_auto_add_mic_boost(codec); + if (err < 0) + return err; + return 1; } @@ -11173,6 +11221,10 @@ static int alc861vd_parse_auto_config(struct hda_codec *codec) spec->num_mux_defs = 1; spec->input_mux = &spec->private_imux; + err = alc_auto_add_mic_boost(codec); + if (err < 0) + return err; + return 1; } -- cgit v1.2.3 From d6c3cf81f05c8dd8e5e656d4bcb8d5f2569d0262 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 29 Aug 2007 15:12:46 +0200 Subject: [ALSA] ac97 - Suppress the reset of audio-codec from modem-codec at resume On codec chips with both audio and modem functions (e.g. Conexant one), performing AC97_RESET resets the whole registers. When both audio and modem drivers are resumed at the same time, the modem one often is resumed after the audio, and it results in the reset of audio registers (ALSA bug#3333). This patch fixes such a problem. Since the modem codec basically doesn't need AC97_RESET, skip this initialization unless specified as audio. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/ac97/ac97_codec.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'sound/pci') diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c index df1333332a5..3e5ff29fc49 100644 --- a/sound/pci/ac97/ac97_codec.c +++ b/sound/pci/ac97/ac97_codec.c @@ -2496,7 +2496,10 @@ void snd_ac97_resume(struct snd_ac97 *ac97) snd_ac97_write(ac97, AC97_POWERDOWN, 0); if (! (ac97->flags & AC97_DEFAULT_POWER_OFF)) { - snd_ac97_write(ac97, AC97_RESET, 0); + if (!(ac97->scaps & AC97_SCAP_SKIP_AUDIO)) + snd_ac97_write(ac97, AC97_RESET, 0); + else if (!(ac97->scaps & AC97_SCAP_SKIP_MODEM)) + snd_ac97_write(ac97, AC97_EXTENDED_MID, 0); udelay(100); snd_ac97_write(ac97, AC97_POWERDOWN, 0); } -- cgit v1.2.3 From 6534599d14892c5b0838b7170f071c850f5ea8e9 Mon Sep 17 00:00:00 2001 From: Remy Bruno Date: Fri, 31 Aug 2007 12:21:08 +0200 Subject: [ALSA] hdspm - Fix autosync bug * better report of speed mode change failures * autosync_ref control bugfix (was reporting pref_sync_ref instead) (changed HDSPM_AES32_AUTOSYNC_FROM_NONE value to comply with array indexing in snd_hdspm_info_autosync_ref()) * added support for master modes up to 192kHz (clock source control value was restricted up to 96kHz) Signed-off-by: Remy Bruno Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/rme9652/hdspm.c | 60 +++++++++++++++++++++++------------------------ 1 file changed, 30 insertions(+), 30 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c index 30e0c4dc948..f1bdda6cbcf 100644 --- a/sound/pci/rme9652/hdspm.c +++ b/sound/pci/rme9652/hdspm.c @@ -359,7 +359,7 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}"); #define HDSPM_AES32_AUTOSYNC_FROM_AES6 6 #define HDSPM_AES32_AUTOSYNC_FROM_AES7 7 #define HDSPM_AES32_AUTOSYNC_FROM_AES8 8 -#define HDSPM_AES32_AUTOSYNC_FROM_NONE -1 +#define HDSPM_AES32_AUTOSYNC_FROM_NONE 9 /* status2 */ /* HDSPM_LockAES_bit is given by HDSPM_LockAES >> (AES# - 1) */ @@ -413,6 +413,13 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}"); /* revisions >= 230 indicate AES32 card */ #define HDSPM_AESREVISION 230 +/* speed factor modes */ +#define HDSPM_SPEED_SINGLE 0 +#define HDSPM_SPEED_DOUBLE 1 +#define HDSPM_SPEED_QUAD 2 +/* names for speed modes */ +static char *hdspm_speed_names[] = { "single", "double", "quad" }; + struct hdspm_midi { struct hdspm *hdspm; int id; @@ -831,7 +838,7 @@ static void hdspm_set_dds_value(struct hdspm *hdspm, int rate) rate /= 2; /* RME says n = 104857600000000, but in the windows MADI driver, I see: - return 104857600000000 / rate; // 100 MHz +// return 104857600000000 / rate; // 100 MHz return 110100480000000 / rate; // 105 MHz */ /* n = 104857600000000ULL; */ /* = 2^20 * 10^8 */ @@ -845,11 +852,10 @@ static void hdspm_set_dds_value(struct hdspm *hdspm, int rate) /* dummy set rate lets see what happens */ static int hdspm_set_rate(struct hdspm * hdspm, int rate, int called_internally) { - int reject_if_open = 0; int current_rate; int rate_bits; int not_set = 0; - int is_single, is_double, is_quad; + int current_speed, target_speed; /* ASSUMPTION: hdspm->lock is either set, or there is no need for it (e.g. during module initialization). @@ -903,66 +909,60 @@ static int hdspm_set_rate(struct hdspm * hdspm, int rate, int called_internally) changes in the read/write routines. */ - is_single = (current_rate <= 48000); - is_double = (current_rate > 48000 && current_rate <= 96000); - is_quad = (current_rate > 96000); + if (current_rate <= 48000) + current_speed = HDSPM_SPEED_SINGLE; + else if (current_rate <= 96000) + current_speed = HDSPM_SPEED_DOUBLE; + else + current_speed = HDSPM_SPEED_QUAD; + + if (rate <= 48000) + target_speed = HDSPM_SPEED_SINGLE; + else if (rate <= 96000) + target_speed = HDSPM_SPEED_DOUBLE; + else + target_speed = HDSPM_SPEED_QUAD; switch (rate) { case 32000: - if (!is_single) - reject_if_open = 1; rate_bits = HDSPM_Frequency32KHz; break; case 44100: - if (!is_single) - reject_if_open = 1; rate_bits = HDSPM_Frequency44_1KHz; break; case 48000: - if (!is_single) - reject_if_open = 1; rate_bits = HDSPM_Frequency48KHz; break; case 64000: - if (!is_double) - reject_if_open = 1; rate_bits = HDSPM_Frequency64KHz; break; case 88200: - if (!is_double) - reject_if_open = 1; rate_bits = HDSPM_Frequency88_2KHz; break; case 96000: - if (!is_double) - reject_if_open = 1; rate_bits = HDSPM_Frequency96KHz; break; case 128000: - if (!is_quad) - reject_if_open = 1; rate_bits = HDSPM_Frequency128KHz; break; case 176400: - if (!is_quad) - reject_if_open = 1; rate_bits = HDSPM_Frequency176_4KHz; break; case 192000: - if (!is_quad) - reject_if_open = 1; rate_bits = HDSPM_Frequency192KHz; break; default: return -EINVAL; } - if (reject_if_open + if (current_speed != target_speed && (hdspm->capture_pid >= 0 || hdspm->playback_pid >= 0)) { snd_printk (KERN_ERR "HDSPM: " - "cannot change between single- and double-speed mode " + "cannot change from %s speed to %s speed mode " "(capture PID = %d, playback PID = %d)\n", + hdspm_speed_names[current_speed], + hdspm_speed_names[target_speed], hdspm->capture_pid, hdspm->playback_pid); return -EBUSY; } @@ -1603,8 +1603,8 @@ static int snd_hdspm_put_clock_source(struct snd_kcontrol *kcontrol, val = ucontrol->value.enumerated.item[0]; if (val < 0) val = 0; - if (val > 6) - val = 6; + if (val > 9) + val = 9; spin_lock_irq(&hdspm->lock); if (val != hdspm_clock_source(hdspm)) change = (hdspm_set_clock_source(hdspm, val) == 0) ? 1 : 0; @@ -1853,7 +1853,7 @@ static int snd_hdspm_get_autosync_ref(struct snd_kcontrol *kcontrol, { struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); - ucontrol->value.enumerated.item[0] = hdspm_pref_sync_ref(hdspm); + ucontrol->value.enumerated.item[0] = hdspm_autosync_ref(hdspm); return 0; } -- cgit v1.2.3 From a3a68c85bfb7acc874ce6d334964b95943d4ed43 Mon Sep 17 00:00:00 2001 From: Remy Bruno Date: Fri, 31 Aug 2007 12:33:54 +0200 Subject: [ALSA] hdsp - Add support for latset RME9632 revisions added support for the latest revision of the 9632 (and hopefully a few following ones). The DSP matrix was not working because of wrong identification of the card in this part of the code. Signed-off-by: Remy Bruno Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/rme9652/hdsp.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c index 8f798f2fc04..2411f0b396b 100644 --- a/sound/pci/rme9652/hdsp.c +++ b/sound/pci/rme9652/hdsp.c @@ -606,28 +606,28 @@ static void snd_hdsp_9652_enable_mixer (struct hdsp *hdsp); static int hdsp_playback_to_output_key (struct hdsp *hdsp, int in, int out) { - switch (hdsp->firmware_rev) { - case 0xa: + switch (hdsp->io_type) { + case Multiface: + case Digiface: + default: return (64 * out) + (32 + (in)); - case 0x96: - case 0x97: - case 0x98: + case H9632: return (32 * out) + (16 + (in)); - default: + case H9652: return (52 * out) + (26 + (in)); } } static int hdsp_input_to_output_key (struct hdsp *hdsp, int in, int out) { - switch (hdsp->firmware_rev) { - case 0xa: + switch (hdsp->io_type) { + case Multiface: + case Digiface: + default: return (64 * out) + in; - case 0x96: - case 0x97: - case 0x98: + case H9632: return (32 * out) + in; - default: + case H9652: return (52 * out) + in; } } -- cgit v1.2.3 From accbe4988c5cf3dc86f0a042396163ed279536a6 Mon Sep 17 00:00:00 2001 From: zhejiang Date: Fri, 31 Aug 2007 12:36:05 +0200 Subject: [ALSA] hda-codec - Fix capture on ALC262 HP machines Fix the index for Front Mic capture source on ALC262 HP machines. Also, added the new capture source list for HP BPC DC7000 series to work properly. From: zhejiang Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_realtek.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index b3062afc481..3557865dde3 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -7746,13 +7746,23 @@ static struct hda_input_mux alc262_HP_capture_source = { .num_items = 5, .items = { { "Mic", 0x0 }, - { "Front Mic", 0x3 }, + { "Front Mic", 0x1 }, { "Line", 0x2 }, { "CD", 0x4 }, { "AUX IN", 0x6 }, }, }; +static struct hda_input_mux alc262_HP_D7000_capture_source = { + .num_items = 4, + .items = { + { "Mic", 0x0 }, + { "Front Mic", 0x2 }, + { "Line", 0x1 }, + { "CD", 0x4 }, + }, +}; + /* mute/unmute internal speaker according to the hp jack and mute state */ static void alc262_fujitsu_automute(struct hda_codec *codec, int force) { @@ -8357,7 +8367,7 @@ static struct alc_config_preset alc262_presets[] = { .hp_nid = 0x03, .num_channel_mode = ARRAY_SIZE(alc262_modes), .channel_mode = alc262_modes, - .input_mux = &alc262_HP_capture_source, + .input_mux = &alc262_HP_D7000_capture_source, }, [ALC262_HP_BPC_D7000_WL] = { .mixers = { alc262_HP_BPC_WildWest_mixer, @@ -8368,7 +8378,7 @@ static struct alc_config_preset alc262_presets[] = { .hp_nid = 0x03, .num_channel_mode = ARRAY_SIZE(alc262_modes), .channel_mode = alc262_modes, - .input_mux = &alc262_HP_capture_source, + .input_mux = &alc262_HP_D7000_capture_source, }, [ALC262_BENQ_ED8] = { .mixers = { alc262_base_mixer }, -- cgit v1.2.3 From ca7c5a8b4b4f61087851bb440118e62a688c1688 Mon Sep 17 00:00:00 2001 From: Maxim Levitsky Date: Fri, 31 Aug 2007 12:52:19 +0200 Subject: [ALSA] hda-codec - code cleanups in patch_sigmatel.c Clean up the mixer entries for Input Source using a macro. Signed-off-by: Maxim Levitsky Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_sigmatel.c | 65 +++++++++++------------------------------- 1 file changed, 17 insertions(+), 48 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index adca2854e50..98144f93dff 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -335,17 +335,21 @@ static struct hda_verb stac9205_core_init[] = { {} }; +#define STAC_INPUT_SOURCE \ + { \ + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ + .name = "Input Source", \ + .count = 1, \ + .info = stac92xx_mux_enum_info, \ + .get = stac92xx_mux_enum_get, \ + .put = stac92xx_mux_enum_put, \ + } + + static struct snd_kcontrol_new stac9200_mixer[] = { HDA_CODEC_VOLUME("Master Playback Volume", 0xb, 0, HDA_OUTPUT), HDA_CODEC_MUTE("Master Playback Switch", 0xb, 0, HDA_OUTPUT), - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Input Source", - .count = 1, - .info = stac92xx_mux_enum_info, - .get = stac92xx_mux_enum_get, - .put = stac92xx_mux_enum_put, - }, + STAC_INPUT_SOURCE, HDA_CODEC_VOLUME("Capture Volume", 0x0a, 0, HDA_OUTPUT), HDA_CODEC_MUTE("Capture Switch", 0x0a, 0, HDA_OUTPUT), HDA_CODEC_VOLUME("Capture Mux Volume", 0x0c, 0, HDA_OUTPUT), @@ -353,14 +357,7 @@ static struct snd_kcontrol_new stac9200_mixer[] = { }; static struct snd_kcontrol_new stac925x_mixer[] = { - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Input Source", - .count = 1, - .info = stac92xx_mux_enum_info, - .get = stac92xx_mux_enum_get, - .put = stac92xx_mux_enum_put, - }, + STAC_INPUT_SOURCE, HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_OUTPUT), HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_OUTPUT), HDA_CODEC_VOLUME("Capture Mux Volume", 0x0f, 0, HDA_OUTPUT), @@ -369,14 +366,7 @@ static struct snd_kcontrol_new stac925x_mixer[] = { /* This needs to be generated dynamically based on sequence */ static struct snd_kcontrol_new stac922x_mixer[] = { - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Input Source", - .count = 1, - .info = stac92xx_mux_enum_info, - .get = stac92xx_mux_enum_get, - .put = stac92xx_mux_enum_put, - }, + STAC_INPUT_SOURCE, HDA_CODEC_VOLUME("Capture Volume", 0x17, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Capture Switch", 0x17, 0x0, HDA_INPUT), HDA_CODEC_VOLUME("Mux Capture Volume", 0x12, 0x0, HDA_OUTPUT), @@ -385,28 +375,14 @@ static struct snd_kcontrol_new stac922x_mixer[] = { /* This needs to be generated dynamically based on sequence */ static struct snd_kcontrol_new stac9227_mixer[] = { - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Input Source", - .count = 1, - .info = stac92xx_mux_enum_info, - .get = stac92xx_mux_enum_get, - .put = stac92xx_mux_enum_put, - }, + STAC_INPUT_SOURCE, HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Capture Switch", 0x1b, 0x0, HDA_OUTPUT), { } /* end */ }; static struct snd_kcontrol_new stac927x_mixer[] = { - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Input Source", - .count = 1, - .info = stac92xx_mux_enum_info, - .get = stac92xx_mux_enum_get, - .put = stac92xx_mux_enum_put, - }, + STAC_INPUT_SOURCE, HDA_CODEC_VOLUME("InMux Capture Volume", 0x15, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("InVol Capture Volume", 0x18, 0x0, HDA_INPUT), HDA_CODEC_MUTE("ADCMux Capture Switch", 0x1b, 0x0, HDA_OUTPUT), @@ -422,14 +398,7 @@ static struct snd_kcontrol_new stac9205_mixer[] = { .get = stac92xx_dmux_enum_get, .put = stac92xx_dmux_enum_put, }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Input Source", - .count = 1, - .info = stac92xx_mux_enum_info, - .get = stac92xx_mux_enum_get, - .put = stac92xx_mux_enum_put, - }, + STAC_INPUT_SOURCE, HDA_CODEC_VOLUME("InMux Capture Volume", 0x19, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("InVol Capture Volume", 0x1b, 0x0, HDA_INPUT), HDA_CODEC_MUTE("ADCMux Capture Switch", 0x1d, 0x0, HDA_OUTPUT), -- cgit v1.2.3 From dc81bed127a93e20d2100624273a27369738ffc7 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 3 Sep 2007 09:36:36 +0200 Subject: [ALSA] hda-codec - Fix wrong pin-setup at resume of STAC codecs The resume procedure for STAC codecs overrides the cached values and results in the wrong (reset) PIN state. The patch gets rid of the overriding part and simplifies the resume. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_sigmatel.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 98144f93dff..39187828503 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -2061,9 +2061,9 @@ static void enable_pin_detect(struct hda_codec *codec, hda_nid_t nid, unsigned int event) { if (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP) - snd_hda_codec_write(codec, nid, 0, - AC_VERB_SET_UNSOLICITED_ENABLE, - (AC_USRSP_EN | event)); + snd_hda_codec_write_cache(codec, nid, 0, + AC_VERB_SET_UNSOLICITED_ENABLE, + (AC_USRSP_EN | event)); } static int stac92xx_init(struct hda_codec *codec) @@ -2236,10 +2236,19 @@ static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res) #ifdef SND_HDA_NEEDS_RESUME static int stac92xx_resume(struct hda_codec *codec) { + struct sigmatel_spec *spec = codec->spec; + stac92xx_set_config_regs(codec); - stac92xx_init(codec); + snd_hda_sequence_write(codec, spec->init); + if (spec->gpio_mute) { + stac922x_gpio_mute(codec, 0, 0); + stac922x_gpio_mute(codec, 1, 0); + } snd_hda_codec_resume_amp(codec); snd_hda_codec_resume_cache(codec); + /* invoke unsolicited event to reset the HP state */ + if (spec->hp_detect) + codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26); return 0; } #endif -- cgit v1.2.3 From c480f79bdca58923e605ff5e4698cfe1779bae70 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 3 Sep 2007 09:43:38 +0200 Subject: [ALSA] hda-codec - Avoid zero NID in line_out_pins[] of STAC codecs The STAC codes adds line_out_pins[] for shared mic/line-inputs accordingly. But, the current code may give a hole with NID=0 in some setting, which results in an error at probe. This patch fixes the problem. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_sigmatel.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 39187828503..b4a1d73b572 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -1479,7 +1479,8 @@ static int stac92xx_add_dyn_out_pins(struct hda_codec *codec, struct auto_pin_cf case 3: /* add line-in as side */ if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 3) { - cfg->line_out_pins[3] = cfg->input_pins[AUTO_PIN_LINE]; + cfg->line_out_pins[cfg->line_outs] = + cfg->input_pins[AUTO_PIN_LINE]; spec->line_switch = 1; cfg->line_outs++; } @@ -1487,12 +1488,14 @@ static int stac92xx_add_dyn_out_pins(struct hda_codec *codec, struct auto_pin_cf case 2: /* add line-in as clfe and mic as side */ if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 2) { - cfg->line_out_pins[2] = cfg->input_pins[AUTO_PIN_LINE]; + cfg->line_out_pins[cfg->line_outs] = + cfg->input_pins[AUTO_PIN_LINE]; spec->line_switch = 1; cfg->line_outs++; } if (cfg->input_pins[AUTO_PIN_MIC] && num_dacs > 3) { - cfg->line_out_pins[3] = cfg->input_pins[AUTO_PIN_MIC]; + cfg->line_out_pins[cfg->line_outs] = + cfg->input_pins[AUTO_PIN_MIC]; spec->mic_switch = 1; cfg->line_outs++; } @@ -1500,12 +1503,14 @@ static int stac92xx_add_dyn_out_pins(struct hda_codec *codec, struct auto_pin_cf case 1: /* add line-in as surr and mic as clfe */ if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 1) { - cfg->line_out_pins[1] = cfg->input_pins[AUTO_PIN_LINE]; + cfg->line_out_pins[cfg->line_outs] = + cfg->input_pins[AUTO_PIN_LINE]; spec->line_switch = 1; cfg->line_outs++; } if (cfg->input_pins[AUTO_PIN_MIC] && num_dacs > 2) { - cfg->line_out_pins[2] = cfg->input_pins[AUTO_PIN_MIC]; + cfg->line_out_pins[cfg->line_outs] = + cfg->input_pins[AUTO_PIN_MIC]; spec->mic_switch = 1; cfg->line_outs++; } -- cgit v1.2.3 From f19a82a119b41d4607b63e6fd0412498a87d30bc Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 3 Sep 2007 09:54:27 +0200 Subject: [ALSA] cmipci: remove invalid channels constraint Remove the constraint that sets the channel limit for the first playback device to that of the second one; the first device supports only stereo. Signed-off-by: Clemens Ladisch Signed-off-by: Jaroslav Kysela --- sound/pci/cmipci.c | 1 - 1 file changed, 1 deletion(-) (limited to 'sound/pci') diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c index 315ba26bbd8..6d3a0abadd7 100644 --- a/sound/pci/cmipci.c +++ b/sound/pci/cmipci.c @@ -1514,7 +1514,6 @@ static int snd_cmipci_playback_open(struct snd_pcm_substream *substream) if ((err = open_device_check(cm, CM_OPEN_PLAYBACK, substream)) < 0) return err; runtime->hw = snd_cmipci_playback; - runtime->hw.channels_max = cm->max_channels; snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 0x10000); cm->dig_pcm_status = cm->dig_status; return 0; -- cgit v1.2.3 From 8992e18db32f5df55fd4b458def7dccd2a5c3266 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 3 Sep 2007 09:54:55 +0200 Subject: [ALSA] cmipci: add 96 kHz support Add support for 88.2 kHz and 96 kHz analog and digital playback on CMI8768/CMI8770 chips. Signed-off-by: Clemens Ladisch Signed-off-by: Jaroslav Kysela --- sound/pci/cmipci.c | 38 +++++++++++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c index 6d3a0abadd7..af266eb8305 100644 --- a/sound/pci/cmipci.c +++ b/sound/pci/cmipci.c @@ -135,11 +135,14 @@ MODULE_PARM_DESC(joystick_port, "Joystick port address."); #define CM_ADCDACLEN_280 0x00003000 #define CM_CH1_SRATE_176K 0x00000800 +#define CM_CH1_SRATE_96K 0x00000800 /* model 055? */ #define CM_CH1_SRATE_88K 0x00000400 #define CM_CH0_SRATE_176K 0x00000200 +#define CM_CH0_SRATE_96K 0x00000200 /* model 055? */ #define CM_CH0_SRATE_88K 0x00000100 #define CM_SPDIF_INVERSE2 0x00000080 /* model 055? */ +#define CM_DBLSPDS 0x00000040 #define CM_CH1FMT_MASK 0x0000000C #define CM_CH1FMT_SHIFT 2 @@ -812,6 +815,16 @@ static int snd_cmipci_pcm_prepare(struct cmipci *cm, struct cmipci_pcm *rec, val &= ~CM_CH0FMT_MASK; val |= rec->fmt << CM_CH0FMT_SHIFT; } + if (cm->chip_version == 68) { + if (runtime->rate == 88200) + val |= CM_CH0_SRATE_88K << (rec->ch * 2); + else + val &= ~(CM_CH0_SRATE_88K << (rec->ch * 2)); + if (runtime->rate == 96000) + val |= CM_CH0_SRATE_96K << (rec->ch * 2); + else + val &= ~(CM_CH0_SRATE_96K << (rec->ch * 2)); + } snd_cmipci_write(cm, CM_REG_CHFORMAT, val); //snd_printd("cmipci: chformat = %08x\n", val); @@ -1198,15 +1211,19 @@ static int setup_spdif_playback(struct cmipci *cm, struct snd_pcm_substream *sub snd_cmipci_set_bit(cm, CM_REG_FUNCTRL1, CM_PLAYBACK_SPDF); setup_ac3(cm, subs, do_ac3, rate); - if (rate == 48000) + if (rate == 48000 || rate == 96000) snd_cmipci_set_bit(cm, CM_REG_MISC_CTRL, CM_SPDIF48K | CM_SPDF_AC97); else snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_SPDIF48K | CM_SPDF_AC97); - + if (rate > 48000) + snd_cmipci_set_bit(cm, CM_REG_CHFORMAT, CM_DBLSPDS); + else + snd_cmipci_clear_bit(cm, CM_REG_CHFORMAT, CM_DBLSPDS); } else { /* they are controlled via "IEC958 Output Switch" */ /* snd_cmipci_clear_bit(cm, CM_REG_LEGACY_CTRL, CM_ENSPDOUT); */ /* snd_cmipci_clear_bit(cm, CM_REG_FUNCTRL1, CM_SPDO2DAC); */ + snd_cmipci_clear_bit(cm, CM_REG_CHFORMAT, CM_DBLSPDS); snd_cmipci_clear_bit(cm, CM_REG_FUNCTRL1, CM_PLAYBACK_SPDF); setup_ac3(cm, subs, 0, 0); } @@ -1226,7 +1243,7 @@ static int snd_cmipci_playback_prepare(struct snd_pcm_substream *substream) int rate = substream->runtime->rate; int err, do_spdif, do_ac3 = 0; - do_spdif = ((rate == 44100 || rate == 48000) && + do_spdif = (rate >= 44100 && substream->runtime->format == SNDRV_PCM_FORMAT_S16_LE && substream->runtime->channels == 2); if (do_spdif && cm->can_ac3_hw) @@ -1514,6 +1531,11 @@ static int snd_cmipci_playback_open(struct snd_pcm_substream *substream) if ((err = open_device_check(cm, CM_OPEN_PLAYBACK, substream)) < 0) return err; runtime->hw = snd_cmipci_playback; + if (cm->chip_version == 68) { + runtime->hw.rates |= SNDRV_PCM_RATE_88200 | + SNDRV_PCM_RATE_96000; + runtime->hw.rate_max = 96000; + } snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 0x10000); cm->dig_pcm_status = cm->dig_status; return 0; @@ -1556,6 +1578,11 @@ static int snd_cmipci_playback2_open(struct snd_pcm_substream *substream) else if (cm->max_channels == 8) snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, &hw_constraints_channels_8); } + if (cm->chip_version == 68) { + runtime->hw.rates |= SNDRV_PCM_RATE_88200 | + SNDRV_PCM_RATE_96000; + runtime->hw.rate_max = 96000; + } snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 0x10000); } mutex_unlock(&cm->open_mutex); @@ -1574,6 +1601,11 @@ static int snd_cmipci_playback_spdif_open(struct snd_pcm_substream *substream) runtime->hw = snd_cmipci_playback_spdif; if (cm->chip_version >= 37) runtime->hw.formats |= SNDRV_PCM_FMTBIT_S32_LE; + if (cm->chip_version == 68) { + runtime->hw.rates |= SNDRV_PCM_RATE_88200 | + SNDRV_PCM_RATE_96000; + runtime->hw.rate_max = 96000; + } } else { runtime->hw = snd_cmipci_playback_iec958_subframe; } -- cgit v1.2.3 From c78c950d28df984e39ad028a90bcdadcd3eda3b6 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 3 Sep 2007 09:55:49 +0200 Subject: [ALSA] cmipci: do not check for integrated FM/MIDI ports with chip version 37 Integrated MPU-401/OPL3 ports are available with chip version 39 and later, so we do not test for the port with version 37. Now that the test is known to work, we can again enable the MIDI port by default. Signed-off-by: Clemens Ladisch Signed-off-by: Jaroslav Kysela --- sound/pci/cmipci.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c index af266eb8305..fdc4615ea0e 100644 --- a/sound/pci/cmipci.c +++ b/sound/pci/cmipci.c @@ -2798,7 +2798,7 @@ static int __devinit snd_cmipci_create_fm(struct cmipci *cm, long fm_port) if (!fm_port) goto disable_fm; - if (cm->chip_version > 33) { + if (cm->chip_version >= 39) { /* first try FM regs in PCI port range */ iosynth = cm->iobase + CM_REG_FM_PCI; err = snd_opl3_create(cm->card, iosynth, iosynth + 2, @@ -2990,8 +2990,7 @@ static int __devinit snd_cmipci_create(struct snd_card *card, struct pci_dev *pc return err; } - val = 0; - if (cm->chip_version > 33 && mpu_port[dev] == 1) { + if (cm->chip_version >= 39) { val = snd_cmipci_read_b(cm, CM_REG_MPU_PCI + 1); if (val != 0x00 && val != 0xff) { iomidi = cm->iobase + CM_REG_MPU_PCI; @@ -2999,6 +2998,7 @@ static int __devinit snd_cmipci_create(struct snd_card *card, struct pci_dev *pc } } if (!integrated_midi) { + val = 0; iomidi = mpu_port[dev]; switch (iomidi) { case 0x320: val = CM_VMPU_320; break; -- cgit v1.2.3 From 88039815d8868fb507eb69448f5a3a65c90b0bf2 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 3 Sep 2007 09:56:23 +0200 Subject: [ALSA] cmipci: check that the legacy MIDI port works Check that the UART_EN bit actually enabled the MPU-401 port. Apparently, C-Media thinks that it is a good idea to be paranoid here. Signed-off-by: Clemens Ladisch Signed-off-by: Jaroslav Kysela --- sound/pci/cmipci.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'sound/pci') diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c index fdc4615ea0e..9149d00d1ad 100644 --- a/sound/pci/cmipci.c +++ b/sound/pci/cmipci.c @@ -3012,6 +3012,13 @@ static int __devinit snd_cmipci_create(struct snd_card *card, struct pci_dev *pc snd_cmipci_write(cm, CM_REG_LEGACY_CTRL, val); /* enable UART */ snd_cmipci_set_bit(cm, CM_REG_FUNCTRL1, CM_UART_EN); + if (inb(iomidi + 1) == 0xff) { + snd_printk(KERN_ERR "cannot enable MPU-401 port" + " at %#lx\n", iomidi); + snd_cmipci_clear_bit(cm, CM_REG_FUNCTRL1, + CM_UART_EN); + iomidi = 0; + } } } -- cgit v1.2.3 From b7e054a76fdc42b442c003f8d19ee5dce6b55f02 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 3 Sep 2007 09:56:45 +0200 Subject: [ALSA] cmipci: show real chip name in card name The '-MCx' suffix that is expected by alsa-lib is only needed in the card driver string, so we can show the actual chip name in the shortname. Signed-off-by: Clemens Ladisch Signed-off-by: Jaroslav Kysela --- sound/pci/cmipci.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c index 9149d00d1ad..a8d6b54143f 100644 --- a/sound/pci/cmipci.c +++ b/sound/pci/cmipci.c @@ -2852,6 +2852,7 @@ static int __devinit snd_cmipci_create(struct snd_card *card, struct pci_dev *pc unsigned int val; long iomidi; int integrated_midi = 0; + char modelstr[16]; int pcm_index, pcm_spdif_index; static struct pci_device_id intel_82437vx[] = { { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82437VX) }, @@ -2951,12 +2952,8 @@ static int __devinit snd_cmipci_create(struct snd_card *card, struct pci_dev *pc break; } - sprintf(card->shortname, "C-Media %s", card->driver); if (cm->chip_version < 68) { val = pci->device < 0x110 ? 8338 : 8738; - sprintf(card->longname, - "C-Media CMI%d (model %d) at 0x%lx, irq %i", - val, cm->chip_version, cm->iobase, cm->irq); } else { switch (snd_cmipci_read_b(cm, CM_REG_INT_HLDCLR + 3) & 0x03) { case 0: @@ -2981,9 +2978,14 @@ static int __devinit snd_cmipci_create(struct snd_card *card, struct pci_dev *pc break; } } - sprintf(card->longname, "C-Media CMI%d at 0x%lx, irq %i", - val, cm->iobase, cm->irq); } + sprintf(card->shortname, "C-Media CMI%d", val); + if (cm->chip_version < 68) + sprintf(modelstr, " (model %d)", cm->chip_version); + else + modelstr[0] = '\0'; + sprintf(card->longname, "%s%s at %#lx, irq %i", + card->shortname, modelstr, cm->iobase, cm->irq); if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, cm, &ops)) < 0) { snd_cmipci_free(cm); -- cgit v1.2.3 From 2e4924628ad957f702631a7a049c586a780f00f8 Mon Sep 17 00:00:00 2001 From: Maxim Levitsky Date: Mon, 3 Sep 2007 15:26:57 +0200 Subject: [ALSA] hda-intel - fix a race in dynamic power managment codec->power_transition is supposed to be true while codec is going to be shut off if in the mean time somebody calls snd_hda_power_up, hda_power_work will not shut down the codec, but nether will clear codec->power_transition, thus it stays on forever. Fix this. Signed-off-by: Maxim Levitsky Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/hda_codec.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 46d4253642d..08104e2a3e9 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -2195,8 +2195,10 @@ static void hda_power_work(struct work_struct *work) struct hda_codec *codec = container_of(work, struct hda_codec, power_work.work); - if (!codec->power_on || codec->power_count) + if (!codec->power_on || codec->power_count) { + codec->power_transition = 0; return; + } hda_call_codec_suspend(codec); if (codec->bus->ops.pm_notify) -- cgit v1.2.3 From d804ad9258c1460916a5e5854655a0dc543fd8a5 Mon Sep 17 00:00:00 2001 From: Maxim Levitsky Date: Mon, 3 Sep 2007 15:28:04 +0200 Subject: [ALSA] hda-intel - Fix resume logic, when dynamic power managment is on Comment in hda_intel.c states that 'the explicit resume is needed only when POWER_SAVE isn't set', but this is not true. There is no code that will automaticly power up the codec on resume, but only code that powers it up when user accesses it. So if user leaves a sound playing, codec will not be powered To fix that I check if there are any codecs that should be powered codec->power_count, and if so I power them up together with main controller. Signed-off-by: Maxim Levitsky Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/hda_codec.c | 16 +++++++++++++--- sound/pci/hda/hda_codec.h | 4 ++++ sound/pci/hda/hda_intel.c | 8 ++++---- 3 files changed, 21 insertions(+), 7 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 08104e2a3e9..e594de0b153 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -2787,7 +2787,6 @@ int snd_hda_suspend(struct hda_bus *bus, pm_message_t state) return 0; } -#ifndef CONFIG_SND_HDA_POWER_SAVE /** * snd_hda_resume - resume the codecs * @bus: the HDA bus @@ -2803,10 +2802,21 @@ int snd_hda_resume(struct hda_bus *bus) struct hda_codec *codec; list_for_each_entry(codec, &bus->codec_list, list) { - hda_call_codec_resume(codec); + if (snd_hda_codec_needs_resume(codec)) + hda_call_codec_resume(codec); } return 0; } -#endif /* !CONFIG_SND_HDA_POWER_SAVE */ +#ifdef CONFIG_SND_HDA_POWER_SAVE +int snd_hda_codecs_inuse(struct hda_bus *bus) +{ + struct hda_codec *codec; + list_for_each_entry(codec, &bus->codec_list, list) { + if (snd_hda_codec_needs_resume(codec)) + return 1; + } + return 0; +} +#endif #endif diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index ca157e5100c..2bce925d84e 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h @@ -686,9 +686,13 @@ int snd_hda_resume(struct hda_bus *bus); #ifdef CONFIG_SND_HDA_POWER_SAVE void snd_hda_power_up(struct hda_codec *codec); void snd_hda_power_down(struct hda_codec *codec); +#define snd_hda_codec_needs_resume(codec) codec->power_count +int snd_hda_codecs_inuse(struct hda_bus *bus); #else static inline void snd_hda_power_up(struct hda_codec *codec) {} static inline void snd_hda_power_down(struct hda_codec *codec) {} +#define snd_hda_codec_needs_resume(codec) 1 +#define snd_hda_codecs_inuse(bus) 1 #endif #endif /* __SOUND_HDA_CODEC_H */ diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 3d06eccc9b9..72fd3453899 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -1586,11 +1586,11 @@ static int azx_resume(struct pci_dev *pci) if (azx_acquire_irq(chip, 1) < 0) return -EIO; azx_init_pci(chip); -#ifndef CONFIG_SND_HDA_POWER_SAVE - /* the explicit resume is needed only when POWER_SAVE isn't set */ - azx_init_chip(chip); + + if (snd_hda_codecs_inuse(chip->bus)) + azx_init_chip(chip); + snd_hda_resume(chip->bus); -#endif snd_power_change_state(card, SNDRV_CTL_POWER_D0); return 0; } -- cgit v1.2.3 From 0fb87bb474f978446786263deff6263284e6e011 Mon Sep 17 00:00:00 2001 From: Maxim Levitsky Date: Mon, 3 Sep 2007 15:29:04 +0200 Subject: [ALSA] hda-codec - add support for swapping center/LFE channels to STAC codecs Center/LFE channels are located on same jack, so it can be usefull to swap them. Signed-off-by: Maxim Levitsky Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_sigmatel.c | 76 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 72 insertions(+), 4 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index b4a1d73b572..297f7401927 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -146,6 +146,7 @@ struct sigmatel_spec { /* i/o switches */ unsigned int io_switch[2]; + unsigned int clfe_swap; struct hda_pcm pcm_rec[2]; /* PCM information */ @@ -1406,6 +1407,36 @@ static int stac92xx_io_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_ return 1; } +#define stac92xx_clfe_switch_info snd_ctl_boolean_mono_info + +static int stac92xx_clfe_switch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + struct sigmatel_spec *spec = codec->spec; + + ucontrol->value.integer.value[0] = spec->clfe_swap; + return 0; +} + +static int stac92xx_clfe_switch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + struct sigmatel_spec *spec = codec->spec; + hda_nid_t nid = kcontrol->private_value & 0xff; + + if (spec->clfe_swap == ucontrol->value.integer.value[0]) + return 0; + + spec->clfe_swap = ucontrol->value.integer.value[0]; + + snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE, + spec->clfe_swap ? 0x4 : 0x0); + + return 1; +} + #define STAC_CODEC_IO_SWITCH(xname, xpval) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ .name = xname, \ @@ -1416,17 +1447,28 @@ static int stac92xx_io_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_ .private_value = xpval, \ } +#define STAC_CODEC_CLFE_SWITCH(xname, xpval) \ + { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ + .name = xname, \ + .index = 0, \ + .info = stac92xx_clfe_switch_info, \ + .get = stac92xx_clfe_switch_get, \ + .put = stac92xx_clfe_switch_put, \ + .private_value = xpval, \ + } enum { STAC_CTL_WIDGET_VOL, STAC_CTL_WIDGET_MUTE, STAC_CTL_WIDGET_IO_SWITCH, + STAC_CTL_WIDGET_CLFE_SWITCH }; static struct snd_kcontrol_new stac92xx_control_templates[] = { HDA_CODEC_VOLUME(NULL, 0, 0, 0), HDA_CODEC_MUTE(NULL, 0, 0, 0), STAC_CODEC_IO_SWITCH(NULL, 0), + STAC_CODEC_CLFE_SWITCH(NULL, 0), }; /* add dynamic controls */ @@ -1620,7 +1662,7 @@ static int create_controls(struct sigmatel_spec *spec, const char *pfx, hda_nid_ } /* add playback controls from the parsed DAC table */ -static int stac92xx_auto_create_multi_out_ctls(struct sigmatel_spec *spec, +static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec, const struct auto_pin_cfg *cfg) { static const char *chname[4] = { @@ -1629,6 +1671,10 @@ static int stac92xx_auto_create_multi_out_ctls(struct sigmatel_spec *spec, hda_nid_t nid; int i, err; + struct sigmatel_spec *spec = codec->spec; + unsigned int wid_caps; + + for (i = 0; i < cfg->line_outs; i++) { if (!spec->multiout.dac_nids[i]) continue; @@ -1643,6 +1689,18 @@ static int stac92xx_auto_create_multi_out_ctls(struct sigmatel_spec *spec, err = create_controls(spec, "LFE", nid, 2); if (err < 0) return err; + + wid_caps = get_wcaps(codec, nid); + + if (wid_caps & AC_WCAP_LR_SWAP) { + err = stac92xx_add_control(spec, + STAC_CTL_WIDGET_CLFE_SWITCH, + "Swap Center/LFE Playback Switch", nid); + + if (err < 0) + return err; + } + } else { err = create_controls(spec, chname[i], nid, 3); if (err < 0) @@ -1895,9 +1953,19 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out if ((err = stac92xx_auto_fill_dac_nids(codec, &spec->autocfg)) < 0) return err; - if ((err = stac92xx_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 || - (err = stac92xx_auto_create_hp_ctls(codec, &spec->autocfg)) < 0 || - (err = stac92xx_auto_create_analog_input_ctls(codec, &spec->autocfg)) < 0) + err = stac92xx_auto_create_multi_out_ctls(codec, &spec->autocfg); + + if (err < 0) + return err; + + err = stac92xx_auto_create_hp_ctls(codec, &spec->autocfg); + + if (err < 0) + return err; + + err = stac92xx_auto_create_analog_input_ctls(codec, &spec->autocfg); + + if (err < 0) return err; if (spec->num_dmics > 0) -- cgit v1.2.3 From 5f10c4a9a0c02597206fe2f027026ee25d3e07ad Mon Sep 17 00:00:00 2001 From: Maxim Levitsky Date: Mon, 3 Sep 2007 15:29:37 +0200 Subject: [ALSA] hda-codec - add support for analog loopback to STAC9204/9205/922x/927x The analog loopback routes the sound just before it enters ADC0 to output of DAC0. Signed-off-by: Maxim Levitsky Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_sigmatel.c | 58 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 297f7401927..c94775c8a0b 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -147,6 +147,7 @@ struct sigmatel_spec { /* i/o switches */ unsigned int io_switch[2]; unsigned int clfe_swap; + unsigned int aloopback; struct hda_pcm pcm_rec[2]; /* PCM information */ @@ -296,6 +297,49 @@ static int stac92xx_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e spec->mux_nids[adc_idx], &spec->cur_mux[adc_idx]); } +#define stac92xx_aloopback_info snd_ctl_boolean_mono_info + +static int stac92xx_aloopback_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + struct sigmatel_spec *spec = codec->spec; + + ucontrol->value.integer.value[0] = spec->aloopback; + return 0; +} + +static int stac92xx_aloopback_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + struct sigmatel_spec *spec = codec->spec; + unsigned int dac_mode; + + if (spec->aloopback == ucontrol->value.integer.value[0]) + return 0; + + spec->aloopback = ucontrol->value.integer.value[0]; + + + dac_mode = snd_hda_codec_read(codec, codec->afg, 0, + kcontrol->private_value & 0xFFFF, 0x0); + + if (spec->aloopback) { + snd_hda_power_up(codec); + dac_mode |= 0x40; + } else { + snd_hda_power_down(codec); + dac_mode &= ~0x40; + } + + snd_hda_codec_write_cache(codec, codec->afg, 0, + kcontrol->private_value >> 16, dac_mode); + + return 1; +} + + static struct hda_verb stac9200_core_init[] = { /* set dac0mux for dac converter */ { 0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, @@ -346,6 +390,17 @@ static struct hda_verb stac9205_core_init[] = { .put = stac92xx_mux_enum_put, \ } +#define STAC_ANALOG_LOOPBACK(verb_read,verb_write) \ + { \ + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ + .name = "Analog Loopback", \ + .count = 1, \ + .info = stac92xx_aloopback_info, \ + .get = stac92xx_aloopback_get, \ + .put = stac92xx_aloopback_put, \ + .private_value = verb_read | (verb_write << 16), \ + } + static struct snd_kcontrol_new stac9200_mixer[] = { HDA_CODEC_VOLUME("Master Playback Volume", 0xb, 0, HDA_OUTPUT), @@ -377,6 +432,7 @@ static struct snd_kcontrol_new stac922x_mixer[] = { /* This needs to be generated dynamically based on sequence */ static struct snd_kcontrol_new stac9227_mixer[] = { STAC_INPUT_SOURCE, + STAC_ANALOG_LOOPBACK(0xFEB, 0x7EB), HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Capture Switch", 0x1b, 0x0, HDA_OUTPUT), { } /* end */ @@ -384,6 +440,7 @@ static struct snd_kcontrol_new stac9227_mixer[] = { static struct snd_kcontrol_new stac927x_mixer[] = { STAC_INPUT_SOURCE, + STAC_ANALOG_LOOPBACK(0xFEB, 0x7EB), HDA_CODEC_VOLUME("InMux Capture Volume", 0x15, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("InVol Capture Volume", 0x18, 0x0, HDA_INPUT), HDA_CODEC_MUTE("ADCMux Capture Switch", 0x1b, 0x0, HDA_OUTPUT), @@ -400,6 +457,7 @@ static struct snd_kcontrol_new stac9205_mixer[] = { .put = stac92xx_dmux_enum_put, }, STAC_INPUT_SOURCE, + STAC_ANALOG_LOOPBACK(0xFE0, 0x7E0), HDA_CODEC_VOLUME("InMux Capture Volume", 0x19, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("InVol Capture Volume", 0x1b, 0x0, HDA_INPUT), HDA_CODEC_MUTE("ADCMux Capture Switch", 0x1d, 0x0, HDA_OUTPUT), -- cgit v1.2.3 From 6e6b88ffea81d7bc5c5da0b8433b4a21131ae340 Mon Sep 17 00:00:00 2001 From: Maxim Levitsky Date: Mon, 3 Sep 2007 15:30:26 +0200 Subject: [ALSA] hda-codec - make volume knob, the master volume for sigmatel codecs VolumeKnob is present on most sigmatel codecs, it allows to decrease volume of all DACs at once, it is a kind of post-procesing volume. Note that all output amps of sigmatel only decrease volume, and all input amps only increase volume. Signed-off-by: Maxim Levitsky Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_sigmatel.c | 48 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index c94775c8a0b..a2b1dd54e2e 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -339,6 +339,39 @@ static int stac92xx_aloopback_put(struct snd_kcontrol *kcontrol, return 1; } +static int stac92xx_volknob_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = 1; + uinfo->value.integer.min = 0; + uinfo->value.integer.max = 127; + return 0; +} + +static int stac92xx_volknob_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = kcontrol->private_value; + return 0; +} + +static int stac92xx_volknob_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + + if (kcontrol->private_value == ucontrol->value.integer.value[0]) + return 0; + + kcontrol->private_value = ucontrol->value.integer.value[0]; + + snd_hda_codec_write_cache(codec, 0x24, 0, + AC_VERB_SET_VOLUME_KNOB_CONTROL, + kcontrol->private_value | 0x80); + return 1; +} + static struct hda_verb stac9200_core_init[] = { /* set dac0mux for dac converter */ @@ -401,6 +434,17 @@ static struct hda_verb stac9205_core_init[] = { .private_value = verb_read | (verb_write << 16), \ } +#define STAC_VOLKNOB \ + { \ + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ + .name = "Master Playback Volume", \ + .count = 1, \ + .info = stac92xx_volknob_info, \ + .get = stac92xx_volknob_get, \ + .put = stac92xx_volknob_put, \ + .private_value = 127, \ + } + static struct snd_kcontrol_new stac9200_mixer[] = { HDA_CODEC_VOLUME("Master Playback Volume", 0xb, 0, HDA_OUTPUT), @@ -423,6 +467,7 @@ static struct snd_kcontrol_new stac925x_mixer[] = { /* This needs to be generated dynamically based on sequence */ static struct snd_kcontrol_new stac922x_mixer[] = { STAC_INPUT_SOURCE, + STAC_VOLKNOB, HDA_CODEC_VOLUME("Capture Volume", 0x17, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Capture Switch", 0x17, 0x0, HDA_INPUT), HDA_CODEC_VOLUME("Mux Capture Volume", 0x12, 0x0, HDA_OUTPUT), @@ -432,6 +477,7 @@ static struct snd_kcontrol_new stac922x_mixer[] = { /* This needs to be generated dynamically based on sequence */ static struct snd_kcontrol_new stac9227_mixer[] = { STAC_INPUT_SOURCE, + STAC_VOLKNOB, STAC_ANALOG_LOOPBACK(0xFEB, 0x7EB), HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Capture Switch", 0x1b, 0x0, HDA_OUTPUT), @@ -440,6 +486,7 @@ static struct snd_kcontrol_new stac9227_mixer[] = { static struct snd_kcontrol_new stac927x_mixer[] = { STAC_INPUT_SOURCE, + STAC_VOLKNOB, STAC_ANALOG_LOOPBACK(0xFEB, 0x7EB), HDA_CODEC_VOLUME("InMux Capture Volume", 0x15, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("InVol Capture Volume", 0x18, 0x0, HDA_INPUT), @@ -458,6 +505,7 @@ static struct snd_kcontrol_new stac9205_mixer[] = { }, STAC_INPUT_SOURCE, STAC_ANALOG_LOOPBACK(0xFE0, 0x7E0), + STAC_VOLKNOB, HDA_CODEC_VOLUME("InMux Capture Volume", 0x19, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("InVol Capture Volume", 0x1b, 0x0, HDA_INPUT), HDA_CODEC_MUTE("ADCMux Capture Switch", 0x1d, 0x0, HDA_OUTPUT), -- cgit v1.2.3 From 9e05b7a3d936ac5eb6c10291b69aee0af1ad03fb Mon Sep 17 00:00:00 2001 From: Maxim Levitsky Date: Mon, 3 Sep 2007 15:31:02 +0200 Subject: [ALSA] hda-codec - Fix support for sigmatel codecs that have 2 or more ADCs 1) Create seperate mixer controls for each ADC 2) Make number of substreams of capture PCM device be equal to number of ADCs Signed-off-by: Maxim Levitsky Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_sigmatel.c | 97 +++++++++++++++++++++++++----------------- 1 file changed, 57 insertions(+), 40 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index a2b1dd54e2e..6dffa54e2da 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -413,11 +413,11 @@ static struct hda_verb stac9205_core_init[] = { {} }; -#define STAC_INPUT_SOURCE \ +#define STAC_INPUT_SOURCE(cnt) \ { \ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ .name = "Input Source", \ - .count = 1, \ + .count = cnt, \ .info = stac92xx_mux_enum_info, \ .get = stac92xx_mux_enum_get, \ .put = stac92xx_mux_enum_put, \ @@ -449,7 +449,7 @@ static struct hda_verb stac9205_core_init[] = { static struct snd_kcontrol_new stac9200_mixer[] = { HDA_CODEC_VOLUME("Master Playback Volume", 0xb, 0, HDA_OUTPUT), HDA_CODEC_MUTE("Master Playback Switch", 0xb, 0, HDA_OUTPUT), - STAC_INPUT_SOURCE, + STAC_INPUT_SOURCE(1), HDA_CODEC_VOLUME("Capture Volume", 0x0a, 0, HDA_OUTPUT), HDA_CODEC_MUTE("Capture Switch", 0x0a, 0, HDA_OUTPUT), HDA_CODEC_VOLUME("Capture Mux Volume", 0x0c, 0, HDA_OUTPUT), @@ -457,58 +457,68 @@ static struct snd_kcontrol_new stac9200_mixer[] = { }; static struct snd_kcontrol_new stac925x_mixer[] = { - STAC_INPUT_SOURCE, + STAC_INPUT_SOURCE(1), HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_OUTPUT), HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_OUTPUT), HDA_CODEC_VOLUME("Capture Mux Volume", 0x0f, 0, HDA_OUTPUT), { } /* end */ }; -/* This needs to be generated dynamically based on sequence */ -static struct snd_kcontrol_new stac922x_mixer[] = { - STAC_INPUT_SOURCE, +static struct snd_kcontrol_new stac9205_mixer[] = { + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Digital Input Source", + .count = 1, + .info = stac92xx_dmux_enum_info, + .get = stac92xx_dmux_enum_get, + .put = stac92xx_dmux_enum_put, + }, + STAC_INPUT_SOURCE(2), + STAC_ANALOG_LOOPBACK(0xFE0, 0x7E0), STAC_VOLKNOB, - HDA_CODEC_VOLUME("Capture Volume", 0x17, 0x0, HDA_INPUT), - HDA_CODEC_MUTE("Capture Switch", 0x17, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Mux Capture Volume", 0x12, 0x0, HDA_OUTPUT), + + HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1b, 0x0, HDA_INPUT), + HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1d, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x0, 0x19, 0x0, HDA_OUTPUT), + + HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x1c, 0x0, HDA_INPUT), + HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1e, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x1, 0x1A, 0x0, HDA_OUTPUT), + { } /* end */ }; /* This needs to be generated dynamically based on sequence */ -static struct snd_kcontrol_new stac9227_mixer[] = { - STAC_INPUT_SOURCE, +static struct snd_kcontrol_new stac922x_mixer[] = { + STAC_INPUT_SOURCE(2), STAC_VOLKNOB, - STAC_ANALOG_LOOPBACK(0xFEB, 0x7EB), - HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Capture Switch", 0x1b, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x17, 0x0, HDA_INPUT), + HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x17, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x0, 0x12, 0x0, HDA_OUTPUT), + + HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x18, 0x0, HDA_INPUT), + HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x18, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x1, 0x13, 0x0, HDA_OUTPUT), { } /* end */ }; + static struct snd_kcontrol_new stac927x_mixer[] = { - STAC_INPUT_SOURCE, + STAC_INPUT_SOURCE(3), STAC_VOLKNOB, STAC_ANALOG_LOOPBACK(0xFEB, 0x7EB), - HDA_CODEC_VOLUME("InMux Capture Volume", 0x15, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("InVol Capture Volume", 0x18, 0x0, HDA_INPUT), - HDA_CODEC_MUTE("ADCMux Capture Switch", 0x1b, 0x0, HDA_OUTPUT), - { } /* end */ -}; -static struct snd_kcontrol_new stac9205_mixer[] = { - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Digital Input Source", - .count = 1, - .info = stac92xx_dmux_enum_info, - .get = stac92xx_dmux_enum_get, - .put = stac92xx_dmux_enum_put, - }, - STAC_INPUT_SOURCE, - STAC_ANALOG_LOOPBACK(0xFE0, 0x7E0), - STAC_VOLKNOB, - HDA_CODEC_VOLUME("InMux Capture Volume", 0x19, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("InVol Capture Volume", 0x1b, 0x0, HDA_INPUT), - HDA_CODEC_MUTE("ADCMux Capture Switch", 0x1d, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x18, 0x0, HDA_INPUT), + HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1b, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x0, 0x15, 0x0, HDA_OUTPUT), + + HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x19, 0x0, HDA_INPUT), + HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1c, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x1, 0x16, 0x0, HDA_OUTPUT), + + HDA_CODEC_VOLUME_IDX("Capture Volume", 0x2, 0x1A, 0x0, HDA_INPUT), + HDA_CODEC_MUTE_IDX("Capture Switch", 0x2, 0x1d, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x2, 0x17, 0x0, HDA_OUTPUT), { } /* end */ }; @@ -1410,10 +1420,9 @@ static struct hda_pcm_stream stac92xx_pcm_analog_alt_playback = { }; static struct hda_pcm_stream stac92xx_pcm_analog_capture = { - .substreams = 2, .channels_min = 2, .channels_max = 2, - /* NID is set in stac92xx_build_pcms */ + /* NID + .substreams is set in stac92xx_build_pcms */ .ops = { .prepare = stac92xx_capture_pcm_prepare, .cleanup = stac92xx_capture_pcm_cleanup @@ -1432,6 +1441,7 @@ static int stac92xx_build_pcms(struct hda_codec *codec) info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_analog_playback; info->stream[SNDRV_PCM_STREAM_CAPTURE] = stac92xx_pcm_analog_capture; info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0]; + info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = spec->num_adcs; if (spec->alt_switch) { codec->num_pcms++; @@ -2478,6 +2488,7 @@ static int patch_stac9200(struct hda_codec *codec) spec->mux_nids = stac9200_mux_nids; spec->num_muxes = 1; spec->num_dmics = 0; + spec->num_adcs = 1; spec->init = stac9200_core_init; spec->mixer = stac9200_mixer; @@ -2529,6 +2540,7 @@ static int patch_stac925x(struct hda_codec *codec) spec->adc_nids = stac925x_adc_nids; spec->mux_nids = stac925x_mux_nids; spec->num_muxes = 1; + spec->num_adcs = 1; switch (codec->vendor_id) { case 0x83847632: /* STAC9202 */ case 0x83847633: /* STAC9202D */ @@ -2632,6 +2644,7 @@ static int patch_stac922x(struct hda_codec *codec) spec->adc_nids = stac922x_adc_nids; spec->mux_nids = stac922x_mux_nids; spec->num_muxes = ARRAY_SIZE(stac922x_mux_nids); + spec->num_adcs = ARRAY_SIZE(stac922x_adc_nids); spec->num_dmics = 0; spec->init = stac922x_core_init; @@ -2700,22 +2713,25 @@ static int patch_stac927x(struct hda_codec *codec) spec->adc_nids = stac927x_adc_nids; spec->mux_nids = stac927x_mux_nids; spec->num_muxes = ARRAY_SIZE(stac927x_mux_nids); + spec->num_adcs = ARRAY_SIZE(stac927x_adc_nids); spec->num_dmics = 0; spec->init = d965_core_init; - spec->mixer = stac9227_mixer; + spec->mixer = stac927x_mixer; break; case STAC_D965_5ST: spec->adc_nids = stac927x_adc_nids; spec->mux_nids = stac927x_mux_nids; spec->num_muxes = ARRAY_SIZE(stac927x_mux_nids); + spec->num_adcs = ARRAY_SIZE(stac927x_adc_nids); spec->num_dmics = 0; spec->init = d965_core_init; - spec->mixer = stac9227_mixer; + spec->mixer = stac927x_mixer; break; default: spec->adc_nids = stac927x_adc_nids; spec->mux_nids = stac927x_mux_nids; spec->num_muxes = ARRAY_SIZE(stac927x_mux_nids); + spec->num_adcs = ARRAY_SIZE(stac927x_adc_nids); spec->num_dmics = 0; spec->init = stac927x_core_init; spec->mixer = stac927x_mixer; @@ -2776,6 +2792,7 @@ static int patch_stac9205(struct hda_codec *codec) } spec->adc_nids = stac9205_adc_nids; + spec->num_adcs = ARRAY_SIZE(stac9205_adc_nids); spec->mux_nids = stac9205_mux_nids; spec->num_muxes = ARRAY_SIZE(stac9205_mux_nids); spec->dmic_nids = stac9205_dmic_nids; -- cgit v1.2.3 From 7abcacb09ac0f9c6848f1e7d86b284427fa83cee Mon Sep 17 00:00:00 2001 From: Andres Salomon Date: Mon, 3 Sep 2007 15:41:47 +0200 Subject: [ALSA] cs5535audio: correctly set dma->substream We're never actually setting dma->substream to the current substream; that means the dma->substream checks that we do in the suspend/resume path are never satisfied, and the PRD registers are never correctly managed. This changes it so that we set the substream when constructing the specific bus master DMA, and unsetting it when we tear down the BM's DMA. Signed-off-by: Andres Salomon Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/cs5535audio/cs5535audio_pcm.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'sound/pci') diff --git a/sound/pci/cs5535audio/cs5535audio_pcm.c b/sound/pci/cs5535audio/cs5535audio_pcm.c index ec920cbb2a7..9a1e87fd481 100644 --- a/sound/pci/cs5535audio/cs5535audio_pcm.c +++ b/sound/pci/cs5535audio/cs5535audio_pcm.c @@ -161,6 +161,7 @@ static int cs5535audio_build_dma_packets(struct cs5535audio *cs5535au, jmpprd_addr = cpu_to_le32(lastdesc->addr + (sizeof(struct cs5535audio_dma_desc)*periods)); + dma->substream = substream; dma->period_bytes = period_bytes; dma->periods = periods; spin_lock_irq(&cs5535au->reg_lock); @@ -238,6 +239,7 @@ static void cs5535audio_clear_dma_packets(struct cs5535audio *cs5535au, { snd_dma_free_pages(&dma->desc_buf); dma->desc_buf.area = NULL; + dma->substream = NULL; } static int snd_cs5535audio_hw_params(struct snd_pcm_substream *substream, -- cgit v1.2.3 From 222fa0b0d2fdb2373a71d532c2cabd2ec920b3b3 Mon Sep 17 00:00:00 2001 From: Andres Salomon Date: Mon, 3 Sep 2007 15:42:16 +0200 Subject: [ALSA] cs5535audio: fix PRD register save/restore power management race In the suspend path, we currently save the PRD registers and then disable DMA. This is racy; the sound hardware might update the PRD register as it finishes processing some DMA pages between when we've saved the PRD registers and when DMA actually gets disabled. Furthermore, we actively check whether or not DMA is enabled before saving PRD registers; there's no reason to do that, as the PRD registers should not update when we twiddle the ACC_BM[x]_CMD register(s). Worst case, we save the PRD registers twice; even powering down the ACC shouldn't mess with the PRD registers (according to the 5536 data sheet, section 5.3.7.4, power-down procedure). This patch reworks all that to first disable DMA, and then save PRD registers. Signed-off-by: Andres Salomon Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/cs5535audio/cs5535audio.h | 1 - sound/pci/cs5535audio/cs5535audio_pcm.c | 2 -- sound/pci/cs5535audio/cs5535audio_pm.c | 14 +++++++------- 3 files changed, 7 insertions(+), 10 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/cs5535audio/cs5535audio.h b/sound/pci/cs5535audio/cs5535audio.h index 4fd1f31a6cf..c7a20446703 100644 --- a/sound/pci/cs5535audio/cs5535audio.h +++ b/sound/pci/cs5535audio/cs5535audio.h @@ -106,7 +106,6 @@ struct cs5535audio_dma { struct snd_pcm_substream *substream; unsigned int buf_addr, buf_bytes; unsigned int period_bytes, periods; - int suspended; u32 saved_prd; }; diff --git a/sound/pci/cs5535audio/cs5535audio_pcm.c b/sound/pci/cs5535audio/cs5535audio_pcm.c index 9a1e87fd481..21df0634af3 100644 --- a/sound/pci/cs5535audio/cs5535audio_pcm.c +++ b/sound/pci/cs5535audio/cs5535audio_pcm.c @@ -297,14 +297,12 @@ static int snd_cs5535audio_trigger(struct snd_pcm_substream *substream, int cmd) break; case SNDRV_PCM_TRIGGER_RESUME: dma->ops->enable_dma(cs5535au); - dma->suspended = 0; break; case SNDRV_PCM_TRIGGER_STOP: dma->ops->disable_dma(cs5535au); break; case SNDRV_PCM_TRIGGER_SUSPEND: dma->ops->disable_dma(cs5535au); - dma->suspended = 1; break; default: snd_printk(KERN_ERR "unhandled trigger\n"); diff --git a/sound/pci/cs5535audio/cs5535audio_pm.c b/sound/pci/cs5535audio/cs5535audio_pm.c index 3e4d198a450..9a4e84aa3e0 100644 --- a/sound/pci/cs5535audio/cs5535audio_pm.c +++ b/sound/pci/cs5535audio/cs5535audio_pm.c @@ -64,13 +64,13 @@ int snd_cs5535audio_suspend(struct pci_dev *pci, pm_message_t state) int i; snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); + snd_pcm_suspend_all(cs5535au->pcm); + snd_ac97_suspend(cs5535au->ac97); for (i = 0; i < NUM_CS5535AUDIO_DMAS; i++) { struct cs5535audio_dma *dma = &cs5535au->dmas[i]; - if (dma && dma->substream && !dma->suspended) + if (dma && dma->substream) dma->saved_prd = dma->ops->read_prd(cs5535au); } - snd_pcm_suspend_all(cs5535au->pcm); - snd_ac97_suspend(cs5535au->ac97); /* save important regs, then disable aclink in hw */ snd_cs5535audio_stop_hardware(cs5535au); @@ -112,17 +112,17 @@ int snd_cs5535audio_resume(struct pci_dev *pci) if (!timeout) snd_printk(KERN_ERR "Failure getting AC Link ready\n"); - /* we depend on ac97 to perform the codec power up */ - snd_ac97_resume(cs5535au->ac97); /* set up rate regs, dma. actual initiation is done in trig */ for (i = 0; i < NUM_CS5535AUDIO_DMAS; i++) { struct cs5535audio_dma *dma = &cs5535au->dmas[i]; - if (dma && dma->substream && dma->suspended) { + if (dma && dma->substream) { dma->substream->ops->prepare(dma->substream); dma->ops->setup_prd(cs5535au, dma->saved_prd); } } - + + /* we depend on ac97 to perform the codec power up */ + snd_ac97_resume(cs5535au->ac97); snd_power_change_state(card, SNDRV_CTL_POWER_D0); return 0; -- cgit v1.2.3 From 1caae3682e2a712b64ce682702ed56bb3dc9f435 Mon Sep 17 00:00:00 2001 From: Andres Salomon Date: Mon, 3 Sep 2007 15:42:52 +0200 Subject: [ALSA] cs5535audio: update PCI device handling in suspend/resume Save the PCI state before disabling the device, and add some error checking. Signed-off-by: Andres Salomon Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/cs5535audio/cs5535audio_pm.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/cs5535audio/cs5535audio_pm.c b/sound/pci/cs5535audio/cs5535audio_pm.c index 9a4e84aa3e0..838708f6d45 100644 --- a/sound/pci/cs5535audio/cs5535audio_pm.c +++ b/sound/pci/cs5535audio/cs5535audio_pm.c @@ -74,8 +74,11 @@ int snd_cs5535audio_suspend(struct pci_dev *pci, pm_message_t state) /* save important regs, then disable aclink in hw */ snd_cs5535audio_stop_hardware(cs5535au); + if (pci_save_state(pci)) { + printk(KERN_ERR "cs5535audio: pci_save_state failed!\n"); + return -EIO; + } pci_disable_device(pci); - pci_save_state(pci); pci_set_power_state(pci, pci_choose_state(pci, state)); return 0; } @@ -89,7 +92,12 @@ int snd_cs5535audio_resume(struct pci_dev *pci) int i; pci_set_power_state(pci, PCI_D0); - pci_restore_state(pci); + if (pci_restore_state(pci) < 0) { + printk(KERN_ERR "cs5535audio: pci_restore_state failed, " + "disabling device\n"); + snd_card_disconnect(card); + return -EIO; + } if (pci_enable_device(pci) < 0) { printk(KERN_ERR "cs5535audio: pci_enable_device failed, " "disabling device\n"); -- cgit v1.2.3 From 506ea68cd9e8899ac2b97f466956e670d60026dc Mon Sep 17 00:00:00 2001 From: Andres Salomon Date: Mon, 3 Sep 2007 15:43:18 +0200 Subject: [ALSA] cs5535audio: fix ACC_BM[x]_CMD register handling According to 6.3.2.7 of the cs5535/cs5536 data sheets, the ACC_BM[x]_CMD registers are only 8 bits wide. This driver treats them as 32 bits wide, and also has bits in the wrong place. Simple fix to the definitions. Signed-off-by: Andres Salomon Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/cs5535audio/cs5535audio.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/cs5535audio/cs5535audio.h b/sound/pci/cs5535audio/cs5535audio.h index c7a20446703..516219ad5e8 100644 --- a/sound/pci/cs5535audio/cs5535audio.h +++ b/sound/pci/cs5535audio/cs5535audio.h @@ -62,11 +62,11 @@ #define EOP (1<<0) #define BM_EOP_ERR (1<<1) /* ACC_BMX_CTL */ -#define BM_CTL_EN 0x00000001 -#define BM_CTL_PAUSE 0x00000011 -#define BM_CTL_DIS 0x00000000 -#define BM_CTL_BYTE_ORD_LE 0x00000000 -#define BM_CTL_BYTE_ORD_BE 0x00000100 +#define BM_CTL_EN 0x01 +#define BM_CTL_PAUSE 0x03 +#define BM_CTL_DIS 0x00 +#define BM_CTL_BYTE_ORD_LE 0x00 +#define BM_CTL_BYTE_ORD_BE 0x04 /* cs5535 specific ac97 codec register defines */ #define CMD_MASK 0xFF00FFFF #define CMD_NEW 0x00010000 -- cgit v1.2.3 From 4ea24163986e65f8ea6208525a135df2ebfe070a Mon Sep 17 00:00:00 2001 From: Andres Salomon Date: Mon, 3 Sep 2007 15:43:43 +0200 Subject: [ALSA] cs5535audio: drop unused bus master stuff We really only care about the first two bus masters (playback and capture). There's no need to have unused BM code lying around, so let's get rid of it. If for some reason we trigger an IRQ for some BM that we're not using.. well, that warrants spitting out an error message (imo). Signed-off-by: Andres Salomon Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/cs5535audio/cs5535audio.c | 24 +++--------------------- sound/pci/cs5535audio/cs5535audio.h | 31 +------------------------------ 2 files changed, 4 insertions(+), 51 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/cs5535audio/cs5535audio.c b/sound/pci/cs5535audio/cs5535audio.c index b8e75ef9c1e..2b35889787b 100644 --- a/sound/pci/cs5535audio/cs5535audio.c +++ b/sound/pci/cs5535audio/cs5535audio.c @@ -206,7 +206,6 @@ static void process_bm1_irq(struct cs5535audio *cs5535au) static irqreturn_t snd_cs5535audio_interrupt(int irq, void *dev_id) { u16 acc_irq_stat; - u8 bm_stat; unsigned char count; struct cs5535audio *cs5535au = dev_id; @@ -217,7 +216,7 @@ static irqreturn_t snd_cs5535audio_interrupt(int irq, void *dev_id) if (!acc_irq_stat) return IRQ_NONE; - for (count = 0; count < 10; count++) { + for (count = 0; count < 4; count++) { if (acc_irq_stat & (1 << count)) { switch (count) { case IRQ_STS: @@ -232,26 +231,9 @@ static irqreturn_t snd_cs5535audio_interrupt(int irq, void *dev_id) case BM1_IRQ_STS: process_bm1_irq(cs5535au); break; - case BM2_IRQ_STS: - bm_stat = cs_readb(cs5535au, ACC_BM2_STATUS); - break; - case BM3_IRQ_STS: - bm_stat = cs_readb(cs5535au, ACC_BM3_STATUS); - break; - case BM4_IRQ_STS: - bm_stat = cs_readb(cs5535au, ACC_BM4_STATUS); - break; - case BM5_IRQ_STS: - bm_stat = cs_readb(cs5535au, ACC_BM5_STATUS); - break; - case BM6_IRQ_STS: - bm_stat = cs_readb(cs5535au, ACC_BM6_STATUS); - break; - case BM7_IRQ_STS: - bm_stat = cs_readb(cs5535au, ACC_BM7_STATUS); - break; default: - snd_printk(KERN_ERR "Unexpected irq src\n"); + snd_printk(KERN_ERR "Unexpected irq src: " + "0x%x\n", acc_irq_stat); break; } } diff --git a/sound/pci/cs5535audio/cs5535audio.h b/sound/pci/cs5535audio/cs5535audio.h index 516219ad5e8..66bae766419 100644 --- a/sound/pci/cs5535audio/cs5535audio.h +++ b/sound/pci/cs5535audio/cs5535audio.h @@ -16,48 +16,19 @@ #define ACC_IRQ_STATUS 0x12 #define ACC_BM0_CMD 0x20 #define ACC_BM1_CMD 0x28 -#define ACC_BM2_CMD 0x30 -#define ACC_BM3_CMD 0x38 -#define ACC_BM4_CMD 0x40 -#define ACC_BM5_CMD 0x48 -#define ACC_BM6_CMD 0x50 -#define ACC_BM7_CMD 0x58 #define ACC_BM0_PRD 0x24 #define ACC_BM1_PRD 0x2C -#define ACC_BM2_PRD 0x34 -#define ACC_BM3_PRD 0x3C -#define ACC_BM4_PRD 0x44 -#define ACC_BM5_PRD 0x4C -#define ACC_BM6_PRD 0x54 -#define ACC_BM7_PRD 0x5C #define ACC_BM0_STATUS 0x21 #define ACC_BM1_STATUS 0x29 -#define ACC_BM2_STATUS 0x31 -#define ACC_BM3_STATUS 0x39 -#define ACC_BM4_STATUS 0x41 -#define ACC_BM5_STATUS 0x49 -#define ACC_BM6_STATUS 0x51 -#define ACC_BM7_STATUS 0x59 #define ACC_BM0_PNTR 0x60 #define ACC_BM1_PNTR 0x64 -#define ACC_BM2_PNTR 0x68 -#define ACC_BM3_PNTR 0x6C -#define ACC_BM4_PNTR 0x70 -#define ACC_BM5_PNTR 0x74 -#define ACC_BM6_PNTR 0x78 -#define ACC_BM7_PNTR 0x7C + /* acc_codec bar0 reg bits */ /* ACC_IRQ_STATUS */ #define IRQ_STS 0 #define WU_IRQ_STS 1 #define BM0_IRQ_STS 2 #define BM1_IRQ_STS 3 -#define BM2_IRQ_STS 4 -#define BM3_IRQ_STS 5 -#define BM4_IRQ_STS 6 -#define BM5_IRQ_STS 7 -#define BM6_IRQ_STS 8 -#define BM7_IRQ_STS 9 /* ACC_BMX_STATUS */ #define EOP (1<<0) #define BM_EOP_ERR (1<<1) -- cgit v1.2.3 From 8da6470efbfd022c6d228f8829870ba018092b31 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 5 Sep 2007 19:14:38 +0200 Subject: [ALSA] hda-codec - Add support for Acer Aspire 9303 Add the entry for Acer Aspire 9303 (model=acer-aspire) with ALC883 codec. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 3557865dde3..412629d02db 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -6971,6 +6971,7 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = { SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG), SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE), SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE), + SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE), SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER), SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch), SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION), -- cgit v1.2.3 From af6c016ecfd908203217a2d78715adeaa51b003d Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 5 Sep 2007 23:46:03 +0200 Subject: [ALSA] hda-codec - Fix wrong pin config order in STAC92xx dell models The last patch to change/add Dell models have wrong pin config orders. This patch fixes the pin positions. Taken from ALSA bug#3319, https://bugtrack.alsa-project.org/alsa-bug/view.php?id=3319 Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_sigmatel.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 6dffa54e2da..f843e2122a8 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -563,8 +563,8 @@ static unsigned int ref9200_pin_configs[8] = { 102801E8 */ static unsigned int dell9200_d21_pin_configs[8] = { - 0x400001f0, 0x400001f1, 0x01a19021, 0x90100140, - 0x01813122, 0x02214030, 0x01014010, 0x02a19020, + 0x400001f0, 0x400001f1, 0x02214030, 0x01014010, + 0x02a19020, 0x01a19021, 0x90100140, 0x01813122, }; /* @@ -573,8 +573,8 @@ static unsigned int dell9200_d21_pin_configs[8] = { 102801C1 */ static unsigned int dell9200_d22_pin_configs[8] = { - 0x400001f0, 0x400001f1, 0x02a19021, 0x90100140, - 0x400001f2, 0x0221401f, 0x01014010, 0x01813020, + 0x400001f0, 0x400001f1, 0x0221401f, 0x01014010, + 0x01813020, 0x02a19021, 0x90100140, 0x400001f2, }; /* @@ -587,8 +587,8 @@ static unsigned int dell9200_d22_pin_configs[8] = { 102801E3 */ static unsigned int dell9200_d23_pin_configs[8] = { - 0x400001f0, 0x400001f1, 0x01a19021, 0x90100140, - 0x400001f2, 0x0221401f, 0x01014010, 0x01813020, + 0x400001f0, 0x400001f1, 0x0221401f, 0x01014010, + 0x01813020, 0x01a19021, 0x90100140, 0x400001f2, }; @@ -598,8 +598,8 @@ static unsigned int dell9200_d23_pin_configs[8] = { 102801D8 (Dell Inspiron 640m) */ static unsigned int dell9200_m21_pin_configs[8] = { - 0x40c003fa, 0x03441340, 0x03a11020, 0x401003fc, - 0x403003fd, 0x0321121f, 0x0321121f, 0x408003fb, + 0x40c003fa, 0x03441340, 0x0321121f, 0x90170310, + 0x408003fb, 0x03a11020, 0x401003fc, 0x403003fd, }; /* @@ -611,8 +611,8 @@ static unsigned int dell9200_m21_pin_configs[8] = { 102801D6 */ static unsigned int dell9200_m22_pin_configs[8] = { - 0x40c003fa, 0x0144131f, 0x03A11020, 0x401003fb, - 0x40f000fc, 0x0321121f, 0x90170310, 0x90a70321, + 0x40c003fa, 0x0144131f, 0x0321121f, 0x90170310, + 0x90a70321, 0x03a11020, 0x401003fb, 0x40f000fc, }; /* @@ -633,8 +633,8 @@ static unsigned int dell9200_m23_pin_configs[8] = { 102801D3 */ static unsigned int dell9200_m24_pin_configs[8] = { - 0x40c003fa, 0x404003fb, 0x03a11020, 0x401003fd, - 0x403003fe, 0x0321121f, 0x90170310, 0x408003fc, + 0x40c003fa, 0x404003fb, 0x0321121f, 0x90170310, + 0x408003fc, 0x03a11020, 0x401003fd, 0x403003fe, }; /* @@ -644,8 +644,8 @@ static unsigned int dell9200_m24_pin_configs[8] = { 102801EF */ static unsigned int dell9200_m25_pin_configs[8] = { - 0x40c003fa, 0x01441340, 0x04a11020, 0x401003fc, - 0x403003fd, 0x0421121f, 0x90170310, 0x408003fb, + 0x40c003fa, 0x01441340, 0x0421121f, 0x90170310, + 0x408003fb, 0x04a11020, 0x401003fc, 0x403003fd, }; /* @@ -654,8 +654,8 @@ static unsigned int dell9200_m25_pin_configs[8] = { 102801F6 */ static unsigned int dell9200_m26_pin_configs[8] = { - 0x40c003fa, 0x404003fb, 0x04a11020, 0x401003fd, - 0x403003fe, 0x0421121f, 0x90170310, 0x408003fc, + 0x40c003fa, 0x404003fb, 0x0421121f, 0x90170310, + 0x408003fc, 0x04a11020, 0x401003fd, 0x403003fe, }; /* @@ -663,8 +663,8 @@ static unsigned int dell9200_m26_pin_configs[8] = { 102801CD (Dell Inspiron E1705/9400) */ static unsigned int dell9200_m27_pin_configs[8] = { - 0x40c003fa, 0x01441340, 0x04a11020, 0x90170310, - 0x40f003fc, 0x0421121f, 0x90170310, 0x408003fb, + 0x40c003fa, 0x01441340, 0x0421121f, 0x90170310, + 0x90170310, 0x04a11020, 0x90170310, 0x40f003fc, }; -- cgit v1.2.3 From 8ab78c7424588c6b1600dcfd70418617a09326b8 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 6 Sep 2007 14:29:53 +0200 Subject: [ALSA] hda-codec - Add laptop-automute model for AD1986A Added a new model laptop-automute for AD1986A, which has the HP jack detection and auto-muting of the speaker. Currently, it's used for Lenovo N100. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_analog.c | 126 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 125 insertions(+), 1 deletion(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index bc4b797aa97..54cfd4526d2 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c @@ -74,6 +74,8 @@ struct ad198x_spec { struct hda_input_mux private_imux; hda_nid_t private_dac_nids[4]; + unsigned int jack_present :1; + #ifdef CONFIG_SND_HDA_POWER_SAVE struct hda_loopback_check loopback; #endif @@ -588,6 +590,106 @@ static struct snd_kcontrol_new ad1986a_laptop_eapd_mixers[] = { { } /* end */ }; +/* laptop-automute - 2ch only */ + +static void ad1986a_update_hp(struct hda_codec *codec) +{ + struct ad198x_spec *spec = codec->spec; + unsigned int mute; + + if (spec->jack_present) + mute = HDA_AMP_MUTE; /* mute internal speaker */ + else + /* unmute internal speaker if necessary */ + mute = snd_hda_codec_amp_read(codec, 0x1a, 0, HDA_OUTPUT, 0); + snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0, + HDA_AMP_MUTE, mute); +} + +static void ad1986a_hp_automute(struct hda_codec *codec) +{ + struct ad198x_spec *spec = codec->spec; + unsigned int present; + + present = snd_hda_codec_read(codec, 0x1a, 0, AC_VERB_GET_PIN_SENSE, 0); + spec->jack_present = (present & 0x80000000) != 0; + ad1986a_update_hp(codec); +} + +#define AD1986A_HP_EVENT 0x37 + +static void ad1986a_hp_unsol_event(struct hda_codec *codec, unsigned int res) +{ + if ((res >> 26) != AD1986A_HP_EVENT) + return; + ad1986a_hp_automute(codec); +} + +static int ad1986a_hp_init(struct hda_codec *codec) +{ + ad198x_init(codec); + ad1986a_hp_automute(codec); + return 0; +} + +/* bind hp and internal speaker mute (with plug check) */ +static int ad1986a_hp_master_sw_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + long *valp = ucontrol->value.integer.value; + int change; + + change = snd_hda_codec_amp_update(codec, 0x1a, 0, HDA_OUTPUT, 0, + HDA_AMP_MUTE, + valp[0] ? 0 : HDA_AMP_MUTE); + change |= snd_hda_codec_amp_update(codec, 0x1a, 1, HDA_OUTPUT, 0, + HDA_AMP_MUTE, + valp[1] ? 0 : HDA_AMP_MUTE); + if (change) + ad1986a_update_hp(codec); + return change; +} + +static struct snd_kcontrol_new ad1986a_laptop_automute_mixers[] = { + HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol), + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Master Playback Switch", + .info = snd_hda_mixer_amp_switch_info, + .get = snd_hda_mixer_amp_switch_get, + .put = ad1986a_hp_master_sw_put, + .private_value = HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT), + }, + HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x17, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x17, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Mic Boost", 0x0f, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Beep Playback Volume", 0x18, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE("Beep Playback Switch", 0x18, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT), + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Capture Source", + .info = ad198x_mux_enum_info, + .get = ad198x_mux_enum_get, + .put = ad198x_mux_enum_put, + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "External Amplifier", + .info = ad198x_eapd_info, + .get = ad198x_eapd_get, + .put = ad198x_eapd_put, + .private_value = 0x1b | (1 << 8), /* port-D, inversed */ + }, + { } /* end */ +}; + /* * initialization verbs */ @@ -701,12 +803,20 @@ static struct hda_verb ad1986a_ultra_init[] = { { } /* end */ }; +/* pin sensing on HP jack */ +static struct hda_verb ad1986a_hp_init_verbs[] = { + {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1986A_HP_EVENT}, + {} +}; + + /* models */ enum { AD1986A_6STACK, AD1986A_3STACK, AD1986A_LAPTOP, AD1986A_LAPTOP_EAPD, + AD1986A_LAPTOP_AUTOMUTE, AD1986A_ULTRA, AD1986A_MODELS }; @@ -716,6 +826,7 @@ static const char *ad1986a_models[AD1986A_MODELS] = { [AD1986A_3STACK] = "3stack", [AD1986A_LAPTOP] = "laptop", [AD1986A_LAPTOP_EAPD] = "laptop-eapd", + [AD1986A_LAPTOP_AUTOMUTE] = "laptop-automute", [AD1986A_ULTRA] = "ultra", }; @@ -744,7 +855,7 @@ static struct snd_pci_quirk ad1986a_cfg_tbl[] = { SND_PCI_QUIRK(0x144d, 0xc027, "Samsung Q1", AD1986A_ULTRA), SND_PCI_QUIRK(0x17aa, 0x1011, "Lenovo M55", AD1986A_LAPTOP), SND_PCI_QUIRK(0x17aa, 0x1017, "Lenovo A60", AD1986A_3STACK), - SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo N100", AD1986A_LAPTOP_EAPD), + SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo N100", AD1986A_LAPTOP_AUTOMUTE), SND_PCI_QUIRK(0x17c0, 0x2017, "Samsung M50", AD1986A_LAPTOP), {} }; @@ -821,6 +932,19 @@ static int patch_ad1986a(struct hda_codec *codec) spec->multiout.dig_out_nid = 0; spec->input_mux = &ad1986a_laptop_eapd_capture_source; break; + case AD1986A_LAPTOP_AUTOMUTE: + spec->mixers[0] = ad1986a_laptop_automute_mixers; + spec->num_init_verbs = 3; + spec->init_verbs[1] = ad1986a_eapd_init_verbs; + spec->init_verbs[2] = ad1986a_hp_init_verbs; + spec->multiout.max_channels = 2; + spec->multiout.num_dacs = 1; + spec->multiout.dac_nids = ad1986a_laptop_dac_nids; + spec->multiout.dig_out_nid = 0; + spec->input_mux = &ad1986a_laptop_eapd_capture_source; + codec->patch_ops.unsol_event = ad1986a_hp_unsol_event; + codec->patch_ops.init = ad1986a_hp_init; + break; case AD1986A_ULTRA: spec->mixers[0] = ad1986a_laptop_eapd_mixers; spec->num_init_verbs = 2; -- cgit v1.2.3 From 914759b79e28ce74606e99d9f6aaabeec58394ab Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 6 Sep 2007 14:52:04 +0200 Subject: [ALSA] hda-codec - Add support for ASUS A7M Added the support for ASUS A7M with ALC882 codec. It's slightly different from ASUS A7J. The patch taken from ALSA bug#3000 https://bugtrack.alsa-project.org/alsa-bug/view.php?id=3000 Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_realtek.c | 49 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 412629d02db..8491b046a9f 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -155,6 +155,7 @@ enum { ALC882_W2JC, ALC882_TARGA, ALC882_ASUS_A7J, + ALC882_ASUS_A7M, ALC885_MACPRO, ALC885_MBP3, ALC885_IMAC24, @@ -5022,6 +5023,22 @@ static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = { { } /* end */ }; +static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = { + HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), + HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), + HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), + HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), + HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), + HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), + HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), + HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), + { } /* end */ +}; + static struct snd_kcontrol_new alc882_chmode_mixer[] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, @@ -5373,6 +5390,24 @@ static struct hda_verb alc882_asus_a7j_verbs[] = { { } /* end */ }; +static struct hda_verb alc882_asus_a7m_verbs[] = { + {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, + + {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, + {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, + {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, + + {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */ + {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ + {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */ + + {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ + {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */ + {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ + { } /* end */ +}; + static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted) { unsigned int gpiostate, gpiomask, gpiodir; @@ -5563,6 +5598,7 @@ static struct snd_pci_quirk alc882_cfg_tbl[] = { SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */ SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J), + SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M), SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG), SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG), SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC), @@ -5683,6 +5719,19 @@ static struct alc_config_preset alc882_presets[] = { .need_dac_fix = 1, .input_mux = &alc882_capture_source, }, + [ALC882_ASUS_A7M] = { + .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer }, + .init_verbs = { alc882_init_verbs, alc882_eapd_verbs, + alc880_gpio1_init_verbs, + alc882_asus_a7m_verbs }, + .num_dacs = ARRAY_SIZE(alc882_dac_nids), + .dac_nids = alc882_dac_nids, + .dig_out_nid = ALC882_DIGOUT_NID, + .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), + .channel_mode = alc880_threestack_modes, + .need_dac_fix = 1, + .input_mux = &alc882_capture_source, + }, }; -- cgit v1.2.3 From 0438a00e64f38b2f655a10167f9f2d9759856069 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 6 Sep 2007 14:54:11 +0200 Subject: [ALSA] hda-codec - Add missing model names for ALC882 codecs Added the missing model option strings for ALC882 codecs. Also added the corresponding description in ALSA-Configuration.txt. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_realtek.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 8491b046a9f..f06494a9776 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -5585,6 +5585,9 @@ static const char *alc882_models[ALC882_MODEL_LAST] = { [ALC882_6ST_DIG] = "6stack-dig", [ALC882_ARIMA] = "arima", [ALC882_W2JC] = "w2jc", + [ALC882_TARGA] = "targa", + [ALC882_ASUS_A7J] = "asus-a7j", + [ALC882_ASUS_A7M] = "asus-a7m", [ALC885_MACPRO] = "macpro", [ALC885_MBP3] = "mbp3", [ALC885_IMAC24] = "imac24", -- cgit v1.2.3 From b875bf3aaf743fb461ab97e07752fbd825c2d78f Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 6 Sep 2007 15:00:27 +0200 Subject: [ALSA] hda-codec - Add quirk entry for Casper CPR2000 Added the quirk entry for Casper CPR2000 (model=acer) with ALC268 codec (ALSA bug#3343). Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index f06494a9776..90ab518dfe5 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -9100,6 +9100,7 @@ static struct snd_pci_quirk alc268_cfg_tbl[] = { SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA), SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER), SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER), + SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER), {} }; -- cgit v1.2.3 From dcfb4140328eed2d73797f278786eb99efd9f41c Mon Sep 17 00:00:00 2001 From: Trent Piepho Date: Thu, 6 Sep 2007 15:06:44 +0200 Subject: [ALSA] snd-bt87x: Improve support for different board types Different cards have different audio configurations, but the driver didn't support this. The only setting it had was the digital rate. This patch adds a board configuration list. Currently, configurable items are the digital rate and the digital data format (for cards with an external ADC), a flag for the absence of an external ADC, and a flag for no connection to the Bt87x internal ADC. This allows cards that don't use the internal ADC to omit the ALSA 'Bt87x analog' device and related controls. Cards without an external ADC can omit the 'Bt87x digital' device. In order to support the CS5331A ADC used on the Osprey 440 and 2x0 cards, the digital format needs to be different than the default. Support could be added for defining: The connections or lack of them to the Bt87x's internal ADC mux Multiple sample rates for an external ADC (e.g. Osprey) Control of an external mux for an external ADC (e.g. Osprey) The card definitions for cards other than the Ospreys are kept equivalent to their old values. This is likely inaccurate for most cards, as it is doubtful that both an external and the internal ADC would be used. Lacking information on those cards, the behavior is left unchanged. Signed-off-by: Trent Piepho Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/bt87x.c | 172 ++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 114 insertions(+), 58 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c index d87d6a3298a..10c8af1b736 100644 --- a/sound/pci/bt87x.c +++ b/sound/pci/bt87x.c @@ -147,15 +147,52 @@ MODULE_PARM_DESC(load_all, "Allow to load the non-whitelisted cards"); /* SYNC, one WRITE per line, one extra WRITE per page boundary, SYNC, JUMP */ #define MAX_RISC_SIZE ((1 + 255 + (PAGE_ALIGN(255 * 4092) / PAGE_SIZE - 1) + 1 + 1) * 8) +/* Cards with configuration information */ +enum snd_bt87x_boardid { + SND_BT87X_BOARD_GENERIC, /* both an & dig interfaces, 32kHz */ + SND_BT87X_BOARD_ANALOG, /* board with no external A/D */ + SND_BT87X_BOARD_OSPREY2x0, + SND_BT87X_BOARD_OSPREY440, + SND_BT87X_BOARD_AVPHONE98, +}; + +/* Card configuration */ +struct snd_bt87x_board { + int dig_rate; /* Digital input sampling rate */ + u32 digital_fmt; /* Register settings for digital input */ + unsigned no_analog:1; /* No analog input */ + unsigned no_digital:1; /* No digital input */ +}; + +static const __devinitdata struct snd_bt87x_board snd_bt87x_boards[] = { + [SND_BT87X_BOARD_GENERIC] = { + .dig_rate = 32000, + }, + [SND_BT87X_BOARD_ANALOG] = { + .no_digital = 1, + }, + [SND_BT87X_BOARD_OSPREY2x0] = { + .dig_rate = 44100, + .digital_fmt = CTL_DA_LRI | (1 << CTL_DA_LRD_SHIFT), + }, + [SND_BT87X_BOARD_OSPREY440] = { + .dig_rate = 32000, + .digital_fmt = CTL_DA_LRI | (1 << CTL_DA_LRD_SHIFT), + .no_analog = 1, + }, + [SND_BT87X_BOARD_AVPHONE98] = { + .dig_rate = 48000, + }, +}; + struct snd_bt87x { struct snd_card *card; struct pci_dev *pci; + struct snd_bt87x_board board; void __iomem *mmio; int irq; - int dig_rate; - spinlock_t reg_lock; unsigned long opened; struct snd_pcm_substream *substream; @@ -342,9 +379,9 @@ static int snd_bt87x_set_digital_hw(struct snd_bt87x *chip, struct snd_pcm_runti { chip->reg_control |= CTL_DA_IOM_DA; runtime->hw = snd_bt87x_digital_hw; - runtime->hw.rates = snd_pcm_rate_to_rate_bit(chip->dig_rate); - runtime->hw.rate_min = chip->dig_rate; - runtime->hw.rate_max = chip->dig_rate; + runtime->hw.rates = snd_pcm_rate_to_rate_bit(chip->board.dig_rate); + runtime->hw.rate_min = chip->board.dig_rate; + runtime->hw.rate_max = chip->board.dig_rate; return 0; } @@ -709,9 +746,9 @@ static int __devinit snd_bt87x_create(struct snd_card *card, chip->mmio = ioremap_nocache(pci_resource_start(pci, 0), pci_resource_len(pci, 0)); if (!chip->mmio) { - snd_bt87x_free(chip); snd_printk(KERN_ERR "cannot remap io memory\n"); - return -ENOMEM; + err = -ENOMEM; + goto fail; } chip->reg_control = CTL_DA_ES2 | CTL_PKTP_16 | (15 << CTL_DA_SDR_SHIFT); @@ -720,54 +757,57 @@ static int __devinit snd_bt87x_create(struct snd_card *card, snd_bt87x_writel(chip, REG_INT_MASK, 0); snd_bt87x_writel(chip, REG_INT_STAT, MY_INTERRUPTS); - if (request_irq(pci->irq, snd_bt87x_interrupt, IRQF_SHARED, - "Bt87x audio", chip)) { - snd_bt87x_free(chip); - snd_printk(KERN_ERR "cannot grab irq\n"); - return -EBUSY; + err = request_irq(pci->irq, snd_bt87x_interrupt, IRQF_SHARED, + "Bt87x audio", chip); + if (err < 0) { + snd_printk(KERN_ERR "cannot grab irq %d\n", pci->irq); + goto fail; } chip->irq = pci->irq; pci_set_master(pci); synchronize_irq(chip->irq); err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops); - if (err < 0) { - snd_bt87x_free(chip); - return err; - } + if (err < 0) + goto fail; + snd_card_set_dev(card, &pci->dev); *rchip = chip; return 0; + +fail: + snd_bt87x_free(chip); + return err; } -#define BT_DEVICE(chip, subvend, subdev, rate) \ +#define BT_DEVICE(chip, subvend, subdev, id) \ { .vendor = PCI_VENDOR_ID_BROOKTREE, \ .device = chip, \ .subvendor = subvend, .subdevice = subdev, \ - .driver_data = rate } + .driver_data = SND_BT87X_BOARD_ ## id } +/* driver_data is the card id for that device */ -/* driver_data is the default digital_rate value for that device */ static struct pci_device_id snd_bt87x_ids[] = { /* Hauppauge WinTV series */ - BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x0070, 0x13eb, 32000), + BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x0070, 0x13eb, GENERIC), /* Hauppauge WinTV series */ - BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_879, 0x0070, 0x13eb, 32000), + BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_879, 0x0070, 0x13eb, GENERIC), /* Viewcast Osprey 200 */ - BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x0070, 0xff01, 44100), + BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x0070, 0xff01, OSPREY2x0), /* Viewcast Osprey 440 (rate is configurable via gpio) */ - BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x0070, 0xff07, 32000), + BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x0070, 0xff07, OSPREY440), /* ATI TV-Wonder */ - BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x1002, 0x0001, 32000), + BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x1002, 0x0001, GENERIC), /* Leadtek Winfast tv 2000xp delux */ - BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x107d, 0x6606, 32000), + BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x107d, 0x6606, GENERIC), /* Voodoo TV 200 */ - BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x121a, 0x3000, 32000), + BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x121a, 0x3000, GENERIC), /* AVerMedia Studio No. 103, 203, ...? */ - BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x1461, 0x0003, 48000), + BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x1461, 0x0003, AVPHONE98), /* Prolink PixelView PV-M4900 */ - BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x1554, 0x4011, 32000), + BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x1554, 0x4011, GENERIC), /* Pinnacle Studio PCTV rave */ - BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0xbd11, 0x1200, 32000), + BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0xbd11, 0x1200, GENERIC), { } }; MODULE_DEVICE_TABLE(pci, snd_bt87x_ids); @@ -792,7 +832,7 @@ static struct { static struct pci_driver driver; -/* return the rate of the card, or a negative value if it's blacklisted */ +/* return the id of the card, or a negative value if it's blacklisted */ static int __devinit snd_bt87x_detect_card(struct pci_dev *pci) { int i; @@ -810,12 +850,12 @@ static int __devinit snd_bt87x_detect_card(struct pci_dev *pci) return -EBUSY; } - snd_printk(KERN_INFO "unknown card %#04x-%#04x:%#04x, using default rate 32000\n", - pci->device, pci->subsystem_vendor, pci->subsystem_device); + snd_printk(KERN_INFO "unknown card %#04x-%#04x:%#04x\n", + pci->device, pci->subsystem_vendor, pci->subsystem_device); snd_printk(KERN_DEBUG "please mail id, board name, and, " "if it works, the correct digital_rate option to " "\n"); - return 32000; /* default rate */ + return SND_BT87X_BOARD_GENERIC; } static int __devinit snd_bt87x_probe(struct pci_dev *pci, @@ -824,12 +864,16 @@ static int __devinit snd_bt87x_probe(struct pci_dev *pci, static int dev; struct snd_card *card; struct snd_bt87x *chip; - int err, rate; + int err; + enum snd_bt87x_boardid boardid; - rate = pci_id->driver_data; - if (! rate) - if ((rate = snd_bt87x_detect_card(pci)) <= 0) + if (!pci_id->driver_data) { + err = snd_bt87x_detect_card(pci); + if (err < 0) return -ENODEV; + boardid = err; + } else + boardid = pci_id->driver_data; if (dev >= SNDRV_CARDS) return -ENODEV; @@ -846,27 +890,39 @@ static int __devinit snd_bt87x_probe(struct pci_dev *pci, if (err < 0) goto _error; - if (digital_rate[dev] > 0) - chip->dig_rate = digital_rate[dev]; - else - chip->dig_rate = rate; + memcpy(&chip->board, &snd_bt87x_boards[boardid], sizeof(chip->board)); - err = snd_bt87x_pcm(chip, DEVICE_DIGITAL, "Bt87x Digital"); - if (err < 0) - goto _error; - err = snd_bt87x_pcm(chip, DEVICE_ANALOG, "Bt87x Analog"); - if (err < 0) - goto _error; + if (!chip->board.no_digital) { + if (digital_rate[dev] > 0) + chip->board.dig_rate = digital_rate[dev]; - err = snd_ctl_add(card, snd_ctl_new1(&snd_bt87x_capture_volume, chip)); - if (err < 0) - goto _error; - err = snd_ctl_add(card, snd_ctl_new1(&snd_bt87x_capture_boost, chip)); - if (err < 0) - goto _error; - err = snd_ctl_add(card, snd_ctl_new1(&snd_bt87x_capture_source, chip)); - if (err < 0) - goto _error; + chip->reg_control |= chip->board.digital_fmt; + + err = snd_bt87x_pcm(chip, DEVICE_DIGITAL, "Bt87x Digital"); + if (err < 0) + goto _error; + } + if (!chip->board.no_analog) { + err = snd_bt87x_pcm(chip, DEVICE_ANALOG, "Bt87x Analog"); + if (err < 0) + goto _error; + err = snd_ctl_add(card, snd_ctl_new1( + &snd_bt87x_capture_volume, chip)); + if (err < 0) + goto _error; + err = snd_ctl_add(card, snd_ctl_new1( + &snd_bt87x_capture_boost, chip)); + if (err < 0) + goto _error; + err = snd_ctl_add(card, snd_ctl_new1( + &snd_bt87x_capture_source, chip)); + if (err < 0) + goto _error; + } + snd_printk(KERN_INFO "bt87x%d: Using board %d, %sanalog, %sdigital " + "(rate %d Hz)\n", dev, boardid, + chip->board.no_analog ? "no " : "", + chip->board.no_digital ? "no " : "", chip->board.dig_rate); strcpy(card->driver, "Bt87x"); sprintf(card->shortname, "Brooktree Bt%x", pci->device); @@ -897,8 +953,8 @@ static void __devexit snd_bt87x_remove(struct pci_dev *pci) /* default entries for all Bt87x cards - it's not exported */ /* driver_data is set to 0 to call detection */ static struct pci_device_id snd_bt87x_default_ids[] __devinitdata = { - BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, PCI_ANY_ID, PCI_ANY_ID, 0), - BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_879, PCI_ANY_ID, PCI_ANY_ID, 0), + BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, PCI_ANY_ID, PCI_ANY_ID, GENERIC), + BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_879, PCI_ANY_ID, PCI_ANY_ID, GENERIC), { } }; -- cgit v1.2.3 From 96fe7cc867b73690e806406be1562b0e6fa42d2d Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 7 Sep 2007 10:57:44 +0200 Subject: [ALSA] hda-codec - Add missing Mic Boost for some ALC882 models Mic Boost mixer volume was missing in some ALC882 models. Added now. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_realtek.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 90ab518dfe5..b36852ebb4b 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -4999,8 +4999,10 @@ static struct snd_kcontrol_new alc882_targa_mixer[] = { HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), { } /* end */ }; @@ -5020,6 +5022,7 @@ static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = { HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT), HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), { } /* end */ }; -- cgit v1.2.3 From 8e7f00f9248c2dc6b36f3c4d1932aa975b454c48 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 7 Sep 2007 10:58:58 +0200 Subject: [ALSA] hda-codec - Add support for Toshiba A305 Added the proper model=toshiba for Toshiba A305 with ALC268 codec. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index b36852ebb4b..e8270862e1e 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -9100,6 +9100,7 @@ static const char *alc268_models[ALC268_MODEL_LAST] = { static struct snd_pci_quirk alc268_cfg_tbl[] = { SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST), SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA), + SND_PCI_QUIRK(0x1179, 0xff50, "TOSHIBA A305", ALC268_TOSHIBA), SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA), SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER), SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER), -- cgit v1.2.3 From 57bd68b8b18608cf2729f97fcb984b8521d19551 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Fri, 7 Sep 2007 10:44:13 +0200 Subject: [ALSA] cmipci: add msbits constraint for 24-bit format Add a msbits constraint to the SPDIF output device to indicate that S32_LE samples use only 24 bits for data. Signed-off-by: Clemens Ladisch Signed-off-by: Jaroslav Kysela --- sound/pci/cmipci.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'sound/pci') diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c index a8d6b54143f..78a23984eac 100644 --- a/sound/pci/cmipci.c +++ b/sound/pci/cmipci.c @@ -1599,8 +1599,10 @@ static int snd_cmipci_playback_spdif_open(struct snd_pcm_substream *substream) return err; if (cm->can_ac3_hw) { runtime->hw = snd_cmipci_playback_spdif; - if (cm->chip_version >= 37) + if (cm->chip_version >= 37) { runtime->hw.formats |= SNDRV_PCM_FMTBIT_S32_LE; + snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24); + } if (cm->chip_version == 68) { runtime->hw.rates |= SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000; -- cgit v1.2.3 From 950fb626dc28e17ae4ad01dba07957bdc6e0b997 Mon Sep 17 00:00:00 2001 From: Trent Piepho Date: Fri, 7 Sep 2007 13:18:50 +0200 Subject: [ALSA] snd-bt87x: Power down audio ADC when not in use Sets a bit to power down the Bt87x's internal audio ADC when the ALSA device isn't open, or when it is in 'digital mode' using an external ADC. Signed-off-by: Trent Piepho Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/bt87x.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c index 10c8af1b736..42e57fd02d3 100644 --- a/sound/pci/bt87x.c +++ b/sound/pci/bt87x.c @@ -377,7 +377,7 @@ static struct snd_pcm_hardware snd_bt87x_analog_hw = { static int snd_bt87x_set_digital_hw(struct snd_bt87x *chip, struct snd_pcm_runtime *runtime) { - chip->reg_control |= CTL_DA_IOM_DA; + chip->reg_control |= CTL_DA_IOM_DA | CTL_A_PWRDN; runtime->hw = snd_bt87x_digital_hw; runtime->hw.rates = snd_pcm_rate_to_rate_bit(chip->board.dig_rate); runtime->hw.rate_min = chip->board.dig_rate; @@ -398,7 +398,7 @@ static int snd_bt87x_set_analog_hw(struct snd_bt87x *chip, struct snd_pcm_runtim .rats = &analog_clock }; - chip->reg_control &= ~CTL_DA_IOM_DA; + chip->reg_control &= ~(CTL_DA_IOM_DA | CTL_A_PWRDN); runtime->hw = snd_bt87x_analog_hw; return snd_pcm_hw_constraint_ratnums(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &constraint_rates); @@ -437,6 +437,11 @@ static int snd_bt87x_close(struct snd_pcm_substream *substream) { struct snd_bt87x *chip = snd_pcm_substream_chip(substream); + spin_lock_irq(&chip->reg_lock); + chip->reg_control |= CTL_A_PWRDN; + snd_bt87x_writel(chip, REG_GPIO_DMA_CTL, chip->reg_control); + spin_unlock_irq(&chip->reg_lock); + chip->substream = NULL; clear_bit(0, &chip->opened); smp_mb__after_clear_bit(); @@ -751,7 +756,8 @@ static int __devinit snd_bt87x_create(struct snd_card *card, goto fail; } - chip->reg_control = CTL_DA_ES2 | CTL_PKTP_16 | (15 << CTL_DA_SDR_SHIFT); + chip->reg_control = CTL_A_PWRDN | CTL_DA_ES2 | + CTL_PKTP_16 | (15 << CTL_DA_SDR_SHIFT); chip->interrupt_mask = MY_INTERRUPTS; snd_bt87x_writel(chip, REG_GPIO_DMA_CTL, chip->reg_control); snd_bt87x_writel(chip, REG_INT_MASK, 0); -- cgit v1.2.3 From e45e459e88b81fe49129cc9a704fead0fc7d32ed Mon Sep 17 00:00:00 2001 From: Matthew Ranostay Date: Mon, 10 Sep 2007 23:09:42 +0200 Subject: [ALSA] hda: BIOS changing subsystem id Some laptop BIOS change the subsystem id for STAC9205 cards if the microphone isn't toggled on/off in the settings. Signed-off-by: Matthew Ranostay Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_sigmatel.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index f843e2122a8..2feb0f2e38c 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -1185,6 +1185,8 @@ static struct snd_pci_quirk stac9205_cfg_tbl[] = { "Dell Precision", STAC_9205_M43xx), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f9, "Dell Precision", STAC_9205_DELL_M43), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021b, + "Dell Precision", STAC_9205_DELL_M43), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fa, "Dell Precision", STAC_9205_DELL_M43), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fc, -- cgit v1.2.3 From 51c80cb65ff9b7bdf172f9075138793c2bce6883 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Mon, 10 Sep 2007 23:15:50 +0200 Subject: [ALSA] au88x0_synth.c bugfix This patch fixes the code in vortex_wt_SetFrequency() to what seems to have been intended. Signed-off-by: Adrian Bunk Signed-off-by: Andrew Morton Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/au88x0/au88x0_synth.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/au88x0/au88x0_synth.c b/sound/pci/au88x0/au88x0_synth.c index d3e662a1285..978b856f562 100644 --- a/sound/pci/au88x0/au88x0_synth.c +++ b/sound/pci/au88x0/au88x0_synth.c @@ -370,8 +370,8 @@ static void vortex_wt_SetFrequency(vortex_t * vortex, int wt, unsigned int sr) while ((edx & 0x80000000) == 0) { edx <<= 1; eax--; - if (eax == 0) ; - break; + if (eax == 0) + break; } if (eax) edx <<= 1; -- cgit v1.2.3 From 768d8c7df886fc5cc9d6057cc987ef8e52d197b5 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 11 Sep 2007 21:28:50 +0200 Subject: [ALSA] pcxhr - Fix trigger start with non-linked streams The non-linked streams couldn't be started properly due to missing setting of stream->status. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/pcxhr/pcxhr.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sound/pci') diff --git a/sound/pci/pcxhr/pcxhr.c b/sound/pci/pcxhr/pcxhr.c index cd4613a97bd..2d618bd7e62 100644 --- a/sound/pci/pcxhr/pcxhr.c +++ b/sound/pci/pcxhr/pcxhr.c @@ -664,6 +664,7 @@ static int pcxhr_trigger(struct snd_pcm_substream *subs, int cmd) if (pcxhr_update_r_buffer(stream)) return -EINVAL; + stream->status = PCXHR_STREAM_STATUS_SCHEDULE_RUN; if (pcxhr_set_stream_state(stream)) return -EINVAL; stream->status = PCXHR_STREAM_STATUS_RUNNING; -- cgit v1.2.3 From e8a7f136f5edb6ae83b14faaa0da2a3c4558f431 Mon Sep 17 00:00:00 2001 From: Danny Tholen Date: Tue, 11 Sep 2007 21:41:56 +0200 Subject: [ALSA] hda-intel - Improve HD-audio codec probing robustness When modem is disabled in the BIOS, detection of the number of codecs always fails after booting if STATESTS is not cleared first. This patch fixes this problem and also adds an error check in a place where a read error would lead to a very large number of pointless loops. Signed-off-by: Danny Tholen Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/hda_codec.c | 2 ++ sound/pci/hda/hda_intel.c | 3 +++ 2 files changed, 5 insertions(+) (limited to 'sound/pci') diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index e594de0b153..535bcb7601b 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -155,6 +155,8 @@ int snd_hda_get_sub_nodes(struct hda_codec *codec, hda_nid_t nid, unsigned int parm; parm = snd_hda_param_read(codec, nid, AC_PAR_NODE_COUNT); + if (parm == -1) + return 0; *start_id = (parm >> 16) & 0x7fff; return (int)(parm & 0x7fff); } diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 72fd3453899..68dc9a2e3cf 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -687,6 +687,9 @@ static int azx_reset(struct azx *chip) { int count; + /* clear STATESTS */ + azx_writeb(chip, STATESTS, STATESTS_INT_MASK); + /* reset controller */ azx_writel(chip, GCTL, azx_readl(chip, GCTL) & ~ICH6_GCTL_RESET); -- cgit v1.2.3 From f189e14cc41a1fb7db225cacdb2df7498f5ad67a Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 11 Sep 2007 22:11:08 +0200 Subject: [ALSA] echoaudio - Remove superfluous volatile prefix Remove superfluous volatile prefix in the communication struct definition. This eventually fixes the compile warnings with the recent gcc, too. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/echoaudio/echoaudio_dsp.h | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/echoaudio/echoaudio_dsp.h b/sound/pci/echoaudio/echoaudio_dsp.h index e55ee00991a..e352f3ae292 100644 --- a/sound/pci/echoaudio/echoaudio_dsp.h +++ b/sound/pci/echoaudio/echoaudio_dsp.h @@ -642,18 +642,18 @@ struct comm_page { /* Base Length*/ u32 flags; /* See Appendix A below 0x004 4 */ u32 unused; /* Unused entry 0x008 4 */ u32 sample_rate; /* Card sample rate in Hz 0x00c 4 */ - volatile u32 handshake; /* DSP command handshake 0x010 4 */ + u32 handshake; /* DSP command handshake 0x010 4 */ u32 cmd_start; /* Chs. to start mask 0x014 4 */ u32 cmd_stop; /* Chs. to stop mask 0x018 4 */ u32 cmd_reset; /* Chs. to reset mask 0x01c 4 */ u16 audio_format[DSP_MAXPIPES]; /* Chs. audio format 0x020 32*2 */ struct sg_entry sglist_addr[DSP_MAXPIPES]; /* Chs. Physical sglist addrs 0x060 32*8 */ - volatile u32 position[DSP_MAXPIPES]; + u32 position[DSP_MAXPIPES]; /* Positions for ea. ch. 0x160 32*4 */ - volatile s8 vu_meter[DSP_MAXPIPES]; + s8 vu_meter[DSP_MAXPIPES]; /* VU meters 0x1e0 32*1 */ - volatile s8 peak_meter[DSP_MAXPIPES]; + s8 peak_meter[DSP_MAXPIPES]; /* Peak meters 0x200 32*1 */ s8 line_out_level[DSP_MAXAUDIOOUTPUTS]; /* Output gain 0x220 16*1 */ @@ -665,7 +665,7 @@ struct comm_page { /* Base Length*/ /* Gina/Darla play filters - obsolete 0x3c0 168*4 */ u32 rec_coeff[MAX_REC_TAPS]; /* Gina/Darla record filters - obsolete 0x660 192*4 */ - volatile u16 midi_input[MIDI_IN_BUFFER_SIZE]; + u16 midi_input[MIDI_IN_BUFFER_SIZE]; /* MIDI input data transfer buffer 0x960 256*2 */ u8 gd_clock_state; /* Chg Gina/Darla clock state 0xb60 1 */ u8 gd_spdif_status; /* Chg. Gina/Darla S/PDIF state 0xb61 1 */ @@ -674,11 +674,10 @@ struct comm_page { /* Base Length*/ u32 nominal_level_mask; /* -10 level enable mask 0xb64 4 */ u16 input_clock; /* Chg. Input clock state 0xb68 2 */ u16 output_clock; /* Chg. Output clock state 0xb6a 2 */ - volatile u32 status_clocks; - /* Current Input clock state 0xb6c 4 */ + u32 status_clocks; /* Current Input clock state 0xb6c 4 */ u32 ext_box_status; /* External box status 0xb70 4 */ u32 cmd_add_buffer; /* Pipes to add (obsolete) 0xb74 4 */ - volatile u32 midi_out_free_count; + u32 midi_out_free_count; /* # of bytes free in MIDI output FIFO 0xb78 4 */ u32 unused2; /* Cyclic pipes 0xb7c 4 */ u32 control_register; -- cgit v1.2.3 From c818e0a152bcb138411b07f4495b8e6fb9bacf52 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 17 Sep 2007 09:33:37 +0200 Subject: [ALSA] bt87x: fix detection of generic boards Add an 'unknown' board type so that it is possible to differentiate between unknown and generic boards. Signed-off-by: Clemens Ladisch Signed-off-by: Jaroslav Kysela --- sound/pci/bt87x.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c index 42e57fd02d3..91f9e6a112f 100644 --- a/sound/pci/bt87x.c +++ b/sound/pci/bt87x.c @@ -149,6 +149,7 @@ MODULE_PARM_DESC(load_all, "Allow to load the non-whitelisted cards"); /* Cards with configuration information */ enum snd_bt87x_boardid { + SND_BT87X_BOARD_UNKNOWN, SND_BT87X_BOARD_GENERIC, /* both an & dig interfaces, 32kHz */ SND_BT87X_BOARD_ANALOG, /* board with no external A/D */ SND_BT87X_BOARD_OSPREY2x0, @@ -165,6 +166,9 @@ struct snd_bt87x_board { }; static const __devinitdata struct snd_bt87x_board snd_bt87x_boards[] = { + [SND_BT87X_BOARD_UNKNOWN] = { + .dig_rate = 32000, /* just a guess */ + }, [SND_BT87X_BOARD_GENERIC] = { .dig_rate = 32000, }, @@ -861,7 +865,7 @@ static int __devinit snd_bt87x_detect_card(struct pci_dev *pci) snd_printk(KERN_DEBUG "please mail id, board name, and, " "if it works, the correct digital_rate option to " "\n"); - return SND_BT87X_BOARD_GENERIC; + return SND_BT87X_BOARD_UNKNOWN; } static int __devinit snd_bt87x_probe(struct pci_dev *pci, @@ -959,8 +963,8 @@ static void __devexit snd_bt87x_remove(struct pci_dev *pci) /* default entries for all Bt87x cards - it's not exported */ /* driver_data is set to 0 to call detection */ static struct pci_device_id snd_bt87x_default_ids[] __devinitdata = { - BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, PCI_ANY_ID, PCI_ANY_ID, GENERIC), - BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_879, PCI_ANY_ID, PCI_ANY_ID, GENERIC), + BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, PCI_ANY_ID, PCI_ANY_ID, UNKNOWN), + BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_879, PCI_ANY_ID, PCI_ANY_ID, UNKNOWN), { } }; -- cgit v1.2.3 From 6935e68877a875137ea3fe7b690b0bec6504b7ff Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 17 Sep 2007 09:34:59 +0200 Subject: [ALSA] cmipci: fix version 37 detection Use the proper value for the bit that identifies chip version 37. Signed-off-by: Clemens Ladisch Signed-off-by: Jaroslav Kysela --- sound/pci/cmipci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound/pci') diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c index 78a23984eac..751ff00bfec 100644 --- a/sound/pci/cmipci.c +++ b/sound/pci/cmipci.c @@ -2665,7 +2665,7 @@ static void __devinit query_chip(struct cmipci *cm) else cm->can_ac3_hw = 1; break; - case 1: + case CM_CHIP_037: cm->chip_version = 37; cm->can_ac3_hw = 1; break; -- cgit v1.2.3 From a839a33d85184b88735ca3d88c4f7123c5ebb6a1 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 17 Sep 2007 09:35:46 +0200 Subject: [ALSA] cmipci: update register definitions Update comments for many register symbols, add some new register symbols, and rename a few ones. Signed-off-by: Clemens Ladisch Signed-off-by: Jaroslav Kysela --- sound/pci/cmipci.c | 173 +++++++++++++++++++++++++++++++++-------------------- 1 file changed, 109 insertions(+), 64 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c index 751ff00bfec..2d8d3331bb9 100644 --- a/sound/pci/cmipci.c +++ b/sound/pci/cmipci.c @@ -95,30 +95,34 @@ MODULE_PARM_DESC(joystick_port, "Joystick port address."); #define CM_CHADC0 0x00000001 /* ch0, 0:playback, 1:record */ #define CM_REG_FUNCTRL1 0x04 -#define CM_ASFC_MASK 0x0000E000 /* ADC sampling frequency */ -#define CM_ASFC_SHIFT 13 -#define CM_DSFC_MASK 0x00001C00 /* DAC sampling frequency */ -#define CM_DSFC_SHIFT 10 +#define CM_DSFC_MASK 0x0000E000 /* channel 1 (DAC?) sampling frequency */ +#define CM_DSFC_SHIFT 13 +#define CM_ASFC_MASK 0x00001C00 /* channel 0 (ADC?) sampling frequency */ +#define CM_ASFC_SHIFT 10 #define CM_SPDF_1 0x00000200 /* SPDIF IN/OUT at channel B */ #define CM_SPDF_0 0x00000100 /* SPDIF OUT only channel A */ -#define CM_SPDFLOOP 0x00000080 /* ext. SPDIIF/OUT -> IN loopback */ +#define CM_SPDFLOOP 0x00000080 /* ext. SPDIIF/IN -> OUT loopback */ #define CM_SPDO2DAC 0x00000040 /* SPDIF/OUT can be heard from internal DAC */ #define CM_INTRM 0x00000020 /* master control block (MCB) interrupt enabled */ #define CM_BREQ 0x00000010 /* bus master enabled */ #define CM_VOICE_EN 0x00000008 /* legacy voice (SB16,FM) */ -#define CM_UART_EN 0x00000004 /* UART */ -#define CM_JYSTK_EN 0x00000002 /* joy stick */ +#define CM_UART_EN 0x00000004 /* legacy UART */ +#define CM_JYSTK_EN 0x00000002 /* legacy joystick */ +#define CM_ZVPORT 0x00000001 /* ZVPORT */ #define CM_REG_CHFORMAT 0x08 #define CM_CHB3D5C 0x80000000 /* 5,6 channels */ +#define CM_FMOFFSET2 0x40000000 /* initial FM PCM offset 2 when Fmute=1 */ #define CM_CHB3D 0x20000000 /* 4 channels */ #define CM_CHIP_MASK1 0x1f000000 #define CM_CHIP_037 0x01000000 - -#define CM_SPDIF_SELECT1 0x00080000 /* for model <= 037 ? */ +#define CM_SETLAT48 0x00800000 /* set latency timer 48h */ +#define CM_EDGEIRQ 0x00400000 /* emulated edge trigger legacy IRQ */ +#define CM_SPD24SEL39 0x00200000 /* 24-bit spdif: model 039 */ #define CM_AC3EN1 0x00100000 /* enable AC3: model 037 */ +#define CM_SPDIF_SELECT1 0x00080000 /* for model <= 037 ? */ #define CM_SPD24SEL 0x00020000 /* 24bit spdif: model 037 */ /* #define CM_SPDIF_INVERSE 0x00010000 */ /* ??? */ @@ -128,12 +132,18 @@ MODULE_PARM_DESC(joystick_port, "Joystick port address."); #define CM_ADCBITLEN_14 0x00008000 #define CM_ADCBITLEN_13 0x0000C000 -#define CM_ADCDACLEN_MASK 0x00003000 +#define CM_ADCDACLEN_MASK 0x00003000 /* model 037 */ #define CM_ADCDACLEN_060 0x00000000 #define CM_ADCDACLEN_066 0x00001000 #define CM_ADCDACLEN_130 0x00002000 #define CM_ADCDACLEN_280 0x00003000 +#define CM_ADCDLEN_MASK 0x00003000 /* model 039 */ +#define CM_ADCDLEN_ORIGINAL 0x00000000 +#define CM_ADCDLEN_EXTRA 0x00001000 +#define CM_ADCDLEN_24K 0x00002000 +#define CM_ADCDLEN_WEIGHT 0x00003000 + #define CM_CH1_SRATE_176K 0x00000800 #define CM_CH1_SRATE_96K 0x00000800 /* model 055? */ #define CM_CH1_SRATE_88K 0x00000400 @@ -142,24 +152,25 @@ MODULE_PARM_DESC(joystick_port, "Joystick port address."); #define CM_CH0_SRATE_88K 0x00000100 #define CM_SPDIF_INVERSE2 0x00000080 /* model 055? */ -#define CM_DBLSPDS 0x00000040 +#define CM_DBLSPDS 0x00000040 /* double SPDIF sample rate 88.2/96 */ +#define CM_POLVALID 0x00000020 /* inverse SPDIF/IN valid bit */ +#define CM_SPDLOCKED 0x00000010 -#define CM_CH1FMT_MASK 0x0000000C +#define CM_CH1FMT_MASK 0x0000000C /* bit 3: 16 bits, bit 2: stereo */ #define CM_CH1FMT_SHIFT 2 -#define CM_CH0FMT_MASK 0x00000003 +#define CM_CH0FMT_MASK 0x00000003 /* bit 1: 16 bits, bit 0: stereo */ #define CM_CH0FMT_SHIFT 0 #define CM_REG_INT_HLDCLR 0x0C #define CM_CHIP_MASK2 0xff000000 +#define CM_CHIP_8768 0x20000000 +#define CM_CHIP_055 0x08000000 #define CM_CHIP_039 0x04000000 #define CM_CHIP_039_6CH 0x01000000 -#define CM_CHIP_055 0x08000000 -#define CM_CHIP_8768 0x20000000 +#define CM_UNKNOWN_INT_EN 0x00080000 /* ? */ #define CM_TDMA_INT_EN 0x00040000 #define CM_CH1_INT_EN 0x00020000 #define CM_CH0_INT_EN 0x00010000 -#define CM_INT_HOLD 0x00000002 -#define CM_INT_CLEAR 0x00000001 #define CM_REG_INT_STATUS 0x10 #define CM_INTR 0x80000000 @@ -178,12 +189,13 @@ MODULE_PARM_DESC(joystick_port, "Joystick port address."); #define CM_CHINT0 0x00000001 #define CM_REG_LEGACY_CTRL 0x14 -#define CM_NXCHG 0x80000000 /* h/w multi channels? */ +#define CM_NXCHG 0x80000000 /* don't map base reg dword->sample */ #define CM_VMPU_MASK 0x60000000 /* MPU401 i/o port address */ #define CM_VMPU_330 0x00000000 #define CM_VMPU_320 0x20000000 #define CM_VMPU_310 0x40000000 #define CM_VMPU_300 0x60000000 +#define CM_ENWR8237 0x10000000 /* enable bus master to write 8237 base reg */ #define CM_VSBSEL_MASK 0x0C000000 /* SB16 base address */ #define CM_VSBSEL_220 0x00000000 #define CM_VSBSEL_240 0x04000000 @@ -194,44 +206,74 @@ MODULE_PARM_DESC(joystick_port, "Joystick port address."); #define CM_FMSEL_3C8 0x01000000 #define CM_FMSEL_3E0 0x02000000 #define CM_FMSEL_3E8 0x03000000 -#define CM_ENSPDOUT 0x00800000 /* enable XPDIF/OUT to I/O interface */ -#define CM_SPDCOPYRHT 0x00400000 /* set copyright spdif in/out */ +#define CM_ENSPDOUT 0x00800000 /* enable XSPDIF/OUT to I/O interface */ +#define CM_SPDCOPYRHT 0x00400000 /* spdif in/out copyright bit */ #define CM_DAC2SPDO 0x00200000 /* enable wave+fm_midi -> SPDIF/OUT */ -#define CM_SETRETRY 0x00010000 /* 0: legacy i/o wait (default), 1: legacy i/o bus retry */ +#define CM_INVIDWEN 0x00100000 /* internal vendor ID write enable, model 039? */ +#define CM_SETRETRY 0x00100000 /* 0: legacy i/o wait (default), 1: legacy i/o bus retry */ +#define CM_C_EEACCESS 0x00080000 /* direct programming eeprom regs */ +#define CM_C_EECS 0x00040000 +#define CM_C_EEDI46 0x00020000 +#define CM_C_EECK46 0x00010000 #define CM_CHB3D6C 0x00008000 /* 5.1 channels support */ -#define CM_LINE_AS_BASS 0x00006000 /* use line-in as bass */ +#define CM_CENTR2LIN 0x00004000 /* line-in as center out */ +#define CM_BASE2LIN 0x00002000 /* line-in as bass out */ +#define CM_EXBASEN 0x00001000 /* external bass input enable */ #define CM_REG_MISC_CTRL 0x18 -#define CM_PWD 0x80000000 +#define CM_PWD 0x80000000 /* power down */ #define CM_RESET 0x40000000 -#define CM_SFIL_MASK 0x30000000 -#define CM_TXVX 0x08000000 -#define CM_N4SPK3D 0x04000000 /* 4ch output */ +#define CM_SFIL_MASK 0x30000000 /* filter control at front end DAC, model 037? */ +#define CM_VMGAIN 0x10000000 /* analog master amp +6dB, model 039? */ +#define CM_TXVX 0x08000000 /* model 037? */ +#define CM_N4SPK3D 0x04000000 /* copy front to rear */ #define CM_SPDO5V 0x02000000 /* 5V spdif output (1 = 0.5v (coax)) */ #define CM_SPDIF48K 0x01000000 /* write */ #define CM_SPATUS48K 0x01000000 /* read */ -#define CM_ENDBDAC 0x00800000 /* enable dual dac */ +#define CM_ENDBDAC 0x00800000 /* enable double dac */ #define CM_XCHGDAC 0x00400000 /* 0: front=ch0, 1: front=ch1 */ #define CM_SPD32SEL 0x00200000 /* 0: 16bit SPDIF, 1: 32bit */ -#define CM_SPDFLOOPI 0x00100000 /* int. SPDIF-IN -> int. OUT */ -#define CM_FM_EN 0x00080000 /* enalbe FM */ +#define CM_SPDFLOOPI 0x00100000 /* int. SPDIF-OUT -> int. IN */ +#define CM_FM_EN 0x00080000 /* enable legacy FM */ #define CM_AC3EN2 0x00040000 /* enable AC3: model 039 */ -#define CM_VIDWPDSB 0x00010000 +#define CM_ENWRASID 0x00010000 /* choose writable internal SUBID (audio) */ +#define CM_VIDWPDSB 0x00010000 /* model 037? */ #define CM_SPDF_AC97 0x00008000 /* 0: SPDIF/OUT 44.1K, 1: 48K */ -#define CM_MASK_EN 0x00004000 -#define CM_VIDWPPRT 0x00002000 -#define CM_SFILENB 0x00001000 -#define CM_MMODE_MASK 0x00000E00 +#define CM_MASK_EN 0x00004000 /* activate channel mask on legacy DMA */ +#define CM_ENWRMSID 0x00002000 /* choose writable internal SUBID (modem) */ +#define CM_VIDWPPRT 0x00002000 /* model 037? */ +#define CM_SFILENB 0x00001000 /* filter stepping at front end DAC, model 037? */ +#define CM_MMODE_MASK 0x00000E00 /* model DAA interface mode */ #define CM_SPDIF_SELECT2 0x00000100 /* for model > 039 ? */ #define CM_ENCENTER 0x00000080 -#define CM_FLINKON 0x00000040 -#define CM_FLINKOFF 0x00000020 -#define CM_MIDSMP 0x00000010 -#define CM_UPDDMA_MASK 0x0000000C -#define CM_TWAIT_MASK 0x00000003 +#define CM_FLINKON 0x00000080 /* force modem link detection on, model 037 */ +#define CM_MUTECH1 0x00000040 /* mute PCI ch1 to DAC */ +#define CM_FLINKOFF 0x00000040 /* force modem link detection off, model 037 */ +#define CM_UNKNOWN_18_5 0x00000020 /* ? */ +#define CM_MIDSMP 0x00000010 /* 1/2 interpolation at front end DAC */ +#define CM_UPDDMA_MASK 0x0000000C /* TDMA position update notification */ +#define CM_UPDDMA_2048 0x00000000 +#define CM_UPDDMA_1024 0x00000004 +#define CM_UPDDMA_512 0x00000008 +#define CM_UPDDMA_256 0x0000000C +#define CM_TWAIT_MASK 0x00000003 /* model 037 */ +#define CM_TWAIT1 0x00000002 /* FM i/o cycle, 0: 48, 1: 64 PCICLKs */ +#define CM_TWAIT0 0x00000001 /* i/o cycle, 0: 4, 1: 6 PCICLKs */ + +#define CM_REG_TDMA_POSITION 0x1C +#define CM_TDMA_CNT_MASK 0xFFFF0000 /* current byte/word count */ +#define CM_TDMA_ADR_MASK 0x0000FFFF /* current address */ /* byte */ #define CM_REG_MIXER0 0x20 +#define CM_REG_SBVR 0x20 /* write: sb16 version */ +#define CM_REG_DEV 0x20 /* read: hardware device version */ + +#define CM_REG_MIXER21 0x21 +#define CM_UNKNOWN_21_MASK 0x78 /* ? */ +#define CM_X_ADPCM 0x04 /* SB16 ADPCM enable */ +#define CM_PROINV 0x02 /* SBPro left/right channel switching */ +#define CM_X_SB16 0x01 /* SB16 compatible */ #define CM_REG_SB16_DATA 0x22 #define CM_REG_SB16_ADDR 0x23 @@ -246,8 +288,8 @@ MODULE_PARM_DESC(joystick_port, "Joystick port address."); #define CM_FMMUTE_SHIFT 7 #define CM_WSMUTE 0x40 /* mute PCM */ #define CM_WSMUTE_SHIFT 6 -#define CM_SPK4 0x20 /* lin-in -> rear line out */ -#define CM_SPK4_SHIFT 5 +#define CM_REAR2LIN 0x20 /* lin-in -> rear line out */ +#define CM_REAR2LIN_SHIFT 5 #define CM_REAR2FRONT 0x10 /* exchange rear/front */ #define CM_REAR2FRONT_SHIFT 4 #define CM_WAVEINL 0x08 /* digital wave rec. left chan */ @@ -279,12 +321,13 @@ MODULE_PARM_DESC(joystick_port, "Joystick port address."); #define CM_VAUXR_MASK 0x0f #define CM_REG_MISC 0x27 +#define CM_UNKNOWN_27_MASK 0xd8 /* ? */ #define CM_XGPO1 0x20 // #define CM_XGPBIO 0x04 #define CM_MIC_CENTER_LFE 0x04 /* mic as center/lfe out? (model 039 or later?) */ #define CM_SPDIF_INVERSE 0x04 /* spdif input phase inverse (model 037) */ #define CM_SPDVALID 0x02 /* spdif input valid check */ -#define CM_DMAUTO 0x01 +#define CM_DMAUTO 0x01 /* SB16 DMA auto detect */ #define CM_REG_AC97 0x28 /* hmmm.. do we have ac97 link? */ /* @@ -325,18 +368,20 @@ MODULE_PARM_DESC(joystick_port, "Joystick port address."); /* * extended registers */ -#define CM_REG_CH0_FRAME1 0x80 /* base address */ -#define CM_REG_CH0_FRAME2 0x84 +#define CM_REG_CH0_FRAME1 0x80 /* write: base address */ +#define CM_REG_CH0_FRAME2 0x84 /* read: current address */ #define CM_REG_CH1_FRAME1 0x88 /* 0-15: count of samples at bus master; buffer size */ #define CM_REG_CH1_FRAME2 0x8C /* 16-31: count of samples at codec; fragment size */ + #define CM_REG_EXT_MISC 0x90 -#define CM_REG_MISC_CTRL_8768 0x92 /* reg. name the same as 0x18 */ -#define CM_CHB3D8C 0x20 /* 7.1 channels support */ -#define CM_SPD32FMT 0x10 /* SPDIF/IN 32k */ -#define CM_ADC2SPDIF 0x08 /* ADC output to SPDIF/OUT */ -#define CM_SHAREADC 0x04 /* DAC in ADC as Center/LFE */ -#define CM_REALTCMP 0x02 /* monitor the CMPL/CMPR of ADC */ -#define CM_INVLRCK 0x01 /* invert ZVPORT's LRCK */ +#define CM_ADC48K44K 0x10000000 /* ADC parameters group, 0: 44k, 1: 48k */ +#define CM_CHB3D8C 0x00200000 /* 7.1 channels support */ +#define CM_SPD32FMT 0x00100000 /* SPDIF/IN 32k sample rate */ +#define CM_ADC2SPDIF 0x00080000 /* ADC output to SPDIF/OUT */ +#define CM_SHAREADC 0x00040000 /* DAC in ADC as Center/LFE */ +#define CM_REALTCMP 0x00020000 /* monitor the CMPL/CMPR of ADC */ +#define CM_INVLRCK 0x00010000 /* invert ZVPORT's LRCK */ +#define CM_UNKNOWN_90_MASK 0x0000FFFF /* ? */ /* * size of i/o region @@ -717,9 +762,9 @@ static int set_dac_channels(struct cmipci *cm, struct cmipci_pcm *rec, int chann } if (cm->chip_version == 68) { if (channels == 8) { - snd_cmipci_set_bit(cm, CM_REG_MISC_CTRL_8768, CM_CHB3D8C); + snd_cmipci_set_bit(cm, CM_REG_EXT_MISC, CM_CHB3D8C); } else { - snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL_8768, CM_CHB3D8C); + snd_cmipci_clear_bit(cm, CM_REG_EXT_MISC, CM_CHB3D8C); } } spin_unlock_irq(&cm->reg_lock); @@ -797,11 +842,11 @@ static int snd_cmipci_pcm_prepare(struct cmipci *cm, struct cmipci_pcm *rec, freq = snd_cmipci_rate_freq(runtime->rate); val = snd_cmipci_read(cm, CM_REG_FUNCTRL1); if (rec->ch) { - val &= ~CM_ASFC_MASK; - val |= (freq << CM_ASFC_SHIFT) & CM_ASFC_MASK; - } else { val &= ~CM_DSFC_MASK; val |= (freq << CM_DSFC_SHIFT) & CM_DSFC_MASK; + } else { + val &= ~CM_ASFC_MASK; + val |= (freq << CM_ASFC_SHIFT) & CM_ASFC_MASK; } snd_cmipci_write(cm, CM_REG_FUNCTRL1, val); //snd_printd("cmipci: functrl1 = %08x\n", val); @@ -2284,8 +2329,8 @@ DEFINE_SWITCH_ARG(exchange_dac, CM_REG_MISC_CTRL, CM_XCHGDAC, 0, 0, 0); /* rever DEFINE_SWITCH_ARG(exchange_dac, CM_REG_MISC_CTRL, CM_XCHGDAC, CM_XCHGDAC, 0, 0); #endif DEFINE_BIT_SWITCH_ARG(fourch, CM_REG_MISC_CTRL, CM_N4SPK3D, 0, 0); -// DEFINE_BIT_SWITCH_ARG(line_rear, CM_REG_MIXER1, CM_SPK4, 1, 0); -// DEFINE_BIT_SWITCH_ARG(line_bass, CM_REG_LEGACY_CTRL, CM_LINE_AS_BASS, 0, 0); +// DEFINE_BIT_SWITCH_ARG(line_rear, CM_REG_MIXER1, CM_REAR2LIN, 1, 0); +// DEFINE_BIT_SWITCH_ARG(line_bass, CM_REG_LEGACY_CTRL, CM_CENTR2LIN|CM_BASE2LIN, 0, 0); // DEFINE_BIT_SWITCH_ARG(joystick, CM_REG_FUNCTRL1, CM_JYSTK_EN, 0, 0); /* now module option */ DEFINE_SWITCH_ARG(modem, CM_REG_MISC_CTRL, CM_FLINKON|CM_FLINKOFF, CM_FLINKON, 0, 0); @@ -2355,11 +2400,11 @@ static inline unsigned int get_line_in_mode(struct cmipci *cm) unsigned int val; if (cm->chip_version >= 39) { val = snd_cmipci_read(cm, CM_REG_LEGACY_CTRL); - if (val & CM_LINE_AS_BASS) + if (val & (CM_CENTR2LIN | CM_BASE2LIN)) return 2; } val = snd_cmipci_read_b(cm, CM_REG_MIXER1); - if (val & CM_SPK4) + if (val & CM_REAR2LIN) return 1; return 0; } @@ -2383,13 +2428,13 @@ static int snd_cmipci_line_in_mode_put(struct snd_kcontrol *kcontrol, spin_lock_irq(&cm->reg_lock); if (ucontrol->value.enumerated.item[0] == 2) - change = snd_cmipci_set_bit(cm, CM_REG_LEGACY_CTRL, CM_LINE_AS_BASS); + change = snd_cmipci_set_bit(cm, CM_REG_LEGACY_CTRL, CM_CENTR2LIN | CM_BASE2LIN); else - change = snd_cmipci_clear_bit(cm, CM_REG_LEGACY_CTRL, CM_LINE_AS_BASS); + change = snd_cmipci_clear_bit(cm, CM_REG_LEGACY_CTRL, CM_CENTR2LIN | CM_BASE2LIN); if (ucontrol->value.enumerated.item[0] == 1) - change |= snd_cmipci_set_bit_b(cm, CM_REG_MIXER1, CM_SPK4); + change |= snd_cmipci_set_bit_b(cm, CM_REG_MIXER1, CM_REAR2LIN); else - change |= snd_cmipci_clear_bit_b(cm, CM_REG_MIXER1, CM_SPK4); + change |= snd_cmipci_clear_bit_b(cm, CM_REG_MIXER1, CM_REAR2LIN); spin_unlock_irq(&cm->reg_lock); return change; } -- cgit v1.2.3 From 54d030cc400ef5565a90e71288c23c0a18299dba Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 17 Sep 2007 09:36:16 +0200 Subject: [ALSA] cmipci: show more registers in proc file Show a dump of all registers in the 0x00-0x27 and 0x90-0x93 ranges in the 'cmipci' proc file. Signed-off-by: Clemens Ladisch Signed-off-by: Jaroslav Kysela --- sound/pci/cmipci.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c index 2d8d3331bb9..12f33718e6d 100644 --- a/sound/pci/cmipci.c +++ b/sound/pci/cmipci.c @@ -2652,19 +2652,18 @@ static void snd_cmipci_proc_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer) { struct cmipci *cm = entry->private_data; - int i; + int i, v; - snd_iprintf(buffer, "%s\n\n", cm->card->longname); - for (i = 0; i < 0x40; i++) { - int v = inb(cm->iobase + i); + snd_iprintf(buffer, "%s\n", cm->card->longname); + for (i = 0; i < 0x94; i++) { + if (i == 0x28) + i = 0x90; + v = inb(cm->iobase + i); if (i % 4 == 0) - snd_iprintf(buffer, "%02x: ", i); - snd_iprintf(buffer, "%02x", v); - if (i % 4 == 3) - snd_iprintf(buffer, "\n"); - else - snd_iprintf(buffer, " "); + snd_iprintf(buffer, "\n%02x:", i); + snd_iprintf(buffer, " %02x", v); } + snd_iprintf(buffer, "\n"); } static void __devinit snd_cmipci_proc_init(struct cmipci *cm) -- cgit v1.2.3 From 3042ef75203947920adc0ab7ae25bc62a1fec978 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 17 Sep 2007 09:36:49 +0200 Subject: [ALSA] cmipci: reset the chip when initializing When the chip is initialized, reset it. Signed-off-by: Clemens Ladisch Signed-off-by: Jaroslav Kysela --- sound/pci/cmipci.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'sound/pci') diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c index 12f33718e6d..8c5c843099c 100644 --- a/sound/pci/cmipci.c +++ b/sound/pci/cmipci.c @@ -2971,6 +2971,8 @@ static int __devinit snd_cmipci_create(struct snd_card *card, struct pci_dev *pc #endif /* initialize codec registers */ + snd_cmipci_set_bit(cm, CM_REG_MISC_CTRL, CM_RESET); + snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_RESET); snd_cmipci_write(cm, CM_REG_INT_HLDCLR, 0); /* disable ints */ snd_cmipci_ch_reset(cm, CM_CH_PLAY); snd_cmipci_ch_reset(cm, CM_CH_CAPT); -- cgit v1.2.3 From 4ee72717188767b127b22f7a582762b71d448408 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 17 Sep 2007 09:37:19 +0200 Subject: [ALSA] cmipci: initialize 0x90 registers Initialize the registers at 0x90 and 0x91 with some undocumented values. Signed-off-by: Clemens Ladisch Signed-off-by: Jaroslav Kysela --- sound/pci/cmipci.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'sound/pci') diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c index 8c5c843099c..c33c1c77869 100644 --- a/sound/pci/cmipci.c +++ b/sound/pci/cmipci.c @@ -2986,6 +2986,10 @@ static int __devinit snd_cmipci_create(struct snd_card *card, struct pci_dev *pc #else snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_XCHGDAC); #endif + if (cm->chip_version) { + snd_cmipci_write_b(cm, CM_REG_EXT_MISC, 0x20); /* magic */ + snd_cmipci_write_b(cm, CM_REG_EXT_MISC + 1, 0x09); /* more magic */ + } /* Set Bus Master Request */ snd_cmipci_set_bit(cm, CM_REG_FUNCTRL1, CM_BREQ); -- cgit v1.2.3 From 22a22f5aacdbb73ca605d34df76201a2df0fe8ac Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 17 Sep 2007 09:37:47 +0200 Subject: [ALSA] cmipci: allow 96 kHz playback on non-multichannel rear Move the code that enables 96 kHz out of the if() that checks for availability of both DMA channels so that it is enabled even when another stream is playing on the front channels. Signed-off-by: Clemens Ladisch Signed-off-by: Jaroslav Kysela --- sound/pci/cmipci.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c index c33c1c77869..51ba704d4bc 100644 --- a/sound/pci/cmipci.c +++ b/sound/pci/cmipci.c @@ -1623,14 +1623,14 @@ static int snd_cmipci_playback2_open(struct snd_pcm_substream *substream) else if (cm->max_channels == 8) snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, &hw_constraints_channels_8); } - if (cm->chip_version == 68) { - runtime->hw.rates |= SNDRV_PCM_RATE_88200 | - SNDRV_PCM_RATE_96000; - runtime->hw.rate_max = 96000; - } - snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 0x10000); } mutex_unlock(&cm->open_mutex); + if (cm->chip_version == 68) { + runtime->hw.rates |= SNDRV_PCM_RATE_88200 | + SNDRV_PCM_RATE_96000; + runtime->hw.rate_max = 96000; + } + snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 0x10000); return 0; } -- cgit v1.2.3 From 35add1c295c634fdbb1072189286e4eab3fd64fa Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 17 Sep 2007 09:39:10 +0200 Subject: [ALSA] cmipci: remove 5.0 format Disallow playback of five channels because the hardware does not support it (or nobody knows how to do it). Signed-off-by: Clemens Ladisch Signed-off-by: Jaroslav Kysela --- sound/pci/cmipci.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c index 51ba704d4bc..c51ea0ef26f 100644 --- a/sound/pci/cmipci.c +++ b/sound/pci/cmipci.c @@ -718,19 +718,19 @@ static int snd_cmipci_hw_free(struct snd_pcm_substream *substream) /* */ -static unsigned int hw_channels[] = {1, 2, 4, 5, 6, 8}; +static unsigned int hw_channels[] = {1, 2, 4, 6, 8}; static struct snd_pcm_hw_constraint_list hw_constraints_channels_4 = { .count = 3, .list = hw_channels, .mask = 0, }; static struct snd_pcm_hw_constraint_list hw_constraints_channels_6 = { - .count = 5, + .count = 4, .list = hw_channels, .mask = 0, }; static struct snd_pcm_hw_constraint_list hw_constraints_channels_8 = { - .count = 6, + .count = 5, .list = hw_channels, .mask = 0, }; -- cgit v1.2.3 From 8ffbc01e2cb2e203df910468f236c7b4e7b36f25 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 17 Sep 2007 09:39:51 +0200 Subject: [ALSA] cmipci: reorganize set_dac_channels() By reorganizing the code that sets the CHB3DxC bits we can not only simplify this code but also fix the bug where the CHB3D8C bit was not reset when playing a stereo stream after a 7.1 stream. Signed-off-by: Clemens Ladisch Signed-off-by: Jaroslav Kysela --- sound/pci/cmipci.c | 49 +++++++++++++++++++------------------------------ 1 file changed, 19 insertions(+), 30 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c index c51ea0ef26f..b4f74ae9c0b 100644 --- a/sound/pci/cmipci.c +++ b/sound/pci/cmipci.c @@ -738,48 +738,37 @@ static struct snd_pcm_hw_constraint_list hw_constraints_channels_8 = { static int set_dac_channels(struct cmipci *cm, struct cmipci_pcm *rec, int channels) { if (channels > 2) { - if (! cm->can_multi_ch) + if (!cm->can_multi_ch || !rec->ch) return -EINVAL; if (rec->fmt != 0x03) /* stereo 16bit only */ return -EINVAL; + } + if (cm->can_multi_ch) { spin_lock_irq(&cm->reg_lock); - snd_cmipci_set_bit(cm, CM_REG_LEGACY_CTRL, CM_NXCHG); - snd_cmipci_set_bit(cm, CM_REG_MISC_CTRL, CM_XCHGDAC); - if (channels > 4) { - snd_cmipci_clear_bit(cm, CM_REG_CHFORMAT, CM_CHB3D); - snd_cmipci_set_bit(cm, CM_REG_CHFORMAT, CM_CHB3D5C); + if (channels > 2) { + snd_cmipci_set_bit(cm, CM_REG_LEGACY_CTRL, CM_NXCHG); + snd_cmipci_set_bit(cm, CM_REG_MISC_CTRL, CM_XCHGDAC); } else { - snd_cmipci_clear_bit(cm, CM_REG_CHFORMAT, CM_CHB3D5C); - snd_cmipci_set_bit(cm, CM_REG_CHFORMAT, CM_CHB3D); + snd_cmipci_clear_bit(cm, CM_REG_LEGACY_CTRL, CM_NXCHG); + snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_XCHGDAC); } - if (channels >= 6) { + if (channels == 8) + snd_cmipci_set_bit(cm, CM_REG_EXT_MISC, CM_CHB3D8C); + else + snd_cmipci_clear_bit(cm, CM_REG_EXT_MISC, CM_CHB3D8C); + if (channels == 6) { + snd_cmipci_set_bit(cm, CM_REG_CHFORMAT, CM_CHB3D5C); snd_cmipci_set_bit(cm, CM_REG_LEGACY_CTRL, CM_CHB3D6C); - snd_cmipci_set_bit(cm, CM_REG_MISC_CTRL, CM_ENCENTER); } else { - snd_cmipci_clear_bit(cm, CM_REG_LEGACY_CTRL, CM_CHB3D6C); - snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_ENCENTER); - } - if (cm->chip_version == 68) { - if (channels == 8) { - snd_cmipci_set_bit(cm, CM_REG_EXT_MISC, CM_CHB3D8C); - } else { - snd_cmipci_clear_bit(cm, CM_REG_EXT_MISC, CM_CHB3D8C); - } - } - spin_unlock_irq(&cm->reg_lock); - - } else { - if (cm->can_multi_ch) { - spin_lock_irq(&cm->reg_lock); - snd_cmipci_clear_bit(cm, CM_REG_LEGACY_CTRL, CM_NXCHG); - snd_cmipci_clear_bit(cm, CM_REG_CHFORMAT, CM_CHB3D); snd_cmipci_clear_bit(cm, CM_REG_CHFORMAT, CM_CHB3D5C); snd_cmipci_clear_bit(cm, CM_REG_LEGACY_CTRL, CM_CHB3D6C); - snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_ENCENTER); - snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_XCHGDAC); - spin_unlock_irq(&cm->reg_lock); } + if (channels == 4) + snd_cmipci_set_bit(cm, CM_REG_CHFORMAT, CM_CHB3D); + else + snd_cmipci_clear_bit(cm, CM_REG_CHFORMAT, CM_CHB3D); + spin_unlock_irq(&cm->reg_lock); } return 0; } -- cgit v1.2.3 From 0f28eca32b3064db29d4718156e692f4db75c7aa Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 17 Sep 2007 09:40:24 +0200 Subject: [ALSA] cmipci: fix lookup of double rates When using one of the double sampling rates, use half the sample rate to look up in the rates[] table, otherwise we stumble over the BUG(). Signed-off-by: Clemens Ladisch Signed-off-by: Jaroslav Kysela --- sound/pci/cmipci.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'sound/pci') diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c index b4f74ae9c0b..7cf4fc19341 100644 --- a/sound/pci/cmipci.c +++ b/sound/pci/cmipci.c @@ -604,6 +604,9 @@ static unsigned int rates[] = { 5512, 11025, 22050, 44100, 8000, 16000, 32000, 4 static unsigned int snd_cmipci_rate_freq(unsigned int rate) { unsigned int i; + + if (rate > 48000) + rate /= 2; for (i = 0; i < ARRAY_SIZE(rates); i++) { if (rates[i] == rate) return i; -- cgit v1.2.3 From ebe9e289d870816b5d5dd6992a253f9a87f26cba Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 17 Sep 2007 09:40:57 +0200 Subject: [ALSA] cmipci: clean up struct cmipci_pcm Remove some unused field from the struct cmipci_pcm, and change the type of some others to save some space. Signed-off-by: Clemens Ladisch Signed-off-by: Jaroslav Kysela --- sound/pci/cmipci.c | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c index 7cf4fc19341..085a36751ac 100644 --- a/sound/pci/cmipci.c +++ b/sound/pci/cmipci.c @@ -431,15 +431,13 @@ MODULE_PARM_DESC(joystick_port, "Joystick port address."); struct cmipci_pcm { struct snd_pcm_substream *substream; - int running; /* dac/adc running? */ + u8 running; /* dac/adc running? */ + u8 fmt; /* format bits */ + u8 is_dac; unsigned int dma_size; /* in frames */ - unsigned int period_size; /* in frames */ + unsigned int shift; + unsigned int ch; /* channel (0/1) */ unsigned int offset; /* physical address of the buffer */ - unsigned int fmt; /* format bits */ - int ch; /* channel (0/1) */ - unsigned int is_dac; /* is dac? */ - int bytes_per_frame; - int shift; }; /* mixer elements toggled/resumed during ac3 playback */ @@ -785,6 +783,7 @@ static int snd_cmipci_pcm_prepare(struct cmipci *cm, struct cmipci_pcm *rec, struct snd_pcm_substream *substream) { unsigned int reg, freq, val; + unsigned int period_size; struct snd_pcm_runtime *runtime = substream->runtime; rec->fmt = 0; @@ -804,11 +803,11 @@ static int snd_cmipci_pcm_prepare(struct cmipci *cm, struct cmipci_pcm *rec, rec->offset = runtime->dma_addr; /* buffer and period sizes in frame */ rec->dma_size = runtime->buffer_size << rec->shift; - rec->period_size = runtime->period_size << rec->shift; + period_size = runtime->period_size << rec->shift; if (runtime->channels > 2) { /* multi-channels */ rec->dma_size = (rec->dma_size * runtime->channels) / 2; - rec->period_size = (rec->period_size * runtime->channels) / 2; + period_size = (period_size * runtime->channels) / 2; } spin_lock_irq(&cm->reg_lock); @@ -819,7 +818,7 @@ static int snd_cmipci_pcm_prepare(struct cmipci *cm, struct cmipci_pcm *rec, /* program sample counts */ reg = rec->ch ? CM_REG_CH1_FRAME2 : CM_REG_CH0_FRAME2; snd_cmipci_write_w(cm, reg, rec->dma_size - 1); - snd_cmipci_write_w(cm, reg + 2, rec->period_size - 1); + snd_cmipci_write_w(cm, reg + 2, period_size - 1); /* set adc/dac flag */ val = rec->ch ? CM_CHADC1 : CM_CHADC0; @@ -875,7 +874,7 @@ static int snd_cmipci_pcm_prepare(struct cmipci *cm, struct cmipci_pcm *rec, * PCM trigger/stop */ static int snd_cmipci_pcm_trigger(struct cmipci *cm, struct cmipci_pcm *rec, - struct snd_pcm_substream *substream, int cmd) + int cmd) { unsigned int inthld, chen, reset, pause; int result = 0; @@ -955,7 +954,7 @@ static int snd_cmipci_playback_trigger(struct snd_pcm_substream *substream, int cmd) { struct cmipci *cm = snd_pcm_substream_chip(substream); - return snd_cmipci_pcm_trigger(cm, &cm->channel[CM_CH_PLAY], substream, cmd); + return snd_cmipci_pcm_trigger(cm, &cm->channel[CM_CH_PLAY], cmd); } static snd_pcm_uframes_t snd_cmipci_playback_pointer(struct snd_pcm_substream *substream) @@ -974,7 +973,7 @@ static int snd_cmipci_capture_trigger(struct snd_pcm_substream *substream, int cmd) { struct cmipci *cm = snd_pcm_substream_chip(substream); - return snd_cmipci_pcm_trigger(cm, &cm->channel[CM_CH_CAPT], substream, cmd); + return snd_cmipci_pcm_trigger(cm, &cm->channel[CM_CH_CAPT], cmd); } static snd_pcm_uframes_t snd_cmipci_capture_pointer(struct snd_pcm_substream *substream) -- cgit v1.2.3 From c36fd8c3cd682fa9bbe5b2cb4b99e16625a37c94 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 17 Sep 2007 09:41:36 +0200 Subject: [ALSA] cmipci: fix distortion on rear channels When playing multichannel data, the rear channels can get distorted if the last sample of the last played stereo stream was not zero. To avoid this, add a hack to play a few silence samples after the stream is stopped. Signed-off-by: Clemens Ladisch Signed-off-by: Jaroslav Kysela --- sound/pci/cmipci.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 67 insertions(+), 1 deletion(-) (limited to 'sound/pci') diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c index 085a36751ac..6832649879c 100644 --- a/sound/pci/cmipci.c +++ b/sound/pci/cmipci.c @@ -434,6 +434,7 @@ struct cmipci_pcm { u8 running; /* dac/adc running? */ u8 fmt; /* format bits */ u8 is_dac; + u8 needs_silencing; unsigned int dma_size; /* in frames */ unsigned int shift; unsigned int ch; /* channel (0/1) */ @@ -903,6 +904,7 @@ static int snd_cmipci_pcm_trigger(struct cmipci *cm, struct cmipci_pcm *rec, cm->ctrl &= ~chen; snd_cmipci_write(cm, CM_REG_FUNCTRL0, cm->ctrl | reset); snd_cmipci_write(cm, CM_REG_FUNCTRL0, cm->ctrl & ~reset); + rec->needs_silencing = rec->is_dac; break; case SNDRV_PCM_TRIGGER_PAUSE_PUSH: case SNDRV_PCM_TRIGGER_SUSPEND: @@ -1304,11 +1306,75 @@ static int snd_cmipci_playback_spdif_prepare(struct snd_pcm_substream *substream return snd_cmipci_pcm_prepare(cm, &cm->channel[CM_CH_PLAY], substream); } +/* + * Apparently, the samples last played on channel A stay in some buffer, even + * after the channel is reset, and get added to the data for the rear DACs when + * playing a multichannel stream on channel B. This is likely to generate + * wraparounds and thus distortions. + * To avoid this, we play at least one zero sample after the actual stream has + * stopped. + */ +static void snd_cmipci_silence_hack(struct cmipci *cm, struct cmipci_pcm *rec) +{ + struct snd_pcm_runtime *runtime = rec->substream->runtime; + unsigned int reg, val; + + if (rec->needs_silencing && runtime && runtime->dma_area) { + /* set up a small silence buffer */ + memset(runtime->dma_area, 0, PAGE_SIZE); + reg = rec->ch ? CM_REG_CH1_FRAME2 : CM_REG_CH0_FRAME2; + val = ((PAGE_SIZE / 4) - 1) | (((PAGE_SIZE / 4) / 2 - 1) << 16); + snd_cmipci_write(cm, reg, val); + + /* configure for 16 bits, 2 channels, 8 kHz */ + if (runtime->channels > 2) + set_dac_channels(cm, rec, 2); + spin_lock_irq(&cm->reg_lock); + val = snd_cmipci_read(cm, CM_REG_FUNCTRL1); + val &= ~(CM_ASFC_MASK << (rec->ch * 3)); + val |= (4 << CM_ASFC_SHIFT) << (rec->ch * 3); + snd_cmipci_write(cm, CM_REG_FUNCTRL1, val); + val = snd_cmipci_read(cm, CM_REG_CHFORMAT); + val &= ~(CM_CH0FMT_MASK << (rec->ch * 2)); + val |= (3 << CM_CH0FMT_SHIFT) << (rec->ch * 2); + if (cm->chip_version == 68) { + val &= ~(CM_CH0_SRATE_88K << (rec->ch * 2)); + val &= ~(CM_CH0_SRATE_96K << (rec->ch * 2)); + } + snd_cmipci_write(cm, CM_REG_CHFORMAT, val); + + /* start stream (we don't need interrupts) */ + cm->ctrl |= CM_CHEN0 << rec->ch; + snd_cmipci_write(cm, CM_REG_FUNCTRL0, cm->ctrl); + spin_unlock_irq(&cm->reg_lock); + + msleep(1); + + /* stop and reset stream */ + spin_lock_irq(&cm->reg_lock); + cm->ctrl &= ~(CM_CHEN0 << rec->ch); + val = CM_RST_CH0 << rec->ch; + snd_cmipci_write(cm, CM_REG_FUNCTRL0, cm->ctrl | val); + snd_cmipci_write(cm, CM_REG_FUNCTRL0, cm->ctrl & ~val); + spin_unlock_irq(&cm->reg_lock); + + rec->needs_silencing = 0; + } +} + static int snd_cmipci_playback_hw_free(struct snd_pcm_substream *substream) { struct cmipci *cm = snd_pcm_substream_chip(substream); setup_spdif_playback(cm, substream, 0, 0); restore_mixer_state(cm); + snd_cmipci_silence_hack(cm, &cm->channel[0]); + return snd_cmipci_hw_free(substream); +} + +static int snd_cmipci_playback2_hw_free(struct snd_pcm_substream *substream) +{ + struct cmipci *cm = snd_pcm_substream_chip(substream); + snd_cmipci_silence_hack(cm, &cm->channel[1]); return snd_cmipci_hw_free(substream); } @@ -1736,7 +1802,7 @@ static struct snd_pcm_ops snd_cmipci_playback2_ops = { .close = snd_cmipci_playback2_close, .ioctl = snd_pcm_lib_ioctl, .hw_params = snd_cmipci_playback2_hw_params, - .hw_free = snd_cmipci_hw_free, + .hw_free = snd_cmipci_playback2_hw_free, .prepare = snd_cmipci_capture_prepare, /* channel B */ .trigger = snd_cmipci_capture_trigger, /* channel B */ .pointer = snd_cmipci_capture_pointer, /* channel B */ -- cgit v1.2.3 From b201131c43c155c62e799d9410708d10b2c9a6ad Mon Sep 17 00:00:00 2001 From: Tobin Davis Date: Mon, 17 Sep 2007 12:45:11 +0200 Subject: [ALSA] hda-codec: Add 4 channel support for Realtek ALC883 I had a request for a 4 channel mode. This should implement front and surround outputs, leaving the 3rd plug for mic input. Signed-off-by: Tobin Davis Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_realtek.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index e8270862e1e..93ff155f594 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -6086,6 +6086,18 @@ static struct hda_verb alc883_3ST_ch2_init[] = { { } /* end */ }; +/* + * 4ch mode + */ +static struct hda_verb alc883_3ST_ch4_init[] = { + { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, + { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, + { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, + { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, + { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, + { } /* end */ +}; + /* * 6ch mode */ @@ -6099,8 +6111,9 @@ static struct hda_verb alc883_3ST_ch6_init[] = { { } /* end */ }; -static struct hda_channel_mode alc883_3ST_6ch_modes[2] = { +static struct hda_channel_mode alc883_3ST_6ch_modes[3] = { { 2, alc883_3ST_ch2_init }, + { 4, alc883_3ST_ch4_init }, { 6, alc883_3ST_ch6_init }, }; -- cgit v1.2.3 From 11370ee2c1c578a704f47d5513d57274c335db43 Mon Sep 17 00:00:00 2001 From: Tobin Davis Date: Mon, 17 Sep 2007 12:46:12 +0200 Subject: [ALSA] hda-codec: Add two new systems to ALC883 This patch adds support for the Asus M2A-VM HDMI and Abit IP35-PRO motherboards. Signed-off-by: Tobin Davis Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_realtek.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 93ff155f594..b642c8bf162 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -7054,6 +7054,8 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = { SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2), SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66), SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763), + SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG), + SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG), {} }; -- cgit v1.2.3 From 22d3a20030439420bf2795c60529ba0e89b4d82c Mon Sep 17 00:00:00 2001 From: Giuliano Pochini Date: Mon, 17 Sep 2007 12:49:40 +0200 Subject: [ALSA] echoaudio - Add barrier() to prevent compiler optimization This patch adds a barrier() to prevent the compiler from moving the read outside of the loop. It also fixes a comment. Signed-off-by: Giuliano Pochini Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/echoaudio/echoaudio_dsp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/echoaudio/echoaudio_dsp.c b/sound/pci/echoaudio/echoaudio_dsp.c index 42afa837d9b..e6c10077039 100644 --- a/sound/pci/echoaudio/echoaudio_dsp.c +++ b/sound/pci/echoaudio/echoaudio_dsp.c @@ -43,11 +43,11 @@ static int wait_handshake(struct echoaudio *chip) { int i; - /* Wait up to 10ms for the handshake from the DSP */ + /* Wait up to 20ms for the handshake from the DSP */ for (i = 0; i < HANDSHAKE_TIMEOUT; i++) { /* Look for the handshake value */ + barrier(); if (chip->comm_page->handshake) { - /*if (i) DE_ACT(("Handshake time: %d\n", i));*/ return 0; } udelay(1); -- cgit v1.2.3 From 50f47ff1b9295f126a1256d607e5b6e951d6f34e Mon Sep 17 00:00:00 2001 From: Matthias Kaehlcke Date: Mon, 17 Sep 2007 14:39:05 +0200 Subject: [ALSA] ESS Maestro 1/2/2E Sound Card: Use list_for_each_entry ESS Maestro 1/2/2E Sound Card: Use list_for_each_entry instead of list_for_each Signed-off-by: Matthias Kaehlcke Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/es1968.c | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c index 2faf009076b..d69b11d1f99 100644 --- a/sound/pci/es1968.c +++ b/sound/pci/es1968.c @@ -843,10 +843,9 @@ static void snd_es1968_bob_dec(struct es1968 *chip) snd_es1968_bob_stop(chip); else if (chip->bob_freq > ESM_BOB_FREQ) { /* check reduction of timer frequency */ - struct list_head *p; int max_freq = ESM_BOB_FREQ; - list_for_each(p, &chip->substream_list) { - struct esschan *es = list_entry(p, struct esschan, list); + struct esschan *es; + list_for_each_entry(es, &chip->substream_list, list) { if (max_freq < es->bob_freq) max_freq = es->bob_freq; } @@ -1316,12 +1315,11 @@ static struct snd_pcm_hardware snd_es1968_capture = { static int calc_available_memory_size(struct es1968 *chip) { - struct list_head *p; int max_size = 0; - + struct esm_memory *buf; + mutex_lock(&chip->memory_mutex); - list_for_each(p, &chip->buf_list) { - struct esm_memory *buf = list_entry(p, struct esm_memory, list); + list_for_each_entry(buf, &chip->buf_list, list) { if (buf->empty && buf->buf.bytes > max_size) max_size = buf->buf.bytes; } @@ -1335,12 +1333,10 @@ static int calc_available_memory_size(struct es1968 *chip) static struct esm_memory *snd_es1968_new_memory(struct es1968 *chip, int size) { struct esm_memory *buf; - struct list_head *p; - + size = ALIGN(size, ESM_MEM_ALIGN); mutex_lock(&chip->memory_mutex); - list_for_each(p, &chip->buf_list) { - buf = list_entry(p, struct esm_memory, list); + list_for_each_entry(buf, &chip->buf_list, list) { if (buf->empty && buf->buf.bytes >= size) goto __found; } @@ -1938,10 +1934,9 @@ static irqreturn_t snd_es1968_interrupt(int irq, void *dev_id) } if (event & ESM_SOUND_IRQ) { - struct list_head *p; + struct esschan *es; spin_lock(&chip->substream_lock); - list_for_each(p, &chip->substream_list) { - struct esschan *es = list_entry(p, struct esschan, list); + list_for_each_entry(es, &chip->substream_list, list) { if (es->running) snd_es1968_update_pcm(chip, es); } @@ -2345,7 +2340,7 @@ static int es1968_resume(struct pci_dev *pci) { struct snd_card *card = pci_get_drvdata(pci); struct es1968 *chip = card->private_data; - struct list_head *p; + struct esschan *es; if (! chip->do_pm) return 0; @@ -2374,8 +2369,7 @@ static int es1968_resume(struct pci_dev *pci) /* restore ac97 state */ snd_ac97_resume(chip->ac97); - list_for_each(p, &chip->substream_list) { - struct esschan *es = list_entry(p, struct esschan, list); + list_for_each_entry(es, &chip->substream_list, list) { switch (es->mode) { case ESM_MODE_PLAY: snd_es1968_playback_setup(chip, es, es->substream->runtime); -- cgit v1.2.3 From 33206e862edb930615a586f5156c2760ddb4bac0 Mon Sep 17 00:00:00 2001 From: Matthias Kaehlcke Date: Mon, 17 Sep 2007 14:40:04 +0200 Subject: [ALSA] Intel HD Audio: Use list_for_each_entry(_safe) Intel HD Audio: Use list_for_each_entry(_safe) instead of list_for_each(_safe) Signed-off-by: Matthias Kaehlcke Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/hda_generic.c | 25 +++++++------------------ sound/pci/hda/hda_intel.c | 7 ++----- 2 files changed, 9 insertions(+), 23 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c index 819c804a579..c957eb58de5 100644 --- a/sound/pci/hda/hda_generic.c +++ b/sound/pci/hda/hda_generic.c @@ -95,13 +95,12 @@ struct hda_gspec { static void snd_hda_generic_free(struct hda_codec *codec) { struct hda_gspec *spec = codec->spec; - struct list_head *p, *n; + struct hda_gnode *node, *n; if (! spec) return; /* free all widgets */ - list_for_each_safe(p, n, &spec->nid_list) { - struct hda_gnode *node = list_entry(p, struct hda_gnode, list); + list_for_each_entry_safe(node, n, &spec->nid_list, list) { if (node->conn_list != node->slist) kfree(node->conn_list); kfree(node); @@ -203,11 +202,9 @@ static int build_afg_tree(struct hda_codec *codec) /* FIXME: should avoid the braindead linear search */ static struct hda_gnode *hda_get_node(struct hda_gspec *spec, hda_nid_t nid) { - struct list_head *p; struct hda_gnode *node; - list_for_each(p, &spec->nid_list) { - node = list_entry(p, struct hda_gnode, list); + list_for_each_entry(node, &spec->nid_list, list) { if (node->nid == nid) return node; } @@ -260,11 +257,9 @@ static int select_input_connection(struct hda_codec *codec, struct hda_gnode *no */ static void clear_check_flags(struct hda_gspec *spec) { - struct list_head *p; struct hda_gnode *node; - list_for_each(p, &spec->nid_list) { - node = list_entry(p, struct hda_gnode, list); + list_for_each_entry(node, &spec->nid_list, list) { node->checked = 0; } } @@ -347,12 +342,10 @@ static struct hda_gnode *parse_output_jack(struct hda_codec *codec, struct hda_gspec *spec, int jack_type) { - struct list_head *p; struct hda_gnode *node; int err; - list_for_each(p, &spec->nid_list) { - node = list_entry(p, struct hda_gnode, list); + list_for_each_entry(node, &spec->nid_list, list) { if (node->type != AC_WID_PIN) continue; /* output capable? */ @@ -664,7 +657,6 @@ static int parse_input_path(struct hda_codec *codec, struct hda_gnode *adc_node) static int parse_input(struct hda_codec *codec) { struct hda_gspec *spec = codec->spec; - struct list_head *p; struct hda_gnode *node; int err; @@ -673,8 +665,7 @@ static int parse_input(struct hda_codec *codec) * If it reaches to certain input PINs, we take it as the * input path. */ - list_for_each(p, &spec->nid_list) { - node = list_entry(p, struct hda_gnode, list); + list_for_each_entry(node, &spec->nid_list, list) { if (node->wid_caps & AC_WCAP_DIGITAL) continue; /* skip SPDIF */ if (node->type == AC_WID_AUD_IN) { @@ -943,7 +934,6 @@ static int parse_loopback_path(struct hda_codec *codec, struct hda_gspec *spec, static int build_loopback_controls(struct hda_codec *codec) { struct hda_gspec *spec = codec->spec; - struct list_head *p; struct hda_gnode *node; int err; const char *type; @@ -951,8 +941,7 @@ static int build_loopback_controls(struct hda_codec *codec) if (! spec->out_pin_node[0]) return 0; - list_for_each(p, &spec->nid_list) { - node = list_entry(p, struct hda_gnode, list); + list_for_each_entry(node, &spec->nid_list, list) { if (node->type != AC_WID_PIN) continue; /* input capable? */ diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 68dc9a2e3cf..cbb3da408e8 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -1393,7 +1393,6 @@ static int __devinit create_codec_pcm(struct azx *chip, struct hda_codec *codec, static int __devinit azx_pcm_create(struct azx *chip) { - struct list_head *p; struct hda_codec *codec; int c, err; int pcm_dev; @@ -1404,8 +1403,7 @@ static int __devinit azx_pcm_create(struct azx *chip) /* create audio PCMs */ pcm_dev = 0; - list_for_each(p, &chip->bus->codec_list) { - codec = list_entry(p, struct hda_codec, list); + list_for_each_entry(codec, &chip->bus->codec_list, list) { for (c = 0; c < codec->num_pcms; c++) { if (codec->pcm_info[c].is_modem) continue; /* create later */ @@ -1424,8 +1422,7 @@ static int __devinit azx_pcm_create(struct azx *chip) /* create modem PCMs */ pcm_dev = AZX_MAX_AUDIO_PCMS; - list_for_each(p, &chip->bus->codec_list) { - codec = list_entry(p, struct hda_codec, list); + list_for_each_entry(codec, &chip->bus->codec_list, list) { for (c = 0; c < codec->num_pcms; c++) { if (!codec->pcm_info[c].is_modem) continue; /* already created */ -- cgit v1.2.3 From c2d7051ed1727e6a7b0debe448b5f6ba915e246b Mon Sep 17 00:00:00 2001 From: Matthias Kaehlcke Date: Mon, 17 Sep 2007 14:41:16 +0200 Subject: [ALSA] Routines for effect processor FX8010: Use list_for_each_entry Routines for effect processor FX8010: Use list_for_each_entry instead of list_for_each Signed-off-by: Matthias Kaehlcke Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/emu10k1/emufx.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/emu10k1/emufx.c b/sound/pci/emu10k1/emufx.c index 5967e60119f..3c503bb92d2 100644 --- a/sound/pci/emu10k1/emufx.c +++ b/sound/pci/emu10k1/emufx.c @@ -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) { -- cgit v1.2.3 From 7a5a27cfaedf8589600b7ae585f3ca42b2d3c78a Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Sep 2007 19:07:46 +0200 Subject: [ALSA] Add default values for power-saving as Kconfig options Added CONFIG_SND_AC97_POWER_SAVE_DEFAULT and CONFIG_SND_HDA_POWER_SAVE_DEFAULT Kconfig options as the default values for power-saving mode of AC97 and HD-audio drivers, respectively. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/Kconfig | 15 +++++++++++++++ sound/pci/ac97/ac97_codec.c | 2 +- sound/pci/hda/hda_codec.c | 2 +- 3 files changed, 17 insertions(+), 2 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig index 5d0732c09f2..2c6486c23a5 100644 --- a/sound/pci/Kconfig +++ b/sound/pci/Kconfig @@ -589,6 +589,14 @@ config SND_HDA_POWER_SAVE HD-audio driver. The power-saving timeout can be configured via power_save option or over sysfs on-the-fly. +config SND_HDA_POWER_SAVE_DEFAULT + int "Default time-out for HD-audio power-save mode" + depends on SND_HDA_POWER_SAVE + default 0 + help + The default time-out value in seconds for HD-audio automatic + power-save mode. 0 means to disable the power-save mode. + config SND_HDSP tristate "RME Hammerfall DSP Audio" depends on SND @@ -888,4 +896,11 @@ config SND_AC97_POWER_SAVE snd-ac97-codec driver. You can toggle it dynamically over sysfs, too. +config SND_AC97_POWER_SAVE_DEFAULT + int "Default time-out for AC97 power-save mode" + depends on SND_AC97_POWER_SAVE + default 0 + The default time-out value in seconds for AC97 automatic + power-save mode. 0 means to disable the power-save mode. + endmenu diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c index 3e5ff29fc49..0906f1717f2 100644 --- a/sound/pci/ac97/ac97_codec.c +++ b/sound/pci/ac97/ac97_codec.c @@ -49,7 +49,7 @@ module_param(enable_loopback, bool, 0444); MODULE_PARM_DESC(enable_loopback, "Enable AC97 ADC/DAC Loopback Control"); #ifdef CONFIG_SND_AC97_POWER_SAVE -static int power_save; +static int power_save = CONFIG_SND_AC97_POWER_SAVE_DEFAULT; module_param(power_save, bool, 0644); MODULE_PARM_DESC(power_save, "Enable AC97 power-saving control"); #endif diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 535bcb7601b..18ef0aa69d9 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -35,7 +35,7 @@ #ifdef CONFIG_SND_HDA_POWER_SAVE /* define this option here to hide as static */ -static int power_save = 10; +static int power_save = CONFIG_SND_HDA_POWER_SAVE_DEFAULT; module_param(power_save, int, 0644); MODULE_PARM_DESC(power_save, "Automatic power-saving timeout " "(in second, 0 = disable)."); -- cgit v1.2.3 From b44ef2f1544a0a8d3d8907890662924082d0f1fa Mon Sep 17 00:00:00 2001 From: Matthew Ranostay Date: Tue, 18 Sep 2007 00:52:38 +0200 Subject: [ALSA] hda: More subsystem id BIOS changes More laptop BIOS changes the subsystem id for STAC9205 cards if the microphone is toggled on/off in the settings. The patch removes the old STAC_9205_M43xx and use STAC_9205_DELL_M43. Signed-off-by: Matthew Ranostay Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_sigmatel.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 2feb0f2e38c..27360d278bc 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -57,7 +57,6 @@ enum { STAC_9205_DELL_M42, STAC_9205_DELL_M43, STAC_9205_DELL_M44, - STAC_9205_M43xx, STAC_9205_MODELS }; @@ -1163,7 +1162,6 @@ static unsigned int *stac9205_brd_tbl[STAC_9205_MODELS] = { [STAC_9205_DELL_M42] = dell_9205_m42_pin_configs, [STAC_9205_DELL_M43] = dell_9205_m43_pin_configs, [STAC_9205_DELL_M44] = dell_9205_m44_pin_configs, - [STAC_9205_M43xx] = NULL, }; static const char *stac9205_models[STAC_9205_MODELS] = { @@ -1182,7 +1180,9 @@ static struct snd_pci_quirk stac9205_cfg_tbl[] = { SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f2, "unknown Dell", STAC_9205_DELL_M42), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f8, - "Dell Precision", STAC_9205_M43xx), + "Dell Precision", STAC_9205_DELL_M43), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021c, + "Dell Precision", STAC_9205_DELL_M43), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f9, "Dell Precision", STAC_9205_DELL_M43), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021b, @@ -2807,7 +2807,6 @@ static int patch_stac9205(struct hda_codec *codec) spec->multiout.dac_nids = spec->dac_nids; switch (spec->board_config){ - case STAC_9205_M43xx: case STAC_9205_DELL_M43: /* Enable SPDIF in/out */ stac92xx_set_config_reg(codec, 0x1f, 0x01441030); -- cgit v1.2.3 From d86d01935a4c4c818514d8c23579703abd768329 Mon Sep 17 00:00:00 2001 From: Rene Herman Date: Tue, 18 Sep 2007 18:10:49 +0200 Subject: [ALSA] alsa-kernel: schedule_timeout() fixes Fix schedule_timeout() use in alsa-kernel. Mostly just schedule_timeout(1) --> schedule_timeout_uninterruptible(1) The wavefront_synth one fixes the surrounding loop as well. In ymfpci_main, delete a superfluous set_current_state() and in soc/soc-dapm.c replace an _interruptible with _uninterruptible in some debug code; it's not waiting for signals. Signed-off-by: Rene Herman Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/hda_intel.c | 2 +- sound/pci/via82xx.c | 4 ++-- sound/pci/via82xx_modem.c | 4 ++-- sound/pci/ymfpci/ymfpci_main.c | 1 - 4 files changed, 5 insertions(+), 6 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index cbb3da408e8..4e3474c2b66 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -555,7 +555,7 @@ static unsigned int azx_rirb_get_response(struct hda_codec *codec) } if (!chip->rirb.cmds) return chip->rirb.res; /* the last value */ - schedule_timeout(1); + schedule_timeout_uninterruptible(1); } while (time_after_eq(timeout, jiffies)); if (chip->msi) { diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c index 5faa57956ca..45d89deb64e 100644 --- a/sound/pci/via82xx.c +++ b/sound/pci/via82xx.c @@ -2090,7 +2090,7 @@ static int snd_via82xx_chip_init(struct via82xx *chip) pci_read_config_byte(chip->pci, VIA_ACLINK_STAT, &pval); if (pval & VIA_ACLINK_C00_READY) /* primary codec ready */ break; - schedule_timeout(1); + schedule_timeout_uninterruptible(1); } while (time_before(jiffies, end_time)); if ((val = snd_via82xx_codec_xread(chip)) & VIA_REG_AC97_BUSY) @@ -2109,7 +2109,7 @@ static int snd_via82xx_chip_init(struct via82xx *chip) chip->ac97_secondary = 1; goto __ac97_ok2; } - schedule_timeout(1); + schedule_timeout_uninterruptible(1); } while (time_before(jiffies, end_time)); /* This is ok, the most of motherboards have only one codec */ diff --git a/sound/pci/via82xx_modem.c b/sound/pci/via82xx_modem.c index 72425e73aba..3aa9d31d999 100644 --- a/sound/pci/via82xx_modem.c +++ b/sound/pci/via82xx_modem.c @@ -983,7 +983,7 @@ static int snd_via82xx_chip_init(struct via82xx_modem *chip) pci_read_config_byte(chip->pci, VIA_ACLINK_STAT, &pval); if (pval & VIA_ACLINK_C00_READY) /* primary codec ready */ break; - schedule_timeout(1); + schedule_timeout_uninterruptible(1); } while (time_before(jiffies, end_time)); if ((val = snd_via82xx_codec_xread(chip)) & VIA_REG_AC97_BUSY) @@ -1001,7 +1001,7 @@ static int snd_via82xx_chip_init(struct via82xx_modem *chip) chip->ac97_secondary = 1; goto __ac97_ok2; } - schedule_timeout(1); + schedule_timeout_uninterruptible(1); } while (time_before(jiffies, end_time)); /* This is ok, the most of motherboards have only one codec */ diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c index e33e4aa6855..e76ed5dfc86 100644 --- a/sound/pci/ymfpci/ymfpci_main.c +++ b/sound/pci/ymfpci/ymfpci_main.c @@ -84,7 +84,6 @@ static int snd_ymfpci_codec_ready(struct snd_ymfpci *chip, int secondary) do { if ((snd_ymfpci_readw(chip, reg) & 0x8000) == 0) return 0; - set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout_uninterruptible(1); } while (time_before(jiffies, end_time)); snd_printk(KERN_ERR "codec_ready: codec %i is not ready [0x%x]\n", secondary, snd_ymfpci_readw(chip, reg)); -- cgit v1.2.3 From 13043984e7e3952b0030ec8f27eb1e66b6529770 Mon Sep 17 00:00:00 2001 From: Keita Maehara Date: Wed, 19 Sep 2007 14:27:38 +0200 Subject: [ALSA] ac97: YMF743 missing controls support (1/2) These patches enable some YMF743 controls (Tone/3D/IEC958) that won't be detected with the current version of ALSA. The first one contains only cosmetic changes to share a few YMF753-specific symbols with YMF743. Signed-off-by: Keita Maehara Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/ac97/ac97_patch.c | 70 ++++++++++++++++++++++++++++----------------- 1 file changed, 43 insertions(+), 27 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c index 630c961895d..075ac4e14bc 100644 --- a/sound/pci/ac97/ac97_patch.c +++ b/sound/pci/ac97/ac97_patch.c @@ -205,8 +205,11 @@ static inline int is_shared_micin(struct snd_ac97 *ac97) /* The following snd_ac97_ymf753_... items added by David Shust (dshust@shustring.com) */ -/* It is possible to indicate to the Yamaha YMF753 the type of speakers being used. */ -static int snd_ac97_ymf753_info_speaker(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) +/* It is possible to indicate to the Yamaha YMF7x3 the type of + speakers being used. */ + +static int snd_ac97_ymf7x3_info_speaker(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) { static char *texts[3] = { "Standard", "Small", "Smaller" @@ -221,12 +224,13 @@ static int snd_ac97_ymf753_info_speaker(struct snd_kcontrol *kcontrol, struct sn return 0; } -static int snd_ac97_ymf753_get_speaker(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int snd_ac97_ymf7x3_get_speaker(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); unsigned short val; - val = ac97->regs[AC97_YMF753_3D_MODE_SEL]; + val = ac97->regs[AC97_YMF7X3_3D_MODE_SEL]; val = (val >> 10) & 3; if (val > 0) /* 0 = invalid */ val--; @@ -234,7 +238,8 @@ static int snd_ac97_ymf753_get_speaker(struct snd_kcontrol *kcontrol, struct snd return 0; } -static int snd_ac97_ymf753_put_speaker(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int snd_ac97_ymf7x3_put_speaker(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); unsigned short val; @@ -242,20 +247,22 @@ static int snd_ac97_ymf753_put_speaker(struct snd_kcontrol *kcontrol, struct snd if (ucontrol->value.enumerated.item[0] > 2) return -EINVAL; val = (ucontrol->value.enumerated.item[0] + 1) << 10; - return snd_ac97_update(ac97, AC97_YMF753_3D_MODE_SEL, val); + return snd_ac97_update(ac97, AC97_YMF7X3_3D_MODE_SEL, val); } -static const struct snd_kcontrol_new snd_ac97_ymf753_controls_speaker = +static const struct snd_kcontrol_new snd_ac97_ymf7x3_controls_speaker = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "3D Control - Speaker", - .info = snd_ac97_ymf753_info_speaker, - .get = snd_ac97_ymf753_get_speaker, - .put = snd_ac97_ymf753_put_speaker, + .info = snd_ac97_ymf7x3_info_speaker, + .get = snd_ac97_ymf7x3_get_speaker, + .put = snd_ac97_ymf7x3_put_speaker, }; -/* It is possible to indicate to the Yamaha YMF753 the source to direct to the S/PDIF output. */ -static int snd_ac97_ymf753_spdif_source_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) +/* It is possible to indicate to the Yamaha YMF7x3 the source to + direct to the S/PDIF output. */ +static int snd_ac97_ymf7x3_spdif_source_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) { static char *texts[2] = { "AC-Link", "A/D Converter" }; @@ -268,17 +275,19 @@ static int snd_ac97_ymf753_spdif_source_info(struct snd_kcontrol *kcontrol, stru return 0; } -static int snd_ac97_ymf753_spdif_source_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int snd_ac97_ymf7x3_spdif_source_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); unsigned short val; - val = ac97->regs[AC97_YMF753_DIT_CTRL2]; + val = ac97->regs[AC97_YMF7X3_DIT_CTRL]; ucontrol->value.enumerated.item[0] = (val >> 1) & 1; return 0; } -static int snd_ac97_ymf753_spdif_source_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int snd_ac97_ymf7x3_spdif_source_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); unsigned short val; @@ -286,7 +295,7 @@ static int snd_ac97_ymf753_spdif_source_put(struct snd_kcontrol *kcontrol, struc if (ucontrol->value.enumerated.item[0] > 1) return -EINVAL; val = ucontrol->value.enumerated.item[0] << 1; - return snd_ac97_update_bits(ac97, AC97_YMF753_DIT_CTRL2, 0x0002, val); + return snd_ac97_update_bits(ac97, AC97_YMF7X3_DIT_CTRL, 0x0002, val); } /* The AC'97 spec states that the S/PDIF signal is to be output at pin 48. @@ -311,7 +320,7 @@ static int snd_ac97_ymf753_spdif_output_pin_get(struct snd_kcontrol *kcontrol, s struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); unsigned short val; - val = ac97->regs[AC97_YMF753_DIT_CTRL2]; + val = ac97->regs[AC97_YMF7X3_DIT_CTRL]; ucontrol->value.enumerated.item[0] = (val & 0x0008) ? 2 : (val & 0x0020) ? 1 : 0; return 0; } @@ -325,7 +334,7 @@ static int snd_ac97_ymf753_spdif_output_pin_put(struct snd_kcontrol *kcontrol, s return -EINVAL; val = (ucontrol->value.enumerated.item[0] == 2) ? 0x0008 : (ucontrol->value.enumerated.item[0] == 1) ? 0x0020 : 0; - return snd_ac97_update_bits(ac97, AC97_YMF753_DIT_CTRL2, 0x0028, val); + return snd_ac97_update_bits(ac97, AC97_YMF7X3_DIT_CTRL, 0x0028, val); /* The following can be used to direct S/PDIF output to pin 47 (EAPD). snd_ac97_write_cache(ac97, 0x62, snd_ac97_read(ac97, 0x62) | 0x0008); */ } @@ -334,9 +343,9 @@ static const struct snd_kcontrol_new snd_ac97_ymf753_controls_spdif[3] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source", - .info = snd_ac97_ymf753_spdif_source_info, - .get = snd_ac97_ymf753_spdif_source_get, - .put = snd_ac97_ymf753_spdif_source_put, + .info = snd_ac97_ymf7x3_spdif_source_info, + .get = snd_ac97_ymf7x3_spdif_source_get, + .put = snd_ac97_ymf7x3_spdif_source_put, }, { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, @@ -345,22 +354,29 @@ static const struct snd_kcontrol_new snd_ac97_ymf753_controls_spdif[3] = { .get = snd_ac97_ymf753_spdif_output_pin_get, .put = snd_ac97_ymf753_spdif_output_pin_put, }, - AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",NONE,NONE) "Mute", AC97_YMF753_DIT_CTRL2, 2, 1, 1) + AC97_SINGLE(SNDRV_CTL_NAME_IEC958("", NONE, NONE) "Mute", + AC97_YMF7X3_DIT_CTRL, 2, 1, 1) }; -static int patch_yamaha_ymf753_3d(struct snd_ac97 * ac97) +static int patch_yamaha_ymf7x3_3d(struct snd_ac97 *ac97) { struct snd_kcontrol *kctl; int err; - if ((err = snd_ctl_add(ac97->bus->card, kctl = snd_ac97_cnew(&snd_ac97_controls_3d[0], ac97))) < 0) + kctl = snd_ac97_cnew(&snd_ac97_controls_3d[0], ac97); + err = snd_ctl_add(ac97->bus->card, kctl); + if (err < 0) return err; strcpy(kctl->id.name, "3D Control - Wide"); kctl->private_value = AC97_SINGLE_VALUE(AC97_3D_CONTROL, 9, 7, 0); snd_ac97_write_cache(ac97, AC97_3D_CONTROL, 0x0000); - if ((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&snd_ac97_ymf753_controls_speaker, ac97))) < 0) + + err = snd_ctl_add(ac97->bus->card, + snd_ac97_cnew(&snd_ac97_ymf7x3_controls_speaker, + ac97)); + if (err < 0) return err; - snd_ac97_write_cache(ac97, AC97_YMF753_3D_MODE_SEL, 0x0c00); + snd_ac97_write_cache(ac97, AC97_YMF7X3_3D_MODE_SEL, 0x0c00); return 0; } @@ -374,7 +390,7 @@ static int patch_yamaha_ymf753_post_spdif(struct snd_ac97 * ac97) } static struct snd_ac97_build_ops patch_yamaha_ymf753_ops = { - .build_3d = patch_yamaha_ymf753_3d, + .build_3d = patch_yamaha_ymf7x3_3d, .build_post_spdif = patch_yamaha_ymf753_post_spdif }; -- cgit v1.2.3 From 43115f58e215f2c88c3cc2514dbf47e4643cab5b Mon Sep 17 00:00:00 2001 From: Keita Maehara Date: Wed, 19 Sep 2007 14:29:37 +0200 Subject: [ALSA] ac97: YMF743 missing controls support (2/2) These patches enable a few YMF743 controls (Tone/3D/IEC958) that won't be detected with the current version of ALSA. The second one contains following changes: - A chip-specific SPDIF support for YMF743 (It doesn't have AC97 standard SPDIF registers seen on YMF753). - The implementation for 'IEC958 Playback Source' and 'IEC958 Mute' are identical to the ones for YMF753. But there is no 'IEC958 Output Pin' for YMF743. Signed-off-by: Keita Maehara Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/ac97/ac97_codec.c | 11 +++++- sound/pci/ac97/ac97_id.h | 1 + sound/pci/ac97/ac97_patch.c | 91 ++++++++++++++++++++++++++++++++++----------- sound/pci/ac97/ac97_proc.c | 8 +++- 4 files changed, 85 insertions(+), 26 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c index 0906f1717f2..e13893d72a2 100644 --- a/sound/pci/ac97/ac97_codec.c +++ b/sound/pci/ac97/ac97_codec.c @@ -176,7 +176,7 @@ static const struct ac97_codec_id snd_ac97_codec_ids[] = { { 0x574d4C09, 0xffffffff, "WM9709", NULL, NULL}, { 0x574d4C12, 0xffffffff, "WM9711,WM9712", patch_wolfson11, NULL}, { 0x574d4c13, 0xffffffff, "WM9713,WM9714", patch_wolfson13, NULL, AC97_DEFAULT_POWER_OFF}, -{ 0x594d4800, 0xffffffff, "YMF743", NULL, NULL }, +{ 0x594d4800, 0xffffffff, "YMF743", patch_yamaha_ymf743, NULL }, { 0x594d4802, 0xffffffff, "YMF752", NULL, NULL }, { 0x594d4803, 0xffffffff, "YMF753", patch_yamaha_ymf753, NULL }, { 0x83847600, 0xffffffff, "STAC9700,83,84", patch_sigmatel_stac9700, NULL }, @@ -779,6 +779,12 @@ static int snd_ac97_spdif_default_put(struct snd_kcontrol *kcontrol, struct snd_ change |= snd_ac97_update_bits_nolock(ac97, AC97_CXR_AUDIO_MISC, AC97_CXR_SPDIF_MASK | AC97_CXR_COPYRGT, v); + } else if (ac97->id == AC97_ID_YMF743) { + change |= snd_ac97_update_bits_nolock(ac97, + AC97_YMF7X3_DIT_CTRL, + 0xff38, + ((val << 4) & 0xff00) | + ((val << 2) & 0x0038)); } else { unsigned short extst = snd_ac97_read_cache(ac97, AC97_EXTENDED_STATUS); snd_ac97_update_bits_nolock(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, 0); /* turn off */ @@ -1375,7 +1381,8 @@ static int snd_ac97_mixer_build(struct snd_ac97 * ac97) for (idx = 0; idx < 2; idx++) { if ((err = snd_ctl_add(card, kctl = snd_ac97_cnew(&snd_ac97_controls_tone[idx], ac97))) < 0) return err; - if (ac97->id == AC97_ID_YMF753) { + if (ac97->id == AC97_ID_YMF743 || + ac97->id == AC97_ID_YMF753) { kctl->private_value &= ~(0xff << 16); kctl->private_value |= 7 << 16; } diff --git a/sound/pci/ac97/ac97_id.h b/sound/pci/ac97/ac97_id.h index 6d73514dc49..0a7dadc244f 100644 --- a/sound/pci/ac97/ac97_id.h +++ b/sound/pci/ac97/ac97_id.h @@ -54,6 +54,7 @@ #define AC97_ID_ALC658 0x414c4780 #define AC97_ID_ALC658D 0x414c4781 #define AC97_ID_ALC850 0x414c4790 +#define AC97_ID_YMF743 0x594d4800 #define AC97_ID_YMF753 0x594d4803 #define AC97_ID_VT1616 0x49434551 #define AC97_ID_CM9738 0x434d4941 diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c index 075ac4e14bc..2e683dd4e86 100644 --- a/sound/pci/ac97/ac97_patch.c +++ b/sound/pci/ac97/ac97_patch.c @@ -204,6 +204,7 @@ static inline int is_shared_micin(struct snd_ac97 *ac97) /* The following snd_ac97_ymf753_... items added by David Shust (dshust@shustring.com) */ +/* Modified for YMF743 by Keita Maehara */ /* It is possible to indicate to the Yamaha YMF7x3 the type of speakers being used. */ @@ -298,6 +299,74 @@ static int snd_ac97_ymf7x3_spdif_source_put(struct snd_kcontrol *kcontrol, return snd_ac97_update_bits(ac97, AC97_YMF7X3_DIT_CTRL, 0x0002, val); } +static int patch_yamaha_ymf7x3_3d(struct snd_ac97 *ac97) +{ + struct snd_kcontrol *kctl; + int err; + + kctl = snd_ac97_cnew(&snd_ac97_controls_3d[0], ac97); + err = snd_ctl_add(ac97->bus->card, kctl); + if (err < 0) + return err; + strcpy(kctl->id.name, "3D Control - Wide"); + kctl->private_value = AC97_SINGLE_VALUE(AC97_3D_CONTROL, 9, 7, 0); + snd_ac97_write_cache(ac97, AC97_3D_CONTROL, 0x0000); + err = snd_ctl_add(ac97->bus->card, + snd_ac97_cnew(&snd_ac97_ymf7x3_controls_speaker, + ac97)); + if (err < 0) + return err; + snd_ac97_write_cache(ac97, AC97_YMF7X3_3D_MODE_SEL, 0x0c00); + return 0; +} + +static const struct snd_kcontrol_new snd_ac97_yamaha_ymf743_controls_spdif[3] = +{ + AC97_SINGLE(SNDRV_CTL_NAME_IEC958("", PLAYBACK, SWITCH), + AC97_YMF7X3_DIT_CTRL, 0, 1, 0), + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, NONE) "Source", + .info = snd_ac97_ymf7x3_spdif_source_info, + .get = snd_ac97_ymf7x3_spdif_source_get, + .put = snd_ac97_ymf7x3_spdif_source_put, + }, + AC97_SINGLE(SNDRV_CTL_NAME_IEC958("", NONE, NONE) "Mute", + AC97_YMF7X3_DIT_CTRL, 2, 1, 1) +}; + +static int patch_yamaha_ymf743_build_spdif(struct snd_ac97 *ac97) +{ + int err; + + err = patch_build_controls(ac97, &snd_ac97_controls_spdif[0], 3); + if (err < 0) + return err; + err = patch_build_controls(ac97, + snd_ac97_yamaha_ymf743_controls_spdif, 3); + if (err < 0) + return err; + /* set default PCM S/PDIF params */ + /* PCM audio,no copyright,no preemphasis,PCM coder,original */ + snd_ac97_write_cache(ac97, AC97_YMF7X3_DIT_CTRL, 0xa201); + return 0; +} + +static struct snd_ac97_build_ops patch_yamaha_ymf743_ops = { + .build_spdif = patch_yamaha_ymf743_build_spdif, + .build_3d = patch_yamaha_ymf7x3_3d, +}; + +static int patch_yamaha_ymf743(struct snd_ac97 *ac97) +{ + ac97->build_ops = &patch_yamaha_ymf743_ops; + ac97->caps |= AC97_BC_BASS_TREBLE; + ac97->caps |= 0x04 << 10; /* Yamaha 3D enhancement */ + ac97->rates[AC97_RATES_SPDIF] = SNDRV_PCM_RATE_48000; /* 48k only */ + ac97->ext_id |= AC97_EI_SPDIF; /* force the detection of spdif */ + return 0; +} + /* The AC'97 spec states that the S/PDIF signal is to be output at pin 48. The YMF753 will output the S/PDIF signal to pin 43, 47 (EAPD), or 48. By default, no output pin is selected, and the S/PDIF signal is not output. @@ -358,28 +427,6 @@ static const struct snd_kcontrol_new snd_ac97_ymf753_controls_spdif[3] = { AC97_YMF7X3_DIT_CTRL, 2, 1, 1) }; -static int patch_yamaha_ymf7x3_3d(struct snd_ac97 *ac97) -{ - struct snd_kcontrol *kctl; - int err; - - kctl = snd_ac97_cnew(&snd_ac97_controls_3d[0], ac97); - err = snd_ctl_add(ac97->bus->card, kctl); - if (err < 0) - return err; - strcpy(kctl->id.name, "3D Control - Wide"); - kctl->private_value = AC97_SINGLE_VALUE(AC97_3D_CONTROL, 9, 7, 0); - snd_ac97_write_cache(ac97, AC97_3D_CONTROL, 0x0000); - - err = snd_ctl_add(ac97->bus->card, - snd_ac97_cnew(&snd_ac97_ymf7x3_controls_speaker, - ac97)); - if (err < 0) - return err; - snd_ac97_write_cache(ac97, AC97_YMF7X3_3D_MODE_SEL, 0x0c00); - return 0; -} - static int patch_yamaha_ymf753_post_spdif(struct snd_ac97 * ac97) { int err; diff --git a/sound/pci/ac97/ac97_proc.c b/sound/pci/ac97/ac97_proc.c index a3fdd7da911..f547986d845 100644 --- a/sound/pci/ac97/ac97_proc.c +++ b/sound/pci/ac97/ac97_proc.c @@ -236,10 +236,14 @@ static void snd_ac97_proc_read_main(struct snd_ac97 *ac97, struct snd_info_buffe val = snd_ac97_read(ac97, AC97_PCM_MIC_ADC_RATE); snd_iprintf(buffer, "PCM MIC ADC : %iHz\n", val); } - if ((ext & AC97_EI_SPDIF) || (ac97->flags & AC97_CS_SPDIF)) { + if ((ext & AC97_EI_SPDIF) || (ac97->flags & AC97_CS_SPDIF) || + (ac97->id == AC97_ID_YMF743)) { if (ac97->flags & AC97_CS_SPDIF) val = snd_ac97_read(ac97, AC97_CSR_SPDIF); - else + else if (ac97->id == AC97_ID_YMF743) { + val = snd_ac97_read(ac97, AC97_YMF7X3_DIT_CTRL); + val = 0x2000 | (val & 0xff00) >> 4 | (val & 0x38) >> 2; + } else val = snd_ac97_read(ac97, AC97_SPDIF); snd_iprintf(buffer, "SPDIF Control :%s%s%s%s Category=0x%x Generation=%i%s%s%s\n", -- cgit v1.2.3 From b60dd394f8af01d1b0a8b1d9d1aa6b75c645eb8e Mon Sep 17 00:00:00 2001 From: Kailang Yang Date: Thu, 20 Sep 2007 12:50:29 +0200 Subject: [ALSA] hda-codec - Fix ALC662 codec support * Fixed ALC662 init verbs (wrong NIDs) * Fixed ALC662 auto model issue (wrong DAC index) Signed-off-by: Kailang Yang Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_realtek.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index b642c8bf162..096ef296db1 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -11665,12 +11665,12 @@ static struct hda_verb alc662_init_verbs[] = { {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, - {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, + {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, + {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, + {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, /* Front Pin: output 0 (0x0c) */ {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, @@ -11748,12 +11748,12 @@ static struct hda_verb alc662_auto_init_verbs[] = { /* set up input amps for analog loopback */ /* Amp Indices: DAC = 0, mixer = 1 */ - {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, + {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, + {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, + {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, /* FIXME: use matrix-type input source selection */ @@ -11935,7 +11935,7 @@ static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec, for (i = 0; i < cfg->line_outs; i++) { if (!spec->multiout.dac_nids[i]) continue; - nid = alc880_idx_to_mixer(i); + nid = alc880_idx_to_dac(i); if (i == 2) { /* Center/LFE */ err = add_control(spec, ALC_CTL_WIDGET_VOL, -- cgit v1.2.3 From ac8842a0391a776dfa8f59cc83582f6feffa913b Mon Sep 17 00:00:00 2001 From: Kailang Yang Date: Thu, 20 Sep 2007 12:51:39 +0200 Subject: [ALSA] hda-codec - Missing support ASUS A7J Added the missing support for ASUS A7J [0x1043 0x1243] Signed-off-by: Kailang Yang Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 096ef296db1..ec14dd513fe 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -5604,6 +5604,7 @@ static struct snd_pci_quirk alc882_cfg_tbl[] = { SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */ SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J), + SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J), SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M), SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG), SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG), -- cgit v1.2.3 From c10710676728846f5c0a92431ebab2161f9c0b7e Mon Sep 17 00:00:00 2001 From: Peer Chen Date: Fri, 21 Sep 2007 18:20:25 +0200 Subject: [ALSA] alsa: Add the MCP79 support to hda_intel driver Add the MCP79 support to hda driver. The patch base on kernel 2.6.23-rc7 Signed-off-by: Peer Chen Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/hda_intel.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'sound/pci') diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 4e3474c2b66..3fa0f970490 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -1959,6 +1959,10 @@ static struct pci_device_id azx_ids[] = { { 0x10de, 0x0775, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA MCP77 */ { 0x10de, 0x0776, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA MCP77 */ { 0x10de, 0x0777, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA MCP77 */ + { 0x10de, 0x0ac0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA MCP79 */ + { 0x10de, 0x0ac1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA MCP79 */ + { 0x10de, 0x0ac2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA MCP79 */ + { 0x10de, 0x0ac3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA MCP79 */ { 0, } }; MODULE_DEVICE_TABLE(pci, azx_ids); -- cgit v1.2.3 From 213e84ec71abf596be76abcf18b988afeb2c210e Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Fri, 21 Sep 2007 18:25:40 +0200 Subject: [ALSA] sound/hda: fix help text Fix hda help text typo. Signed-off-by: Randy Dunlap Signed-off-by: Andrew Morton Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound/pci') diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig index 2c6486c23a5..c127e79ed29 100644 --- a/sound/pci/Kconfig +++ b/sound/pci/Kconfig @@ -506,7 +506,7 @@ config SND_HDA_HWDEP select SND_HWDEP help Say Y here to build a hwdep interface for HD-audio driver. - This interface can be used for out-of-bound communication + This interface can be used for out-of-band communication with codecs for debugging purposes. config SND_HDA_CODEC_REALTEK -- cgit v1.2.3 From 6eda7cf184670764a6f6bfc883bd5005379d7251 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Fri, 21 Sep 2007 23:25:00 +0200 Subject: [ALSA] git-alsa kconfig fix Signed-off-by: Andrew Morton Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'sound/pci') diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig index c127e79ed29..356bf21a150 100644 --- a/sound/pci/Kconfig +++ b/sound/pci/Kconfig @@ -900,6 +900,7 @@ config SND_AC97_POWER_SAVE_DEFAULT int "Default time-out for AC97 power-save mode" depends on SND_AC97_POWER_SAVE default 0 + help The default time-out value in seconds for AC97 automatic power-save mode. 0 means to disable the power-save mode. -- cgit v1.2.3 From 5513b0c58222d21b704cf352c554d9ab86c3fd97 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 9 Oct 2007 11:58:41 +0200 Subject: [ALSA] hda-codec - Add zero checks in input-mux helper functions Added zero checks in input-mux helper functions to avoid Oops. Some devices may have no input pins while the driver registers control elements calling these functions. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/hda_codec.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'sound/pci') diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 18ef0aa69d9..239cdd855df 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -2341,6 +2341,8 @@ int snd_hda_input_mux_info(const struct hda_input_mux *imux, uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; uinfo->count = 1; uinfo->value.enumerated.items = imux->num_items; + if (!imux->num_items) + return 0; index = uinfo->value.enumerated.item; if (index >= imux->num_items) index = imux->num_items - 1; @@ -2356,6 +2358,8 @@ int snd_hda_input_mux_put(struct hda_codec *codec, { unsigned int idx; + if (!imux->num_items) + return 0; idx = ucontrol->value.enumerated.item[0]; if (idx >= imux->num_items) idx = imux->num_items - 1; -- cgit v1.2.3 From 1194b5b70a0a000a4ace54d94d8df5cc3ec6e3e0 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 10 Oct 2007 10:04:26 +0200 Subject: [ALSA] hda-codec - Fix Gateway laptops with STAC9200 Fix the output of Gateway laptops with STAC9200 codec chip. They require the EAPD control for some pins. These pins shouldn't be powered down. To enable EAPD control, a new model 'gateway' was added to STAC9200. The known PCI SSIDs are included in the quirk list. The fix was originally suggested by Brian Hinz, in ALSA bug#2948. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/hda_codec.c | 16 +++++++++++++++- sound/pci/hda/patch_sigmatel.c | 21 +++++++++++++++++++-- 2 files changed, 34 insertions(+), 3 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 239cdd855df..187533e477c 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -1630,10 +1630,24 @@ static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg, nid = codec->start_nid; for (i = 0; i < codec->num_nodes; i++, nid++) { - if (get_wcaps(codec, nid) & AC_WCAP_POWER) + if (get_wcaps(codec, nid) & AC_WCAP_POWER) { + unsigned int pincap; + /* + * don't power down the widget if it controls eapd + * and EAPD_BTLENABLE is set. + */ + pincap = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP); + if (pincap & AC_PINCAP_EAPD) { + int eapd = snd_hda_codec_read(codec, nid, + 0, AC_VERB_GET_EAPD_BTLENABLE, 0); + eapd &= 0x02; + if (power_state == AC_PWRST_D3 && eapd) + continue; + } snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_POWER_STATE, power_state); + } } if (power_state == AC_PWRST_D0) { diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 27360d278bc..fe91b9b46b6 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -49,6 +49,7 @@ enum { STAC_9200_DELL_M25, STAC_9200_DELL_M26, STAC_9200_DELL_M27, + STAC_9200_GATEWAY, STAC_9200_MODELS }; @@ -378,6 +379,13 @@ static struct hda_verb stac9200_core_init[] = { {} }; +static struct hda_verb stac9200_eapd_init[] = { + /* set dac0mux for dac converter */ + {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, + {0x08, AC_VERB_SET_EAPD_BTLENABLE, 0x02}, + {} +}; + static struct hda_verb stac925x_core_init[] = { /* set dac0mux for dac converter */ { 0x06, AC_VERB_SET_CONNECT_SEL, 0x00}, @@ -693,6 +701,7 @@ static const char *stac9200_models[STAC_9200_MODELS] = { [STAC_9200_DELL_M25] = "dell-m25", [STAC_9200_DELL_M26] = "dell-m26", [STAC_9200_DELL_M27] = "dell-m27", + [STAC_9200_GATEWAY] = "gateway", }; static struct snd_pci_quirk stac9200_cfg_tbl[] = { @@ -760,7 +769,12 @@ static struct snd_pci_quirk stac9200_cfg_tbl[] = { "unknown Dell", STAC_9200_DELL_M26), /* Panasonic */ SND_PCI_QUIRK(0x10f7, 0x8338, "Panasonic CF-74", STAC_REF), - + /* Gateway machines needs EAPD to be set on resume */ + SND_PCI_QUIRK(0x107b, 0x0205, "Gateway S-7110M", STAC_9200_GATEWAY), + SND_PCI_QUIRK(0x107b, 0x0317, "Gateway MT3423, MX341*", + STAC_9200_GATEWAY), + SND_PCI_QUIRK(0x107b, 0x0318, "Gateway ML3019, MT3707", + STAC_9200_GATEWAY), {} /* terminator */ }; @@ -2492,7 +2506,10 @@ static int patch_stac9200(struct hda_codec *codec) spec->num_dmics = 0; spec->num_adcs = 1; - spec->init = stac9200_core_init; + if (spec->board_config == STAC_9200_GATEWAY) + spec->init = stac9200_eapd_init; + else + spec->init = stac9200_core_init; spec->mixer = stac9200_mixer; err = stac9200_parse_auto_config(codec); -- cgit v1.2.3 From e6382cf8b0c34be26e667d45911fa827aea8df5c Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 10 Oct 2007 10:06:46 +0200 Subject: [ALSA] pcxhr - Fix dB level information Some dB level information is wrong in pcxhr driver according to the datasheet. Fixed now. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/pcxhr/pcxhr_mixer.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/pcxhr/pcxhr_mixer.c b/sound/pci/pcxhr/pcxhr_mixer.c index b913453063f..5f8d42633b0 100644 --- a/sound/pci/pcxhr/pcxhr_mixer.c +++ b/sound/pci/pcxhr/pcxhr_mixer.c @@ -44,8 +44,8 @@ #define PCXHR_ANALOG_PLAYBACK_LEVEL_MAX 128 /* 0.0 dB */ #define PCXHR_ANALOG_PLAYBACK_ZERO_LEVEL 104 /* -24.0 dB ( 0.0 dB - fix level +24.0 dB ) */ -static const DECLARE_TLV_DB_SCALE(db_scale_analog_capture, -9600, 50, 0); -static const DECLARE_TLV_DB_SCALE(db_scale_analog_playback, -12800, 100, 0); +static const DECLARE_TLV_DB_SCALE(db_scale_analog_capture, -9600, 50, 3150); +static const DECLARE_TLV_DB_SCALE(db_scale_analog_playback, -10400, 100, 2400); static int pcxhr_update_analog_audio_level(struct snd_pcxhr *chip, int is_capture, int channel) { @@ -188,7 +188,7 @@ static struct snd_kcontrol_new pcxhr_control_output_switch = { #define PCXHR_DIGITAL_LEVEL_MAX 0x1ff /* +18 dB */ #define PCXHR_DIGITAL_ZERO_LEVEL 0x1b7 /* 0 dB */ -static const DECLARE_TLV_DB_SCALE(db_scale_digital, -10950, 50, 0); +static const DECLARE_TLV_DB_SCALE(db_scale_digital, -10975, 25, 1800); #define MORE_THAN_ONE_STREAM_LEVEL 0x000001 #define VALID_STREAM_PAN_LEVEL_MASK 0x800000 -- cgit v1.2.3 From 5e915bb3677f1369223a87e488c340236f81bfc2 Mon Sep 17 00:00:00 2001 From: Tim Gardner Date: Wed, 10 Oct 2007 10:42:00 +0200 Subject: [ALSA] hda-codec - Re-add quirk support for Dell XPS 1330 and Inspiron 1420 Signed-off-by: Tim Gardner Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_sigmatel.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index fe91b9b46b6..9fae4f1296b 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -1111,11 +1111,13 @@ static struct snd_pci_quirk stac927x_cfg_tbl[] = { SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2003, "Intel D965", STAC_D965_3ST), SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2002, "Intel D965", STAC_D965_3ST), SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2001, "Intel D965", STAC_D965_3ST), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f3, "Dell Inspiron 1420", STAC_D965_3ST), /* Dell 3 stack systems */ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01dd, "Dell Dimension E520", STAC_DELL_3ST), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ed, "Dell ", STAC_DELL_3ST), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f4, "Dell ", STAC_DELL_3ST), /* 965 based 5 stack systems */ + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0209, "Dell XPS 1330", STAC_D965_5ST), SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2301, "Intel D965", STAC_D965_5ST), SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2302, "Intel D965", STAC_D965_5ST), SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2303, "Intel D965", STAC_D965_5ST), -- cgit v1.2.3 From a3a2f429e55997e3b7a0c23baf1208991970ecc1 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 11 Oct 2007 11:21:21 +0200 Subject: [ALSA] hda-codec - Fix input_mux numbers for vaio stac92xx My bad, I forgot to update the num_items field when added a new item to vaio_mux items table, so the last item 'PCM' disappeared. Now it has the right number 3. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_sigmatel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 9fae4f1296b..8b3576007d4 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -2875,7 +2875,7 @@ static hda_nid_t vaio_adcs[] = { 0x8 /*,0x6*/ }; static hda_nid_t vaio_mux_nids[] = { 0x15 }; static struct hda_input_mux vaio_mux = { - .num_items = 2, + .num_items = 3, .items = { /* { "HP", 0x0 }, */ { "Mic Jack", 0x1 }, -- cgit v1.2.3 From 11be265f7fd4976a1139d6ec9b2ef1e8adaf835f Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 11 Oct 2007 14:35:00 +0200 Subject: [ALSA] via82xx - Add DXS quirk for Shuttle AK31v2 Shuttle AK31v2 works well with dxs_support=5 (ALSA bug#2926). Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/via82xx.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sound/pci') diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c index 45d89deb64e..69487f68118 100644 --- a/sound/pci/via82xx.c +++ b/sound/pci/via82xx.c @@ -2363,6 +2363,7 @@ static struct snd_pci_quirk dxs_whitelist[] __devinitdata = { SND_PCI_QUIRK(0x1071, 0, "Diverse Notebook", VIA_DXS_NO_VRA), SND_PCI_QUIRK(0x10cf, 0x118e, "FSC Laptop", VIA_DXS_ENABLE), SND_PCI_QUIRK(0x1106, 0, "ASRock", VIA_DXS_SRC), + SND_PCI_QUIRK(0x1297, 0xa231, "Shuttle AK31v2", VIA_DXS_SRC), SND_PCI_QUIRK(0x1297, 0xa232, "Shuttle", VIA_DXS_ENABLE), SND_PCI_QUIRK(0x1297, 0xc160, "Shuttle Sk41G", VIA_DXS_ENABLE), SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte GA-7VAXP", VIA_DXS_ENABLE), -- cgit v1.2.3 From 39d3ed381877246719184897c853c0c58028fe54 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 12 Oct 2007 15:03:48 +0200 Subject: [ALSA] hda-codec - Fix for Fujitsu Lifebook C1410 Fixed ALC262 fujitsu model to support Fujitsu Lifebook C1410 properly. It requires EAPD and has separate int/ext mic inputs (which was missing in the current driver). Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_realtek.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index ec14dd513fe..1d2cd4c4b16 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -7807,9 +7807,10 @@ static struct hda_verb alc262_fujitsu_unsol_verbs[] = { }; static struct hda_input_mux alc262_fujitsu_capture_source = { - .num_items = 2, + .num_items = 3, .items = { { "Mic", 0x0 }, + { "Int Mic", 0x1 }, { "CD", 0x4 }, }, }; @@ -7915,6 +7916,9 @@ static struct snd_kcontrol_new alc262_fujitsu_mixer[] = { HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), { } /* end */ }; @@ -8411,7 +8415,8 @@ static struct alc_config_preset alc262_presets[] = { }, [ALC262_FUJITSU] = { .mixers = { alc262_fujitsu_mixer }, - .init_verbs = { alc262_init_verbs, alc262_fujitsu_unsol_verbs }, + .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs, + alc262_fujitsu_unsol_verbs }, .num_dacs = ARRAY_SIZE(alc262_dac_nids), .dac_nids = alc262_dac_nids, .hp_nid = 0x03, -- cgit v1.2.3 From c1017a4cdb68ae5368fbc9ee42c77f1f5dca8916 Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Mon, 15 Oct 2007 09:50:19 +0200 Subject: [ALSA] Changed Jaroslav Kysela's e-mail from perex@suse.cz to perex@perex.cz Signed-off-by: Jaroslav Kysela --- sound/pci/Makefile | 2 +- sound/pci/ac97/Makefile | 2 +- sound/pci/ac97/ac97_codec.c | 4 ++-- sound/pci/ac97/ac97_id.h | 2 +- sound/pci/ac97/ac97_local.h | 2 +- sound/pci/ac97/ac97_patch.c | 2 +- sound/pci/ac97/ac97_patch.h | 2 +- sound/pci/ac97/ac97_pcm.c | 2 +- sound/pci/ac97/ac97_proc.c | 2 +- sound/pci/ac97/ak4531_codec.c | 4 ++-- sound/pci/ali5451/Makefile | 2 +- sound/pci/als4000.c | 2 +- sound/pci/au88x0/au88x0_mpu401.c | 2 +- sound/pci/ca0106/ca_midi.c | 2 +- sound/pci/cs4281.c | 4 ++-- sound/pci/cs46xx/Makefile | 2 +- sound/pci/cs46xx/cs46xx.c | 4 ++-- sound/pci/cs46xx/cs46xx_lib.c | 2 +- sound/pci/cs46xx/cs46xx_lib.h | 2 +- sound/pci/cs46xx/dsp_spos.h | 2 +- sound/pci/emu10k1/Makefile | 2 +- sound/pci/emu10k1/emu10k1.c | 4 ++-- sound/pci/emu10k1/emu10k1_main.c | 2 +- sound/pci/emu10k1/emufx.c | 2 +- sound/pci/emu10k1/emumixer.c | 2 +- sound/pci/emu10k1/emumpu401.c | 2 +- sound/pci/emu10k1/emupcm.c | 2 +- sound/pci/emu10k1/emuproc.c | 2 +- sound/pci/emu10k1/io.c | 2 +- sound/pci/emu10k1/irq.c | 2 +- sound/pci/emu10k1/memory.c | 2 +- sound/pci/emu10k1/voice.c | 2 +- sound/pci/ens1370.c | 4 ++-- sound/pci/es1938.c | 2 +- sound/pci/fm801.c | 4 ++-- sound/pci/ice1712/Makefile | 2 +- sound/pci/ice1712/ak4xxx.c | 4 ++-- sound/pci/ice1712/amp.c | 2 +- sound/pci/ice1712/amp.h | 2 +- sound/pci/ice1712/delta.c | 2 +- sound/pci/ice1712/delta.h | 2 +- sound/pci/ice1712/envy24ht.h | 2 +- sound/pci/ice1712/ews.c | 2 +- sound/pci/ice1712/ews.h | 2 +- sound/pci/ice1712/hoontech.c | 2 +- sound/pci/ice1712/hoontech.h | 2 +- sound/pci/ice1712/ice1712.c | 4 ++-- sound/pci/ice1712/ice1712.h | 2 +- sound/pci/ice1712/ice1724.c | 4 ++-- sound/pci/ice1712/juli.c | 2 +- sound/pci/intel8x0.c | 4 ++-- sound/pci/intel8x0m.c | 4 ++-- sound/pci/korg1212/Makefile | 2 +- sound/pci/mixart/Makefile | 2 +- sound/pci/nm256/Makefile | 2 +- sound/pci/rme9652/Makefile | 2 +- sound/pci/sonicvibes.c | 4 ++-- sound/pci/trident/Makefile | 2 +- sound/pci/trident/trident.c | 2 +- sound/pci/trident/trident_main.c | 2 +- sound/pci/trident/trident_memory.c | 2 +- sound/pci/via82xx.c | 4 ++-- sound/pci/via82xx_modem.c | 4 ++-- sound/pci/vx222/Makefile | 2 +- sound/pci/ymfpci/Makefile | 2 +- sound/pci/ymfpci/ymfpci.c | 4 ++-- sound/pci/ymfpci/ymfpci_main.c | 2 +- 67 files changed, 83 insertions(+), 83 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/Makefile b/sound/pci/Makefile index cd76e0293d0..09ddc82eeca 100644 --- a/sound/pci/Makefile +++ b/sound/pci/Makefile @@ -1,6 +1,6 @@ # # Makefile for ALSA -# Copyright (c) 2001 by Jaroslav Kysela +# Copyright (c) 2001 by Jaroslav Kysela # snd-ad1889-objs := ad1889.o diff --git a/sound/pci/ac97/Makefile b/sound/pci/ac97/Makefile index f5d471896b9..0be48b1a22d 100644 --- a/sound/pci/ac97/Makefile +++ b/sound/pci/ac97/Makefile @@ -1,6 +1,6 @@ # # Makefile for ALSA -# Copyright (c) 2001 by Jaroslav Kysela +# Copyright (c) 2001 by Jaroslav Kysela # snd-ac97-codec-objs := ac97_codec.o ac97_pcm.o diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c index e13893d72a2..6a9966df0cc 100644 --- a/sound/pci/ac97/ac97_codec.c +++ b/sound/pci/ac97/ac97_codec.c @@ -1,5 +1,5 @@ /* - * Copyright (c) by Jaroslav Kysela + * Copyright (c) by Jaroslav Kysela * Universal interface for Audio Codec '97 * * For more details look to AC '97 component specification revision 2.2 @@ -39,7 +39,7 @@ #include "ac97_patch.c" -MODULE_AUTHOR("Jaroslav Kysela "); +MODULE_AUTHOR("Jaroslav Kysela "); MODULE_DESCRIPTION("Universal interface for Audio Codec '97"); MODULE_LICENSE("GPL"); diff --git a/sound/pci/ac97/ac97_id.h b/sound/pci/ac97/ac97_id.h index 0a7dadc244f..c129492c82b 100644 --- a/sound/pci/ac97/ac97_id.h +++ b/sound/pci/ac97/ac97_id.h @@ -1,5 +1,5 @@ /* - * Copyright (c) by Jaroslav Kysela + * Copyright (c) by Jaroslav Kysela * Universal interface for Audio Codec '97 * * For more details look to AC '97 component specification revision 2.2 diff --git a/sound/pci/ac97/ac97_local.h b/sound/pci/ac97/ac97_local.h index 78745c5c6df..c276a5e3f7a 100644 --- a/sound/pci/ac97/ac97_local.h +++ b/sound/pci/ac97/ac97_local.h @@ -1,5 +1,5 @@ /* - * Copyright (c) by Jaroslav Kysela + * Copyright (c) by Jaroslav Kysela * Universal interface for Audio Codec '97 * * For more details look to AC '97 component specification revision 2.2 diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c index 2e683dd4e86..98c8b727b62 100644 --- a/sound/pci/ac97/ac97_patch.c +++ b/sound/pci/ac97/ac97_patch.c @@ -1,5 +1,5 @@ /* - * Copyright (c) by Jaroslav Kysela + * Copyright (c) by Jaroslav Kysela * Universal interface for Audio Codec '97 * * For more details look to AC '97 component specification revision 2.2 diff --git a/sound/pci/ac97/ac97_patch.h b/sound/pci/ac97/ac97_patch.h index fd341ce6376..9cccc27ea1b 100644 --- a/sound/pci/ac97/ac97_patch.h +++ b/sound/pci/ac97/ac97_patch.h @@ -1,5 +1,5 @@ /* - * Copyright (c) by Jaroslav Kysela + * Copyright (c) by Jaroslav Kysela * Universal interface for Audio Codec '97 * * For more details look to AC '97 component specification revision 2.2 diff --git a/sound/pci/ac97/ac97_pcm.c b/sound/pci/ac97/ac97_pcm.c index 4281e6d0c5b..8cbc03332b0 100644 --- a/sound/pci/ac97/ac97_pcm.c +++ b/sound/pci/ac97/ac97_pcm.c @@ -1,5 +1,5 @@ /* - * Copyright (c) by Jaroslav Kysela + * Copyright (c) by Jaroslav Kysela * Universal interface for Audio Codec '97 * * For more details look to AC '97 component specification revision 2.2 diff --git a/sound/pci/ac97/ac97_proc.c b/sound/pci/ac97/ac97_proc.c index f547986d845..fed4a2c3d8a 100644 --- a/sound/pci/ac97/ac97_proc.c +++ b/sound/pci/ac97/ac97_proc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) by Jaroslav Kysela + * Copyright (c) by Jaroslav Kysela * Universal interface for Audio Codec '97 * * For more details look to AC '97 component specification revision 2.2 diff --git a/sound/pci/ac97/ak4531_codec.c b/sound/pci/ac97/ak4531_codec.c index dc26820a03a..722de451d15 100644 --- a/sound/pci/ac97/ak4531_codec.c +++ b/sound/pci/ac97/ak4531_codec.c @@ -1,5 +1,5 @@ /* - * Copyright (c) by Jaroslav Kysela + * Copyright (c) by Jaroslav Kysela * Universal routines for AK4531 codec * * @@ -29,7 +29,7 @@ #include #include -MODULE_AUTHOR("Jaroslav Kysela "); +MODULE_AUTHOR("Jaroslav Kysela "); MODULE_DESCRIPTION("Universal routines for AK4531 codec"); MODULE_LICENSE("GPL"); diff --git a/sound/pci/ali5451/Makefile b/sound/pci/ali5451/Makefile index 2e183159747..713459c12d2 100644 --- a/sound/pci/ali5451/Makefile +++ b/sound/pci/ali5451/Makefile @@ -1,6 +1,6 @@ # # Makefile for ALSA -# Copyright (c) 2001 by Jaroslav Kysela +# Copyright (c) 2001 by Jaroslav Kysela # snd-ali5451-objs := ali5451.o diff --git a/sound/pci/als4000.c b/sound/pci/als4000.c index 8fb55d3b454..1190ef366a4 100644 --- a/sound/pci/als4000.c +++ b/sound/pci/als4000.c @@ -1,7 +1,7 @@ /* * card-als4000.c - driver for Avance Logic ALS4000 based soundcards. * Copyright (C) 2000 by Bart Hartgers , - * Jaroslav Kysela + * Jaroslav Kysela * Copyright (C) 2002 by Andreas Mohr * * Framework borrowed from Massimo Piccioni's card-als100.c. diff --git a/sound/pci/au88x0/au88x0_mpu401.c b/sound/pci/au88x0/au88x0_mpu401.c index c75d368ea08..8db3d3e6f7b 100644 --- a/sound/pci/au88x0/au88x0_mpu401.c +++ b/sound/pci/au88x0/au88x0_mpu401.c @@ -1,5 +1,5 @@ /* - * Copyright (c) by Jaroslav Kysela + * Copyright (c) by Jaroslav Kysela * Routines for control of MPU-401 in UART mode * * Modified for the Aureal Vortex based Soundcards diff --git a/sound/pci/ca0106/ca_midi.c b/sound/pci/ca0106/ca_midi.c index 2e6eab1f118..ad32eff2713 100644 --- a/sound/pci/ca0106/ca_midi.c +++ b/sound/pci/ca0106/ca_midi.c @@ -6,7 +6,7 @@ * Changelog: * Implementation is based on mpu401 and emu10k1x and * tested with ca0106. - * mpu401: Copyright (c) by Jaroslav Kysela + * mpu401: Copyright (c) by Jaroslav Kysela * emu10k1x: Copyright (c) by Francisco Moraes * * This program is free software; you can redistribute it and/or modify diff --git a/sound/pci/cs4281.c b/sound/pci/cs4281.c index 1fca49a1641..9a55f4a9739 100644 --- a/sound/pci/cs4281.c +++ b/sound/pci/cs4281.c @@ -1,6 +1,6 @@ /* * Driver for Cirrus Logic CS4281 based PCI soundcard - * Copyright (c) by Jaroslav Kysela , + * Copyright (c) by Jaroslav Kysela , * * * This program is free software; you can redistribute it and/or modify @@ -38,7 +38,7 @@ #include -MODULE_AUTHOR("Jaroslav Kysela "); +MODULE_AUTHOR("Jaroslav Kysela "); MODULE_DESCRIPTION("Cirrus Logic CS4281"); MODULE_LICENSE("GPL"); MODULE_SUPPORTED_DEVICE("{{Cirrus Logic,CS4281}}"); diff --git a/sound/pci/cs46xx/Makefile b/sound/pci/cs46xx/Makefile index 7fcc967440c..67e811ec853 100644 --- a/sound/pci/cs46xx/Makefile +++ b/sound/pci/cs46xx/Makefile @@ -1,6 +1,6 @@ # # Makefile for ALSA -# Copyright (c) 2001 by Jaroslav Kysela +# Copyright (c) 2001 by Jaroslav Kysela # snd-cs46xx-y := cs46xx.o cs46xx_lib.o diff --git a/sound/pci/cs46xx/cs46xx.c b/sound/pci/cs46xx/cs46xx.c index 8b6cd144d10..2699cb6c2cd 100644 --- a/sound/pci/cs46xx/cs46xx.c +++ b/sound/pci/cs46xx/cs46xx.c @@ -1,6 +1,6 @@ /* * The driver for the Cirrus Logic's Sound Fusion CS46XX based soundcards - * Copyright (c) by Jaroslav Kysela + * Copyright (c) by Jaroslav Kysela * * * This program is free software; you can redistribute it and/or modify @@ -34,7 +34,7 @@ #include #include -MODULE_AUTHOR("Jaroslav Kysela "); +MODULE_AUTHOR("Jaroslav Kysela "); MODULE_DESCRIPTION("Cirrus Logic Sound Fusion CS46XX"); MODULE_LICENSE("GPL"); MODULE_SUPPORTED_DEVICE("{{Cirrus Logic,Sound Fusion (CS4280)}," diff --git a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c index 0dc69d07140..2c7bfc9fef6 100644 --- a/sound/pci/cs46xx/cs46xx_lib.c +++ b/sound/pci/cs46xx/cs46xx_lib.c @@ -1,5 +1,5 @@ /* - * Copyright (c) by Jaroslav Kysela + * Copyright (c) by Jaroslav Kysela * Abramo Bagnara * Cirrus Logic, Inc. * Routines for control of Cirrus Logic CS461x chips diff --git a/sound/pci/cs46xx/cs46xx_lib.h b/sound/pci/cs46xx/cs46xx_lib.h index 20dcd72f06c..018a7de5601 100644 --- a/sound/pci/cs46xx/cs46xx_lib.h +++ b/sound/pci/cs46xx/cs46xx_lib.h @@ -1,6 +1,6 @@ /* * The driver for the Cirrus Logic's Sound Fusion CS46XX based soundcards - * Copyright (c) by Jaroslav Kysela + * Copyright (c) by Jaroslav Kysela * * * This program is free software; you can redistribute it and/or modify diff --git a/sound/pci/cs46xx/dsp_spos.h b/sound/pci/cs46xx/dsp_spos.h index 0d246bca418..f9e169d33c0 100644 --- a/sound/pci/cs46xx/dsp_spos.h +++ b/sound/pci/cs46xx/dsp_spos.h @@ -1,6 +1,6 @@ /* * The driver for the Cirrus Logic's Sound Fusion CS46XX based soundcards - * Copyright (c) by Jaroslav Kysela + * Copyright (c) by Jaroslav Kysela * * * This program is free software; you can redistribute it and/or modify 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 +# Copyright (c) 2001 by Jaroslav Kysela # 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 + * Copyright (c) by Jaroslav Kysela * * Copyright (c) by James Courtier-Dutton * Added support for Audigy 2 Value. @@ -32,7 +32,7 @@ #include #include -MODULE_AUTHOR("Jaroslav Kysela "); +MODULE_AUTHOR("Jaroslav Kysela "); 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 b112b295e9c..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 + * Copyright (c) by Jaroslav Kysela * Creative Labs, Inc. * Routines for control of EMU10K1 chips * diff --git a/sound/pci/emu10k1/emufx.c b/sound/pci/emu10k1/emufx.c index 3c503bb92d2..9bf1cd59219 100644 --- a/sound/pci/emu10k1/emufx.c +++ b/sound/pci/emu10k1/emufx.c @@ -1,5 +1,5 @@ /* - * Copyright (c) by Jaroslav Kysela + * Copyright (c) by Jaroslav Kysela * Creative Labs, Inc. * Routines for effect processor FX8010 * diff --git a/sound/pci/emu10k1/emumixer.c b/sound/pci/emu10k1/emumixer.c index 71ad5a038e8..54a2034d8ed 100644 --- a/sound/pci/emu10k1/emumixer.c +++ b/sound/pci/emu10k1/emumixer.c @@ -1,5 +1,5 @@ /* - * Copyright (c) by Jaroslav Kysela , + * Copyright (c) by Jaroslav Kysela , * Takashi Iwai * Creative Labs, Inc. * Routines for control of EMU10K1 chips / mixer routines 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 + * Copyright (c) by Jaroslav Kysela * 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 + * Copyright (c) by Jaroslav Kysela * Creative Labs, Inc. * Routines for control of EMU10K1 chips / PCM routines * Multichannel PCM support Copyright (c) Lee Revell diff --git a/sound/pci/emu10k1/emuproc.c b/sound/pci/emu10k1/emuproc.c index 3e2ed1d9d5f..c3fb10e81c9 100644 --- a/sound/pci/emu10k1/emuproc.c +++ b/sound/pci/emu10k1/emuproc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) by Jaroslav Kysela + * Copyright (c) by Jaroslav Kysela * Creative Labs, Inc. * Routines for control of EMU10K1 chips / proc interface routines * diff --git a/sound/pci/emu10k1/io.c b/sound/pci/emu10k1/io.c index 971458b4594..6702c15fefa 100644 --- a/sound/pci/emu10k1/io.c +++ b/sound/pci/emu10k1/io.c @@ -1,5 +1,5 @@ /* - * Copyright (c) by Jaroslav Kysela + * Copyright (c) by Jaroslav Kysela * Creative Labs, Inc. * Routines for control of EMU10K1 chips * 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 + * Copyright (c) by Jaroslav Kysela * 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 + * Copyright (c) by Jaroslav Kysela * Copyright (c) by Takashi Iwai * * EMU10K1 memory page allocation (PTB area) 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 + * Copyright (c) by Jaroslav Kysela * Creative Labs, Inc. * Lee Revell * Routines for control of EMU10K1 chips - voice manager diff --git a/sound/pci/ens1370.c b/sound/pci/ens1370.c index 9017bdb513a..b958f869cb1 100644 --- a/sound/pci/ens1370.c +++ b/sound/pci/ens1370.c @@ -1,6 +1,6 @@ /* * Driver for Ensoniq ES1370/ES1371 AudioPCI soundcard - * Copyright (c) by Jaroslav Kysela , + * Copyright (c) by Jaroslav Kysela , * Thomas Sailer * * This program is free software; you can redistribute it and/or modify @@ -61,7 +61,7 @@ #endif -MODULE_AUTHOR("Jaroslav Kysela , Thomas Sailer "); +MODULE_AUTHOR("Jaroslav Kysela , Thomas Sailer "); MODULE_LICENSE("GPL"); #ifdef CHIP1370 MODULE_DESCRIPTION("Ensoniq AudioPCI ES1370"); diff --git a/sound/pci/es1938.c b/sound/pci/es1938.c index fc686db59ce..fb25abe68a0 100644 --- a/sound/pci/es1938.c +++ b/sound/pci/es1938.c @@ -1,7 +1,7 @@ /* * Driver for ESS Solo-1 (ES1938, ES1946, ES1969) soundcard * Copyright (c) by Jaromir Koutek , - * Jaroslav Kysela , + * Jaroslav Kysela , * Thomas Sailer , * Abramo Bagnara , * Markus Gruber diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c index 11015178e20..9939109f05a 100644 --- a/sound/pci/fm801.c +++ b/sound/pci/fm801.c @@ -1,6 +1,6 @@ /* * The driver for the ForteMedia FM801 based soundcards - * Copyright (c) by Jaroslav Kysela + * Copyright (c) by Jaroslav Kysela * * Support FM only card by Andy Shevchenko * @@ -42,7 +42,7 @@ #define TEA575X_RADIO 1 #endif -MODULE_AUTHOR("Jaroslav Kysela "); +MODULE_AUTHOR("Jaroslav Kysela "); MODULE_DESCRIPTION("ForteMedia FM801"); MODULE_LICENSE("GPL"); MODULE_SUPPORTED_DEVICE("{{ForteMedia,FM801}," diff --git a/sound/pci/ice1712/Makefile b/sound/pci/ice1712/Makefile index 6efdd62f683..65ce66adba5 100644 --- a/sound/pci/ice1712/Makefile +++ b/sound/pci/ice1712/Makefile @@ -1,6 +1,6 @@ # # Makefile for ALSA -# Copyright (c) 2001 by Jaroslav Kysela +# Copyright (c) 2001 by Jaroslav Kysela # snd-ice17xx-ak4xxx-objs := ak4xxx.o diff --git a/sound/pci/ice1712/ak4xxx.c b/sound/pci/ice1712/ak4xxx.c index ab00cce2c39..a1aba0d7d0e 100644 --- a/sound/pci/ice1712/ak4xxx.c +++ b/sound/pci/ice1712/ak4xxx.c @@ -3,7 +3,7 @@ * * AK4524 / AK4528 / AK4529 / AK4355 / AK4381 interface * - * Copyright (c) 2000 Jaroslav Kysela + * Copyright (c) 2000 Jaroslav Kysela * * 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 @@ -30,7 +30,7 @@ #include #include "ice1712.h" -MODULE_AUTHOR("Jaroslav Kysela "); +MODULE_AUTHOR("Jaroslav Kysela "); MODULE_DESCRIPTION("ICEnsemble ICE17xx <-> AK4xxx AD/DA chip interface"); MODULE_LICENSE("GPL"); diff --git a/sound/pci/ice1712/amp.c b/sound/pci/ice1712/amp.c index 44bbb630b94..6e13d758bb5 100644 --- a/sound/pci/ice1712/amp.c +++ b/sound/pci/ice1712/amp.c @@ -3,7 +3,7 @@ * * Lowlevel functions for Advanced Micro Peripherals Ltd AUDIO2000 * - * Copyright (c) 2000 Jaroslav Kysela + * Copyright (c) 2000 Jaroslav Kysela * * 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/pci/ice1712/amp.h b/sound/pci/ice1712/amp.h index a0fc89b4812..bf81d30d915 100644 --- a/sound/pci/ice1712/amp.h +++ b/sound/pci/ice1712/amp.h @@ -6,7 +6,7 @@ * * Lowlevel functions for Advanced Micro Peripherals Ltd AUDIO2000 * - * Copyright (c) 2000 Jaroslav Kysela + * Copyright (c) 2000 Jaroslav Kysela * * 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/pci/ice1712/delta.c b/sound/pci/ice1712/delta.c index 66886dff484..371f78461db 100644 --- a/sound/pci/ice1712/delta.c +++ b/sound/pci/ice1712/delta.c @@ -4,7 +4,7 @@ * Lowlevel functions for M-Audio Delta 1010, 44, 66, Dio2496, Audiophile * Digigram VX442 * - * Copyright (c) 2000 Jaroslav Kysela + * Copyright (c) 2000 Jaroslav Kysela * * 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/pci/ice1712/delta.h b/sound/pci/ice1712/delta.h index 2697156607e..26ea05a32f5 100644 --- a/sound/pci/ice1712/delta.h +++ b/sound/pci/ice1712/delta.h @@ -7,7 +7,7 @@ * Lowlevel functions for M-Audio Delta 1010, 44, 66, Dio2496, Audiophile * Digigram VX442 * - * Copyright (c) 2000 Jaroslav Kysela + * Copyright (c) 2000 Jaroslav Kysela * * 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/pci/ice1712/envy24ht.h b/sound/pci/ice1712/envy24ht.h index b58afcda9ed..43b9e3e858b 100644 --- a/sound/pci/ice1712/envy24ht.h +++ b/sound/pci/ice1712/envy24ht.h @@ -4,7 +4,7 @@ /* * ALSA driver for ICEnsemble VT1724 (Envy24) * - * Copyright (c) 2000 Jaroslav Kysela + * Copyright (c) 2000 Jaroslav Kysela * * 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/pci/ice1712/ews.c b/sound/pci/ice1712/ews.c index b2b4eff1ac6..75e4e5e0f1e 100644 --- a/sound/pci/ice1712/ews.c +++ b/sound/pci/ice1712/ews.c @@ -3,7 +3,7 @@ * * Lowlevel functions for Terratec EWS88MT/D, EWX24/96, DMX 6Fire * - * Copyright (c) 2000 Jaroslav Kysela + * Copyright (c) 2000 Jaroslav Kysela * 2002 Takashi Iwai * * This program is free software; you can redistribute it and/or modify diff --git a/sound/pci/ice1712/ews.h b/sound/pci/ice1712/ews.h index a12a0b05355..e4ed1b475b0 100644 --- a/sound/pci/ice1712/ews.h +++ b/sound/pci/ice1712/ews.h @@ -6,7 +6,7 @@ * * Lowlevel functions for Terratec EWS88MT/D, EWX24/96, DMX 6Fire * - * Copyright (c) 2000 Jaroslav Kysela + * Copyright (c) 2000 Jaroslav Kysela * 2002 Takashi Iwai * * This program is free software; you can redistribute it and/or modify diff --git a/sound/pci/ice1712/hoontech.c b/sound/pci/ice1712/hoontech.c index 8203562ef7e..abcfd1da658 100644 --- a/sound/pci/ice1712/hoontech.c +++ b/sound/pci/ice1712/hoontech.c @@ -3,7 +3,7 @@ * * Lowlevel functions for Hoontech STDSP24 * - * Copyright (c) 2000 Jaroslav Kysela + * Copyright (c) 2000 Jaroslav Kysela * * 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/pci/ice1712/hoontech.h b/sound/pci/ice1712/hoontech.h index 1ee538b20fb..cc1da1e69ad 100644 --- a/sound/pci/ice1712/hoontech.h +++ b/sound/pci/ice1712/hoontech.h @@ -6,7 +6,7 @@ * * Lowlevel functions for Hoontech STDSP24 * - * Copyright (c) 2000 Jaroslav Kysela + * Copyright (c) 2000 Jaroslav Kysela * * 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/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c index caa0886d460..052fc3cb327 100644 --- a/sound/pci/ice1712/ice1712.c +++ b/sound/pci/ice1712/ice1712.c @@ -1,7 +1,7 @@ /* * ALSA driver for ICEnsemble ICE1712 (Envy24) * - * Copyright (c) 2000 Jaroslav Kysela + * Copyright (c) 2000 Jaroslav Kysela * * 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 @@ -73,7 +73,7 @@ #include "ews.h" #include "hoontech.h" -MODULE_AUTHOR("Jaroslav Kysela "); +MODULE_AUTHOR("Jaroslav Kysela "); MODULE_DESCRIPTION("ICEnsemble ICE1712 (Envy24)"); MODULE_LICENSE("GPL"); MODULE_SUPPORTED_DEVICE("{" diff --git a/sound/pci/ice1712/ice1712.h b/sound/pci/ice1712/ice1712.h index d072f7b98b2..58640afa540 100644 --- a/sound/pci/ice1712/ice1712.h +++ b/sound/pci/ice1712/ice1712.h @@ -4,7 +4,7 @@ /* * ALSA driver for ICEnsemble ICE1712 (Envy24) * - * Copyright (c) 2000 Jaroslav Kysela + * Copyright (c) 2000 Jaroslav Kysela * * 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/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c index 23c9383e7cc..0b0bbb0d96b 100644 --- a/sound/pci/ice1712/ice1724.c +++ b/sound/pci/ice1712/ice1724.c @@ -2,7 +2,7 @@ * ALSA driver for VT1724 ICEnsemble ICE1724 / VIA VT1724 (Envy24HT) * VIA VT1720 (Envy24PT) * - * Copyright (c) 2000 Jaroslav Kysela + * Copyright (c) 2000 Jaroslav Kysela * 2002 James Stafford * 2003 Takashi Iwai * @@ -52,7 +52,7 @@ #include "phase.h" #include "wtm.h" -MODULE_AUTHOR("Jaroslav Kysela "); +MODULE_AUTHOR("Jaroslav Kysela "); MODULE_DESCRIPTION("VIA ICEnsemble ICE1724/1720 (Envy24HT/PT)"); MODULE_LICENSE("GPL"); MODULE_SUPPORTED_DEVICE("{" diff --git a/sound/pci/ice1712/juli.c b/sound/pci/ice1712/juli.c index 3d8e74e493d..1fbe3ef8e60 100644 --- a/sound/pci/ice1712/juli.c +++ b/sound/pci/ice1712/juli.c @@ -3,7 +3,7 @@ * * Lowlevel functions for ESI Juli@ cards * - * Copyright (c) 2004 Jaroslav Kysela + * Copyright (c) 2004 Jaroslav Kysela * * 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/pci/intel8x0.c b/sound/pci/intel8x0.c index da9734073db..b4a38a3d855 100644 --- a/sound/pci/intel8x0.c +++ b/sound/pci/intel8x0.c @@ -1,7 +1,7 @@ /* * ALSA driver for Intel ICH (i8x0) chipsets * - * Copyright (c) 2000 Jaroslav Kysela + * Copyright (c) 2000 Jaroslav Kysela * * * This code also contains alpha support for SiS 735 chipsets provided @@ -43,7 +43,7 @@ #include #include -MODULE_AUTHOR("Jaroslav Kysela "); +MODULE_AUTHOR("Jaroslav Kysela "); MODULE_DESCRIPTION("Intel 82801AA,82901AB,i810,i820,i830,i840,i845,MX440; SiS 7012; Ali 5455"); MODULE_LICENSE("GPL"); MODULE_SUPPORTED_DEVICE("{{Intel,82801AA-ICH}," diff --git a/sound/pci/intel8x0m.c b/sound/pci/intel8x0m.c index c155e1f3a0e..fad806e60f3 100644 --- a/sound/pci/intel8x0m.c +++ b/sound/pci/intel8x0m.c @@ -1,7 +1,7 @@ /* * ALSA modem driver for Intel ICH (i8x0) chipsets * - * Copyright (c) 2000 Jaroslav Kysela + * Copyright (c) 2000 Jaroslav Kysela * * This is modified (by Sasha Khapyorsky ) version * of ALSA ICH sound driver intel8x0.c . @@ -37,7 +37,7 @@ #include #include -MODULE_AUTHOR("Jaroslav Kysela "); +MODULE_AUTHOR("Jaroslav Kysela "); MODULE_DESCRIPTION("Intel 82801AA,82901AB,i810,i820,i830,i840,i845,MX440; " "SiS 7013; NVidia MCP/2/2S/3 modems"); MODULE_LICENSE("GPL"); diff --git a/sound/pci/korg1212/Makefile b/sound/pci/korg1212/Makefile index 78c9dc6eeb2..f11ce1b1b3d 100644 --- a/sound/pci/korg1212/Makefile +++ b/sound/pci/korg1212/Makefile @@ -1,6 +1,6 @@ # # Makefile for ALSA -# Copyright (c) 2001 by Jaroslav Kysela +# Copyright (c) 2001 by Jaroslav Kysela # snd-korg1212-objs := korg1212.o diff --git a/sound/pci/mixart/Makefile b/sound/pci/mixart/Makefile index fe6ba0c4b56..cce159ec562 100644 --- a/sound/pci/mixart/Makefile +++ b/sound/pci/mixart/Makefile @@ -1,6 +1,6 @@ # # Makefile for ALSA -# Copyright (c) 2001 by Jaroslav Kysela +# Copyright (c) 2001 by Jaroslav Kysela # snd-mixart-objs := mixart.o mixart_core.o mixart_hwdep.o mixart_mixer.o diff --git a/sound/pci/nm256/Makefile b/sound/pci/nm256/Makefile index d91d8c51921..a1bd44ff850 100644 --- a/sound/pci/nm256/Makefile +++ b/sound/pci/nm256/Makefile @@ -1,6 +1,6 @@ # # Makefile for ALSA -# Copyright (c) 2001 by Jaroslav Kysela +# Copyright (c) 2001 by Jaroslav Kysela # snd-nm256-objs := nm256.o diff --git a/sound/pci/rme9652/Makefile b/sound/pci/rme9652/Makefile index d2c294e136f..dcba5604020 100644 --- a/sound/pci/rme9652/Makefile +++ b/sound/pci/rme9652/Makefile @@ -1,6 +1,6 @@ # # Makefile for ALSA -# Copyright (c) 2001 by Jaroslav Kysela +# Copyright (c) 2001 by Jaroslav Kysela # snd-rme9652-objs := rme9652.o diff --git a/sound/pci/sonicvibes.c b/sound/pci/sonicvibes.c index 9f25d93cbec..44a7f5fad57 100644 --- a/sound/pci/sonicvibes.c +++ b/sound/pci/sonicvibes.c @@ -1,6 +1,6 @@ /* * Driver for S3 SonicVibes soundcard - * Copyright (c) by Jaroslav Kysela + * Copyright (c) by Jaroslav Kysela * * BUGS: * It looks like 86c617 rev 3 doesn't supports DDMA buffers above 16MB? @@ -42,7 +42,7 @@ #include -MODULE_AUTHOR("Jaroslav Kysela "); +MODULE_AUTHOR("Jaroslav Kysela "); MODULE_DESCRIPTION("S3 SonicVibes PCI"); MODULE_LICENSE("GPL"); MODULE_SUPPORTED_DEVICE("{{S3,SonicVibes PCI}}"); diff --git a/sound/pci/trident/Makefile b/sound/pci/trident/Makefile index 65bc5b70323..65f2c218324 100644 --- a/sound/pci/trident/Makefile +++ b/sound/pci/trident/Makefile @@ -1,6 +1,6 @@ # # Makefile for ALSA -# Copyright (c) 2001 by Jaroslav Kysela +# Copyright (c) 2001 by Jaroslav Kysela # snd-trident-objs := trident.o trident_main.o trident_memory.o diff --git a/sound/pci/trident/trident.c b/sound/pci/trident/trident.c index 9145f7c57fb..84884567df6 100644 --- a/sound/pci/trident/trident.c +++ b/sound/pci/trident/trident.c @@ -30,7 +30,7 @@ #include #include -MODULE_AUTHOR("Jaroslav Kysela , "); +MODULE_AUTHOR("Jaroslav Kysela , "); MODULE_DESCRIPTION("Trident 4D-WaveDX/NX & SiS SI7018"); MODULE_LICENSE("GPL"); MODULE_SUPPORTED_DEVICE("{{Trident,4DWave DX}," diff --git a/sound/pci/trident/trident_main.c b/sound/pci/trident/trident_main.c index 00e4004d563..a235e034a69 100644 --- a/sound/pci/trident/trident_main.c +++ b/sound/pci/trident/trident_main.c @@ -1,5 +1,5 @@ /* - * Maintained by Jaroslav Kysela + * Maintained by Jaroslav Kysela * Originated by audio@tridentmicro.com * Fri Feb 19 15:55:28 MST 1999 * Routines for control of Trident 4DWave (DX and NX) chip diff --git a/sound/pci/trident/trident_memory.c b/sound/pci/trident/trident_memory.c index aff3f874131..847b8c6d5c0 100644 --- a/sound/pci/trident/trident_memory.c +++ b/sound/pci/trident/trident_memory.c @@ -1,5 +1,5 @@ /* - * Copyright (c) by Jaroslav Kysela + * Copyright (c) by Jaroslav Kysela * Copyright (c) by Takashi Iwai * Copyright (c) by Scott McNab * diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c index 69487f68118..cf62d2ab8d7 100644 --- a/sound/pci/via82xx.c +++ b/sound/pci/via82xx.c @@ -3,7 +3,7 @@ * * VT82C686A/B/C, VT8233A/C, VT8235 * - * Copyright (c) 2000 Jaroslav Kysela + * Copyright (c) 2000 Jaroslav Kysela * Tjeerd.Mulder * 2002 Takashi Iwai * @@ -68,7 +68,7 @@ #define POINTER_DEBUG #endif -MODULE_AUTHOR("Jaroslav Kysela "); +MODULE_AUTHOR("Jaroslav Kysela "); MODULE_DESCRIPTION("VIA VT82xx audio"); MODULE_LICENSE("GPL"); MODULE_SUPPORTED_DEVICE("{{VIA,VT82C686A/B/C,pci},{VIA,VT8233A/C,8235}}"); diff --git a/sound/pci/via82xx_modem.c b/sound/pci/via82xx_modem.c index 3aa9d31d999..57fb9ae22f9 100644 --- a/sound/pci/via82xx_modem.c +++ b/sound/pci/via82xx_modem.c @@ -3,7 +3,7 @@ * * VT82C686A/B/C, VT8233A/C, VT8235 * - * Copyright (c) 2000 Jaroslav Kysela + * Copyright (c) 2000 Jaroslav Kysela * Tjeerd.Mulder * 2002 Takashi Iwai * @@ -50,7 +50,7 @@ #define POINTER_DEBUG #endif -MODULE_AUTHOR("Jaroslav Kysela "); +MODULE_AUTHOR("Jaroslav Kysela "); MODULE_DESCRIPTION("VIA VT82xx modem"); MODULE_LICENSE("GPL"); MODULE_SUPPORTED_DEVICE("{{VIA,VT82C686A/B/C modem,pci}}"); diff --git a/sound/pci/vx222/Makefile b/sound/pci/vx222/Makefile index 058c8bff7c1..a4d08d4de35 100644 --- a/sound/pci/vx222/Makefile +++ b/sound/pci/vx222/Makefile @@ -1,6 +1,6 @@ # # Makefile for ALSA -# Copyright (c) 2001 by Jaroslav Kysela +# Copyright (c) 2001 by Jaroslav Kysela # snd-vx222-objs := vx222.o vx222_ops.o diff --git a/sound/pci/ymfpci/Makefile b/sound/pci/ymfpci/Makefile index 8790c5f3ed0..bd3d514ed76 100644 --- a/sound/pci/ymfpci/Makefile +++ b/sound/pci/ymfpci/Makefile @@ -1,6 +1,6 @@ # # Makefile for ALSA -# Copyright (c) 2001 by Jaroslav Kysela +# Copyright (c) 2001 by Jaroslav Kysela # snd-ymfpci-objs := ymfpci.o ymfpci_main.o diff --git a/sound/pci/ymfpci/ymfpci.c b/sound/pci/ymfpci/ymfpci.c index fd9b7b83a88..5c4256a4d4b 100644 --- a/sound/pci/ymfpci/ymfpci.c +++ b/sound/pci/ymfpci/ymfpci.c @@ -1,6 +1,6 @@ /* * The driver for the Yamaha's DS1/DS1E cards - * Copyright (c) by Jaroslav Kysela + * Copyright (c) by Jaroslav Kysela * * * This program is free software; you can redistribute it and/or modify @@ -30,7 +30,7 @@ #include #include -MODULE_AUTHOR("Jaroslav Kysela "); +MODULE_AUTHOR("Jaroslav Kysela "); MODULE_DESCRIPTION("Yamaha DS-1 PCI"); MODULE_LICENSE("GPL"); MODULE_SUPPORTED_DEVICE("{{Yamaha,YMF724}," diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c index e76ed5dfc86..1fe39ed2876 100644 --- a/sound/pci/ymfpci/ymfpci_main.c +++ b/sound/pci/ymfpci/ymfpci_main.c @@ -1,5 +1,5 @@ /* - * Copyright (c) by Jaroslav Kysela + * Copyright (c) by Jaroslav Kysela * Routines for control of YMF724/740/744/754 chips * * This program is free software; you can redistribute it and/or modify -- cgit v1.2.3 From 9066f2443122c1501da64b6faa0038c13f0209f9 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 16 Oct 2007 14:25:16 +0200 Subject: [ALSA] hda-codec - Fix STAC922x volume knob control Reported by zhejiang 'I found that STAC_VOLKNOB hardwired the KNOB nid to 0x24. It is okay for stac9205 and stac927x. But the VolumeKnob nid of stac9220-9221 is 0x16.' Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_sigmatel.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 8b3576007d4..626a5edde06 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -352,7 +352,7 @@ static int stac92xx_volknob_info(struct snd_kcontrol *kcontrol, static int stac92xx_volknob_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - ucontrol->value.integer.value[0] = kcontrol->private_value; + ucontrol->value.integer.value[0] = kcontrol->private_value & 0xff; return 0; } @@ -360,15 +360,17 @@ static int stac92xx_volknob_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + unsigned int val = kcontrol->private_value & 0xff; - if (kcontrol->private_value == ucontrol->value.integer.value[0]) + if (val == ucontrol->value.integer.value[0]) return 0; - kcontrol->private_value = ucontrol->value.integer.value[0]; + val = ucontrol->value.integer.value[0]; + kcontrol->private_value &= ~0xff; + kcontrol->private_value |= val; - snd_hda_codec_write_cache(codec, 0x24, 0, - AC_VERB_SET_VOLUME_KNOB_CONTROL, - kcontrol->private_value | 0x80); + snd_hda_codec_write_cache(codec, kcontrol->private_value >> 16, 0, + AC_VERB_SET_VOLUME_KNOB_CONTROL, val | 0x80); return 1; } @@ -441,7 +443,7 @@ static struct hda_verb stac9205_core_init[] = { .private_value = verb_read | (verb_write << 16), \ } -#define STAC_VOLKNOB \ +#define STAC_VOLKNOB(knob_nid) \ { \ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ .name = "Master Playback Volume", \ @@ -449,7 +451,7 @@ static struct hda_verb stac9205_core_init[] = { .info = stac92xx_volknob_info, \ .get = stac92xx_volknob_get, \ .put = stac92xx_volknob_put, \ - .private_value = 127, \ + .private_value = 127 | (knob_nid << 16), \ } @@ -482,7 +484,7 @@ static struct snd_kcontrol_new stac9205_mixer[] = { }, STAC_INPUT_SOURCE(2), STAC_ANALOG_LOOPBACK(0xFE0, 0x7E0), - STAC_VOLKNOB, + STAC_VOLKNOB(0x24), HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1b, 0x0, HDA_INPUT), HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1d, 0x0, HDA_OUTPUT), @@ -498,7 +500,7 @@ static struct snd_kcontrol_new stac9205_mixer[] = { /* This needs to be generated dynamically based on sequence */ static struct snd_kcontrol_new stac922x_mixer[] = { STAC_INPUT_SOURCE(2), - STAC_VOLKNOB, + STAC_VOLKNOB(0x16), HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x17, 0x0, HDA_INPUT), HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x17, 0x0, HDA_INPUT), HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x0, 0x12, 0x0, HDA_OUTPUT), @@ -512,7 +514,7 @@ static struct snd_kcontrol_new stac922x_mixer[] = { static struct snd_kcontrol_new stac927x_mixer[] = { STAC_INPUT_SOURCE(3), - STAC_VOLKNOB, + STAC_VOLKNOB(0x24), STAC_ANALOG_LOOPBACK(0xFEB, 0x7EB), HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x18, 0x0, HDA_INPUT), -- cgit v1.2.3 From 2a3988f6d2c5be9d02463097775d1c66a8290527 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 16 Oct 2007 14:26:32 +0200 Subject: [ALSA] hdsp - Fix zero division Fix zero-division bug in the calculation dds offset. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/rme9652/hdsp.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'sound/pci') diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c index 2411f0b396b..ff26a3672d4 100644 --- a/sound/pci/rme9652/hdsp.c +++ b/sound/pci/rme9652/hdsp.c @@ -3059,6 +3059,9 @@ static int hdsp_dds_offset(struct hdsp *hdsp) unsigned int dds_value = hdsp->dds_value; int system_sample_rate = hdsp->system_sample_rate; + if (!dds_value) + return 0; + n = DDS_NUMERATOR; /* * dds_value = n / rate -- cgit v1.2.3 From f6e9852ad05fa28301c83d4e2b082620de010358 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 16 Oct 2007 14:27:04 +0200 Subject: [ALSA] hda-codec - Add array terminator for dmic in STAC codec Reported by Jan-Marek Glogowski. The dmic array is passed to snd_hda_parse_pin_def_config() and should be zero-terminated. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_sigmatel.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 626a5edde06..bf950195107 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -183,8 +183,9 @@ static hda_nid_t stac925x_dac_nids[1] = { 0x02, }; -static hda_nid_t stac925x_dmic_nids[1] = { - 0x15, +#define STAC925X_NUM_DMICS 1 +static hda_nid_t stac925x_dmic_nids[STAC925X_NUM_DMICS + 1] = { + 0x15, 0 }; static hda_nid_t stac922x_adc_nids[2] = { @@ -211,8 +212,9 @@ static hda_nid_t stac9205_mux_nids[2] = { 0x19, 0x1a }; -static hda_nid_t stac9205_dmic_nids[2] = { - 0x17, 0x18, +#define STAC9205_NUM_DMICS 2 +static hda_nid_t stac9205_dmic_nids[STAC9205_NUM_DMICS + 1] = { + 0x17, 0x18, 0 }; static hda_nid_t stac9200_pin_nids[8] = { @@ -2569,7 +2571,7 @@ static int patch_stac925x(struct hda_codec *codec) case 0x83847633: /* STAC9202D */ case 0x83847636: /* STAC9251 */ case 0x83847637: /* STAC9251D */ - spec->num_dmics = 1; + spec->num_dmics = STAC925X_NUM_DMICS; spec->dmic_nids = stac925x_dmic_nids; break; default: @@ -2819,7 +2821,7 @@ static int patch_stac9205(struct hda_codec *codec) spec->mux_nids = stac9205_mux_nids; spec->num_muxes = ARRAY_SIZE(stac9205_mux_nids); spec->dmic_nids = stac9205_dmic_nids; - spec->num_dmics = ARRAY_SIZE(stac9205_dmic_nids); + spec->num_dmics = STAC9205_NUM_DMICS; spec->dmux_nid = 0x1d; spec->init = stac9205_core_init; -- cgit v1.2.3 From 291702f017efdfe556cb87b8530eb7d1ff08cbae Mon Sep 17 00:00:00 2001 From: Kailang Yang Date: Tue, 16 Oct 2007 14:28:03 +0200 Subject: [ALSA] Support ASUS P701 eeepc [0x1043 0x82a1] support Signed-off-by: Kailang Yang Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_realtek.c | 100 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 94 insertions(+), 6 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 1d2cd4c4b16..c8ca97b2c31 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -143,6 +143,7 @@ enum { ALC662_3ST_6ch, ALC662_5ST_DIG, ALC662_LENOVO_101E, + ALC662_ASUS_EEEPC_P701, ALC662_AUTO, ALC662_MODEL_LAST, }; @@ -11432,6 +11433,15 @@ static struct hda_input_mux alc662_lenovo_101e_capture_source = { { "Line", 0x2 }, }, }; + +static struct hda_input_mux alc662_eeepc_capture_source = { + .num_items = 2, + .items = { + { "i-Mic", 0x1 }, + { "e-Mic", 0x0 }, + }, +}; + #define alc662_mux_enum_info alc_mux_enum_info #define alc662_mux_enum_get alc_mux_enum_get @@ -11648,6 +11658,22 @@ static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = { { } /* end */ }; +static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = { + HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), + + HDA_CODEC_VOLUME("LineOut Playback Volume", 0x02, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE("LineOut Playback Switch", 0x1b, 0x0, HDA_OUTPUT), + + HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT), + HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), + + HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT), + HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), + { } /* end */ +}; + static struct snd_kcontrol_new alc662_chmode_mixer[] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, @@ -11713,13 +11739,24 @@ static struct hda_verb alc662_init_verbs[] = { {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, + + {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, + {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, + {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, { } }; static struct hda_verb alc662_sue_init_verbs[] = { {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT}, {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT}, - {} + {} +}; + +static struct hda_verb alc662_eeepc_sue_init_verbs[] = { + {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, + {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, + {} }; /* @@ -11825,6 +11862,39 @@ static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec, alc662_lenovo_101e_ispeaker_automute(codec); } +static void alc662_eeepc_mic_automute(struct hda_codec *codec) +{ + unsigned int present; + + present = snd_hda_codec_read(codec, 0x18, 0, + AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; + snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE, + 0x7000 | (0x00 << 8) | (present ? 0 : 0x80)); + snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE, + 0x7000 | (0x00 << 8) | (present ? 0 : 0x80)); + snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE, + 0x7000 | (0x01 << 8) | (present ? 0x80 : 0)); + snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE, + 0x7000 | (0x01 << 8) | (present ? 0x80 : 0)); +} + +/* unsolicited event for HP jack sensing */ +static void alc662_eeepc_unsol_event(struct hda_codec *codec, + unsigned int res) +{ + if ((res >> 26) == ALC880_HP_EVENT) + alc262_hippo1_automute( codec ); + + if ((res >> 26) == ALC880_MIC_EVENT) + alc662_eeepc_mic_automute(codec); +} + +static void alc662_eeepc_inithook(struct hda_codec *codec) +{ + alc262_hippo1_automute( codec ); + alc662_eeepc_mic_automute(codec); +} + #ifdef CONFIG_SND_HDA_POWER_SAVE #define alc662_loopbacks alc880_loopbacks #endif @@ -11850,12 +11920,13 @@ static const char *alc662_models[ALC662_MODEL_LAST] = { static struct snd_pci_quirk alc662_cfg_tbl[] = { SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E), + SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701), {} }; static struct alc_config_preset alc662_presets[] = { [ALC662_3ST_2ch_DIG] = { - .mixers = { alc662_3ST_2ch_mixer }, + .mixers = { alc662_3ST_2ch_mixer, alc662_capture_mixer }, .init_verbs = { alc662_init_verbs }, .num_dacs = ARRAY_SIZE(alc662_dac_nids), .dac_nids = alc662_dac_nids, @@ -11868,7 +11939,8 @@ static struct alc_config_preset alc662_presets[] = { .input_mux = &alc662_capture_source, }, [ALC662_3ST_6ch_DIG] = { - .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer }, + .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer, + alc662_capture_mixer }, .init_verbs = { alc662_init_verbs }, .num_dacs = ARRAY_SIZE(alc662_dac_nids), .dac_nids = alc662_dac_nids, @@ -11882,7 +11954,8 @@ static struct alc_config_preset alc662_presets[] = { .input_mux = &alc662_capture_source, }, [ALC662_3ST_6ch] = { - .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer }, + .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer, + alc662_capture_mixer }, .init_verbs = { alc662_init_verbs }, .num_dacs = ARRAY_SIZE(alc662_dac_nids), .dac_nids = alc662_dac_nids, @@ -11894,7 +11967,8 @@ static struct alc_config_preset alc662_presets[] = { .input_mux = &alc662_capture_source, }, [ALC662_5ST_DIG] = { - .mixers = { alc662_base_mixer, alc662_chmode_mixer }, + .mixers = { alc662_base_mixer, alc662_chmode_mixer, + alc662_capture_mixer }, .init_verbs = { alc662_init_verbs }, .num_dacs = ARRAY_SIZE(alc662_dac_nids), .dac_nids = alc662_dac_nids, @@ -11907,7 +11981,7 @@ static struct alc_config_preset alc662_presets[] = { .input_mux = &alc662_capture_source, }, [ALC662_LENOVO_101E] = { - .mixers = { alc662_lenovo_101e_mixer }, + .mixers = { alc662_lenovo_101e_mixer, alc662_capture_mixer }, .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs }, .num_dacs = ARRAY_SIZE(alc662_dac_nids), .dac_nids = alc662_dac_nids, @@ -11919,6 +11993,20 @@ static struct alc_config_preset alc662_presets[] = { .unsol_event = alc662_lenovo_101e_unsol_event, .init_hook = alc662_lenovo_101e_all_automute, }, + [ALC662_ASUS_EEEPC_P701] = { + .mixers = { alc662_eeepc_p701_mixer, alc662_capture_mixer }, + .init_verbs = { alc662_init_verbs, + alc662_eeepc_sue_init_verbs }, + .num_dacs = ARRAY_SIZE(alc662_dac_nids), + .dac_nids = alc662_dac_nids, + .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids), + .adc_nids = alc662_adc_nids, + .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), + .channel_mode = alc662_3ST_2ch_modes, + .input_mux = &alc662_eeepc_capture_source, + .unsol_event = alc662_eeepc_unsol_event, + .init_hook = alc662_eeepc_inithook, + }, }; -- cgit v1.2.3 From c9b58006be7e471a5f55d171cbaa08f4aa8078ea Mon Sep 17 00:00:00 2001 From: Kailang Yang Date: Tue, 16 Oct 2007 14:30:01 +0200 Subject: [ALSA] hda-codec - Fix SKU ID function for realtek codecs Fixed SKU ID function for realtek codecs. It's used by the automatic BIOS configuration mode. Now it supports the correct jack-detection mechanism, too. Signed-off-by: Kailang Yang Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_realtek.c | 193 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 168 insertions(+), 25 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index c8ca97b2c31..53b0428abfc 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -662,6 +662,44 @@ static struct hda_verb alc_gpio3_init_verbs[] = { { } }; +static void alc_sku_automute(struct hda_codec *codec) +{ + struct alc_spec *spec = codec->spec; + unsigned int mute; + unsigned int present; + unsigned int hp_nid = spec->autocfg.hp_pins[0]; + unsigned int sp_nid = spec->autocfg.speaker_pins[0]; + + /* need to execute and sync at first */ + snd_hda_codec_read(codec, hp_nid, 0, AC_VERB_SET_PIN_SENSE, 0); + present = snd_hda_codec_read(codec, hp_nid, 0, + AC_VERB_GET_PIN_SENSE, 0); + spec->jack_present = (present & 0x80000000) != 0; + if (spec->jack_present) { + /* mute internal speaker */ + snd_hda_codec_amp_stereo(codec, sp_nid, HDA_OUTPUT, 0, + HDA_AMP_MUTE, HDA_AMP_MUTE); + } else { + /* unmute internal speaker if necessary */ + mute = snd_hda_codec_amp_read(codec, hp_nid, 0, HDA_OUTPUT, 0); + snd_hda_codec_amp_stereo(codec, sp_nid, HDA_OUTPUT, 0, + HDA_AMP_MUTE, mute); + } +} + +/* unsolicited event for HP jack sensing */ +static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res) +{ + if (codec->vendor_id == 0x10ec0880) + res >>= 28; + else + res >>= 26; + if (res != ALC880_HP_EVENT) + return; + + alc_sku_automute(codec); +} + /* 32-bit subsystem ID for BIOS loading in HD Audio codec. * 31 ~ 16 : Manufacture ID * 15 ~ 8 : SKU ID @@ -672,13 +710,48 @@ static void alc_subsystem_id(struct hda_codec *codec, unsigned int porta, unsigned int porte, unsigned int portd) { - unsigned int ass, tmp; + unsigned int ass, tmp, i; + unsigned nid; + struct alc_spec *spec = codec->spec; - ass = codec->subsystem_id; - if (!(ass & 1)) + ass = codec->subsystem_id & 0xffff; + if ((ass != codec->bus->pci->subsystem_device) && (ass & 1)) + goto do_sku; + + /* + * 31~30 : port conetcivity + * 29~21 : reserve + * 20 : PCBEEP input + * 19~16 : Check sum (15:1) + * 15~1 : Custom + * 0 : override + */ + nid = 0x1d; + if (codec->vendor_id == 0x10ec0260) + nid = 0x17; + ass = snd_hda_codec_read(codec, nid, 0, + AC_VERB_GET_CONFIG_DEFAULT, 0); + if (!(ass & 1) && !(ass & 0x100000)) + return; + if ((ass >> 30) != 1) /* no physical connection */ return; - /* Override */ + /* check sum */ + tmp = 0; + for (i = 1; i < 16; i++) { + if ((ass >> i) && 1) + tmp++; + } + if (((ass >> 16) & 0xf) != tmp) + return; +do_sku: + /* + * 0 : override + * 1 : Swap Jack + * 2 : 0 --> Desktop, 1 --> Laptop + * 3~5 : External Amplifier control + * 7~6 : Reserved + */ tmp = (ass & 0x38) >> 3; /* external Amp control */ switch (tmp) { case 1: @@ -690,38 +763,108 @@ static void alc_subsystem_id(struct hda_codec *codec, case 7: snd_hda_sequence_write(codec, alc_gpio3_init_verbs); break; - case 5: + case 5: /* set EAPD output high */ switch (codec->vendor_id) { - case 0x10ec0862: - case 0x10ec0660: - case 0x10ec0662: + case 0x10ec0260: + snd_hda_codec_write(codec, 0x0f, 0, + AC_VERB_SET_EAPD_BTLENABLE, 2); + snd_hda_codec_write(codec, 0x10, 0, + AC_VERB_SET_EAPD_BTLENABLE, 2); + break; + case 0x10ec0262: case 0x10ec0267: case 0x10ec0268: + case 0x10ec0269: + case 0x10ec0862: + case 0x10ec0662: snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_EAPD_BTLENABLE, 2); snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_EAPD_BTLENABLE, 2); - return; + break; } - case 6: - if (ass & 4) { /* bit 2 : 0 = Desktop, 1 = Laptop */ - hda_nid_t port = 0; - tmp = (ass & 0x1800) >> 11; - switch (tmp) { - case 0: port = porta; break; - case 1: port = porte; break; - case 2: port = portd; break; - } - if (port) - snd_hda_codec_write(codec, port, 0, - AC_VERB_SET_EAPD_BTLENABLE, - 2); + switch (codec->vendor_id) { + case 0x10ec0260: + snd_hda_codec_write(codec, 0x1a, 0, + AC_VERB_SET_COEF_INDEX, 7); + tmp = snd_hda_codec_read(codec, 0x1a, 0, + AC_VERB_GET_PROC_COEF, 0); + snd_hda_codec_write(codec, 0x1a, 0, + AC_VERB_SET_COEF_INDEX, 7); + snd_hda_codec_write(codec, 0x1a, 0, + AC_VERB_SET_PROC_COEF, + tmp | 0x2010); + break; + case 0x10ec0262: + case 0x10ec0880: + case 0x10ec0882: + case 0x10ec0883: + case 0x10ec0885: + case 0x10ec0888: + snd_hda_codec_write(codec, 0x20, 0, + AC_VERB_SET_COEF_INDEX, 7); + tmp = snd_hda_codec_read(codec, 0x20, 0, + AC_VERB_GET_PROC_COEF, 0); + snd_hda_codec_write(codec, 0x20, 0, + AC_VERB_SET_COEF_INDEX, 7); + snd_hda_codec_write(codec, 0x20, 0, + AC_VERB_SET_PROC_COEF, + tmp | 0x2010); + break; + case 0x10ec0267: + case 0x10ec0268: + snd_hda_codec_write(codec, 0x20, 0, + AC_VERB_SET_COEF_INDEX, 7); + tmp = snd_hda_codec_read(codec, 0x20, 0, + AC_VERB_GET_PROC_COEF, 0); + snd_hda_codec_write(codec, 0x20, 0, + AC_VERB_SET_COEF_INDEX, 7); + snd_hda_codec_write(codec, 0x20, 0, + AC_VERB_SET_PROC_COEF, + tmp | 0x3000); + break; } - snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7); - snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, - (tmp == 5 ? 0x3040 : 0x3050)); + default: break; } + + /* is laptop and enable the function "Mute internal speaker + * when the external headphone out jack is plugged" + */ + if (!(ass & 0x4) || !(ass & 0x8000)) + return; + /* + * 10~8 : Jack location + * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered + * 14~13: Resvered + * 15 : 1 --> enable the function "Mute internal speaker + * when the external headphone out jack is plugged" + */ + if (!spec->autocfg.speaker_pins[0]) { + if (spec->multiout.dac_nids[0]) + spec->autocfg.speaker_pins[0] = + spec->multiout.dac_nids[0]; + else + return; + } + + if (!spec->autocfg.hp_pins[0]) { + tmp = (ass >> 11) & 0x3; /* HP to chassis */ + if (tmp == 0) + spec->autocfg.hp_pins[0] = porta; + else if (tmp == 1) + spec->autocfg.hp_pins[0] = porte; + else if (tmp == 2) + spec->autocfg.hp_pins[0] = portd; + else + return; + } + + snd_hda_codec_write(codec, spec->autocfg.hp_pins[0], 0, + AC_VERB_SET_UNSOLICITED_ENABLE, + AC_USRSP_EN | ALC880_HP_EVENT); + spec->unsol_event = alc_sku_unsol_event; + spec->init_hook = alc_sku_automute; } /* -- cgit v1.2.3