summaryrefslogtreecommitdiff
path: root/sound/pci
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2008-10-15 13:46:29 +0200
committerIngo Molnar <mingo@elte.hu>2008-10-15 13:46:29 +0200
commitb2aaf8f74cdc84a9182f6cabf198b7763bcb9d40 (patch)
tree53ccb1c2c14751fe69cf93102e76e97021f6df07 /sound/pci
parent4f962d4d65923d7b722192e729840cfb79af0a5a (diff)
parent278429cff8809958d25415ba0ed32b59866ab1a8 (diff)
Merge branch 'linus' into stackprotector
Conflicts: arch/x86/kernel/Makefile include/asm-x86/pda.h
Diffstat (limited to 'sound/pci')
-rw-r--r--sound/pci/Kconfig167
-rw-r--r--sound/pci/Makefile2
-rw-r--r--sound/pci/ac97/Makefile12
-rw-r--r--sound/pci/ac97/ac97_codec.c55
-rw-r--r--sound/pci/ac97/ac97_patch.c291
-rw-r--r--sound/pci/ad1889.c6
-rw-r--r--sound/pci/ak4531_codec.c (renamed from sound/pci/ac97/ak4531_codec.c)44
-rw-r--r--sound/pci/als4000.c391
-rw-r--r--sound/pci/atiixp.c13
-rw-r--r--sound/pci/atiixp_modem.c10
-rw-r--r--sound/pci/au88x0/au88x0.h7
-rw-r--r--sound/pci/au88x0/au88x0_core.c40
-rw-r--r--sound/pci/au88x0/au88x0_game.c2
-rw-r--r--sound/pci/au88x0/au88x0_pcm.c14
-rw-r--r--sound/pci/azt3328.c1239
-rw-r--r--sound/pci/azt3328.h207
-rw-r--r--sound/pci/bt87x.c5
-rw-r--r--sound/pci/ca0106/ca0106_main.c6
-rw-r--r--sound/pci/ca0106/ca_midi.c20
-rw-r--r--sound/pci/cmipci.c9
-rw-r--r--sound/pci/cs4281.c13
-rw-r--r--sound/pci/cs46xx/cs46xx_lib.c91
-rw-r--r--sound/pci/cs46xx/dsp_spos.c51
-rw-r--r--sound/pci/cs46xx/dsp_spos_scb_lib.c115
-rw-r--r--sound/pci/echoaudio/darla20_dsp.c3
-rw-r--r--sound/pci/echoaudio/darla24_dsp.c8
-rw-r--r--sound/pci/echoaudio/echo3g_dsp.c9
-rw-r--r--sound/pci/echoaudio/echoaudio.c22
-rw-r--r--sound/pci/echoaudio/echoaudio_3g.c11
-rw-r--r--sound/pci/echoaudio/echoaudio_dsp.c21
-rw-r--r--sound/pci/echoaudio/echoaudio_gml.c6
-rw-r--r--sound/pci/echoaudio/gina20_dsp.c6
-rw-r--r--sound/pci/echoaudio/gina24_dsp.c11
-rw-r--r--sound/pci/echoaudio/indigo_dsp.c8
-rw-r--r--sound/pci/echoaudio/indigodj_dsp.c8
-rw-r--r--sound/pci/echoaudio/indigoio_dsp.c8
-rw-r--r--sound/pci/echoaudio/layla20_dsp.c9
-rw-r--r--sound/pci/echoaudio/layla24_dsp.c11
-rw-r--r--sound/pci/echoaudio/mia_dsp.c13
-rw-r--r--sound/pci/echoaudio/midi.c6
-rw-r--r--sound/pci/echoaudio/mona_dsp.c6
-rw-r--r--sound/pci/emu10k1/emu10k1_callback.c6
-rw-r--r--sound/pci/emu10k1/emu10k1_main.c1
-rw-r--r--sound/pci/emu10k1/emu10k1_patch.c23
-rw-r--r--sound/pci/emu10k1/emu10k1x.c18
-rw-r--r--sound/pci/emu10k1/emufx.c6
-rw-r--r--sound/pci/emu10k1/emumixer.c13
-rw-r--r--sound/pci/emu10k1/emumpu401.c18
-rw-r--r--sound/pci/emu10k1/memory.c100
-rw-r--r--sound/pci/emu10k1/voice.c9
-rw-r--r--sound/pci/ens1370.c3
-rw-r--r--sound/pci/es1938.c3
-rw-r--r--sound/pci/es1968.c6
-rw-r--r--sound/pci/hda/Makefile2
-rw-r--r--sound/pci/hda/hda_beep.c134
-rw-r--r--sound/pci/hda/hda_beep.h44
-rw-r--r--sound/pci/hda/hda_codec.c115
-rw-r--r--sound/pci/hda/hda_codec.h95
-rw-r--r--sound/pci/hda/hda_generic.c3
-rw-r--r--sound/pci/hda/hda_hwdep.c2
-rw-r--r--sound/pci/hda/hda_intel.c453
-rw-r--r--sound/pci/hda/hda_local.h24
-rw-r--r--sound/pci/hda/hda_patch.h2
-rw-r--r--sound/pci/hda/hda_proc.c30
-rw-r--r--sound/pci/hda/patch_analog.c134
-rw-r--r--sound/pci/hda/patch_atihdmi.c45
-rw-r--r--sound/pci/hda/patch_conexant.c33
-rw-r--r--sound/pci/hda/patch_nvhdmi.c164
-rw-r--r--sound/pci/hda/patch_realtek.c2426
-rw-r--r--sound/pci/hda/patch_sigmatel.c1084
-rw-r--r--sound/pci/hda/patch_via.c1407
-rw-r--r--sound/pci/ice1712/ak4xxx.c3
-rw-r--r--sound/pci/ice1712/aureon.c699
-rw-r--r--sound/pci/ice1712/delta.c2
-rw-r--r--sound/pci/ice1712/delta.h1
-rw-r--r--sound/pci/ice1712/envy24ht.h10
-rw-r--r--sound/pci/ice1712/ews.c9
-rw-r--r--sound/pci/ice1712/ice1712.c240
-rw-r--r--sound/pci/ice1712/ice1712.h50
-rw-r--r--sound/pci/ice1712/ice1724.c401
-rw-r--r--sound/pci/ice1712/juli.c47
-rw-r--r--sound/pci/ice1712/phase.c277
-rw-r--r--sound/pci/ice1712/phase.h8
-rw-r--r--sound/pci/ice1712/pontis.c5
-rw-r--r--sound/pci/ice1712/revo.c25
-rw-r--r--sound/pci/ice1712/wtm.c104
-rw-r--r--sound/pci/ice1712/wtm.h4
-rw-r--r--sound/pci/intel8x0.c50
-rw-r--r--sound/pci/intel8x0m.c3
-rw-r--r--sound/pci/korg1212/korg1212-firmware.h987
-rw-r--r--sound/pci/korg1212/korg1212.c27
-rw-r--r--sound/pci/maestro3.c238
-rw-r--r--sound/pci/mixart/mixart.c4
-rw-r--r--sound/pci/mixart/mixart_core.c18
-rw-r--r--sound/pci/mixart/mixart_hwdep.c21
-rw-r--r--sound/pci/mixart/mixart_mixer.c8
-rw-r--r--sound/pci/nm256/nm256.c19
-rw-r--r--sound/pci/oxygen/hifier.c50
-rw-r--r--sound/pci/oxygen/oxygen.c170
-rw-r--r--sound/pci/oxygen/oxygen.h107
-rw-r--r--sound/pci/oxygen/oxygen_io.c44
-rw-r--r--sound/pci/oxygen/oxygen_lib.c199
-rw-r--r--sound/pci/oxygen/oxygen_mixer.c53
-rw-r--r--sound/pci/oxygen/oxygen_pcm.c100
-rw-r--r--sound/pci/oxygen/virtuoso.c789
-rw-r--r--sound/pci/pcxhr/pcxhr.c10
-rw-r--r--sound/pci/pcxhr/pcxhr_core.c49
-rw-r--r--sound/pci/pcxhr/pcxhr_hwdep.c17
-rw-r--r--sound/pci/riptide/riptide.c41
-rw-r--r--sound/pci/rme9652/hdsp.c25
-rw-r--r--sound/pci/rme9652/hdspm.c52
-rw-r--r--sound/pci/rme9652/rme9652.c23
-rw-r--r--sound/pci/sonicvibes.c10
-rw-r--r--sound/pci/trident/trident_main.c27
-rw-r--r--sound/pci/trident/trident_memory.c215
-rw-r--r--sound/pci/via82xx.c66
-rw-r--r--sound/pci/via82xx_modem.c8
-rw-r--r--sound/pci/vx222/vx222_ops.c14
-rw-r--r--sound/pci/ymfpci/ymfpci_image.h1565
-rw-r--r--sound/pci/ymfpci/ymfpci_main.c97
120 files changed, 10339 insertions, 6031 deletions
diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig
index 7e4742109572..7003711f4fcc 100644
--- a/sound/pci/Kconfig
+++ b/sound/pci/Kconfig
@@ -1,11 +1,16 @@
# ALSA PCI drivers
-menu "PCI devices"
- depends on SND!=n && PCI
+menuconfig SND_PCI
+ bool "PCI sound devices"
+ depends on PCI
+ default y
+ help
+ Support for sound devices connected via the PCI bus.
+
+if SND_PCI
config SND_AD1889
tristate "Analog Devices AD1889"
- depends on SND
select SND_AC97_CODEC
help
Say Y here to include support for the integrated AC97 sound
@@ -17,7 +22,6 @@ config SND_AD1889
config SND_ALS300
tristate "Avance Logic ALS300/ALS300+"
- depends on SND
select SND_PCM
select SND_AC97_CODEC
select SND_OPL3_LIB
@@ -29,7 +33,7 @@ config SND_ALS300
config SND_ALS4000
tristate "Avance Logic ALS4000"
- depends on SND && ISA_DMA_API
+ depends on ISA_DMA_API
select SND_OPL3_LIB
select SND_MPU401_UART
select SND_PCM
@@ -43,7 +47,6 @@ config SND_ALS4000
config SND_ALI5451
tristate "ALi M5451 PCI Audio Controller"
- depends on SND
select SND_MPU401_UART
select SND_AC97_CODEC
help
@@ -57,7 +60,6 @@ config SND_ALI5451
config SND_ATIIXP
tristate "ATI IXP AC97 Controller"
- depends on SND
select SND_AC97_CODEC
help
Say Y here to include support for the integrated AC97 sound
@@ -69,7 +71,6 @@ config SND_ATIIXP
config SND_ATIIXP_MODEM
tristate "ATI IXP Modem"
- depends on SND
select SND_AC97_CODEC
help
Say Y here to include support for the integrated MC97 modem on
@@ -80,7 +81,6 @@ config SND_ATIIXP_MODEM
config SND_AU8810
tristate "Aureal Advantage"
- depends on SND
select SND_MPU401_UART
select SND_AC97_CODEC
help
@@ -95,7 +95,6 @@ config SND_AU8810
config SND_AU8820
tristate "Aureal Vortex"
- depends on SND
select SND_MPU401_UART
select SND_AC97_CODEC
help
@@ -109,7 +108,6 @@ config SND_AU8820
config SND_AU8830
tristate "Aureal Vortex 2"
- depends on SND
select SND_MPU401_UART
select SND_AC97_CODEC
help
@@ -124,7 +122,6 @@ config SND_AU8830
config SND_AW2
tristate "Emagic Audiowerk 2"
- depends on SND
help
Say Y here to include support for Emagic Audiowerk 2 soundcards.
@@ -139,7 +136,7 @@ config SND_AW2
config SND_AZT3328
tristate "Aztech AZF3328 / PCI168 (EXPERIMENTAL)"
- depends on SND && EXPERIMENTAL
+ depends on EXPERIMENTAL
select SND_OPL3_LIB
select SND_MPU401_UART
select SND_PCM
@@ -152,7 +149,6 @@ config SND_AZT3328
config SND_BT87X
tristate "Bt87x Audio Capture"
- depends on SND
select SND_PCM
help
If you want to record audio from TV cards based on
@@ -174,7 +170,6 @@ config SND_BT87X_OVERCLOCK
config SND_CA0106
tristate "SB Audigy LS / Live 24bit"
- depends on SND
select SND_AC97_CODEC
select SND_RAWMIDI
select SND_VMASTER
@@ -187,7 +182,6 @@ config SND_CA0106
config SND_CMIPCI
tristate "C-Media 8338, 8738, 8768, 8770"
- depends on SND
select SND_OPL3_LIB
select SND_MPU401_UART
select SND_PCM
@@ -201,13 +195,11 @@ config SND_CMIPCI
config SND_OXYGEN_LIB
tristate
- depends on SND
select SND_PCM
select SND_MPU401_UART
config SND_OXYGEN
tristate "C-Media 8788 (Oxygen)"
- depends on SND
select SND_OXYGEN_LIB
help
Say Y here to include support for sound cards based on the
@@ -225,7 +217,6 @@ config SND_OXYGEN
config SND_CS4281
tristate "Cirrus Logic (Sound Fusion) CS4281"
- depends on SND
select SND_OPL3_LIB
select SND_RAWMIDI
select SND_AC97_CODEC
@@ -237,7 +228,6 @@ config SND_CS4281
config SND_CS46XX
tristate "Cirrus Logic (Sound Fusion) CS4280/CS461x/CS462x/CS463x"
- depends on SND
select SND_RAWMIDI
select SND_AC97_CODEC
help
@@ -258,7 +248,7 @@ config SND_CS46XX_NEW_DSP
config SND_CS5530
tristate "CS5530 Audio"
- depends on SND && ISA_DMA_API
+ depends on ISA_DMA_API
select SND_SB16_DSP
help
Say Y here to include support for audio on Cyrix/NatSemi CS5530 chips.
@@ -268,7 +258,7 @@ config SND_CS5530
config SND_CS5535AUDIO
tristate "CS5535/CS5536 Audio"
- depends on SND && X86 && !X86_64
+ depends on X86 && !X86_64
select SND_PCM
select SND_AC97_CODEC
help
@@ -286,7 +276,6 @@ config SND_CS5535AUDIO
config SND_DARLA20
tristate "(Echoaudio) Darla20"
- depends on SND
select FW_LOADER
select SND_PCM
help
@@ -297,7 +286,6 @@ config SND_DARLA20
config SND_GINA20
tristate "(Echoaudio) Gina20"
- depends on SND
select FW_LOADER
select SND_PCM
help
@@ -308,7 +296,6 @@ config SND_GINA20
config SND_LAYLA20
tristate "(Echoaudio) Layla20"
- depends on SND
select FW_LOADER
select SND_RAWMIDI
select SND_PCM
@@ -320,7 +307,6 @@ config SND_LAYLA20
config SND_DARLA24
tristate "(Echoaudio) Darla24"
- depends on SND
select FW_LOADER
select SND_PCM
help
@@ -331,7 +317,6 @@ config SND_DARLA24
config SND_GINA24
tristate "(Echoaudio) Gina24"
- depends on SND
select FW_LOADER
select SND_PCM
help
@@ -342,7 +327,6 @@ config SND_GINA24
config SND_LAYLA24
tristate "(Echoaudio) Layla24"
- depends on SND
select FW_LOADER
select SND_RAWMIDI
select SND_PCM
@@ -354,7 +338,6 @@ config SND_LAYLA24
config SND_MONA
tristate "(Echoaudio) Mona"
- depends on SND
select FW_LOADER
select SND_RAWMIDI
select SND_PCM
@@ -366,7 +349,6 @@ config SND_MONA
config SND_MIA
tristate "(Echoaudio) Mia"
- depends on SND
select FW_LOADER
select SND_RAWMIDI
select SND_PCM
@@ -378,7 +360,6 @@ config SND_MIA
config SND_ECHO3G
tristate "(Echoaudio) 3G cards"
- depends on SND
select FW_LOADER
select SND_RAWMIDI
select SND_PCM
@@ -390,7 +371,6 @@ config SND_ECHO3G
config SND_INDIGO
tristate "(Echoaudio) Indigo"
- depends on SND
select FW_LOADER
select SND_PCM
help
@@ -401,7 +381,6 @@ config SND_INDIGO
config SND_INDIGOIO
tristate "(Echoaudio) Indigo IO"
- depends on SND
select FW_LOADER
select SND_PCM
help
@@ -412,7 +391,6 @@ config SND_INDIGOIO
config SND_INDIGODJ
tristate "(Echoaudio) Indigo DJ"
- depends on SND
select FW_LOADER
select SND_PCM
help
@@ -423,7 +401,6 @@ config SND_INDIGODJ
config SND_EMU10K1
tristate "Emu10k1 (SB Live!, Audigy, E-mu APS)"
- depends on SND
select FW_LOADER
select SND_HWDEP
select SND_RAWMIDI
@@ -441,7 +418,6 @@ config SND_EMU10K1
config SND_EMU10K1X
tristate "Emu10k1X (Dell OEM Version)"
- depends on SND
select SND_AC97_CODEC
select SND_RAWMIDI
help
@@ -453,7 +429,6 @@ config SND_EMU10K1X
config SND_ENS1370
tristate "(Creative) Ensoniq AudioPCI 1370"
- depends on SND
select SND_RAWMIDI
select SND_PCM
help
@@ -464,7 +439,6 @@ config SND_ENS1370
config SND_ENS1371
tristate "(Creative) Ensoniq AudioPCI 1371/1373"
- depends on SND
select SND_RAWMIDI
select SND_AC97_CODEC
help
@@ -476,7 +450,6 @@ config SND_ENS1371
config SND_ES1938
tristate "ESS ES1938/1946/1969 (Solo-1)"
- depends on SND
select SND_OPL3_LIB
select SND_MPU401_UART
select SND_AC97_CODEC
@@ -489,7 +462,6 @@ config SND_ES1938
config SND_ES1968
tristate "ESS ES1968/1978 (Maestro-1/2/2E)"
- depends on SND
select SND_MPU401_UART
select SND_AC97_CODEC
help
@@ -501,7 +473,6 @@ config SND_ES1968
config SND_FM801
tristate "ForteMedia FM801"
- depends on SND
select SND_OPL3_LIB
select SND_MPU401_UART
select SND_AC97_CODEC
@@ -528,7 +499,6 @@ config SND_FM801_TEA575X
config SND_HDA_INTEL
tristate "Intel HD Audio"
- depends on SND
select SND_PCM
select SND_VMASTER
help
@@ -547,6 +517,14 @@ config SND_HDA_HWDEP
This interface can be used for out-of-band communication
with codecs for debugging purposes.
+config SND_HDA_INPUT_BEEP
+ bool "Support digital beep via input layer"
+ depends on SND_HDA_INTEL
+ depends on INPUT=y || INPUT=SND_HDA_INTEL
+ help
+ Say Y here to build a digital beep interface for HD-audio
+ driver. This interface is used to generate digital beeps.
+
config SND_HDA_CODEC_REALTEK
bool "Build Realtek HD-audio codec support"
depends on SND_HDA_INTEL
@@ -587,6 +565,14 @@ config SND_HDA_CODEC_ATIHDMI
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_NVHDMI
+ bool "Build NVIDIA HDMI HD-audio codec support"
+ depends on SND_HDA_INTEL
+ default y
+ help
+ Say Y here to include NVIDIA HDMI HD-audio codec support in
+ snd-hda-intel driver, such as NVIDIA MCP78 HDMI.
+
config SND_HDA_CODEC_CONEXANT
bool "Build Conexant HD-audio codec support"
depends on SND_HDA_INTEL
@@ -637,7 +623,6 @@ config SND_HDA_POWER_SAVE_DEFAULT
config SND_HDSP
tristate "RME Hammerfall DSP Audio"
- depends on SND
select SND_HWDEP
select SND_RAWMIDI
select SND_PCM
@@ -650,7 +635,6 @@ config SND_HDSP
config SND_HDSPM
tristate "RME Hammerfall DSP MADI"
- depends on SND
select SND_HWDEP
select SND_RAWMIDI
select SND_PCM
@@ -663,7 +647,6 @@ config SND_HDSPM
config SND_HIFIER
tristate "TempoTec HiFier Fantasia"
- depends on SND
select SND_OXYGEN_LIB
help
Say Y here to include support for the MediaTek/TempoTec HiFier
@@ -674,7 +657,6 @@ config SND_HIFIER
config SND_ICE1712
tristate "ICEnsemble ICE1712 (Envy24)"
- depends on SND
select SND_MPU401_UART
select SND_AC97_CODEC
help
@@ -683,16 +665,16 @@ config SND_ICE1712
Currently supported hardware is: M-Audio Delta 1010(LT),
DiO 2496, 66, 44, 410, Audiophile 24/96; Digigram VX442;
- TerraTec EWX 24/96, EWS 88MT, 88D, DMX 6Fire, Phase 88;
- Hoontech SoundTrack DSP 24/Value/Media7.1; Event EZ8.
+ TerraTec EWX 24/96, EWS 88MT/D, DMX 6Fire, Phase 88;
+ Hoontech SoundTrack DSP 24/Value/Media7.1; Event EZ8;
+ Lionstracs Mediastation, Terrasoniq TS 88.
To compile this driver as a module, choose M here: the module
will be called snd-ice1712.
config SND_ICE1724
tristate "ICE/VT1724/1720 (Envy24HT/PT)"
- depends on SND
- select SND_MPU401_UART
+ select SND_RAWMIDI
select SND_AC97_CODEC
select SND_VMASTER
help
@@ -700,16 +682,18 @@ config SND_ICE1724
ICE/VT1724/1720 (Envy24HT/PT) chips.
Currently supported hardware is: AMP AUDIO2000; M-Audio
- Revolution 7.1; TerraTec Aureon 5.1 Sky, 7.1 Space/Universe;
- AudioTrak Prodigy 7.1; Pontis MS300; Albatron K8X800 Pro II;
- Chaintech ZNF3-150/250.
+ Revolution 5.1, 7.1, Audiophile 192; TerraTec Aureon 5.1 Sky,
+ 7.1 Space/Universe, Phase 22/28; Onkyo SE-90PCI, SE-200PCI;
+ AudioTrak Prodigy 192, 7.1 (HIFI/LT/XT), HD2; Hercules
+ Fortissimo IV; ESI Juli@; Pontis MS300; EGO-SYS WaveTerminal
+ 192M; Albatron K8X800 Pro II; Chaintech ZNF3-150/250, 9CJS,
+ AV-710; Shuttle SN25P.
To compile this driver as a module, choose M here: the module
will be called snd-ice1724.
config SND_INTEL8X0
tristate "Intel/SiS/nVidia/AMD/ALi AC97 Controller"
- depends on SND
select SND_AC97_CODEC
help
Say Y here to include support for the integrated AC97 sound
@@ -722,7 +706,6 @@ config SND_INTEL8X0
config SND_INTEL8X0M
tristate "Intel/SiS/nVidia/AMD MC97 Modem"
- depends on SND
select SND_AC97_CODEC
help
Say Y here to include support for the integrated MC97 modem on
@@ -733,8 +716,6 @@ config SND_INTEL8X0M
config SND_KORG1212
tristate "Korg 1212 IO"
- depends on SND
- select FW_LOADER if !SND_KORG1212_FIRMWARE_IN_KERNEL
select SND_PCM
help
Say Y here to include support for Korg 1212IO soundcards.
@@ -742,19 +723,8 @@ config SND_KORG1212
To compile this driver as a module, choose M here: the module
will be called snd-korg1212.
-config SND_KORG1212_FIRMWARE_IN_KERNEL
- bool "In-kernel firmware for Korg1212 driver"
- depends on SND_KORG1212
- default y
- help
- Say Y here to include the static firmware built in the kernel
- for the Korg1212 driver. If you choose N here, you need to
- install the firmware files from the alsa-firmware package.
-
config SND_MAESTRO3
tristate "ESS Allegro/Maestro3"
- depends on SND
- select FW_LOADER if !SND_MAESTRO3_FIRMWARE_IN_KERNEL
select SND_AC97_CODEC
help
Say Y here to include support for soundcards based on ESS Maestro 3
@@ -763,18 +733,8 @@ config SND_MAESTRO3
To compile this driver as a module, choose M here: the module
will be called snd-maestro3.
-config SND_MAESTRO3_FIRMWARE_IN_KERNEL
- bool "In-kernel firmware for Maestro3 driver"
- depends on SND_MAESTRO3
- default y
- help
- Say Y here to include the static firmware built in the kernel
- for the Maestro3 driver. If you choose N here, you need to
- install the firmware files from the alsa-firmware package.
-
config SND_MIXART
tristate "Digigram miXart"
- depends on SND
select SND_HWDEP
select SND_PCM
help
@@ -786,7 +746,6 @@ config SND_MIXART
config SND_NM256
tristate "NeoMagic NM256AV/ZX"
- depends on SND
select SND_AC97_CODEC
help
Say Y here to include support for NeoMagic NM256AV/ZX chips.
@@ -796,7 +755,6 @@ config SND_NM256
config SND_PCXHR
tristate "Digigram PCXHR"
- depends on SND
select SND_PCM
select SND_HWDEP
help
@@ -807,7 +765,6 @@ config SND_PCXHR
config SND_RIPTIDE
tristate "Conexant Riptide"
- depends on SND
select FW_LOADER
select SND_OPL3_LIB
select SND_MPU401_UART
@@ -820,7 +777,6 @@ config SND_RIPTIDE
config SND_RME32
tristate "RME Digi32, 32/8, 32 PRO"
- depends on SND
select SND_PCM
help
Say Y to include support for RME Digi32, Digi32 PRO and
@@ -832,7 +788,6 @@ config SND_RME32
config SND_RME96
tristate "RME Digi96, 96/8, 96/8 PRO"
- depends on SND
select SND_PCM
help
Say Y here to include support for RME Digi96, Digi96/8 and
@@ -843,7 +798,6 @@ config SND_RME96
config SND_RME9652
tristate "RME Digi9652 (Hammerfall)"
- depends on SND
select SND_PCM
help
Say Y here to include support for RME Hammerfall (RME
@@ -854,7 +808,7 @@ config SND_RME9652
config SND_SIS7019
tristate "SiS 7019 Audio Accelerator"
- depends on SND && X86 && !X86_64
+ depends on X86 && !X86_64
select SND_AC97_CODEC
help
Say Y here to include support for the SiS 7019 Audio Accelerator.
@@ -864,7 +818,6 @@ config SND_SIS7019
config SND_SONICVIBES
tristate "S3 SonicVibes"
- depends on SND
select SND_OPL3_LIB
select SND_MPU401_UART
select SND_AC97_CODEC
@@ -877,7 +830,6 @@ config SND_SONICVIBES
config SND_TRIDENT
tristate "Trident 4D-Wave DX/NX; SiS 7018"
- depends on SND
select SND_MPU401_UART
select SND_AC97_CODEC
help
@@ -889,7 +841,6 @@ config SND_TRIDENT
config SND_VIA82XX
tristate "VIA 82C686A/B, 8233/8235 AC97 Controller"
- depends on SND
select SND_MPU401_UART
select SND_AC97_CODEC
help
@@ -901,7 +852,6 @@ config SND_VIA82XX
config SND_VIA82XX_MODEM
tristate "VIA 82C686A/B, 8233 based Modems"
- depends on SND
select SND_AC97_CODEC
help
Say Y here to include support for the integrated MC97 modem on
@@ -912,18 +862,17 @@ config SND_VIA82XX_MODEM
config SND_VIRTUOSO
tristate "Asus Virtuoso 100/200 (Xonar)"
- depends on SND
select SND_OXYGEN_LIB
help
Say Y here to include support for sound cards based on the
- Asus AV100/AV200 chips, i.e., Xonar D2, DX and D2X.
+ Asus AV100/AV200 chips, i.e., Xonar D1, DX, D2, D2X and
+ HDAV1.3 (Deluxe).
To compile this driver as a module, choose M here: the module
will be called snd-virtuoso.
config SND_VX222
tristate "Digigram VX222"
- depends on SND
select SND_VX_LIB
help
Say Y here to include support for Digigram VX222 soundcards.
@@ -933,8 +882,6 @@ config SND_VX222
config SND_YMFPCI
tristate "Yamaha YMF724/740/744/754"
- depends on SND
- select FW_LOADER if !SND_YMFPCI_FIRMWARE_IN_KERNEL
select SND_OPL3_LIB
select SND_MPU401_UART
select SND_AC97_CODEC
@@ -945,34 +892,4 @@ config SND_YMFPCI
To compile this driver as a module, choose M here: the module
will be called snd-ymfpci.
-config SND_YMFPCI_FIRMWARE_IN_KERNEL
- bool "In-kernel firmware for YMFPCI driver"
- depends on SND_YMFPCI
- default y
- help
- Say Y here to include the static firmware built in the kernel
- for the YMFPCI driver. If you choose N here, you need to
- install the firmware files from the alsa-firmware package.
-
-config SND_AC97_POWER_SAVE
- bool "AC97 Power-Saving Mode"
- depends on SND_AC97_CODEC && EXPERIMENTAL
- default n
- help
- Say Y here to enable the aggressive power-saving support of
- AC97 codecs. In this mode, the power-mode is dynamically
- controlled at each open/close.
-
- The mode is activated by passing power_save=1 option to
- 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
- help
- The default time-out value in seconds for AC97 automatic
- power-save mode. 0 means to disable the power-save mode.
-
-endmenu
+endif # SND_PCI
diff --git a/sound/pci/Makefile b/sound/pci/Makefile
index 85ef14bc8056..65b25d221cd2 100644
--- a/sound/pci/Makefile
+++ b/sound/pci/Makefile
@@ -13,7 +13,7 @@ snd-bt87x-objs := bt87x.o
snd-cmipci-objs := cmipci.o
snd-cs4281-objs := cs4281.o
snd-cs5530-objs := cs5530.o
-snd-ens1370-objs := ens1370.o
+snd-ens1370-objs := ens1370.o ak4531_codec.o
snd-ens1371-objs := ens1371.o
snd-es1938-objs := es1938.o
snd-es1968-objs := es1968.o
diff --git a/sound/pci/ac97/Makefile b/sound/pci/ac97/Makefile
index 0be48b1a22d0..41fa322f0971 100644
--- a/sound/pci/ac97/Makefile
+++ b/sound/pci/ac97/Makefile
@@ -3,16 +3,8 @@
# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
#
-snd-ac97-codec-objs := ac97_codec.o ac97_pcm.o
-
-ifneq ($(CONFIG_PROC_FS),)
-snd-ac97-codec-objs += ac97_proc.o
-endif
-
-snd-ak4531-codec-objs := ak4531_codec.o
+snd-ac97-codec-y := ac97_codec.o ac97_pcm.o
+snd-ac97-codec-$(CONFIG_PROC_FS) += ac97_proc.o
# Toplevel Module Dependency
obj-$(CONFIG_SND_AC97_CODEC) += snd-ac97-codec.o
-obj-$(CONFIG_SND_ENS1370) += snd-ak4531-codec.o
-
-obj-m := $(sort $(obj-m))
diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c
index 45fd29017ddd..6704acbca8c0 100644
--- a/sound/pci/ac97/ac97_codec.c
+++ b/sound/pci/ac97/ac97_codec.c
@@ -49,8 +49,9 @@ MODULE_PARM_DESC(enable_loopback, "Enable AC97 ADC/DAC Loopback Control");
#ifdef CONFIG_SND_AC97_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");
+module_param(power_save, int, 0644);
+MODULE_PARM_DESC(power_save, "Automatic power-saving timeout "
+ "(in second, 0 = disable).");
#endif
/*
@@ -66,8 +67,8 @@ struct ac97_codec_id {
};
static const struct ac97_codec_id snd_ac97_codec_id_vendors[] = {
-{ 0x414b4d00, 0xffffff00, "Asahi Kasei", NULL, NULL },
{ 0x41445300, 0xffffff00, "Analog Devices", NULL, NULL },
+{ 0x414b4d00, 0xffffff00, "Asahi Kasei", NULL, NULL },
{ 0x414c4300, 0xffffff00, "Realtek", NULL, NULL },
{ 0x414c4700, 0xffffff00, "Realtek", NULL, NULL },
{ 0x434d4900, 0xffffff00, "C-Media Electronics", NULL, NULL },
@@ -93,11 +94,6 @@ static const struct ac97_codec_id snd_ac97_codec_id_vendors[] = {
};
static const struct ac97_codec_id snd_ac97_codec_ids[] = {
-{ 0x414b4d00, 0xffffffff, "AK4540", NULL, NULL },
-{ 0x414b4d01, 0xffffffff, "AK4542", NULL, NULL },
-{ 0x414b4d02, 0xffffffff, "AK4543", NULL, NULL },
-{ 0x414b4d06, 0xffffffff, "AK4544A", NULL, NULL },
-{ 0x414b4d07, 0xffffffff, "AK4545", NULL, NULL },
{ 0x41445303, 0xffffffff, "AD1819", patch_ad1819, NULL },
{ 0x41445340, 0xffffffff, "AD1881", patch_ad1881, NULL },
{ 0x41445348, 0xffffffff, "AD1881A", patch_ad1881, NULL },
@@ -111,20 +107,25 @@ static const struct ac97_codec_id snd_ac97_codec_ids[] = {
{ 0x41445374, 0xffffffff, "AD1981B", patch_ad1981b, NULL },
{ 0x41445375, 0xffffffff, "AD1985", patch_ad1985, NULL },
{ 0x41445378, 0xffffffff, "AD1986", patch_ad1986, NULL },
+{ 0x414b4d00, 0xffffffff, "AK4540", NULL, NULL },
+{ 0x414b4d01, 0xffffffff, "AK4542", NULL, NULL },
+{ 0x414b4d02, 0xffffffff, "AK4543", NULL, NULL },
+{ 0x414b4d06, 0xffffffff, "AK4544A", NULL, NULL },
+{ 0x414b4d07, 0xffffffff, "AK4545", NULL, NULL },
{ 0x414c4300, 0xffffff00, "ALC100,100P", NULL, NULL },
{ 0x414c4710, 0xfffffff0, "ALC200,200P", NULL, NULL },
{ 0x414c4721, 0xffffffff, "ALC650D", NULL, NULL }, /* already patched */
{ 0x414c4722, 0xffffffff, "ALC650E", NULL, NULL }, /* already patched */
{ 0x414c4723, 0xffffffff, "ALC650F", NULL, NULL }, /* already patched */
{ 0x414c4720, 0xfffffff0, "ALC650", patch_alc650, NULL },
+{ 0x414c4730, 0xffffffff, "ALC101", NULL, NULL },
+{ 0x414c4740, 0xfffffff0, "ALC202", NULL, NULL },
+{ 0x414c4750, 0xfffffff0, "ALC250", NULL, NULL },
{ 0x414c4760, 0xfffffff0, "ALC655", patch_alc655, NULL },
+{ 0x414c4770, 0xfffffff0, "ALC203", patch_alc203, NULL },
{ 0x414c4781, 0xffffffff, "ALC658D", NULL, NULL }, /* already patched */
{ 0x414c4780, 0xfffffff0, "ALC658", patch_alc655, NULL },
{ 0x414c4790, 0xfffffff0, "ALC850", patch_alc850, NULL },
-{ 0x414c4730, 0xffffffff, "ALC101", NULL, NULL },
-{ 0x414c4740, 0xfffffff0, "ALC202", NULL, NULL },
-{ 0x414c4750, 0xfffffff0, "ALC250", NULL, NULL },
-{ 0x414c4770, 0xfffffff0, "ALC203", NULL, NULL },
{ 0x434d4941, 0xffffffff, "CMI9738", patch_cm9738, NULL },
{ 0x434d4961, 0xffffffff, "CMI9739", patch_cm9739, NULL },
{ 0x434d4969, 0xffffffff, "CMI9780", patch_cm9780, NULL },
@@ -160,15 +161,16 @@ static const struct ac97_codec_id snd_ac97_codec_ids[] = {
{ 0x50534304, 0xffffffff, "UCB1400", patch_ucb1400, NULL },
{ 0x53494c20, 0xffffffe0, "Si3036,8", mpatch_si3036, mpatch_si3036, AC97_MODEM_PATCH },
{ 0x54524102, 0xffffffff, "TR28022", NULL, NULL },
+{ 0x54524103, 0xffffffff, "TR28023", NULL, NULL },
{ 0x54524106, 0xffffffff, "TR28026", NULL, NULL },
{ 0x54524108, 0xffffffff, "TR28028", patch_tritech_tr28028, NULL }, // added by xin jin [07/09/99]
{ 0x54524123, 0xffffffff, "TR28602", NULL, NULL }, // only guess --jk [TR28023 = eMicro EM28023 (new CT1297)]
{ 0x54584e20, 0xffffffff, "TLC320AD9xC", NULL, NULL },
{ 0x56494161, 0xffffffff, "VIA1612A", NULL, NULL }, // modified ICE1232 with S/PDIF
{ 0x56494170, 0xffffffff, "VIA1617A", patch_vt1617a, NULL }, // modified VT1616 with S/PDIF
-{ 0x56494182, 0xffffffff, "VIA1618", NULL, NULL },
+{ 0x56494182, 0xffffffff, "VIA1618", patch_vt1618, NULL },
{ 0x57454301, 0xffffffff, "W83971D", NULL, NULL },
-{ 0x574d4c00, 0xffffffff, "WM9701A", NULL, NULL },
+{ 0x574d4c00, 0xffffffff, "WM9701,WM9701A", NULL, NULL },
{ 0x574d4C03, 0xffffffff, "WM9703,WM9707,WM9708,WM9717", patch_wolfson03, NULL},
{ 0x574d4C04, 0xffffffff, "WM9704M,WM9704Q", patch_wolfson04, NULL},
{ 0x574d4C05, 0xffffffff, "WM9705,WM9710", patch_wolfson05, NULL},
@@ -1888,8 +1890,8 @@ int snd_ac97_bus(struct snd_card *card, int num, struct snd_ac97_bus_ops *ops,
.dev_free = snd_ac97_bus_dev_free,
};
- snd_assert(card != NULL, return -EINVAL);
- snd_assert(rbus != NULL, return -EINVAL);
+ if (snd_BUG_ON(!card))
+ return -EINVAL;
bus = kzalloc(sizeof(*bus), GFP_KERNEL);
if (bus == NULL)
return -ENOMEM;
@@ -1904,7 +1906,8 @@ int snd_ac97_bus(struct snd_card *card, int num, struct snd_ac97_bus_ops *ops,
snd_ac97_bus_free(bus);
return err;
}
- *rbus = bus;
+ if (rbus)
+ *rbus = bus;
return 0;
}
@@ -1989,10 +1992,14 @@ int snd_ac97_mixer(struct snd_ac97_bus *bus, struct snd_ac97_template *template,
.dev_disconnect = snd_ac97_dev_disconnect,
};
- snd_assert(rac97 != NULL, return -EINVAL);
- *rac97 = NULL;
- snd_assert(bus != NULL && template != NULL, return -EINVAL);
- snd_assert(template->num < 4 && bus->codec[template->num] == NULL, return -EINVAL);
+ if (rac97)
+ *rac97 = NULL;
+ if (snd_BUG_ON(!bus || !template))
+ return -EINVAL;
+ if (snd_BUG_ON(template->num >= 4))
+ return -EINVAL;
+ if (bus->codec[template->num])
+ return -EBUSY;
card = bus->card;
ac97 = kzalloc(sizeof(*ac97), GFP_KERNEL);
@@ -2294,9 +2301,11 @@ static void snd_ac97_powerdown(struct snd_ac97 *ac97)
power |= AC97_PD_PR0 | AC97_PD_PR1; /* ADC & DAC powerdown */
snd_ac97_write(ac97, AC97_POWERDOWN, power);
udelay(100);
- power |= AC97_PD_PR2 | AC97_PD_PR3; /* Analog Mixer powerdown */
+ power |= AC97_PD_PR2; /* Analog Mixer powerdown (Vref on) */
snd_ac97_write(ac97, AC97_POWERDOWN, power);
if (ac97_is_power_save_mode(ac97)) {
+ power |= AC97_PD_PR3; /* Analog Mixer powerdown */
+ snd_ac97_write(ac97, AC97_POWERDOWN, power);
udelay(100);
/* AC-link powerdown, internal Clk disable */
/* FIXME: this may cause click noises on some boards */
@@ -2362,7 +2371,7 @@ int snd_ac97_update_power(struct snd_ac97 *ac97, int reg, int powerup)
* that open/close frequently)
*/
schedule_delayed_work(&ac97->power_work,
- msecs_to_jiffies(2000));
+ msecs_to_jiffies(power_save * 1000));
else {
cancel_delayed_work(&ac97->power_work);
update_power_regs(ac97);
diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c
index 1292dcee072d..6e831aff1bd0 100644
--- a/sound/pci/ac97/ac97_patch.c
+++ b/sound/pci/ac97/ac97_patch.c
@@ -476,7 +476,7 @@ static int patch_yamaha_ymf753(struct snd_ac97 * ac97)
}
/*
- * May 2, 2003 Liam Girdwood <liam.girdwood@wolfsonmicro.com>
+ * May 2, 2003 Liam Girdwood <lrg@slimlogic.co.uk>
* removed broken wolfson00 patch.
* added support for WM9705,WM9708,WM9709,WM9710,WM9711,WM9712 and WM9717.
*/
@@ -669,6 +669,7 @@ AC97_SINGLE("Mic 1 Volume", AC97_MIC, 8, 31, 1),
AC97_SINGLE("Mic 2 Volume", AC97_MIC, 0, 31, 1),
AC97_SINGLE("Mic 20dB Boost Switch", AC97_MIC, 7, 1, 0),
+AC97_SINGLE("Master Left Inv Switch", AC97_MASTER, 6, 1, 0),
AC97_SINGLE("Master ZC Switch", AC97_MASTER, 7, 1, 0),
AC97_SINGLE("Headphone ZC Switch", AC97_HEADPHONE, 7, 1, 0),
AC97_SINGLE("Mono ZC Switch", AC97_MASTER_MONO, 7, 1, 0),
@@ -2559,6 +2560,14 @@ static int patch_ad1986(struct snd_ac97 * ac97)
return 0;
}
+/*
+ * realtek ALC203: use mono-out for pin 37
+ */
+static int patch_alc203(struct snd_ac97 *ac97)
+{
+ snd_ac97_update_bits(ac97, 0x7a, 0x400, 0x400);
+ return 0;
+}
/*
* realtek ALC65x/850 codecs
@@ -3352,8 +3361,66 @@ AC97_SINGLE("Downmix LFE and Center to Front", 0x5a, 12, 1, 0),
AC97_SINGLE("Downmix Surround to Front", 0x5a, 11, 1, 0),
};
+static const char *slave_vols_vt1616[] = {
+ "Front Playback Volume",
+ "Surround Playback Volume",
+ "Center Playback Volume",
+ "LFE Playback Volume",
+ NULL
+};
+
+static const char *slave_sws_vt1616[] = {
+ "Front Playback Switch",
+ "Surround Playback Switch",
+ "Center Playback Switch",
+ "LFE Playback Switch",
+ NULL
+};
+
+/* find a mixer control element with the given name */
+static struct snd_kcontrol *snd_ac97_find_mixer_ctl(struct snd_ac97 *ac97,
+ const char *name)
+{
+ struct snd_ctl_elem_id id;
+ memset(&id, 0, sizeof(id));
+ id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
+ strcpy(id.name, name);
+ return snd_ctl_find_id(ac97->bus->card, &id);
+}
+
+/* create a virtual master control and add slaves */
+static int snd_ac97_add_vmaster(struct snd_ac97 *ac97, char *name,
+ const unsigned int *tlv, const char **slaves)
+{
+ struct snd_kcontrol *kctl;
+ const char **s;
+ int err;
+
+ kctl = snd_ctl_make_virtual_master(name, tlv);
+ if (!kctl)
+ return -ENOMEM;
+ err = snd_ctl_add(ac97->bus->card, kctl);
+ if (err < 0)
+ return err;
+
+ for (s = slaves; *s; s++) {
+ struct snd_kcontrol *sctl;
+
+ sctl = snd_ac97_find_mixer_ctl(ac97, *s);
+ if (!sctl) {
+ snd_printdd("Cannot find slave %s, skipped\n", *s);
+ continue;
+ }
+ err = snd_ctl_add_slave(kctl, sctl);
+ if (err < 0)
+ return err;
+ }
+ return 0;
+}
+
static int patch_vt1616_specific(struct snd_ac97 * ac97)
{
+ struct snd_kcontrol *kctl;
int err;
if (snd_ac97_try_bit(ac97, 0x5a, 9))
@@ -3361,6 +3428,24 @@ static int patch_vt1616_specific(struct snd_ac97 * ac97)
return err;
if ((err = patch_build_controls(ac97, &snd_ac97_controls_vt1616[1], ARRAY_SIZE(snd_ac97_controls_vt1616) - 1)) < 0)
return err;
+
+ /* There is already a misnamed master switch. Rename it. */
+ kctl = snd_ac97_find_mixer_ctl(ac97, "Master Playback Volume");
+ if (!kctl)
+ return -EINVAL;
+
+ snd_ac97_rename_vol_ctl(ac97, "Master Playback", "Front Playback");
+
+ err = snd_ac97_add_vmaster(ac97, "Master Playback Volume",
+ kctl->tlv.p, slave_vols_vt1616);
+ if (err < 0)
+ return err;
+
+ err = snd_ac97_add_vmaster(ac97, "Master Playback Switch",
+ NULL, slave_sws_vt1616);
+ if (err < 0)
+ return err;
+
return 0;
}
@@ -3380,7 +3465,7 @@ static int patch_vt1616(struct snd_ac97 * ac97)
/*
* unfortunately, the vt1617a stashes the twiddlers required for
- * nooding the i/o jacks on 2 different regs. * thameans that we cant
+ * noodling the i/o jacks on 2 different regs. that means that we can't
* use the easy way provided by AC97_ENUM_DOUBLE() we have to write
* are own funcs.
*
@@ -3413,7 +3498,7 @@ static int snd_ac97_vt1617a_smart51_get(struct snd_kcontrol *kcontrol,
pac97 = snd_kcontrol_chip(kcontrol); /* grab codec handle */
- /* grab our desirec bits, then mash them together in a manner
+ /* grab our desired bits, then mash them together in a manner
* consistent with Table 6 on page 17 in the 1617a docs */
usSM51 = snd_ac97_read(pac97, 0x7a) >> 14;
@@ -3463,7 +3548,7 @@ static const struct snd_kcontrol_new snd_ac97_controls_vt1617a[] = {
},
};
-int patch_vt1617a(struct snd_ac97 * ac97)
+static int patch_vt1617a(struct snd_ac97 * ac97)
{
int err = 0;
int val;
@@ -3491,6 +3576,200 @@ int patch_vt1617a(struct snd_ac97 * ac97)
return err;
}
+/* VIA VT1618 8 CHANNEL AC97 CODEC
+ *
+ * VIA implements 'Smart 5.1' completely differently on the 1618 than
+ * it does on the 1617a. awesome! They seem to have sourced this
+ * particular revision of the technology from somebody else, it's
+ * called Universal Audio Jack and it shows up on some other folk's chips
+ * as well.
+ *
+ * ordering in this list reflects vt1618 docs for Reg 60h and
+ * the block diagram, DACs are as follows:
+ *
+ * OUT_O -> Front,
+ * OUT_1 -> Surround,
+ * OUT_2 -> C/LFE
+ *
+ * Unlike the 1617a, each OUT has a consistent set of mappings
+ * for all bitpatterns other than 00:
+ *
+ * 01 Unmixed Output
+ * 10 Line In
+ * 11 Mic In
+ *
+ * Special Case of 00:
+ *
+ * OUT_0 Mixed Output
+ * OUT_1 Reserved
+ * OUT_2 Reserved
+ *
+ * I have no idea what the hell Reserved does, but on an MSI
+ * CN700T, i have to set it to get 5.1 output - YMMV, bad
+ * shit may happen.
+ *
+ * If other chips use Universal Audio Jack, then this code might be applicable
+ * to them.
+ */
+
+struct vt1618_uaj_item {
+ unsigned short mask;
+ unsigned short shift;
+ const char *items[4];
+};
+
+/* This list reflects the vt1618 docs for Vendor Defined Register 0x60. */
+
+static struct vt1618_uaj_item vt1618_uaj[3] = {
+ {
+ /* speaker jack */
+ .mask = 0x03,
+ .shift = 0,
+ .items = {
+ "Speaker Out", "DAC Unmixed Out", "Line In", "Mic In"
+ }
+ },
+ {
+ /* line jack */
+ .mask = 0x0c,
+ .shift = 2,
+ .items = {
+ "Surround Out", "DAC Unmixed Out", "Line In", "Mic In"
+ }
+ },
+ {
+ /* mic jack */
+ .mask = 0x30,
+ .shift = 4,
+ .items = {
+ "Center LFE Out", "DAC Unmixed Out", "Line In", "Mic In"
+ },
+ },
+};
+
+static int snd_ac97_vt1618_UAJ_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ return ac97_enum_text_info(kcontrol, uinfo,
+ vt1618_uaj[kcontrol->private_value].items,
+ 4);
+}
+
+/* All of the vt1618 Universal Audio Jack twiddlers are on
+ * Vendor Defined Register 0x60, page 0. The bits, and thus
+ * the mask, are the only thing that changes
+ */
+static int snd_ac97_vt1618_UAJ_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ unsigned short datpag, uaj;
+ struct snd_ac97 *pac97 = snd_kcontrol_chip(kcontrol);
+
+ mutex_lock(&pac97->page_mutex);
+
+ datpag = snd_ac97_read(pac97, AC97_INT_PAGING) & AC97_PAGE_MASK;
+ snd_ac97_update_bits(pac97, AC97_INT_PAGING, AC97_PAGE_MASK, 0);
+
+ uaj = snd_ac97_read(pac97, 0x60) &
+ vt1618_uaj[kcontrol->private_value].mask;
+
+ snd_ac97_update_bits(pac97, AC97_INT_PAGING, AC97_PAGE_MASK, datpag);
+ mutex_unlock(&pac97->page_mutex);
+
+ ucontrol->value.enumerated.item[0] = uaj >>
+ vt1618_uaj[kcontrol->private_value].shift;
+
+ return 0;
+}
+
+static int snd_ac97_vt1618_UAJ_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ return ac97_update_bits_page(snd_kcontrol_chip(kcontrol), 0x60,
+ vt1618_uaj[kcontrol->private_value].mask,
+ ucontrol->value.enumerated.item[0]<<
+ vt1618_uaj[kcontrol->private_value].shift,
+ 0);
+}
+
+/* config aux in jack - not found on 3 jack motherboards or soundcards */
+
+static int snd_ac97_vt1618_aux_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ static const char *txt_aux[] = {"Aux In", "Back Surr Out"};
+
+ return ac97_enum_text_info(kcontrol, uinfo, txt_aux, 2);
+}
+
+static int snd_ac97_vt1618_aux_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ ucontrol->value.enumerated.item[0] =
+ (snd_ac97_read(snd_kcontrol_chip(kcontrol), 0x5c) & 0x0008)>>3;
+ return 0;
+}
+
+static int snd_ac97_vt1618_aux_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ /* toggle surround rear dac power */
+
+ snd_ac97_update_bits(snd_kcontrol_chip(kcontrol), 0x5c, 0x0008,
+ ucontrol->value.enumerated.item[0] << 3);
+
+ /* toggle aux in surround rear out jack */
+
+ return snd_ac97_update_bits(snd_kcontrol_chip(kcontrol), 0x76, 0x0008,
+ ucontrol->value.enumerated.item[0] << 3);
+}
+
+static const struct snd_kcontrol_new snd_ac97_controls_vt1618[] = {
+ AC97_SINGLE("Exchange Center/LFE", 0x5a, 8, 1, 0),
+ AC97_SINGLE("DC Offset", 0x5a, 10, 1, 0),
+ AC97_SINGLE("Soft Mute", 0x5c, 0, 1, 1),
+ AC97_SINGLE("Headphone Amp", 0x5c, 5, 1, 1),
+ AC97_DOUBLE("Back Surr Volume", 0x5e, 8, 0, 31, 1),
+ AC97_SINGLE("Back Surr Switch", 0x5e, 15, 1, 1),
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "Speaker Jack Mode",
+ .info = snd_ac97_vt1618_UAJ_info,
+ .get = snd_ac97_vt1618_UAJ_get,
+ .put = snd_ac97_vt1618_UAJ_put,
+ .private_value = 0
+ },
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "Line Jack Mode",
+ .info = snd_ac97_vt1618_UAJ_info,
+ .get = snd_ac97_vt1618_UAJ_get,
+ .put = snd_ac97_vt1618_UAJ_put,
+ .private_value = 1
+ },
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "Mic Jack Mode",
+ .info = snd_ac97_vt1618_UAJ_info,
+ .get = snd_ac97_vt1618_UAJ_get,
+ .put = snd_ac97_vt1618_UAJ_put,
+ .private_value = 2
+ },
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "Aux Jack Mode",
+ .info = snd_ac97_vt1618_aux_info,
+ .get = snd_ac97_vt1618_aux_get,
+ .put = snd_ac97_vt1618_aux_put,
+ }
+};
+
+static int patch_vt1618(struct snd_ac97 *ac97)
+{
+ return patch_build_controls(ac97, snd_ac97_controls_vt1618,
+ ARRAY_SIZE(snd_ac97_controls_vt1618));
+}
+
/*
*/
static void it2646_update_jacks(struct snd_ac97 *ac97)
@@ -3633,7 +3912,7 @@ static int patch_ucb1400(struct snd_ac97 * ac97)
{
ac97->build_ops = &patch_ucb1400_ops;
/* enable headphone driver and smart low power mode by default */
- snd_ac97_write(ac97, 0x6a, 0x0050);
- snd_ac97_write(ac97, 0x6c, 0x0030);
+ snd_ac97_write_cache(ac97, 0x6a, 0x0050);
+ snd_ac97_write_cache(ac97, 0x6c, 0x0030);
return 0;
}
diff --git a/sound/pci/ad1889.c b/sound/pci/ad1889.c
index 39ec55b57b1e..92f3a976ef2e 100644
--- a/sound/pci/ad1889.c
+++ b/sound/pci/ad1889.c
@@ -549,7 +549,8 @@ snd_ad1889_playback_pointer(struct snd_pcm_substream *ss)
ptr = ad1889_readl(chip, AD_DMA_WAVCA);
ptr -= chip->wave.addr;
- snd_assert((ptr >= 0) && (ptr < chip->wave.size), return 0);
+ if (snd_BUG_ON(ptr >= chip->wave.size))
+ return 0;
return bytes_to_frames(ss->runtime, ptr);
}
@@ -567,7 +568,8 @@ snd_ad1889_capture_pointer(struct snd_pcm_substream *ss)
ptr = ad1889_readl(chip, AD_DMA_ADCCA);
ptr -= chip->ramc.addr;
- snd_assert((ptr >= 0) && (ptr < chip->ramc.size), return 0);
+ if (snd_BUG_ON(ptr >= chip->ramc.size))
+ return 0;
return bytes_to_frames(ss->runtime, ptr);
}
diff --git a/sound/pci/ac97/ak4531_codec.c b/sound/pci/ak4531_codec.c
index c0c1633999ea..0f819ddb3ebf 100644
--- a/sound/pci/ac97/ak4531_codec.c
+++ b/sound/pci/ak4531_codec.c
@@ -28,9 +28,11 @@
#include <sound/ak4531_codec.h>
#include <sound/tlv.h>
+/*
MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
MODULE_DESCRIPTION("Universal routines for AK4531 codec");
MODULE_LICENSE("GPL");
+*/
#ifdef CONFIG_PROC_FS
static void snd_ak4531_proc_init(struct snd_card *card, struct snd_ak4531 *ak4531);
@@ -270,7 +272,7 @@ static const DECLARE_TLV_DB_SCALE(db_scale_master, -6200, 200, 0);
static const DECLARE_TLV_DB_SCALE(db_scale_mono, -2800, 400, 0);
static const DECLARE_TLV_DB_SCALE(db_scale_input, -5000, 200, 0);
-static struct snd_kcontrol_new snd_ak4531_controls[] = {
+static struct snd_kcontrol_new snd_ak4531_controls[] __devinitdata = {
AK4531_DOUBLE_TLV("Master Playback Switch", 0,
AK4531_LMASTER, AK4531_RMASTER, 7, 7, 1, 1,
@@ -379,8 +381,9 @@ static u8 snd_ak4531_initial_map[0x19 + 1] = {
0x01 /* 19: Mic Amp Setup */
};
-int snd_ak4531_mixer(struct snd_card *card, struct snd_ak4531 *_ak4531,
- struct snd_ak4531 **rak4531)
+int __devinit snd_ak4531_mixer(struct snd_card *card,
+ struct snd_ak4531 *_ak4531,
+ struct snd_ak4531 **rak4531)
{
unsigned int idx;
int err;
@@ -389,9 +392,10 @@ int snd_ak4531_mixer(struct snd_card *card, struct snd_ak4531 *_ak4531,
.dev_free = snd_ak4531_dev_free,
};
- snd_assert(rak4531 != NULL, return -EINVAL);
- *rak4531 = NULL;
- snd_assert(card != NULL && _ak4531 != NULL, return -EINVAL);
+ if (snd_BUG_ON(!card || !_ak4531))
+ return -EINVAL;
+ if (rak4531)
+ *rak4531 = NULL;
ak4531 = kzalloc(sizeof(*ak4531), GFP_KERNEL);
if (ak4531 == NULL)
return -ENOMEM;
@@ -425,7 +429,8 @@ int snd_ak4531_mixer(struct snd_card *card, struct snd_ak4531 *_ak4531,
#if 0
snd_ak4531_dump(ak4531);
#endif
- *rak4531 = ak4531;
+ if (rak4531)
+ *rak4531 = ak4531;
return 0;
}
@@ -476,7 +481,8 @@ static void snd_ak4531_proc_read(struct snd_info_entry *entry,
ak4531->regs[AK4531_MIC_GAIN] & 1 ? "+30dB" : "+0dB");
}
-static void snd_ak4531_proc_init(struct snd_card *card, struct snd_ak4531 *ak4531)
+static void __devinit
+snd_ak4531_proc_init(struct snd_card *card, struct snd_ak4531 *ak4531)
{
struct snd_info_entry *entry;
@@ -484,25 +490,3 @@ static void snd_ak4531_proc_init(struct snd_card *card, struct snd_ak4531 *ak453
snd_info_set_text_ops(entry, ak4531, snd_ak4531_proc_read);
}
#endif
-
-EXPORT_SYMBOL(snd_ak4531_mixer);
-#ifdef CONFIG_PM
-EXPORT_SYMBOL(snd_ak4531_suspend);
-EXPORT_SYMBOL(snd_ak4531_resume);
-#endif
-
-/*
- * INIT part
- */
-
-static int __init alsa_ak4531_init(void)
-{
- return 0;
-}
-
-static void __exit alsa_ak4531_exit(void)
-{
-}
-
-module_init(alsa_ak4531_init)
-module_exit(alsa_ak4531_exit)
diff --git a/sound/pci/als4000.c b/sound/pci/als4000.c
index 27ce6136ab00..ba570053d4d5 100644
--- a/sound/pci/als4000.c
+++ b/sound/pci/als4000.c
@@ -2,7 +2,7 @@
* card-als4000.c - driver for Avance Logic ALS4000 based soundcards.
* Copyright (C) 2000 by Bart Hartgers <bart@etpmod.phys.tue.nl>,
* Jaroslav Kysela <perex@perex.cz>
- * Copyright (C) 2002 by Andreas Mohr <hw7oshyuv3001@sneakemail.com>
+ * Copyright (C) 2002, 2008 by Andreas Mohr <hw7oshyuv3001@sneakemail.com>
*
* Framework borrowed from Massimo Piccioni's card-als100.c.
*
@@ -27,8 +27,10 @@
* bought an ALS4000 based soundcard, I was forced to base this driver
* on reverse engineering.
*
- * Note: this is no longer true. Pretty verbose chip docu (ALS4000a.PDF)
- * can be found on the ALSA web site.
+ * Note: this is no longer true (thank you!):
+ * pretty verbose chip docu (ALS4000a.PDF) can be found on the ALSA web site.
+ * Page numbers stated anywhere below with the "SPECS_PAGE:" tag
+ * refer to: ALS4000a.PDF specs Ver 1.0, May 28th, 1998.
*
* The ALS4000 seems to be the PCI-cousin of the ALS100. It contains an
* ALS100-like SB DSP/mixer, an OPL3 synth, a MPU401 and a gameport
@@ -59,7 +61,7 @@
* - value -> some port 0x0c0d
*
* ToDo:
- * - Proper shared IRQ handling?
+ * - by default, don't enable legacy game and use PCI game I/O
* - power management? (card can do voice wakeup according to datasheet!!)
*/
@@ -78,7 +80,7 @@
#include <sound/sb.h>
#include <sound/initval.h>
-MODULE_AUTHOR("Bart Hartgers <bart@etpmod.phys.tue.nl>");
+MODULE_AUTHOR("Bart Hartgers <bart@etpmod.phys.tue.nl>, Andreas Mohr");
MODULE_DESCRIPTION("Avance Logic ALS4000");
MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("{{Avance Logic,ALS4000}}");
@@ -107,7 +109,7 @@ MODULE_PARM_DESC(joystick_port, "Joystick port address for ALS4000 soundcard. (0
struct snd_card_als4000 {
/* most frequent access first */
- unsigned long gcr;
+ unsigned long iobase;
struct pci_dev *pci;
struct snd_sb *chip;
#ifdef SUPPORT_JOYSTICK
@@ -122,28 +124,168 @@ static struct pci_device_id snd_als4000_ids[] = {
MODULE_DEVICE_TABLE(pci, snd_als4000_ids);
-static inline void snd_als4000_gcr_write_addr(unsigned long port, u32 reg, u32 val)
+enum als4k_iobase_t {
+ /* IOx: B == Byte, W = Word, D = DWord; SPECS_PAGE: 37 */
+ ALS4K_IOD_00_AC97_ACCESS = 0x00,
+ ALS4K_IOW_04_AC97_READ = 0x04,
+ ALS4K_IOB_06_AC97_STATUS = 0x06,
+ ALS4K_IOB_07_IRQSTATUS = 0x07,
+ ALS4K_IOD_08_GCR_DATA = 0x08,
+ ALS4K_IOB_0C_GCR_INDEX = 0x0c,
+ ALS4K_IOB_0E_IRQTYPE_SB_CR1E_MPU = 0x0e,
+ ALS4K_IOB_10_ADLIB_ADDR0 = 0x10,
+ ALS4K_IOB_11_ADLIB_ADDR1 = 0x11,
+ ALS4K_IOB_12_ADLIB_ADDR2 = 0x12,
+ ALS4K_IOB_13_ADLIB_ADDR3 = 0x13,
+ ALS4K_IOB_14_MIXER_INDEX = 0x14,
+ ALS4K_IOB_15_MIXER_DATA = 0x15,
+ ALS4K_IOB_16_ESP_RESET = 0x16,
+ ALS4K_IOB_16_ACK_FOR_CR1E = 0x16, /* 2nd function */
+ ALS4K_IOB_18_OPL_ADDR0 = 0x18,
+ ALS4K_IOB_19_OPL_ADDR1 = 0x19,
+ ALS4K_IOB_1A_ESP_RD_DATA = 0x1a,
+ ALS4K_IOB_1C_ESP_CMD_DATA = 0x1c,
+ ALS4K_IOB_1C_ESP_WR_STATUS = 0x1c, /* 2nd function */
+ ALS4K_IOB_1E_ESP_RD_STATUS8 = 0x1e,
+ ALS4K_IOB_1F_ESP_RD_STATUS16 = 0x1f,
+ ALS4K_IOB_20_ESP_GAMEPORT_200 = 0x20,
+ ALS4K_IOB_21_ESP_GAMEPORT_201 = 0x21,
+ ALS4K_IOB_30_MIDI_DATA = 0x30,
+ ALS4K_IOB_31_MIDI_STATUS = 0x31,
+ ALS4K_IOB_31_MIDI_COMMAND = 0x31, /* 2nd function */
+};
+
+enum als4k_iobase_0e_t {
+ ALS4K_IOB_0E_MPU_IRQ = 0x10,
+ ALS4K_IOB_0E_CR1E_IRQ = 0x40,
+ ALS4K_IOB_0E_SB_DMA_IRQ = 0x80,
+};
+
+enum als4k_gcr_t { /* all registers 32bit wide; SPECS_PAGE: 38 to 42 */
+ ALS4K_GCR8C_MISC_CTRL = 0x8c,
+ ALS4K_GCR90_TEST_MODE_REG = 0x90,
+ ALS4K_GCR91_DMA0_ADDR = 0x91,
+ ALS4K_GCR92_DMA0_MODE_COUNT = 0x92,
+ ALS4K_GCR93_DMA1_ADDR = 0x93,
+ ALS4K_GCR94_DMA1_MODE_COUNT = 0x94,
+ ALS4K_GCR95_DMA3_ADDR = 0x95,
+ ALS4K_GCR96_DMA3_MODE_COUNT = 0x96,
+ ALS4K_GCR99_DMA_EMULATION_CTRL = 0x99,
+ ALS4K_GCRA0_FIFO1_CURRENT_ADDR = 0xa0,
+ ALS4K_GCRA1_FIFO1_STATUS_BYTECOUNT = 0xa1,
+ ALS4K_GCRA2_FIFO2_PCIADDR = 0xa2,
+ ALS4K_GCRA3_FIFO2_COUNT = 0xa3,
+ ALS4K_GCRA4_FIFO2_CURRENT_ADDR = 0xa4,
+ ALS4K_GCRA5_FIFO1_STATUS_BYTECOUNT = 0xa5,
+ ALS4K_GCRA6_PM_CTRL = 0xa6,
+ ALS4K_GCRA7_PCI_ACCESS_STORAGE = 0xa7,
+ ALS4K_GCRA8_LEGACY_CFG1 = 0xa8,
+ ALS4K_GCRA9_LEGACY_CFG2 = 0xa9,
+ ALS4K_GCRFF_DUMMY_SCRATCH = 0xff,
+};
+
+enum als4k_gcr8c_t {
+ ALS4K_GCR8C_IRQ_MASK_CTRL_ENABLE = 0x8000,
+ ALS4K_GCR8C_CHIP_REV_MASK = 0xf0000
+};
+
+static inline void snd_als4k_iobase_writeb(unsigned long iobase,
+ enum als4k_iobase_t reg,
+ u8 val)
+{
+ outb(val, iobase + reg);
+}
+
+static inline void snd_als4k_iobase_writel(unsigned long iobase,
+ enum als4k_iobase_t reg,
+ u32 val)
+{
+ outl(val, iobase + reg);
+}
+
+static inline u8 snd_als4k_iobase_readb(unsigned long iobase,
+ enum als4k_iobase_t reg)
+{
+ return inb(iobase + reg);
+}
+
+static inline u32 snd_als4k_iobase_readl(unsigned long iobase,
+ enum als4k_iobase_t reg)
+{
+ return inl(iobase + reg);
+}
+
+static inline void snd_als4k_gcr_write_addr(unsigned long iobase,
+ enum als4k_gcr_t reg,
+ u32 val)
{
- outb(reg, port+0x0c);
- outl(val, port+0x08);
+ snd_als4k_iobase_writeb(iobase, ALS4K_IOB_0C_GCR_INDEX, reg);
+ snd_als4k_iobase_writel(iobase, ALS4K_IOD_08_GCR_DATA, val);
}
-static inline void snd_als4000_gcr_write(struct snd_sb *sb, u32 reg, u32 val)
+static inline void snd_als4k_gcr_write(struct snd_sb *sb,
+ enum als4k_gcr_t reg,
+ u32 val)
{
- snd_als4000_gcr_write_addr(sb->alt_port, reg, val);
+ snd_als4k_gcr_write_addr(sb->alt_port, reg, val);
}
-static inline u32 snd_als4000_gcr_read_addr(unsigned long port, u32 reg)
+static inline u32 snd_als4k_gcr_read_addr(unsigned long iobase,
+ enum als4k_gcr_t reg)
{
- outb(reg, port+0x0c);
- return inl(port+0x08);
+ /* SPECS_PAGE: 37/38 */
+ snd_als4k_iobase_writeb(iobase, ALS4K_IOB_0C_GCR_INDEX, reg);
+ return snd_als4k_iobase_readl(iobase, ALS4K_IOD_08_GCR_DATA);
}
-static inline u32 snd_als4000_gcr_read(struct snd_sb *sb, u32 reg)
+static inline u32 snd_als4k_gcr_read(struct snd_sb *sb, enum als4k_gcr_t reg)
{
- return snd_als4000_gcr_read_addr(sb->alt_port, reg);
+ return snd_als4k_gcr_read_addr(sb->alt_port, reg);
}
+enum als4k_cr_t { /* all registers 8bit wide; SPECS_PAGE: 20 to 23 */
+ ALS4K_CR0_SB_CONFIG = 0x00,
+ ALS4K_CR2_MISC_CONTROL = 0x02,
+ ALS4K_CR3_CONFIGURATION = 0x03,
+ ALS4K_CR17_FIFO_STATUS = 0x17,
+ ALS4K_CR18_ESP_MAJOR_VERSION = 0x18,
+ ALS4K_CR19_ESP_MINOR_VERSION = 0x19,
+ ALS4K_CR1A_MPU401_UART_MODE_CONTROL = 0x1a,
+ ALS4K_CR1C_FIFO2_BLOCK_LENGTH_LO = 0x1c,
+ ALS4K_CR1D_FIFO2_BLOCK_LENGTH_HI = 0x1d,
+ ALS4K_CR1E_FIFO2_CONTROL = 0x1e, /* secondary PCM FIFO (recording) */
+ ALS4K_CR3A_MISC_CONTROL = 0x3a,
+ ALS4K_CR3B_CRC32_BYTE0 = 0x3b, /* for testing, activate via CR3A */
+ ALS4K_CR3C_CRC32_BYTE1 = 0x3c,
+ ALS4K_CR3D_CRC32_BYTE2 = 0x3d,
+ ALS4K_CR3E_CRC32_BYTE3 = 0x3e,
+};
+
+enum als4k_cr0_t {
+ ALS4K_CR0_DMA_CONTIN_MODE_CTRL = 0x02, /* IRQ/FIFO controlled for 0/1 */
+ ALS4K_CR0_DMA_90H_MODE_CTRL = 0x04, /* IRQ/FIFO controlled for 0/1 */
+ ALS4K_CR0_MX80_81_REG_WRITE_ENABLE = 0x80,
+};
+
+static inline void snd_als4_cr_write(struct snd_sb *chip,
+ enum als4k_cr_t reg,
+ u8 data)
+{
+ /* Control Register is reg | 0xc0 (bit 7, 6 set) on sbmixer_index
+ * NOTE: assumes chip->mixer_lock to be locked externally already!
+ * SPECS_PAGE: 6 */
+ snd_sbmixer_write(chip, reg | 0xc0, data);
+}
+
+static inline u8 snd_als4_cr_read(struct snd_sb *chip,
+ enum als4k_cr_t reg)
+{
+ /* NOTE: assumes chip->mixer_lock to be locked externally already! */
+ return snd_sbmixer_read(chip, reg | 0xc0);
+}
+
+
+
static void snd_als4000_set_rate(struct snd_sb *chip, unsigned int rate)
{
if (!(chip->mode & SB_RATE_LOCK)) {
@@ -156,15 +298,19 @@ static void snd_als4000_set_rate(struct snd_sb *chip, unsigned int rate)
static inline void snd_als4000_set_capture_dma(struct snd_sb *chip,
dma_addr_t addr, unsigned size)
{
- snd_als4000_gcr_write(chip, 0xa2, addr);
- snd_als4000_gcr_write(chip, 0xa3, (size-1));
+ /* SPECS_PAGE: 40 */
+ snd_als4k_gcr_write(chip, ALS4K_GCRA2_FIFO2_PCIADDR, addr);
+ snd_als4k_gcr_write(chip, ALS4K_GCRA3_FIFO2_COUNT, (size-1));
}
static inline void snd_als4000_set_playback_dma(struct snd_sb *chip,
- dma_addr_t addr, unsigned size)
+ dma_addr_t addr,
+ unsigned size)
{
- snd_als4000_gcr_write(chip, 0x91, addr);
- snd_als4000_gcr_write(chip, 0x92, (size-1)|0x180000);
+ /* SPECS_PAGE: 38 */
+ snd_als4k_gcr_write(chip, ALS4K_GCR91_DMA0_ADDR, addr);
+ snd_als4k_gcr_write(chip, ALS4K_GCR92_DMA0_MODE_COUNT,
+ (size-1)|0x180000);
}
#define ALS4000_FORMAT_SIGNED (1<<0)
@@ -248,7 +394,7 @@ static int snd_als4000_capture_prepare(struct snd_pcm_substream *substream)
count = snd_pcm_lib_period_bytes(substream);
if (chip->capture_format & ALS4000_FORMAT_16BIT)
- count >>=1;
+ count >>= 1;
count--;
spin_lock_irq(&chip->reg_lock);
@@ -256,8 +402,8 @@ static int snd_als4000_capture_prepare(struct snd_pcm_substream *substream)
snd_als4000_set_capture_dma(chip, runtime->dma_addr, size);
spin_unlock_irq(&chip->reg_lock);
spin_lock_irq(&chip->mixer_lock);
- snd_sbmixer_write(chip, 0xdc, count);
- snd_sbmixer_write(chip, 0xdd, count>>8);
+ snd_als4_cr_write(chip, ALS4K_CR1C_FIFO2_BLOCK_LENGTH_LO, count & 0xff);
+ snd_als4_cr_write(chip, ALS4K_CR1D_FIFO2_BLOCK_LENGTH_HI, count >> 8);
spin_unlock_irq(&chip->mixer_lock);
return 0;
}
@@ -275,7 +421,7 @@ static int snd_als4000_playback_prepare(struct snd_pcm_substream *substream)
count = snd_pcm_lib_period_bytes(substream);
if (chip->playback_format & ALS4000_FORMAT_16BIT)
- count >>=1;
+ count >>= 1;
count--;
/* FIXME: from second playback on, there's a lot more clicks and pops
@@ -292,8 +438,8 @@ static int snd_als4000_playback_prepare(struct snd_pcm_substream *substream)
/* snd_sbdsp_command(chip, SB_DSP_SPEAKER_ON); */
snd_sbdsp_command(chip, playback_cmd(chip).dsp_cmd);
snd_sbdsp_command(chip, playback_cmd(chip).format);
- snd_sbdsp_command(chip, count);
- snd_sbdsp_command(chip, count>>8);
+ snd_sbdsp_command(chip, count & 0xff);
+ snd_sbdsp_command(chip, count >> 8);
snd_sbdsp_command(chip, playback_cmd(chip).dma_off);
spin_unlock_irq(&chip->reg_lock);
@@ -305,17 +451,25 @@ static int snd_als4000_capture_trigger(struct snd_pcm_substream *substream, int
struct snd_sb *chip = snd_pcm_substream_chip(substream);
int result = 0;
+ /* FIXME race condition in here!!!
+ chip->mode non-atomic update gets consistently protected
+ by reg_lock always, _except_ for this place!!
+ Probably need to take reg_lock as outer (or inner??) lock, too.
+ (or serialize both lock operations? probably not, though... - racy?)
+ */
spin_lock(&chip->mixer_lock);
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_RESUME:
chip->mode |= SB_RATE_LOCK_CAPTURE;
- snd_sbmixer_write(chip, 0xde, capture_cmd(chip));
+ snd_als4_cr_write(chip, ALS4K_CR1E_FIFO2_CONTROL,
+ capture_cmd(chip));
break;
case SNDRV_PCM_TRIGGER_STOP:
case SNDRV_PCM_TRIGGER_SUSPEND:
chip->mode &= ~SB_RATE_LOCK_CAPTURE;
- snd_sbmixer_write(chip, 0xde, 0);
+ snd_als4_cr_write(chip, ALS4K_CR1E_FIFO2_CONTROL,
+ capture_cmd(chip));
break;
default:
result = -EINVAL;
@@ -356,8 +510,9 @@ static snd_pcm_uframes_t snd_als4000_capture_pointer(struct snd_pcm_substream *s
unsigned int result;
spin_lock(&chip->reg_lock);
- result = snd_als4000_gcr_read(chip, 0xa4) & 0xffff;
+ result = snd_als4k_gcr_read(chip, ALS4K_GCRA4_FIFO2_CURRENT_ADDR);
spin_unlock(&chip->reg_lock);
+ result &= 0xffff;
return bytes_to_frames( substream->runtime, result );
}
@@ -367,8 +522,9 @@ static snd_pcm_uframes_t snd_als4000_playback_pointer(struct snd_pcm_substream *
unsigned result;
spin_lock(&chip->reg_lock);
- result = snd_als4000_gcr_read(chip, 0xa0) & 0xffff;
+ result = snd_als4k_gcr_read(chip, ALS4K_GCRA0_FIFO1_CURRENT_ADDR);
spin_unlock(&chip->reg_lock);
+ result &= 0xffff;
return bytes_to_frames( substream->runtime, result );
}
@@ -376,45 +532,63 @@ static snd_pcm_uframes_t snd_als4000_playback_pointer(struct snd_pcm_substream *
* return IRQ_HANDLED no matter whether we actually had an IRQ flag or not).
* ALS4000a.PDF writes that while ACKing IRQ in PCI block will *not* ACK
* the IRQ in the SB core, ACKing IRQ in SB block *will* ACK the PCI IRQ
- * register (alt_port + 0x0e). Probably something could be optimized here to
- * query/write one register only...
+ * register (alt_port + ALS4K_IOB_0E_IRQTYPE_SB_CR1E_MPU). Probably something
+ * could be optimized here to query/write one register only...
* And even if both registers need to be queried, then there's still the
* question of whether it's actually correct to ACK PCI IRQ before reading
* SB IRQ like we do now, since ALS4000a.PDF mentions that PCI IRQ will *clear*
* SB IRQ status.
+ * (hmm, SPECS_PAGE: 38 mentions it the other way around!)
* And do we *really* need the lock here for *reading* SB_DSP4_IRQSTATUS??
* */
static irqreturn_t snd_als4000_interrupt(int irq, void *dev_id)
{
struct snd_sb *chip = dev_id;
- unsigned gcr_status;
- unsigned sb_status;
-
- /* find out which bit of the ALS4000 produced the interrupt */
- gcr_status = inb(chip->alt_port + 0xe);
-
- if ((gcr_status & 0x80) && (chip->playback_substream)) /* playback */
+ unsigned pci_irqstatus;
+ unsigned sb_irqstatus;
+
+ /* find out which bit of the ALS4000 PCI block produced the interrupt,
+ SPECS_PAGE: 38, 5 */
+ pci_irqstatus = snd_als4k_iobase_readb(chip->alt_port,
+ ALS4K_IOB_0E_IRQTYPE_SB_CR1E_MPU);
+ if ((pci_irqstatus & ALS4K_IOB_0E_SB_DMA_IRQ)
+ && (chip->playback_substream)) /* playback */
snd_pcm_period_elapsed(chip->playback_substream);
- if ((gcr_status & 0x40) && (chip->capture_substream)) /* capturing */
+ if ((pci_irqstatus & ALS4K_IOB_0E_CR1E_IRQ)
+ && (chip->capture_substream)) /* capturing */
snd_pcm_period_elapsed(chip->capture_substream);
- if ((gcr_status & 0x10) && (chip->rmidi)) /* MPU401 interrupt */
+ if ((pci_irqstatus & ALS4K_IOB_0E_MPU_IRQ)
+ && (chip->rmidi)) /* MPU401 interrupt */
snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data);
- /* release the gcr */
- outb(gcr_status, chip->alt_port + 0xe);
+ /* ACK the PCI block IRQ */
+ snd_als4k_iobase_writeb(chip->alt_port,
+ ALS4K_IOB_0E_IRQTYPE_SB_CR1E_MPU, pci_irqstatus);
spin_lock(&chip->mixer_lock);
- sb_status = snd_sbmixer_read(chip, SB_DSP4_IRQSTATUS);
+ /* SPECS_PAGE: 20 */
+ sb_irqstatus = snd_sbmixer_read(chip, SB_DSP4_IRQSTATUS);
spin_unlock(&chip->mixer_lock);
- if (sb_status & SB_IRQTYPE_8BIT)
+ if (sb_irqstatus & SB_IRQTYPE_8BIT)
snd_sb_ack_8bit(chip);
- if (sb_status & SB_IRQTYPE_16BIT)
+ if (sb_irqstatus & SB_IRQTYPE_16BIT)
snd_sb_ack_16bit(chip);
- if (sb_status & SB_IRQTYPE_MPUIN)
+ if (sb_irqstatus & SB_IRQTYPE_MPUIN)
inb(chip->mpu_port);
- if (sb_status & 0x20)
- inb(SBP(chip, RESET));
- return IRQ_HANDLED;
+ if (sb_irqstatus & ALS4K_IRQTYPE_CR1E_DMA)
+ snd_als4k_iobase_readb(chip->alt_port,
+ ALS4K_IOB_16_ACK_FOR_CR1E);
+
+ /* printk(KERN_INFO "als4000: irq 0x%04x 0x%04x\n",
+ pci_irqstatus, sb_irqstatus); */
+
+ /* only ack the things we actually handled above */
+ return IRQ_RETVAL(
+ (pci_irqstatus & (ALS4K_IOB_0E_SB_DMA_IRQ|ALS4K_IOB_0E_CR1E_IRQ|
+ ALS4K_IOB_0E_MPU_IRQ))
+ || (sb_irqstatus & (SB_IRQTYPE_8BIT|SB_IRQTYPE_16BIT|
+ SB_IRQTYPE_MPUIN|ALS4K_IRQTYPE_CR1E_DMA))
+ );
}
/*****************************************************************/
@@ -526,7 +700,8 @@ static int __devinit snd_als4000_pcm(struct snd_sb *chip, int device)
struct snd_pcm *pcm;
int err;
- if ((err = snd_pcm_new(chip->card, "ALS4000 DSP", device, 1, 1, &pcm)) < 0)
+ err = snd_pcm_new(chip->card, "ALS4000 DSP", device, 1, 1, &pcm);
+ if (err < 0)
return err;
pcm->private_data = chip;
pcm->info_flags = SNDRV_PCM_INFO_JOINT_DUPLEX;
@@ -543,48 +718,55 @@ static int __devinit snd_als4000_pcm(struct snd_sb *chip, int device)
/******************************************************************/
-static void snd_als4000_set_addr(unsigned long gcr,
- unsigned int sb,
- unsigned int mpu,
- unsigned int opl,
- unsigned int game)
+static void snd_als4000_set_addr(unsigned long iobase,
+ unsigned int sb_io,
+ unsigned int mpu_io,
+ unsigned int opl_io,
+ unsigned int game_io)
{
- u32 confA = 0;
- u32 confB = 0;
-
- if (mpu > 0)
- confB |= (mpu | 1) << 16;
- if (sb > 0)
- confB |= (sb | 1);
- if (game > 0)
- confA |= (game | 1) << 16;
- if (opl > 0)
- confA |= (opl | 1);
- snd_als4000_gcr_write_addr(gcr, 0xa8, confA);
- snd_als4000_gcr_write_addr(gcr, 0xa9, confB);
+ u32 cfg1 = 0;
+ u32 cfg2 = 0;
+
+ if (mpu_io > 0)
+ cfg2 |= (mpu_io | 1) << 16;
+ if (sb_io > 0)
+ cfg2 |= (sb_io | 1);
+ if (game_io > 0)
+ cfg1 |= (game_io | 1) << 16;
+ if (opl_io > 0)
+ cfg1 |= (opl_io | 1);
+ snd_als4k_gcr_write_addr(iobase, ALS4K_GCRA8_LEGACY_CFG1, cfg1);
+ snd_als4k_gcr_write_addr(iobase, ALS4K_GCRA9_LEGACY_CFG2, cfg2);
}
static void snd_als4000_configure(struct snd_sb *chip)
{
- unsigned tmp;
+ u8 tmp;
int i;
/* do some more configuration */
spin_lock_irq(&chip->mixer_lock);
- tmp = snd_sbmixer_read(chip, 0xc0);
- snd_sbmixer_write(chip, 0xc0, tmp|0x80);
- /* always select DMA channel 0, since we do not actually use DMA */
+ tmp = snd_als4_cr_read(chip, ALS4K_CR0_SB_CONFIG);
+ snd_als4_cr_write(chip, ALS4K_CR0_SB_CONFIG,
+ tmp|ALS4K_CR0_MX80_81_REG_WRITE_ENABLE);
+ /* always select DMA channel 0, since we do not actually use DMA
+ * SPECS_PAGE: 19/20 */
snd_sbmixer_write(chip, SB_DSP4_DMASETUP, SB_DMASETUP_DMA0);
- snd_sbmixer_write(chip, 0xc0, tmp&0x7f);
+ snd_als4_cr_write(chip, ALS4K_CR0_SB_CONFIG,
+ tmp & ~ALS4K_CR0_MX80_81_REG_WRITE_ENABLE);
spin_unlock_irq(&chip->mixer_lock);
spin_lock_irq(&chip->reg_lock);
- /* magic number. Enables interrupts(?) */
- snd_als4000_gcr_write(chip, 0x8c, 0x28000);
- for(i = 0x91; i <= 0x96; ++i)
- snd_als4000_gcr_write(chip, i, 0);
+ /* enable interrupts */
+ snd_als4k_gcr_write(chip, ALS4K_GCR8C_MISC_CTRL,
+ ALS4K_GCR8C_IRQ_MASK_CTRL_ENABLE);
+
+ /* SPECS_PAGE: 39 */
+ for (i = ALS4K_GCR91_DMA0_ADDR; i <= ALS4K_GCR96_DMA3_MODE_COUNT; ++i)
+ snd_als4k_gcr_write(chip, i, 0);
- snd_als4000_gcr_write(chip, 0x99, snd_als4000_gcr_read(chip, 0x99));
+ snd_als4k_gcr_write(chip, ALS4K_GCR99_DMA_EMULATION_CTRL,
+ snd_als4k_gcr_read(chip, ALS4K_GCR99_DMA_EMULATION_CTRL));
spin_unlock_irq(&chip->reg_lock);
}
@@ -628,7 +810,7 @@ static int __devinit snd_als4000_create_gameport(struct snd_card_als4000 *acard,
gameport_set_port_data(gp, r);
/* Enable legacy joystick port */
- snd_als4000_set_addr(acard->gcr, 0, 0, 0, 1);
+ snd_als4000_set_addr(acard->iobase, 0, 0, 0, 1);
gameport_register_port(acard->gameport);
@@ -643,7 +825,9 @@ static void snd_als4000_free_gameport(struct snd_card_als4000 *acard)
gameport_unregister_port(acard->gameport);
acard->gameport = NULL;
- snd_als4000_set_addr(acard->gcr, 0, 0, 0, 0); /* disable joystick */
+ /* disable joystick */
+ snd_als4000_set_addr(acard->iobase, 0, 0, 0, 0);
+
release_and_free_resource(r);
}
}
@@ -654,10 +838,10 @@ static inline void snd_als4000_free_gameport(struct snd_card_als4000 *acard) { }
static void snd_card_als4000_free( struct snd_card *card )
{
- struct snd_card_als4000 * acard = (struct snd_card_als4000 *)card->private_data;
+ struct snd_card_als4000 *acard = card->private_data;
/* make sure that interrupts are disabled */
- snd_als4000_gcr_write_addr( acard->gcr, 0x8c, 0);
+ snd_als4k_gcr_write_addr(acard->iobase, ALS4K_GCR8C_MISC_CTRL, 0);
/* free resources */
snd_als4000_free_gameport(acard);
pci_release_regions(acard->pci);
@@ -670,7 +854,7 @@ static int __devinit snd_card_als4000_probe(struct pci_dev *pci,
static int dev;
struct snd_card *card;
struct snd_card_als4000 *acard;
- unsigned long gcr;
+ unsigned long iobase;
struct snd_sb *chip;
struct snd_opl3 *opl3;
unsigned short word;
@@ -699,31 +883,32 @@ static int __devinit snd_card_als4000_probe(struct pci_dev *pci,
pci_disable_device(pci);
return err;
}
- gcr = pci_resource_start(pci, 0);
+ iobase = pci_resource_start(pci, 0);
pci_read_config_word(pci, PCI_COMMAND, &word);
pci_write_config_word(pci, PCI_COMMAND, word | PCI_COMMAND_IO);
pci_set_master(pci);
card = snd_card_new(index[dev], id[dev], THIS_MODULE,
- sizeof( struct snd_card_als4000 ) );
+ sizeof(*acard) /* private_data: acard */);
if (card == NULL) {
pci_release_regions(pci);
pci_disable_device(pci);
return -ENOMEM;
}
- acard = (struct snd_card_als4000 *)card->private_data;
+ acard = card->private_data;
acard->pci = pci;
- acard->gcr = gcr;
+ acard->iobase = iobase;
card->private_free = snd_card_als4000_free;
/* disable all legacy ISA stuff */
- snd_als4000_set_addr(acard->gcr, 0, 0, 0, 0);
+ snd_als4000_set_addr(acard->iobase, 0, 0, 0, 0);
if ((err = snd_sbdsp_create(card,
- gcr + 0x10,
+ iobase + ALS4K_IOB_10_ADLIB_ADDR0,
pci->irq,
+ /* internally registered as IRQF_SHARED in case of ALS4000 SB */
snd_als4000_interrupt,
-1,
-1,
@@ -734,7 +919,7 @@ static int __devinit snd_card_als4000_probe(struct pci_dev *pci,
acard->chip = chip;
chip->pci = pci;
- chip->alt_port = gcr;
+ chip->alt_port = iobase;
snd_card_set_dev(card, &pci->dev);
snd_als4000_configure(chip);
@@ -745,11 +930,18 @@ static int __devinit snd_card_als4000_probe(struct pci_dev *pci,
card->shortname, chip->alt_port, chip->irq);
if ((err = snd_mpu401_uart_new( card, 0, MPU401_HW_ALS4000,
- gcr+0x30, MPU401_INFO_INTEGRATED,
+ iobase + ALS4K_IOB_30_MIDI_DATA,
+ MPU401_INFO_INTEGRATED,
pci->irq, 0, &chip->rmidi)) < 0) {
- printk(KERN_ERR "als4000: no MPU-401 device at 0x%lx?\n", gcr+0x30);
+ printk(KERN_ERR "als4000: no MPU-401 device at 0x%lx?\n",
+ iobase + ALS4K_IOB_30_MIDI_DATA);
goto out_err;
}
+ /* FIXME: ALS4000 has interesting MPU401 configuration features
+ * at ALS4K_CR1A_MPU401_UART_MODE_CONTROL
+ * (pass-thru / UART switching, fast MIDI clock, etc.),
+ * however there doesn't seem to be an ALSA API for this...
+ * SPECS_PAGE: 21 */
if ((err = snd_als4000_pcm(chip, 0)) < 0) {
goto out_err;
@@ -758,10 +950,13 @@ static int __devinit snd_card_als4000_probe(struct pci_dev *pci,
goto out_err;
}
- if (snd_opl3_create(card, gcr+0x10, gcr+0x12,
+ if (snd_opl3_create(card,
+ iobase + ALS4K_IOB_10_ADLIB_ADDR0,
+ iobase + ALS4K_IOB_12_ADLIB_ADDR2,
OPL3_HW_AUTO, 1, &opl3) < 0) {
printk(KERN_ERR "als4000: no OPL device at 0x%lx-0x%lx?\n",
- gcr+0x10, gcr+0x12 );
+ iobase + ALS4K_IOB_10_ADLIB_ADDR0,
+ iobase + ALS4K_IOB_12_ADLIB_ADDR2);
} else {
if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) {
goto out_err;
@@ -831,13 +1026,13 @@ static int snd_als4000_resume(struct pci_dev *pci)
#ifdef SUPPORT_JOYSTICK
if (acard->gameport)
- snd_als4000_set_addr(acard->gcr, 0, 0, 0, 1);
+ snd_als4000_set_addr(acard->iobase, 0, 0, 0, 1);
#endif
snd_power_change_state(card, SNDRV_CTL_POWER_D0);
return 0;
}
-#endif
+#endif /* CONFIG_PM */
static struct pci_driver driver = {
diff --git a/sound/pci/atiixp.c b/sound/pci/atiixp.c
index 457228fb22aa..085a52b8c807 100644
--- a/sound/pci/atiixp.c
+++ b/sound/pci/atiixp.c
@@ -37,7 +37,7 @@
MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>");
MODULE_DESCRIPTION("ATI IXP AC97 controller");
MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{ATI,IXP150/200/250/300/400}}");
+MODULE_SUPPORTED_DEVICE("{{ATI,IXP150/200/250/300/400/600}}");
static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */
static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */
@@ -290,6 +290,7 @@ static struct pci_device_id snd_atiixp_ids[] = {
{ 0x1002, 0x4341, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* SB200 */
{ 0x1002, 0x4361, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* SB300 */
{ 0x1002, 0x4370, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* SB400 */
+ { 0x1002, 0x4382, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* SB600 */
{ 0, }
};
@@ -722,7 +723,9 @@ static int snd_atiixp_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
struct atiixp_dma *dma = substream->runtime->private_data;
int err = 0;
- snd_assert(dma->ops->enable_transfer && dma->ops->flush_dma, return -EINVAL);
+ if (snd_BUG_ON(!dma->ops->enable_transfer ||
+ !dma->ops->flush_dma))
+ return -EINVAL;
spin_lock(&chip->reg_lock);
switch (cmd) {
@@ -1032,7 +1035,8 @@ static int snd_atiixp_pcm_open(struct snd_pcm_substream *substream,
struct snd_pcm_runtime *runtime = substream->runtime;
int err;
- snd_assert(dma->ops && dma->ops->enable_dma, return -EINVAL);
+ if (snd_BUG_ON(!dma->ops || !dma->ops->enable_dma))
+ return -EINVAL;
if (dma->opened)
return -EBUSY;
@@ -1064,7 +1068,8 @@ static int snd_atiixp_pcm_close(struct snd_pcm_substream *substream,
{
struct atiixp *chip = snd_pcm_substream_chip(substream);
/* disable DMA bits */
- snd_assert(dma->ops && dma->ops->enable_dma, return -EINVAL);
+ if (snd_BUG_ON(!dma->ops || !dma->ops->enable_dma))
+ return -EINVAL;
spin_lock_irq(&chip->reg_lock);
dma->ops->enable_dma(chip, 0);
spin_unlock_irq(&chip->reg_lock);
diff --git a/sound/pci/atiixp_modem.c b/sound/pci/atiixp_modem.c
index d457a32a7939..2f106306c7fe 100644
--- a/sound/pci/atiixp_modem.c
+++ b/sound/pci/atiixp_modem.c
@@ -674,7 +674,9 @@ static int snd_atiixp_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
struct atiixp_dma *dma = substream->runtime->private_data;
int err = 0;
- snd_assert(dma->ops->enable_transfer && dma->ops->flush_dma, return -EINVAL);
+ if (snd_BUG_ON(!dma->ops->enable_transfer ||
+ !dma->ops->flush_dma))
+ return -EINVAL;
spin_lock(&chip->reg_lock);
switch(cmd) {
@@ -865,7 +867,8 @@ static int snd_atiixp_pcm_open(struct snd_pcm_substream *substream,
.mask = 0,
};
- snd_assert(dma->ops && dma->ops->enable_dma, return -EINVAL);
+ if (snd_BUG_ON(!dma->ops || !dma->ops->enable_dma))
+ return -EINVAL;
if (dma->opened)
return -EBUSY;
@@ -895,7 +898,8 @@ static int snd_atiixp_pcm_close(struct snd_pcm_substream *substream,
{
struct atiixp_modem *chip = snd_pcm_substream_chip(substream);
/* disable DMA bits */
- snd_assert(dma->ops && dma->ops->enable_dma, return -EINVAL);
+ if (snd_BUG_ON(!dma->ops || !dma->ops->enable_dma))
+ return -EINVAL;
spin_lock_irq(&chip->reg_lock);
dma->ops->enable_dma(chip, 0);
spin_unlock_irq(&chip->reg_lock);
diff --git a/sound/pci/au88x0/au88x0.h b/sound/pci/au88x0/au88x0.h
index 4aad35bba11a..cf46bba563cf 100644
--- a/sound/pci/au88x0/au88x0.h
+++ b/sound/pci/au88x0/au88x0.h
@@ -125,7 +125,6 @@ typedef struct {
/* Virtual page extender stuff */
int nr_periods;
int period_bytes;
- struct snd_sg_buf *sgbuf; /* DMA Scatter Gather struct */
int period_real;
int period_virt;
@@ -195,16 +194,14 @@ static void vortex_adb_setsrc(vortex_t * vortex, int adbdma,
/* DMA Engines. */
static void vortex_adbdma_setbuffers(vortex_t * vortex, int adbdma,
- struct snd_sg_buf * sgbuf, int size,
- int count);
+ int size, int count);
static void vortex_adbdma_setmode(vortex_t * vortex, int adbdma, int ie,
int dir, int fmt, int d,
u32 offset);
static void vortex_adbdma_setstartbuffer(vortex_t * vortex, int adbdma, int sb);
#ifndef CHIP_AU8810
static void vortex_wtdma_setbuffers(vortex_t * vortex, int wtdma,
- struct snd_sg_buf * sgbuf, int size,
- int count);
+ int size, int count);
static void vortex_wtdma_setmode(vortex_t * vortex, int wtdma, int ie, int fmt, int d, /*int e, */
u32 offset);
static void vortex_wtdma_setstartbuffer(vortex_t * vortex, int wtdma, int sb);
diff --git a/sound/pci/au88x0/au88x0_core.c b/sound/pci/au88x0/au88x0_core.c
index 333c62de8620..b070e5714514 100644
--- a/sound/pci/au88x0/au88x0_core.c
+++ b/sound/pci/au88x0/au88x0_core.c
@@ -427,7 +427,7 @@ static void vortex_mixer_init(vortex_t * vortex)
/* Set clipping ceiling (this may be all wrong). */
/*
- for (x = 0; x > 0x80; x++) {
+ for (x = 0; x < 0x80; x++) {
hwwrite(vortex->mmio, VORTEX_MIXER_CLIP + (x << 2), 0x3ffff);
}
*/
@@ -1097,19 +1097,12 @@ static void vortex_adbdma_setstartbuffer(vortex_t * vortex, int adbdma, int sb)
static void
vortex_adbdma_setbuffers(vortex_t * vortex, int adbdma,
- struct snd_sg_buf * sgbuf, int psize, int count)
+ int psize, int count)
{
stream_t *dma = &vortex->dma_adb[adbdma];
- if (sgbuf == NULL) {
- printk(KERN_INFO "vortex: FATAL: sgbuf is NULL!\n");
- return;
- }
- //printk(KERN_INFO "vortex: page count = %d, tblcount = %d\n", count, sgbuf->tblsize);
-
dma->period_bytes = psize;
dma->nr_periods = count;
- dma->sgbuf = sgbuf;
dma->cfg0 = 0;
dma->cfg1 = 0;
@@ -1120,26 +1113,26 @@ vortex_adbdma_setbuffers(vortex_t * vortex, int adbdma,
dma->cfg1 |= 0x88000000 | 0x44000000 | 0x30000000 | (psize - 1);
hwwrite(vortex->mmio,
VORTEX_ADBDMA_BUFBASE + (adbdma << 4) + 0xc,
- snd_sgbuf_get_addr(sgbuf, psize * 3));
+ snd_pcm_sgbuf_get_addr(dma->substream, psize * 3));
/* 3 pages */
case 3:
dma->cfg0 |= 0x12000000;
dma->cfg1 |= 0x80000000 | 0x40000000 | ((psize - 1) << 0xc);
hwwrite(vortex->mmio,
VORTEX_ADBDMA_BUFBASE + (adbdma << 4) + 0x8,
- snd_sgbuf_get_addr(sgbuf, psize * 2));
+ snd_pcm_sgbuf_get_addr(dma->substream, psize * 2));
/* 2 pages */
case 2:
dma->cfg0 |= 0x88000000 | 0x44000000 | 0x10000000 | (psize - 1);
hwwrite(vortex->mmio,
VORTEX_ADBDMA_BUFBASE + (adbdma << 4) + 0x4,
- snd_sgbuf_get_addr(sgbuf, psize));
+ snd_pcm_sgbuf_get_addr(dma->substream, psize));
/* 1 page */
case 1:
dma->cfg0 |= 0x80000000 | 0x40000000 | ((psize - 1) << 0xc);
hwwrite(vortex->mmio,
VORTEX_ADBDMA_BUFBASE + (adbdma << 4),
- snd_sgbuf_get_addr(sgbuf, 0));
+ snd_pcm_sgbuf_get_addr(dma->substream, 0));
break;
}
//printk("vortex: cfg0 = 0x%x\nvortex: cfg1=0x%x\n", dma->cfg0, dma->cfg1);
@@ -1205,7 +1198,7 @@ static int vortex_adbdma_bufshift(vortex_t * vortex, int adbdma)
//hwwrite(vortex->mmio, VORTEX_ADBDMA_BUFBASE+(((adbdma << 2)+pp) << 2), dma->table[p].addr);
hwwrite(vortex->mmio,
VORTEX_ADBDMA_BUFBASE + (((adbdma << 2) + pp) << 2),
- snd_sgbuf_get_addr(dma->sgbuf,
+ snd_pcm_sgbuf_get_addr(dma->substream,
dma->period_bytes * p));
/* Force write thru cache. */
hwread(vortex->mmio, VORTEX_ADBDMA_BUFBASE +
@@ -1244,7 +1237,10 @@ static void vortex_adbdma_resetup(vortex_t *vortex, int adbdma) {
if (pp >= 4)
pp -= 4;
}
- hwwrite(vortex->mmio, VORTEX_ADBDMA_BUFBASE+(((adbdma << 2)+pp) << 2), snd_sgbuf_get_addr(dma->sgbuf, dma->period_bytes * p));
+ hwwrite(vortex->mmio,
+ VORTEX_ADBDMA_BUFBASE + (((adbdma << 2) + pp) << 2),
+ snd_pcm_sgbuf_get_addr(dma->substream,
+ dma->period_bytes * p));
/* Force write thru cache. */
hwread(vortex->mmio, VORTEX_ADBDMA_BUFBASE + (((adbdma << 2)+pp) << 2));
}
@@ -1367,13 +1363,12 @@ static void vortex_wtdma_setstartbuffer(vortex_t * vortex, int wtdma, int sb)
static void
vortex_wtdma_setbuffers(vortex_t * vortex, int wtdma,
- struct snd_sg_buf * sgbuf, int psize, int count)
+ int psize, int count)
{
stream_t *dma = &vortex->dma_wt[wtdma];
dma->period_bytes = psize;
dma->nr_periods = count;
- dma->sgbuf = sgbuf;
dma->cfg0 = 0;
dma->cfg1 = 0;
@@ -1383,23 +1378,23 @@ vortex_wtdma_setbuffers(vortex_t * vortex, int wtdma,
case 4:
dma->cfg1 |= 0x88000000 | 0x44000000 | 0x30000000 | (psize-1);
hwwrite(vortex->mmio, VORTEX_WTDMA_BUFBASE + (wtdma << 4) + 0xc,
- snd_sgbuf_get_addr(sgbuf, psize * 3));
+ snd_pcm_sgbuf_get_addr(dma->substream, psize * 3));
/* 3 pages */
case 3:
dma->cfg0 |= 0x12000000;
dma->cfg1 |= 0x80000000 | 0x40000000 | ((psize-1) << 0xc);
hwwrite(vortex->mmio, VORTEX_WTDMA_BUFBASE + (wtdma << 4) + 0x8,
- snd_sgbuf_get_addr(sgbuf, psize * 2));
+ snd_pcm_sgbuf_get_addr(dma->substream, psize * 2));
/* 2 pages */
case 2:
dma->cfg0 |= 0x88000000 | 0x44000000 | 0x10000000 | (psize-1);
hwwrite(vortex->mmio, VORTEX_WTDMA_BUFBASE + (wtdma << 4) + 0x4,
- snd_sgbuf_get_addr(sgbuf, psize));
+ snd_pcm_sgbuf_get_addr(dma->substream, psize));
/* 1 page */
case 1:
dma->cfg0 |= 0x80000000 | 0x40000000 | ((psize-1) << 0xc);
hwwrite(vortex->mmio, VORTEX_WTDMA_BUFBASE + (wtdma << 4),
- snd_sgbuf_get_addr(sgbuf, 0));
+ snd_pcm_sgbuf_get_addr(dma->substream, 0));
break;
}
hwwrite(vortex->mmio, VORTEX_WTDMA_BUFCFG0 + (wtdma << 3), dma->cfg0);
@@ -1465,7 +1460,8 @@ static int vortex_wtdma_bufshift(vortex_t * vortex, int wtdma)
hwwrite(vortex->mmio,
VORTEX_WTDMA_BUFBASE +
(((wtdma << 2) + pp) << 2),
- snd_sgbuf_get_addr(dma->sgbuf, dma->period_bytes * p));
+ snd_pcm_sgbuf_get_addr(dma->substream,
+ dma->period_bytes * p));
/* Force write thru cache. */
hwread(vortex->mmio, VORTEX_WTDMA_BUFBASE +
(((wtdma << 2) + pp) << 2));
diff --git a/sound/pci/au88x0/au88x0_game.c b/sound/pci/au88x0/au88x0_game.c
index bc212f41a38a..e291aa59742e 100644
--- a/sound/pci/au88x0/au88x0_game.c
+++ b/sound/pci/au88x0/au88x0_game.c
@@ -1,6 +1,4 @@
/*
- * $Id: au88x0_game.c,v 1.9 2003/09/22 03:51:28 mjander Exp $
- *
* Manuel Jander.
*
* Based on the work of:
diff --git a/sound/pci/au88x0/au88x0_pcm.c b/sound/pci/au88x0/au88x0_pcm.c
index f9a58b4a30eb..b9d2f202cf9b 100644
--- a/sound/pci/au88x0/au88x0_pcm.c
+++ b/sound/pci/au88x0/au88x0_pcm.c
@@ -189,7 +189,6 @@ snd_vortex_pcm_hw_params(struct snd_pcm_substream *substream,
{
vortex_t *chip = snd_pcm_substream_chip(substream);
stream_t *stream = (stream_t *) (substream->runtime->private_data);
- struct snd_sg_buf *sgbuf;
int err;
// Alloc buffer memory.
@@ -199,8 +198,6 @@ snd_vortex_pcm_hw_params(struct snd_pcm_substream *substream,
printk(KERN_ERR "Vortex: pcm page alloc failed!\n");
return err;
}
- //sgbuf = (struct snd_sg_buf *) substream->runtime->dma_private;
- sgbuf = snd_pcm_substream_sgbuf(substream);
/*
printk(KERN_INFO "Vortex: periods %d, period_bytes %d, channels = %d\n", params_periods(hw_params),
params_period_bytes(hw_params), params_channels(hw_params));
@@ -226,7 +223,7 @@ snd_vortex_pcm_hw_params(struct snd_pcm_substream *substream,
stream = substream->runtime->private_data = &chip->dma_adb[dma];
stream->substream = substream;
/* Setup Buffers. */
- vortex_adbdma_setbuffers(chip, dma, sgbuf,
+ vortex_adbdma_setbuffers(chip, dma,
params_period_bytes(hw_params),
params_periods(hw_params));
}
@@ -240,7 +237,7 @@ snd_vortex_pcm_hw_params(struct snd_pcm_substream *substream,
&chip->dma_wt[substream->number];
stream->dma = substream->number;
stream->substream = substream;
- vortex_wtdma_setbuffers(chip, substream->number, sgbuf,
+ vortex_wtdma_setbuffers(chip, substream->number,
params_period_bytes(hw_params),
params_periods(hw_params));
}
@@ -392,13 +389,6 @@ static snd_pcm_uframes_t snd_vortex_pcm_pointer(struct snd_pcm_substream *substr
return (bytes_to_frames(substream->runtime, current_ptr));
}
-/* Page callback. */
-/*
-static struct page *snd_pcm_sgbuf_ops_page(struct snd_pcm_substream *substream, unsigned long offset) {
-
-
-}
-*/
/* operators */
static struct snd_pcm_ops snd_vortex_playback_ops = {
.open = snd_vortex_pcm_open,
diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c
index 5f63af6b88a2..333007c523a1 100644
--- a/sound/pci/azt3328.c
+++ b/sound/pci/azt3328.c
@@ -1,6 +1,6 @@
/*
* azt3328.c - driver for Aztech AZF3328 based soundcards (e.g. PCI168).
- * Copyright (C) 2002, 2005, 2006, 2007 by Andreas Mohr <andi AT lisas.de>
+ * Copyright (C) 2002, 2005 - 2008 by Andreas Mohr <andi AT lisas.de>
*
* Framework borrowed from Bart Hartgers's als4000.c.
* Driver developed on PCI168 AP(W) version (PCI rev. 10, subsystem ID 1801),
@@ -35,9 +35,20 @@
* (3 weeks' worth of evenings filled with driver work).
* (and no, I did NOT go the easy way: to pick up a SB PCI128 for 9 Euros)
*
+ * It is quite likely that the AZF3328 chip is the PCI cousin of the
+ * AZF3318 ("azt1020 pnp", "MM Pro 16") ISA chip, given very similar specs.
+ *
* The AZF3328 chip (note: AZF3328, *not* AZT3328, that's just the driver name
- * for compatibility reasons) has the following features:
+ * for compatibility reasons) from Azfin (joint-venture of Aztech and Fincitec,
+ * Fincitec acquired by National Semiconductor in 2002, together with the
+ * Fincitec-related company ARSmikro) has the following features:
*
+ * - compatibility & compliance:
+ * - Microsoft PC 97 ("PC 97 Hardware Design Guide",
+ * http://www.microsoft.com/whdc/archive/pcguides.mspx)
+ * - Microsoft PC 98 Baseline Audio
+ * - MPU401 UART
+ * - Sound Blaster Emulation (DOS Box)
* - builtin AC97 conformant codec (SNR over 80dB)
* Note that "conformant" != "compliant"!! this chip's mixer register layout
* *differs* from the standard AC97 layout:
@@ -48,21 +59,28 @@
* addresses illegally. So far unfortunately it looks like the very flexible
* ALSA AC97 support is still not enough to easily compensate for such a
* grave layout violation despite all tweaks and quirks mechanisms it offers.
- * - builtin genuine OPL3
+ * - builtin genuine OPL3 - verified to work fine, 20080506
* - full duplex 16bit playback/record at independent sampling rate
- * - MPU401 (+ legacy address support) FIXME: how to enable legacy addr??
+ * - MPU401 (+ legacy address support, claimed by one official spec sheet)
+ * FIXME: how to enable legacy addr??
* - game port (legacy address support)
- * - builtin 3D enhancement (said to be YAMAHA Ymersion)
* - builtin DirectInput support, helps reduce CPU overhead (interrupt-driven
- * features supported)
+ * features supported). - See common term "Digital Enhanced Game Port"...
+ * (probably DirectInput 3.0 spec - confirm)
+ * - builtin 3D enhancement (said to be YAMAHA Ymersion)
* - built-in General DirectX timer having a 20 bits counter
* with 1us resolution (see below!)
- * - I2S serial port for external DAC
+ * - I2S serial output port for external DAC
* - supports 33MHz PCI spec 2.1, PCI power management 1.0, compliant with ACPI
* - supports hardware volume control
* - single chip low cost solution (128 pin QFP)
* - supports programmable Sub-vendor and Sub-system ID
* required for Microsoft's logo compliance (FIXME: where?)
+ * At least the Trident 4D Wave DX has one bit somewhere
+ * to enable writes to PCI subsystem VID registers, that should be it.
+ * This might easily be in extended PCI reg space, since PCI168 also has
+ * some custom data starting at 0x80. What kind of config settings
+ * are located in our extended PCI space anyway??
* - PCI168 AP(W) card: power amplifier with 4 Watts/channel at 4 Ohms
*
* Note that this driver now is actually *better* than the Windows driver,
@@ -74,6 +92,24 @@
* - "timidity -iAv -B2,8 -Os -EFreverb=0"
* - "pmidi -p 128:0 jazz.mid"
*
+ * OPL3 hardware playback testing, try something like:
+ * cat /proc/asound/hwdep
+ * and
+ * aconnect -o
+ * Then use
+ * sbiload -Dhw:x,y --opl3 /usr/share/sounds/opl3/std.o3 ......./drums.o3
+ * where x,y is the xx-yy number as given in hwdep.
+ * Then try
+ * pmidi -p a:b jazz.mid
+ * where a:b is the client number plus 0 usually, as given by aconnect above.
+ * Oh, and make sure to unmute the FM mixer control (doh!)
+ * NOTE: power use during OPL3 playback is _VERY_ high (70W --> 90W!)
+ * despite no CPU activity, possibly due to hindering ACPI idling somehow.
+ * Shouldn't be a problem of the AZF3328 chip itself, I'd hope.
+ * Higher PCM / FM mixer levels seem to conflict (causes crackling),
+ * at least sometimes. Maybe even use with hardware sequencer timer above :)
+ * adplay/adplug-utils might soon offer hardware-based OPL3 playback, too.
+ *
* Certain PCI versions of this card are susceptible to DMA traffic underruns
* in some systems (resulting in sound crackling/clicking/popping),
* probably because they don't have a DMA FIFO buffer or so.
@@ -87,6 +123,8 @@
* better than a VIA, yet ironically I still get crackling, like many other
* people with the same chipset.
* Possible remedies:
+ * - use speaker (amplifier) output instead of headphone output
+ * (in case crackling is due to overloaded output clipping)
* - plug card into a different PCI slot, preferrably one that isn't shared
* too much (this helps a lot, but not completely!)
* - get rid of PCI VGA card, use AGP instead
@@ -94,18 +132,23 @@
* - fiddle with PCI latency settings (setpci -v -s BUSID latency_timer=XX)
* Not too helpful.
* - Disable ACPI/power management/"Auto Detect RAM/PCI Clk" in BIOS
- *
+ *
* BUGS
- * - full-duplex might *still* be problematic, not fully tested recently
+ * - full-duplex might *still* be problematic, however a recent test was fine
* - (non-bug) "Bass/Treble or 3D settings don't work" - they do get evaluated
* if you set PCM output switch to "pre 3D" instead of "post 3D".
* If this can't be set, then get a mixer application that Isn't Stupid (tm)
* (e.g. kmix, gamix) - unfortunately several are!!
- *
+ * - locking is not entirely clean, especially the audio stream activity
+ * ints --> may be racy
+ * - an _unconnected_ secondary joystick at the gameport will be reported
+ * to be "active" (floating values, not precisely -1) due to the way we need
+ * to read the Digital Enhanced Game Port. Not sure whether it is fixable.
+ *
* TODO
* - test MPU401 MIDI playback etc.
- * - add some power micro-management (disable various units of the card
- * as long as they're unused). However this requires I/O ports which I
+ * - add more power micro-management (disable various units of the card
+ * as long as they're unused). However this requires more I/O ports which I
* haven't figured out yet and which thus might not even exist...
* The standard suspend/resume functionality could probably make use of
* some improvement, too...
@@ -113,6 +156,7 @@
* - figure out some cleverly evil scheme to possibly make ALSA AC97 code
* fully accept our quite incompatible ""AC97"" mixer and thus save some
* code (but I'm not too optimistic that doing this is possible at all)
+ * - use MMIO (memory-mapped I/O)? Slightly faster access, e.g. for gameport.
*/
#include <asm/io.h>
@@ -138,7 +182,7 @@ MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("{{Aztech,AZF3328}}");
#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
-#define SUPPORT_JOYSTICK 1
+#define SUPPORT_GAMEPORT 1
#endif
#define DEBUG_MISC 0
@@ -147,13 +191,14 @@ MODULE_SUPPORTED_DEVICE("{{Aztech,AZF3328}}");
#define DEBUG_PLAY_REC 0
#define DEBUG_IO 0
#define DEBUG_TIMER 0
+#define DEBUG_GAME 0
#define MIXER_TESTING 0
#if DEBUG_MISC
#define snd_azf3328_dbgmisc(format, args...) printk(KERN_ERR format, ##args)
#else
#define snd_azf3328_dbgmisc(format, args...)
-#endif
+#endif
#if DEBUG_CALLS
#define snd_azf3328_dbgcalls(format, args...) printk(format, ##args)
@@ -163,25 +208,31 @@ MODULE_SUPPORTED_DEVICE("{{Aztech,AZF3328}}");
#define snd_azf3328_dbgcalls(format, args...)
#define snd_azf3328_dbgcallenter()
#define snd_azf3328_dbgcallleave()
-#endif
+#endif
#if DEBUG_MIXER
#define snd_azf3328_dbgmixer(format, args...) printk(format, ##args)
#else
#define snd_azf3328_dbgmixer(format, args...)
-#endif
+#endif
#if DEBUG_PLAY_REC
#define snd_azf3328_dbgplay(format, args...) printk(KERN_ERR format, ##args)
#else
#define snd_azf3328_dbgplay(format, args...)
-#endif
+#endif
#if DEBUG_MISC
#define snd_azf3328_dbgtimer(format, args...) printk(KERN_ERR format, ##args)
#else
#define snd_azf3328_dbgtimer(format, args...)
-#endif
+#endif
+
+#if DEBUG_GAME
+#define snd_azf3328_dbggame(format, args...) printk(KERN_ERR format, ##args)
+#else
+#define snd_azf3328_dbggame(format, args...)
+#endif
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
module_param_array(index, int, NULL, 0444);
@@ -195,51 +246,62 @@ static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card *
module_param_array(enable, bool, NULL, 0444);
MODULE_PARM_DESC(enable, "Enable AZF3328 soundcard.");
-#ifdef SUPPORT_JOYSTICK
-static int joystick[SNDRV_CARDS];
-module_param_array(joystick, bool, NULL, 0444);
-MODULE_PARM_DESC(joystick, "Enable joystick for AZF3328 soundcard.");
-#endif
-
static int seqtimer_scaling = 128;
module_param(seqtimer_scaling, int, 0444);
MODULE_PARM_DESC(seqtimer_scaling, "Set 1024000Hz sequencer timer scale factor (lockup danger!). Default 128.");
+struct snd_azf3328_audio_stream {
+ struct snd_pcm_substream *substream;
+ int enabled;
+ int running;
+ unsigned long portbase;
+};
+
+enum snd_azf3328_stream_index {
+ AZF_PLAYBACK = 0,
+ AZF_CAPTURE = 1,
+};
+
struct snd_azf3328 {
/* often-used fields towards beginning, then grouped */
- unsigned long codec_port;
- unsigned long io2_port;
- unsigned long mpu_port;
- unsigned long synth_port;
- unsigned long mixer_port;
+
+ unsigned long codec_io; /* usually 0xb000, size 128 */
+ unsigned long game_io; /* usually 0xb400, size 8 */
+ unsigned long mpu_io; /* usually 0xb800, size 4 */
+ unsigned long opl3_io; /* usually 0xbc00, size 8 */
+ unsigned long mixer_io; /* usually 0xc000, size 64 */
spinlock_t reg_lock;
struct snd_timer *timer;
-
+
struct snd_pcm *pcm;
- struct snd_pcm_substream *playback_substream;
- struct snd_pcm_substream *capture_substream;
- unsigned int is_playing;
- unsigned int is_recording;
+ struct snd_azf3328_audio_stream audio_stream[2];
struct snd_card *card;
struct snd_rawmidi *rmidi;
-#ifdef SUPPORT_JOYSTICK
+#ifdef SUPPORT_GAMEPORT
struct gameport *gameport;
+ int axes[4];
#endif
struct pci_dev *pci;
int irq;
+ /* register 0x6a is write-only, thus need to remember setting.
+ * If we need to add more registers here, then we might try to fold this
+ * into some transparent combined shadow register handling with
+ * CONFIG_PM register storage below, but that's slightly difficult. */
+ u16 shadow_reg_codec_6AH;
+
#ifdef CONFIG_PM
/* register value containers for power management
* Note: not always full I/O range preserved (just like Win driver!) */
- u16 saved_regs_codec [AZF_IO_SIZE_CODEC_PM / 2];
- u16 saved_regs_io2 [AZF_IO_SIZE_IO2_PM / 2];
- u16 saved_regs_mpu [AZF_IO_SIZE_MPU_PM / 2];
- u16 saved_regs_synth[AZF_IO_SIZE_SYNTH_PM / 2];
+ u16 saved_regs_codec[AZF_IO_SIZE_CODEC_PM / 2];
+ u16 saved_regs_game [AZF_IO_SIZE_GAME_PM / 2];
+ u16 saved_regs_mpu [AZF_IO_SIZE_MPU_PM / 2];
+ u16 saved_regs_opl3 [AZF_IO_SIZE_OPL3_PM / 2];
u16 saved_regs_mixer[AZF_IO_SIZE_MIXER_PM / 2];
#endif
};
@@ -252,126 +314,166 @@ static const struct pci_device_id snd_azf3328_ids[] = {
MODULE_DEVICE_TABLE(pci, snd_azf3328_ids);
+
+static int
+snd_azf3328_io_reg_setb(unsigned reg, u8 mask, int do_set)
+{
+ u8 prev = inb(reg), new;
+
+ new = (do_set) ? (prev|mask) : (prev & ~mask);
+ /* we need to always write the new value no matter whether it differs
+ * or not, since some register bits don't indicate their setting */
+ outb(new, reg);
+ if (new != prev)
+ return 1;
+
+ return 0;
+}
+
static inline void
-snd_azf3328_codec_outb(const struct snd_azf3328 *chip, int reg, u8 value)
+snd_azf3328_codec_outb(const struct snd_azf3328 *chip, unsigned reg, u8 value)
{
- outb(value, chip->codec_port + reg);
+ outb(value, chip->codec_io + reg);
}
static inline u8
-snd_azf3328_codec_inb(const struct snd_azf3328 *chip, int reg)
+snd_azf3328_codec_inb(const struct snd_azf3328 *chip, unsigned reg)
{
- return inb(chip->codec_port + reg);
+ return inb(chip->codec_io + reg);
}
static inline void
-snd_azf3328_codec_outw(const struct snd_azf3328 *chip, int reg, u16 value)
+snd_azf3328_codec_outw(const struct snd_azf3328 *chip, unsigned reg, u16 value)
{
- outw(value, chip->codec_port + reg);
+ outw(value, chip->codec_io + reg);
}
static inline u16
-snd_azf3328_codec_inw(const struct snd_azf3328 *chip, int reg)
+snd_azf3328_codec_inw(const struct snd_azf3328 *chip, unsigned reg)
+{
+ return inw(chip->codec_io + reg);
+}
+
+static inline void
+snd_azf3328_codec_outl(const struct snd_azf3328 *chip, unsigned reg, u32 value)
+{
+ outl(value, chip->codec_io + reg);
+}
+
+static inline u32
+snd_azf3328_codec_inl(const struct snd_azf3328 *chip, unsigned reg)
{
- return inw(chip->codec_port + reg);
+ return inl(chip->codec_io + reg);
}
static inline void
-snd_azf3328_codec_outl(const struct snd_azf3328 *chip, int reg, u32 value)
+snd_azf3328_game_outb(const struct snd_azf3328 *chip, unsigned reg, u8 value)
{
- outl(value, chip->codec_port + reg);
+ outb(value, chip->game_io + reg);
}
static inline void
-snd_azf3328_io2_outb(const struct snd_azf3328 *chip, int reg, u8 value)
+snd_azf3328_game_outw(const struct snd_azf3328 *chip, unsigned reg, u16 value)
{
- outb(value, chip->io2_port + reg);
+ outw(value, chip->game_io + reg);
}
static inline u8
-snd_azf3328_io2_inb(const struct snd_azf3328 *chip, int reg)
+snd_azf3328_game_inb(const struct snd_azf3328 *chip, unsigned reg)
{
- return inb(chip->io2_port + reg);
+ return inb(chip->game_io + reg);
+}
+
+static inline u16
+snd_azf3328_game_inw(const struct snd_azf3328 *chip, unsigned reg)
+{
+ return inw(chip->game_io + reg);
}
static inline void
-snd_azf3328_mixer_outw(const struct snd_azf3328 *chip, int reg, u16 value)
+snd_azf3328_mixer_outw(const struct snd_azf3328 *chip, unsigned reg, u16 value)
{
- outw(value, chip->mixer_port + reg);
+ outw(value, chip->mixer_io + reg);
}
static inline u16
-snd_azf3328_mixer_inw(const struct snd_azf3328 *chip, int reg)
+snd_azf3328_mixer_inw(const struct snd_azf3328 *chip, unsigned reg)
{
- return inw(chip->mixer_port + reg);
+ return inw(chip->mixer_io + reg);
}
-static void
-snd_azf3328_mixer_set_mute(const struct snd_azf3328 *chip, int reg, int do_mute)
+#define AZF_MUTE_BIT 0x80
+
+static int
+snd_azf3328_mixer_set_mute(const struct snd_azf3328 *chip,
+ unsigned reg, int do_mute
+)
{
- unsigned long portbase = chip->mixer_port + reg + 1;
- unsigned char oldval;
+ unsigned long portbase = chip->mixer_io + reg + 1;
+ int updated;
/* the mute bit is on the *second* (i.e. right) register of a
* left/right channel setting */
- oldval = inb(portbase);
- if (do_mute)
- oldval |= 0x80;
- else
- oldval &= ~0x80;
- outb(oldval, portbase);
+ updated = snd_azf3328_io_reg_setb(portbase, AZF_MUTE_BIT, do_mute);
+
+ /* indicate whether it was muted before */
+ return (do_mute) ? !updated : updated;
}
static void
-snd_azf3328_mixer_write_volume_gradually(const struct snd_azf3328 *chip, int reg, unsigned char dst_vol_left, unsigned char dst_vol_right, int chan_sel, int delay)
+snd_azf3328_mixer_write_volume_gradually(const struct snd_azf3328 *chip,
+ unsigned reg,
+ unsigned char dst_vol_left,
+ unsigned char dst_vol_right,
+ int chan_sel, int delay
+)
{
- unsigned long portbase = chip->mixer_port + reg;
+ unsigned long portbase = chip->mixer_io + reg;
unsigned char curr_vol_left = 0, curr_vol_right = 0;
- int left_done = 0, right_done = 0;
-
+ int left_change = 0, right_change = 0;
+
snd_azf3328_dbgcallenter();
- if (chan_sel & SET_CHAN_LEFT)
+
+ if (chan_sel & SET_CHAN_LEFT) {
curr_vol_left = inb(portbase + 1);
- else
- left_done = 1;
- if (chan_sel & SET_CHAN_RIGHT)
+
+ /* take care of muting flag contained in left channel */
+ if (curr_vol_left & AZF_MUTE_BIT)
+ dst_vol_left |= AZF_MUTE_BIT;
+ else
+ dst_vol_left &= ~AZF_MUTE_BIT;
+
+ left_change = (curr_vol_left > dst_vol_left) ? -1 : 1;
+ }
+
+ if (chan_sel & SET_CHAN_RIGHT) {
curr_vol_right = inb(portbase + 0);
- else
- right_done = 1;
-
- /* take care of muting flag (0x80) contained in left channel */
- if (curr_vol_left & 0x80)
- dst_vol_left |= 0x80;
- else
- dst_vol_left &= ~0x80;
+
+ right_change = (curr_vol_right > dst_vol_right) ? -1 : 1;
+ }
do {
- if (!left_done) {
- if (curr_vol_left > dst_vol_left)
- curr_vol_left--;
- else
- if (curr_vol_left < dst_vol_left)
- curr_vol_left++;
- else
- left_done = 1;
- outb(curr_vol_left, portbase + 1);
+ if (left_change) {
+ if (curr_vol_left != dst_vol_left) {
+ curr_vol_left += left_change;
+ outb(curr_vol_left, portbase + 1);
+ } else
+ left_change = 0;
}
- if (!right_done) {
- if (curr_vol_right > dst_vol_right)
- curr_vol_right--;
- else
- if (curr_vol_right < dst_vol_right)
- curr_vol_right++;
- else
- right_done = 1;
+ if (right_change) {
+ if (curr_vol_right != dst_vol_right) {
+ curr_vol_right += right_change;
+
/* during volume change, the right channel is crackling
* somewhat more than the left channel, unfortunately.
* This seems to be a hardware issue. */
- outb(curr_vol_right, portbase + 0);
+ outb(curr_vol_right, portbase + 0);
+ } else
+ right_change = 0;
}
if (delay)
mdelay(delay);
- } while ((!left_done) || (!right_done));
+ } while ((left_change) || (right_change));
snd_azf3328_dbgcallleave();
}
@@ -379,7 +481,7 @@ snd_azf3328_mixer_write_volume_gradually(const struct snd_azf3328 *chip, int reg
* general mixer element
*/
struct azf3328_mixer_reg {
- unsigned int reg;
+ unsigned reg;
unsigned int lchan_shift, rchan_shift;
unsigned int mask;
unsigned int invert: 1;
@@ -544,13 +646,14 @@ snd_azf3328_info_mixer_enum(struct snd_kcontrol *kcontrol,
"Mix", "Mic"
};
static const char * const texts3[] = {
- "Mic", "CD", "Video", "Aux",
+ "Mic", "CD", "Video", "Aux",
"Line", "Mix", "Mix Mono", "Phone"
};
static const char * const texts4[] = {
"pre 3D", "post 3D"
};
struct azf3328_mixer_reg reg;
+ const char * const *p = NULL;
snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value);
uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
@@ -561,18 +664,20 @@ snd_azf3328_info_mixer_enum(struct snd_kcontrol *kcontrol,
if (reg.reg == IDX_MIXER_ADVCTL2) {
switch(reg.lchan_shift) {
case 8: /* modem out sel */
- strcpy(uinfo->value.enumerated.name, texts1[uinfo->value.enumerated.item]);
+ p = texts1;
break;
case 9: /* mono sel source */
- strcpy(uinfo->value.enumerated.name, texts2[uinfo->value.enumerated.item]);
+ p = texts2;
break;
case 15: /* PCM Out Path */
- strcpy(uinfo->value.enumerated.name, texts4[uinfo->value.enumerated.item]);
+ p = texts4;
break;
}
} else
- strcpy(uinfo->value.enumerated.name, texts3[uinfo->value.enumerated.item]
-);
+ if (reg.reg == IDX_MIXER_REC_SELECT)
+ p = texts3;
+
+ strcpy(uinfo->value.enumerated.name, p[uinfo->value.enumerated.item]);
return 0;
}
@@ -583,7 +688,7 @@ snd_azf3328_get_mixer_enum(struct snd_kcontrol *kcontrol,
struct snd_azf3328 *chip = snd_kcontrol_chip(kcontrol);
struct azf3328_mixer_reg reg;
unsigned short val;
-
+
snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value);
val = snd_azf3328_mixer_inw(chip, reg.reg);
if (reg.reg == IDX_MIXER_REC_SELECT) {
@@ -605,7 +710,7 @@ snd_azf3328_put_mixer_enum(struct snd_kcontrol *kcontrol,
struct snd_azf3328 *chip = snd_kcontrol_chip(kcontrol);
struct azf3328_mixer_reg reg;
unsigned int oreg, nreg, val;
-
+
snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value);
oreg = snd_azf3328_mixer_inw(chip, reg.reg);
val = oreg;
@@ -631,9 +736,11 @@ snd_azf3328_put_mixer_enum(struct snd_kcontrol *kcontrol,
static struct snd_kcontrol_new snd_azf3328_mixer_controls[] __devinitdata = {
AZF3328_MIXER_SWITCH("Master Playback Switch", IDX_MIXER_PLAY_MASTER, 15, 1),
AZF3328_MIXER_VOL_STEREO("Master Playback Volume", IDX_MIXER_PLAY_MASTER, 0x1f, 1),
- AZF3328_MIXER_SWITCH("Wave Playback Switch", IDX_MIXER_WAVEOUT, 15, 1),
- AZF3328_MIXER_VOL_STEREO("Wave Playback Volume", IDX_MIXER_WAVEOUT, 0x1f, 1),
- AZF3328_MIXER_SWITCH("Wave 3D Bypass Playback Switch", IDX_MIXER_ADVCTL2, 7, 1),
+ AZF3328_MIXER_SWITCH("PCM Playback Switch", IDX_MIXER_WAVEOUT, 15, 1),
+ AZF3328_MIXER_VOL_STEREO("PCM Playback Volume",
+ IDX_MIXER_WAVEOUT, 0x1f, 1),
+ AZF3328_MIXER_SWITCH("PCM 3D Bypass Playback Switch",
+ IDX_MIXER_ADVCTL2, 7, 1),
AZF3328_MIXER_SWITCH("FM Playback Switch", IDX_MIXER_FMSYNTH, 15, 1),
AZF3328_MIXER_VOL_STEREO("FM Playback Volume", IDX_MIXER_FMSYNTH, 0x1f, 1),
AZF3328_MIXER_SWITCH("CD Playback Switch", IDX_MIXER_CDAUDIO, 15, 1),
@@ -709,7 +816,8 @@ snd_azf3328_mixer_new(struct snd_azf3328 *chip)
int err;
snd_azf3328_dbgcallenter();
- snd_assert(chip != NULL && chip->card != NULL, return -EINVAL);
+ if (snd_BUG_ON(!chip || !chip->card))
+ return -EINVAL;
card = chip->card;
@@ -717,15 +825,16 @@ snd_azf3328_mixer_new(struct snd_azf3328 *chip)
snd_azf3328_mixer_outw(chip, IDX_MIXER_RESET, 0x0000);
/* mute and zero volume channels */
- for (idx = 0; idx < ARRAY_SIZE(snd_azf3328_init_values); idx++) {
+ for (idx = 0; idx < ARRAY_SIZE(snd_azf3328_init_values); ++idx) {
snd_azf3328_mixer_outw(chip,
snd_azf3328_init_values[idx][0],
snd_azf3328_init_values[idx][1]);
}
-
+
/* add mixer controls */
sw = snd_azf3328_mixer_controls;
- for (idx = 0; idx < ARRAY_SIZE(snd_azf3328_mixer_controls); idx++, sw++) {
+ for (idx = 0; idx < ARRAY_SIZE(snd_azf3328_mixer_controls);
+ ++idx, ++sw) {
if ((err = snd_ctl_add(chip->card, snd_ctl_new1(sw, chip))) < 0)
return err;
}
@@ -757,9 +866,9 @@ snd_azf3328_hw_free(struct snd_pcm_substream *substream)
}
static void
-snd_azf3328_setfmt(struct snd_azf3328 *chip,
- unsigned int reg,
- unsigned int bitrate,
+snd_azf3328_codec_setfmt(struct snd_azf3328 *chip,
+ unsigned reg,
+ enum azf_freq_t bitrate,
unsigned int format_width,
unsigned int channels
)
@@ -769,24 +878,25 @@ snd_azf3328_setfmt(struct snd_azf3328 *chip,
snd_azf3328_dbgcallenter();
switch (bitrate) {
- case 4000: val |= SOUNDFORMAT_FREQ_SUSPECTED_4000; break;
- case 4800: val |= SOUNDFORMAT_FREQ_SUSPECTED_4800; break;
- case 5512: val |= SOUNDFORMAT_FREQ_5510; break; /* the AZF3328 names it "5510" for some strange reason */
- case 6620: val |= SOUNDFORMAT_FREQ_6620; break;
- case 8000: val |= SOUNDFORMAT_FREQ_8000; break;
- case 9600: val |= SOUNDFORMAT_FREQ_9600; break;
- case 11025: val |= SOUNDFORMAT_FREQ_11025; break;
- case 13240: val |= SOUNDFORMAT_FREQ_SUSPECTED_13240; break;
- case 16000: val |= SOUNDFORMAT_FREQ_16000; break;
- case 22050: val |= SOUNDFORMAT_FREQ_22050; break;
- case 32000: val |= SOUNDFORMAT_FREQ_32000; break;
- case 44100: val |= SOUNDFORMAT_FREQ_44100; break;
- case 48000: val |= SOUNDFORMAT_FREQ_48000; break;
- case 66200: val |= SOUNDFORMAT_FREQ_SUSPECTED_66200; break;
+ case AZF_FREQ_4000: val |= SOUNDFORMAT_FREQ_SUSPECTED_4000; break;
+ case AZF_FREQ_4800: val |= SOUNDFORMAT_FREQ_SUSPECTED_4800; break;
+ case AZF_FREQ_5512:
+ /* the AZF3328 names it "5510" for some strange reason */
+ val |= SOUNDFORMAT_FREQ_5510; break;
+ case AZF_FREQ_6620: val |= SOUNDFORMAT_FREQ_6620; break;
+ case AZF_FREQ_8000: val |= SOUNDFORMAT_FREQ_8000; break;
+ case AZF_FREQ_9600: val |= SOUNDFORMAT_FREQ_9600; break;
+ case AZF_FREQ_11025: val |= SOUNDFORMAT_FREQ_11025; break;
+ case AZF_FREQ_13240: val |= SOUNDFORMAT_FREQ_SUSPECTED_13240; break;
+ case AZF_FREQ_16000: val |= SOUNDFORMAT_FREQ_16000; break;
+ case AZF_FREQ_22050: val |= SOUNDFORMAT_FREQ_22050; break;
+ case AZF_FREQ_32000: val |= SOUNDFORMAT_FREQ_32000; break;
default:
snd_printk(KERN_WARNING "unknown bitrate %d, assuming 44.1kHz!\n", bitrate);
- val |= SOUNDFORMAT_FREQ_44100;
- break;
+ /* fall-through */
+ case AZF_FREQ_44100: val |= SOUNDFORMAT_FREQ_44100; break;
+ case AZF_FREQ_48000: val |= SOUNDFORMAT_FREQ_48000; break;
+ case AZF_FREQ_66200: val |= SOUNDFORMAT_FREQ_SUSPECTED_66200; break;
}
/* val = 0xff07; 3m27.993s (65301Hz; -> 64000Hz???) hmm, 66120, 65967, 66123 */
/* val = 0xff09; 17m15.098s (13123,478Hz; -> 12000Hz???) hmm, 13237.2Hz? */
@@ -805,10 +915,10 @@ snd_azf3328_setfmt(struct snd_azf3328 *chip,
val |= SOUNDFORMAT_FLAG_16BIT;
spin_lock_irqsave(&chip->reg_lock, flags);
-
+
/* set bitrate/format */
snd_azf3328_codec_outw(chip, reg, val);
-
+
/* changing the bitrate/format settings switches off the
* audio output with an annoying click in case of 8/16bit format change
* (maybe shutting down DAC/ADC?), thus immediately
@@ -830,31 +940,95 @@ snd_azf3328_setfmt(struct snd_azf3328 *chip,
snd_azf3328_dbgcallleave();
}
+static inline void
+snd_azf3328_codec_setfmt_lowpower(struct snd_azf3328 *chip,
+ unsigned reg
+)
+{
+ /* choose lowest frequency for low power consumption.
+ * While this will cause louder noise due to rather coarse frequency,
+ * it should never matter since output should always
+ * get disabled properly when idle anyway. */
+ snd_azf3328_codec_setfmt(chip, reg, AZF_FREQ_4000, 8, 1);
+}
+
+static void
+snd_azf3328_codec_reg_6AH_update(struct snd_azf3328 *chip,
+ unsigned bitmask,
+ int enable
+)
+{
+ if (enable)
+ chip->shadow_reg_codec_6AH &= ~bitmask;
+ else
+ chip->shadow_reg_codec_6AH |= bitmask;
+ snd_azf3328_dbgplay("6AH_update mask 0x%04x enable %d: val 0x%04x\n",
+ bitmask, enable, chip->shadow_reg_codec_6AH);
+ snd_azf3328_codec_outw(chip, IDX_IO_6AH, chip->shadow_reg_codec_6AH);
+}
+
+static inline void
+snd_azf3328_codec_enable(struct snd_azf3328 *chip, int enable)
+{
+ snd_azf3328_dbgplay("codec_enable %d\n", enable);
+ /* no idea what exactly is being done here, but I strongly assume it's
+ * PM related */
+ snd_azf3328_codec_reg_6AH_update(
+ chip, IO_6A_PAUSE_PLAYBACK_BIT8, enable
+ );
+}
+
+static void
+snd_azf3328_codec_activity(struct snd_azf3328 *chip,
+ enum snd_azf3328_stream_index stream_type,
+ int enable
+)
+{
+ int need_change = (chip->audio_stream[stream_type].running != enable);
+
+ snd_azf3328_dbgplay(
+ "codec_activity: type %d, enable %d, need_change %d\n",
+ stream_type, enable, need_change
+ );
+ if (need_change) {
+ enum snd_azf3328_stream_index other =
+ (stream_type == AZF_PLAYBACK) ?
+ AZF_CAPTURE : AZF_PLAYBACK;
+ /* small check to prevent shutting down the other party
+ * in case it's active */
+ if ((enable) || !(chip->audio_stream[other].running))
+ snd_azf3328_codec_enable(chip, enable);
+
+ /* ...and adjust clock, too
+ * (reduce noise and power consumption) */
+ if (!enable)
+ snd_azf3328_codec_setfmt_lowpower(
+ chip,
+ chip->audio_stream[stream_type].portbase
+ + IDX_IO_PLAY_SOUNDFORMAT
+ );
+ }
+ chip->audio_stream[stream_type].running = enable;
+}
+
static void
snd_azf3328_setdmaa(struct snd_azf3328 *chip,
long unsigned int addr,
unsigned int count,
unsigned int size,
- int do_recording)
+ enum snd_azf3328_stream_index stream_type
+)
{
- unsigned long flags, portbase;
- unsigned int is_running;
-
snd_azf3328_dbgcallenter();
- if (do_recording) {
- /* access capture registers, i.e. skip playback reg section */
- portbase = chip->codec_port + 0x20;
- is_running = chip->is_recording;
- } else {
- /* access the playback register section */
- portbase = chip->codec_port + 0x00;
- is_running = chip->is_playing;
- }
+ if (!chip->audio_stream[stream_type].running) {
+ /* AZF3328 uses a two buffer pointer DMA playback approach */
- /* AZF3328 uses a two buffer pointer DMA playback approach */
- if (!is_running) {
- unsigned long addr_area2;
- unsigned long count_areas, count_tmp; /* width 32bit -- overflow!! */
+ unsigned long flags, portbase, addr_area2;
+
+ /* width 32bit (prevent overflow): */
+ unsigned long count_areas, count_tmp;
+
+ portbase = chip->audio_stream[stream_type].portbase;
count_areas = size/2;
addr_area2 = addr+count_areas;
count_areas--; /* max. index */
@@ -884,11 +1058,11 @@ snd_azf3328_playback_prepare(struct snd_pcm_substream *substream)
snd_azf3328_dbgcallenter();
#if 0
- snd_azf3328_setfmt(chip, IDX_IO_PLAY_SOUNDFORMAT,
+ snd_azf3328_codec_setfmt(chip, IDX_IO_PLAY_SOUNDFORMAT,
runtime->rate,
snd_pcm_format_width(runtime->format),
runtime->channels);
- snd_azf3328_setdmaa(chip, runtime->dma_addr, count, size, 0);
+ snd_azf3328_setdmaa(chip, runtime->dma_addr, count, size, AZF_PLAYBACK);
#endif
snd_azf3328_dbgcallleave();
return 0;
@@ -906,11 +1080,11 @@ snd_azf3328_capture_prepare(struct snd_pcm_substream *substream)
snd_azf3328_dbgcallenter();
#if 0
- snd_azf3328_setfmt(chip, IDX_IO_REC_SOUNDFORMAT,
+ snd_azf3328_codec_setfmt(chip, IDX_IO_REC_SOUNDFORMAT,
runtime->rate,
snd_pcm_format_width(runtime->format),
runtime->channels);
- snd_azf3328_setdmaa(chip, runtime->dma_addr, count, size, 1);
+ snd_azf3328_setdmaa(chip, runtime->dma_addr, count, size, AZF_CAPTURE);
#endif
snd_azf3328_dbgcallleave();
return 0;
@@ -923,6 +1097,7 @@ snd_azf3328_playback_trigger(struct snd_pcm_substream *substream, int cmd)
struct snd_pcm_runtime *runtime = substream->runtime;
int result = 0;
unsigned int status1;
+ int previously_muted;
snd_azf3328_dbgcalls("snd_azf3328_playback_trigger cmd %d\n", cmd);
@@ -930,20 +1105,23 @@ snd_azf3328_playback_trigger(struct snd_pcm_substream *substream, int cmd)
case SNDRV_PCM_TRIGGER_START:
snd_azf3328_dbgplay("START PLAYBACK\n");
- /* mute WaveOut */
- snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 1);
+ /* mute WaveOut (avoid clicking during setup) */
+ previously_muted =
+ snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 1);
- snd_azf3328_setfmt(chip, IDX_IO_PLAY_SOUNDFORMAT,
+ snd_azf3328_codec_setfmt(chip, IDX_IO_PLAY_SOUNDFORMAT,
runtime->rate,
snd_pcm_format_width(runtime->format),
runtime->channels);
spin_lock(&chip->reg_lock);
- /* stop playback */
+ /* first, remember current value: */
status1 = snd_azf3328_codec_inw(chip, IDX_IO_PLAY_FLAGS);
+
+ /* stop playback */
status1 &= ~DMA_RESUME;
snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS, status1);
-
+
/* FIXME: clear interrupts or what??? */
snd_azf3328_codec_outw(chip, IDX_IO_PLAY_IRQTYPE, 0xffff);
spin_unlock(&chip->reg_lock);
@@ -951,7 +1129,7 @@ snd_azf3328_playback_trigger(struct snd_pcm_substream *substream, int cmd)
snd_azf3328_setdmaa(chip, runtime->dma_addr,
snd_pcm_lib_period_bytes(substream),
snd_pcm_lib_buffer_bytes(substream),
- 0);
+ AZF_PLAYBACK);
spin_lock(&chip->reg_lock);
#ifdef WIN9X
@@ -978,30 +1156,35 @@ snd_azf3328_playback_trigger(struct snd_pcm_substream *substream, int cmd)
DMA_SOMETHING_ELSE);
#endif
spin_unlock(&chip->reg_lock);
+ snd_azf3328_codec_activity(chip, AZF_PLAYBACK, 1);
/* now unmute WaveOut */
- snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 0);
+ if (!previously_muted)
+ snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 0);
- chip->is_playing = 1;
snd_azf3328_dbgplay("STARTED PLAYBACK\n");
break;
case SNDRV_PCM_TRIGGER_RESUME:
snd_azf3328_dbgplay("RESUME PLAYBACK\n");
/* resume playback if we were active */
- if (chip->is_playing)
+ spin_lock(&chip->reg_lock);
+ if (chip->audio_stream[AZF_PLAYBACK].running)
snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS,
snd_azf3328_codec_inw(chip, IDX_IO_PLAY_FLAGS) | DMA_RESUME);
+ spin_unlock(&chip->reg_lock);
break;
case SNDRV_PCM_TRIGGER_STOP:
snd_azf3328_dbgplay("STOP PLAYBACK\n");
- /* mute WaveOut */
- snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 1);
+ /* mute WaveOut (avoid clicking during setup) */
+ previously_muted =
+ snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 1);
spin_lock(&chip->reg_lock);
- /* stop playback */
+ /* first, remember current value: */
status1 = snd_azf3328_codec_inw(chip, IDX_IO_PLAY_FLAGS);
+ /* stop playback */
status1 &= ~DMA_RESUME;
snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS, status1);
@@ -1013,10 +1196,12 @@ snd_azf3328_playback_trigger(struct snd_pcm_substream *substream, int cmd)
status1 &= ~DMA_PLAY_SOMETHING1;
snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS, status1);
spin_unlock(&chip->reg_lock);
-
+ snd_azf3328_codec_activity(chip, AZF_PLAYBACK, 0);
+
/* now unmute WaveOut */
- snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 0);
- chip->is_playing = 0;
+ if (!previously_muted)
+ snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 0);
+
snd_azf3328_dbgplay("STOPPED PLAYBACK\n");
break;
case SNDRV_PCM_TRIGGER_SUSPEND:
@@ -1035,7 +1220,7 @@ snd_azf3328_playback_trigger(struct snd_pcm_substream *substream, int cmd)
printk(KERN_ERR "FIXME: unknown trigger mode!\n");
return -EINVAL;
}
-
+
snd_azf3328_dbgcallleave();
return result;
}
@@ -1057,17 +1242,19 @@ snd_azf3328_capture_trigger(struct snd_pcm_substream *substream, int cmd)
snd_azf3328_dbgplay("START CAPTURE\n");
- snd_azf3328_setfmt(chip, IDX_IO_REC_SOUNDFORMAT,
+ snd_azf3328_codec_setfmt(chip, IDX_IO_REC_SOUNDFORMAT,
runtime->rate,
snd_pcm_format_width(runtime->format),
runtime->channels);
spin_lock(&chip->reg_lock);
- /* stop recording */
+ /* first, remember current value: */
status1 = snd_azf3328_codec_inw(chip, IDX_IO_REC_FLAGS);
+
+ /* stop recording */
status1 &= ~DMA_RESUME;
snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS, status1);
-
+
/* FIXME: clear interrupts or what??? */
snd_azf3328_codec_outw(chip, IDX_IO_REC_IRQTYPE, 0xffff);
spin_unlock(&chip->reg_lock);
@@ -1075,7 +1262,7 @@ snd_azf3328_capture_trigger(struct snd_pcm_substream *substream, int cmd)
snd_azf3328_setdmaa(chip, runtime->dma_addr,
snd_pcm_lib_period_bytes(substream),
snd_pcm_lib_buffer_bytes(substream),
- 1);
+ AZF_CAPTURE);
spin_lock(&chip->reg_lock);
#ifdef WIN9X
@@ -1102,24 +1289,27 @@ snd_azf3328_capture_trigger(struct snd_pcm_substream *substream, int cmd)
DMA_SOMETHING_ELSE);
#endif
spin_unlock(&chip->reg_lock);
+ snd_azf3328_codec_activity(chip, AZF_CAPTURE, 1);
- chip->is_recording = 1;
snd_azf3328_dbgplay("STARTED CAPTURE\n");
break;
case SNDRV_PCM_TRIGGER_RESUME:
snd_azf3328_dbgplay("RESUME CAPTURE\n");
/* resume recording if we were active */
- if (chip->is_recording)
+ spin_lock(&chip->reg_lock);
+ if (chip->audio_stream[AZF_CAPTURE].running)
snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS,
snd_azf3328_codec_inw(chip, IDX_IO_REC_FLAGS) | DMA_RESUME);
+ spin_unlock(&chip->reg_lock);
break;
case SNDRV_PCM_TRIGGER_STOP:
snd_azf3328_dbgplay("STOP CAPTURE\n");
spin_lock(&chip->reg_lock);
- /* stop recording */
+ /* first, remember current value: */
status1 = snd_azf3328_codec_inw(chip, IDX_IO_REC_FLAGS);
+ /* stop recording */
status1 &= ~DMA_RESUME;
snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS, status1);
@@ -1129,8 +1319,8 @@ snd_azf3328_capture_trigger(struct snd_pcm_substream *substream, int cmd)
status1 &= ~DMA_PLAY_SOMETHING1;
snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS, status1);
spin_unlock(&chip->reg_lock);
-
- chip->is_recording = 0;
+ snd_azf3328_codec_activity(chip, AZF_CAPTURE, 0);
+
snd_azf3328_dbgplay("STOPPED CAPTURE\n");
break;
case SNDRV_PCM_TRIGGER_SUSPEND:
@@ -1149,7 +1339,7 @@ snd_azf3328_capture_trigger(struct snd_pcm_substream *substream, int cmd)
printk(KERN_ERR "FIXME: unknown trigger mode!\n");
return -EINVAL;
}
-
+
snd_azf3328_dbgcallleave();
return result;
}
@@ -1162,11 +1352,11 @@ snd_azf3328_playback_pointer(struct snd_pcm_substream *substream)
snd_pcm_uframes_t frmres;
#ifdef QUERY_HARDWARE
- bufptr = inl(chip->codec_port+IDX_IO_PLAY_DMA_START_1);
+ bufptr = snd_azf3328_codec_inl(chip, IDX_IO_PLAY_DMA_START_1);
#else
bufptr = substream->runtime->dma_addr;
#endif
- result = inl(chip->codec_port+IDX_IO_PLAY_DMA_CURRPOS);
+ result = snd_azf3328_codec_inl(chip, IDX_IO_PLAY_DMA_CURRPOS);
/* calculate offset */
result -= bufptr;
@@ -1183,11 +1373,11 @@ snd_azf3328_capture_pointer(struct snd_pcm_substream *substream)
snd_pcm_uframes_t frmres;
#ifdef QUERY_HARDWARE
- bufptr = inl(chip->codec_port+IDX_IO_REC_DMA_START_1);
+ bufptr = snd_azf3328_codec_inl(chip, IDX_IO_REC_DMA_START_1);
#else
bufptr = substream->runtime->dma_addr;
#endif
- result = inl(chip->codec_port+IDX_IO_REC_DMA_CURRPOS);
+ result = snd_azf3328_codec_inl(chip, IDX_IO_REC_DMA_CURRPOS);
/* calculate offset */
result -= bufptr;
@@ -1196,27 +1386,242 @@ snd_azf3328_capture_pointer(struct snd_pcm_substream *substream)
return frmres;
}
+/******************************************************************/
+
+#ifdef SUPPORT_GAMEPORT
+static inline void
+snd_azf3328_gameport_irq_enable(struct snd_azf3328 *chip, int enable)
+{
+ snd_azf3328_io_reg_setb(
+ chip->game_io+IDX_GAME_HWCONFIG,
+ GAME_HWCFG_IRQ_ENABLE,
+ enable
+ );
+}
+
+static inline void
+snd_azf3328_gameport_legacy_address_enable(struct snd_azf3328 *chip, int enable)
+{
+ snd_azf3328_io_reg_setb(
+ chip->game_io+IDX_GAME_HWCONFIG,
+ GAME_HWCFG_LEGACY_ADDRESS_ENABLE,
+ enable
+ );
+}
+
+static inline void
+snd_azf3328_gameport_axis_circuit_enable(struct snd_azf3328 *chip, int enable)
+{
+ snd_azf3328_codec_reg_6AH_update(
+ chip, IO_6A_SOMETHING2_GAMEPORT, enable
+ );
+}
+
+static inline void
+snd_azf3328_gameport_interrupt(struct snd_azf3328 *chip)
+{
+ /*
+ * skeleton handler only
+ * (we do not want axis reading in interrupt handler - too much load!)
+ */
+ snd_azf3328_dbggame("gameport irq\n");
+
+ /* this should ACK the gameport IRQ properly, hopefully. */
+ snd_azf3328_game_inw(chip, IDX_GAME_AXIS_VALUE);
+}
+
+static int
+snd_azf3328_gameport_open(struct gameport *gameport, int mode)
+{
+ struct snd_azf3328 *chip = gameport_get_port_data(gameport);
+ int res;
+
+ snd_azf3328_dbggame("gameport_open, mode %d\n", mode);
+ switch (mode) {
+ case GAMEPORT_MODE_COOKED:
+ case GAMEPORT_MODE_RAW:
+ res = 0;
+ break;
+ default:
+ res = -1;
+ break;
+ }
+
+ snd_azf3328_gameport_axis_circuit_enable(chip, (res == 0));
+
+ return res;
+}
+
+static void
+snd_azf3328_gameport_close(struct gameport *gameport)
+{
+ struct snd_azf3328 *chip = gameport_get_port_data(gameport);
+
+ snd_azf3328_dbggame("gameport_close\n");
+ snd_azf3328_gameport_axis_circuit_enable(chip, 0);
+}
+
+static int
+snd_azf3328_gameport_cooked_read(struct gameport *gameport,
+ int *axes,
+ int *buttons
+)
+{
+ struct snd_azf3328 *chip = gameport_get_port_data(gameport);
+ int i;
+ u8 val;
+ unsigned long flags;
+
+ if (snd_BUG_ON(!chip))
+ return 0;
+
+ spin_lock_irqsave(&chip->reg_lock, flags);
+ val = snd_azf3328_game_inb(chip, IDX_GAME_LEGACY_COMPATIBLE);
+ *buttons = (~(val) >> 4) & 0xf;
+
+ /* ok, this one is a bit dirty: cooked_read is being polled by a timer,
+ * thus we're atomic and cannot actively wait in here
+ * (which would be useful for us since it probably would be better
+ * to trigger a measurement in here, then wait a short amount of
+ * time until it's finished, then read values of _this_ measurement).
+ *
+ * Thus we simply resort to reading values if they're available already
+ * and trigger the next measurement.
+ */
+
+ val = snd_azf3328_game_inb(chip, IDX_GAME_AXES_CONFIG);
+ if (val & GAME_AXES_SAMPLING_READY) {
+ for (i = 0; i < 4; ++i) {
+ /* configure the axis to read */
+ val = (i << 4) | 0x0f;
+ snd_azf3328_game_outb(chip, IDX_GAME_AXES_CONFIG, val);
+
+ chip->axes[i] = snd_azf3328_game_inw(
+ chip, IDX_GAME_AXIS_VALUE
+ );
+ }
+ }
+
+ /* trigger next axes sampling, to be evaluated the next time we
+ * enter this function */
+
+ /* for some very, very strange reason we cannot enable
+ * Measurement Ready monitoring for all axes here,
+ * at least not when only one joystick connected */
+ val = 0x03; /* we're able to monitor axes 1 and 2 only */
+ snd_azf3328_game_outb(chip, IDX_GAME_AXES_CONFIG, val);
+
+ snd_azf3328_game_outw(chip, IDX_GAME_AXIS_VALUE, 0xffff);
+ spin_unlock_irqrestore(&chip->reg_lock, flags);
+
+ for (i = 0; i < 4; i++) {
+ axes[i] = chip->axes[i];
+ if (axes[i] == 0xffff)
+ axes[i] = -1;
+ }
+
+ snd_azf3328_dbggame("cooked_read: axes %d %d %d %d buttons %d\n",
+ axes[0], axes[1], axes[2], axes[3], *buttons
+ );
+
+ return 0;
+}
+
+static int __devinit
+snd_azf3328_gameport(struct snd_azf3328 *chip, int dev)
+{
+ struct gameport *gp;
+
+ chip->gameport = gp = gameport_allocate_port();
+ if (!gp) {
+ printk(KERN_ERR "azt3328: cannot alloc memory for gameport\n");
+ return -ENOMEM;
+ }
+
+ gameport_set_name(gp, "AZF3328 Gameport");
+ gameport_set_phys(gp, "pci%s/gameport0", pci_name(chip->pci));
+ gameport_set_dev_parent(gp, &chip->pci->dev);
+ gp->io = chip->game_io;
+ gameport_set_port_data(gp, chip);
+
+ gp->open = snd_azf3328_gameport_open;
+ gp->close = snd_azf3328_gameport_close;
+ gp->fuzz = 16; /* seems ok */
+ gp->cooked_read = snd_azf3328_gameport_cooked_read;
+
+ /* DISABLE legacy address: we don't need it! */
+ snd_azf3328_gameport_legacy_address_enable(chip, 0);
+
+ snd_azf3328_gameport_axis_circuit_enable(chip, 0);
+
+ gameport_register_port(chip->gameport);
+
+ return 0;
+}
+
+static void
+snd_azf3328_gameport_free(struct snd_azf3328 *chip)
+{
+ if (chip->gameport) {
+ gameport_unregister_port(chip->gameport);
+ chip->gameport = NULL;
+ }
+ snd_azf3328_gameport_irq_enable(chip, 0);
+}
+#else
+static inline int
+snd_azf3328_gameport(struct snd_azf3328 *chip, int dev) { return -ENOSYS; }
+static inline void
+snd_azf3328_gameport_free(struct snd_azf3328 *chip) { }
+static inline void
+snd_azf3328_gameport_interrupt(struct snd_azf3328 *chip)
+{
+ printk(KERN_WARNING "huh, game port IRQ occurred!?\n");
+}
+#endif /* SUPPORT_GAMEPORT */
+
+/******************************************************************/
+
+static inline void
+snd_azf3328_irq_log_unknown_type(u8 which)
+{
+ snd_azf3328_dbgplay(
+ "azt3328: unknown IRQ type (%x) occurred, please report!\n",
+ which
+ );
+}
+
static irqreturn_t
snd_azf3328_interrupt(int irq, void *dev_id)
{
struct snd_azf3328 *chip = dev_id;
u8 status, which;
+#if DEBUG_PLAY_REC
static unsigned long irq_count;
+#endif
status = snd_azf3328_codec_inb(chip, IDX_IO_IRQSTATUS);
/* fast path out, to ease interrupt sharing */
- if (!(status & (IRQ_PLAYBACK|IRQ_RECORDING|IRQ_MPU401|IRQ_TIMER)))
+ if (!(status &
+ (IRQ_PLAYBACK|IRQ_RECORDING|IRQ_GAMEPORT|IRQ_MPU401|IRQ_TIMER)
+ ))
return IRQ_NONE; /* must be interrupt for another device */
- snd_azf3328_dbgplay("Interrupt %ld!\nIDX_IO_PLAY_FLAGS %04x, IDX_IO_PLAY_IRQTYPE %04x, IDX_IO_IRQSTATUS %04x\n",
- irq_count,
- snd_azf3328_codec_inw(chip, IDX_IO_PLAY_FLAGS),
- snd_azf3328_codec_inw(chip, IDX_IO_PLAY_IRQTYPE),
- status);
-
+ snd_azf3328_dbgplay(
+ "irq_count %ld! IDX_IO_PLAY_FLAGS %04x, "
+ "IDX_IO_PLAY_IRQTYPE %04x, IDX_IO_IRQSTATUS %04x\n",
+ irq_count++ /* debug-only */,
+ snd_azf3328_codec_inw(chip, IDX_IO_PLAY_FLAGS),
+ snd_azf3328_codec_inw(chip, IDX_IO_PLAY_IRQTYPE),
+ status
+ );
+
if (status & IRQ_TIMER) {
- /* snd_azf3328_dbgplay("timer %ld\n", inl(chip->codec_port+IDX_IO_TIMER_VALUE) & TIMER_VALUE_MASK); */
+ /* snd_azf3328_dbgplay("timer %ld\n",
+ snd_azf3328_codec_inl(chip, IDX_IO_TIMER_VALUE)
+ & TIMER_VALUE_MASK
+ ); */
if (chip->timer)
snd_timer_interrupt(chip->timer, chip->timer->sticks);
/* ACK timer */
@@ -1232,15 +1637,20 @@ snd_azf3328_interrupt(int irq, void *dev_id)
snd_azf3328_codec_outb(chip, IDX_IO_PLAY_IRQTYPE, which);
spin_unlock(&chip->reg_lock);
- if (chip->pcm && chip->playback_substream) {
- snd_pcm_period_elapsed(chip->playback_substream);
+ if (chip->pcm && chip->audio_stream[AZF_PLAYBACK].substream) {
+ snd_pcm_period_elapsed(
+ chip->audio_stream[AZF_PLAYBACK].substream
+ );
snd_azf3328_dbgplay("PLAY period done (#%x), @ %x\n",
which,
- inl(chip->codec_port+IDX_IO_PLAY_DMA_CURRPOS));
+ snd_azf3328_codec_inl(
+ chip, IDX_IO_PLAY_DMA_CURRPOS
+ )
+ );
} else
- snd_azf3328_dbgplay("azt3328: ouch, irq handler problem!\n");
+ printk(KERN_WARNING "azt3328: irq handler problem!\n");
if (which & IRQ_PLAY_SOMETHING)
- snd_azf3328_dbgplay("azt3328: unknown play IRQ type occurred, please report!\n");
+ snd_azf3328_irq_log_unknown_type(which);
}
if (status & IRQ_RECORDING) {
spin_lock(&chip->reg_lock);
@@ -1249,16 +1659,23 @@ snd_azf3328_interrupt(int irq, void *dev_id)
snd_azf3328_codec_outb(chip, IDX_IO_REC_IRQTYPE, which);
spin_unlock(&chip->reg_lock);
- if (chip->pcm && chip->capture_substream) {
- snd_pcm_period_elapsed(chip->capture_substream);
+ if (chip->pcm && chip->audio_stream[AZF_CAPTURE].substream) {
+ snd_pcm_period_elapsed(
+ chip->audio_stream[AZF_CAPTURE].substream
+ );
snd_azf3328_dbgplay("REC period done (#%x), @ %x\n",
which,
- inl(chip->codec_port+IDX_IO_REC_DMA_CURRPOS));
+ snd_azf3328_codec_inl(
+ chip, IDX_IO_REC_DMA_CURRPOS
+ )
+ );
} else
- snd_azf3328_dbgplay("azt3328: ouch, irq handler problem!\n");
+ printk(KERN_WARNING "azt3328: irq handler problem!\n");
if (which & IRQ_REC_SOMETHING)
- snd_azf3328_dbgplay("azt3328: unknown rec IRQ type occurred, please report!\n");
+ snd_azf3328_irq_log_unknown_type(which);
}
+ if (status & IRQ_GAMEPORT)
+ snd_azf3328_gameport_interrupt(chip);
/* MPU401 has less critical IRQ requirements
* than timer and playback/recording, right? */
if (status & IRQ_MPU401) {
@@ -1268,7 +1685,6 @@ snd_azf3328_interrupt(int irq, void *dev_id)
* If so, then I don't know how... */
snd_azf3328_dbgplay("azt3328: MPU401 IRQ\n");
}
- irq_count++;
return IRQ_HANDLED;
}
@@ -1287,8 +1703,8 @@ static const struct snd_pcm_hardware snd_azf3328_playback =
.rates = SNDRV_PCM_RATE_5512 |
SNDRV_PCM_RATE_8000_48000 |
SNDRV_PCM_RATE_KNOT,
- .rate_min = 4000,
- .rate_max = 66200,
+ .rate_min = AZF_FREQ_4000,
+ .rate_max = AZF_FREQ_66200,
.channels_min = 1,
.channels_max = 2,
.buffer_bytes_max = 65536,
@@ -1315,8 +1731,8 @@ static const struct snd_pcm_hardware snd_azf3328_capture =
.rates = SNDRV_PCM_RATE_5512 |
SNDRV_PCM_RATE_8000_48000 |
SNDRV_PCM_RATE_KNOT,
- .rate_min = 4000,
- .rate_max = 66200,
+ .rate_min = AZF_FREQ_4000,
+ .rate_max = AZF_FREQ_66200,
.channels_min = 1,
.channels_max = 2,
.buffer_bytes_max = 65536,
@@ -1329,10 +1745,24 @@ static const struct snd_pcm_hardware snd_azf3328_capture =
static unsigned int snd_azf3328_fixed_rates[] = {
- 4000, 4800, 5512, 6620, 8000, 9600, 11025, 13240, 16000, 22050, 32000,
- 44100, 48000, 66200 };
+ AZF_FREQ_4000,
+ AZF_FREQ_4800,
+ AZF_FREQ_5512,
+ AZF_FREQ_6620,
+ AZF_FREQ_8000,
+ AZF_FREQ_9600,
+ AZF_FREQ_11025,
+ AZF_FREQ_13240,
+ AZF_FREQ_16000,
+ AZF_FREQ_22050,
+ AZF_FREQ_32000,
+ AZF_FREQ_44100,
+ AZF_FREQ_48000,
+ AZF_FREQ_66200
+};
+
static struct snd_pcm_hw_constraint_list snd_azf3328_hw_constraints_rates = {
- .count = ARRAY_SIZE(snd_azf3328_fixed_rates),
+ .count = ARRAY_SIZE(snd_azf3328_fixed_rates),
.list = snd_azf3328_fixed_rates,
.mask = 0,
};
@@ -1346,7 +1776,7 @@ snd_azf3328_playback_open(struct snd_pcm_substream *substream)
struct snd_pcm_runtime *runtime = substream->runtime;
snd_azf3328_dbgcallenter();
- chip->playback_substream = substream;
+ chip->audio_stream[AZF_PLAYBACK].substream = substream;
runtime->hw = snd_azf3328_playback;
snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
&snd_azf3328_hw_constraints_rates);
@@ -1361,7 +1791,7 @@ snd_azf3328_capture_open(struct snd_pcm_substream *substream)
struct snd_pcm_runtime *runtime = substream->runtime;
snd_azf3328_dbgcallenter();
- chip->capture_substream = substream;
+ chip->audio_stream[AZF_CAPTURE].substream = substream;
runtime->hw = snd_azf3328_capture;
snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
&snd_azf3328_hw_constraints_rates);
@@ -1375,7 +1805,7 @@ snd_azf3328_playback_close(struct snd_pcm_substream *substream)
struct snd_azf3328 *chip = snd_pcm_substream_chip(substream);
snd_azf3328_dbgcallenter();
- chip->playback_substream = NULL;
+ chip->audio_stream[AZF_PLAYBACK].substream = NULL;
snd_azf3328_dbgcallleave();
return 0;
}
@@ -1386,7 +1816,7 @@ snd_azf3328_capture_close(struct snd_pcm_substream *substream)
struct snd_azf3328 *chip = snd_pcm_substream_chip(substream);
snd_azf3328_dbgcallenter();
- chip->capture_substream = NULL;
+ chip->audio_stream[AZF_CAPTURE].substream = NULL;
snd_azf3328_dbgcallleave();
return 0;
}
@@ -1441,102 +1871,8 @@ snd_azf3328_pcm(struct snd_azf3328 *chip, int device)
/******************************************************************/
-#ifdef SUPPORT_JOYSTICK
-static int __devinit
-snd_azf3328_config_joystick(struct snd_azf3328 *chip, int dev)
-{
- struct gameport *gp;
- struct resource *r;
-
- if (!joystick[dev])
- return -ENODEV;
-
- if (!(r = request_region(0x200, 8, "AZF3328 gameport"))) {
- printk(KERN_WARNING "azt3328: cannot reserve joystick ports\n");
- return -EBUSY;
- }
-
- chip->gameport = gp = gameport_allocate_port();
- if (!gp) {
- printk(KERN_ERR "azt3328: cannot allocate memory for gameport\n");
- release_and_free_resource(r);
- return -ENOMEM;
- }
-
- gameport_set_name(gp, "AZF3328 Gameport");
- gameport_set_phys(gp, "pci%s/gameport0", pci_name(chip->pci));
- gameport_set_dev_parent(gp, &chip->pci->dev);
- gp->io = 0x200;
- gameport_set_port_data(gp, r);
-
- snd_azf3328_io2_outb(chip, IDX_IO2_LEGACY_ADDR,
- snd_azf3328_io2_inb(chip, IDX_IO2_LEGACY_ADDR) | LEGACY_JOY);
-
- gameport_register_port(chip->gameport);
-
- return 0;
-}
-
-static void
-snd_azf3328_free_joystick(struct snd_azf3328 *chip)
-{
- if (chip->gameport) {
- struct resource *r = gameport_get_port_data(chip->gameport);
-
- gameport_unregister_port(chip->gameport);
- chip->gameport = NULL;
- /* disable gameport */
- snd_azf3328_io2_outb(chip, IDX_IO2_LEGACY_ADDR,
- snd_azf3328_io2_inb(chip, IDX_IO2_LEGACY_ADDR) & ~LEGACY_JOY);
- release_and_free_resource(r);
- }
-}
-#else
-static inline int
-snd_azf3328_config_joystick(struct snd_azf3328 *chip, int dev) { return -ENOSYS; }
-static inline void
-snd_azf3328_free_joystick(struct snd_azf3328 *chip) { }
-#endif
-
-/******************************************************************/
-
-static int
-snd_azf3328_free(struct snd_azf3328 *chip)
-{
- if (chip->irq < 0)
- goto __end_hw;
-
- /* reset (close) mixer */
- snd_azf3328_mixer_set_mute(chip, IDX_MIXER_PLAY_MASTER, 1); /* first mute master volume */
- snd_azf3328_mixer_outw(chip, IDX_MIXER_RESET, 0x0000);
-
- /* interrupt setup - mask everything (FIXME!) */
- /* well, at least we know how to disable the timer IRQ */
- snd_azf3328_codec_outb(chip, IDX_IO_TIMER_VALUE + 3, 0x00);
-
- if (chip->irq >= 0)
- synchronize_irq(chip->irq);
-__end_hw:
- snd_azf3328_free_joystick(chip);
- if (chip->irq >= 0)
- free_irq(chip->irq, chip);
- pci_release_regions(chip->pci);
- pci_disable_device(chip->pci);
-
- kfree(chip);
- return 0;
-}
-
-static int
-snd_azf3328_dev_free(struct snd_device *device)
-{
- struct snd_azf3328 *chip = device->device_data;
- return snd_azf3328_free(chip);
-}
-
-/******************************************************************/
-
-/*** NOTE: the physical timer resolution actually is 1024000 ticks per second,
+/*** NOTE: the physical timer resolution actually is 1024000 ticks per second
+ *** (probably derived from main crystal via a divider of 24),
*** but announcing those attributes to user-space would make programs
*** configure the timer to a 1 tick value, resulting in an absolutely fatal
*** timer IRQ storm.
@@ -1564,7 +1900,7 @@ snd_azf3328_timer_start(struct snd_timer *timer)
delay = 49; /* minimum time is 49 ticks */
}
snd_azf3328_dbgtimer("setting timer countdown value %d, add COUNTDOWN|IRQ\n", delay);
- delay |= TIMER_ENABLE_COUNTDOWN | TIMER_ENABLE_IRQ;
+ delay |= TIMER_COUNTDOWN_ENABLE | TIMER_IRQ_ENABLE;
spin_lock_irqsave(&chip->reg_lock, flags);
snd_azf3328_codec_outl(chip, IDX_IO_TIMER_VALUE, delay);
spin_unlock_irqrestore(&chip->reg_lock, flags);
@@ -1582,7 +1918,7 @@ snd_azf3328_timer_stop(struct snd_timer *timer)
chip = snd_timer_chip(timer);
spin_lock_irqsave(&chip->reg_lock, flags);
/* disable timer countdown and interrupt */
- /* FIXME: should we write TIMER_ACK_IRQ here? */
+ /* FIXME: should we write TIMER_IRQ_ACK here? */
snd_azf3328_codec_outb(chip, IDX_IO_TIMER_VALUE + 3, 0);
spin_unlock_irqrestore(&chip->reg_lock, flags);
snd_azf3328_dbgcallleave();
@@ -1626,9 +1962,10 @@ snd_azf3328_timer(struct snd_azf3328 *chip, int device)
snd_azf3328_timer_hw.resolution *= seqtimer_scaling;
snd_azf3328_timer_hw.ticks /= seqtimer_scaling;
- if ((err = snd_timer_new(chip->card, "AZF3328", &tid, &timer)) < 0) {
+
+ err = snd_timer_new(chip->card, "AZF3328", &tid, &timer);
+ if (err < 0)
goto out;
- }
strcpy(timer->name, "AZF3328 timer");
timer->private_data = chip;
@@ -1636,6 +1973,8 @@ snd_azf3328_timer(struct snd_azf3328 *chip, int device)
chip->timer = timer;
+ snd_azf3328_timer_stop(timer);
+
err = 0;
out:
@@ -1645,10 +1984,44 @@ out:
/******************************************************************/
+static int
+snd_azf3328_free(struct snd_azf3328 *chip)
+{
+ if (chip->irq < 0)
+ goto __end_hw;
+
+ /* reset (close) mixer:
+ * first mute master volume, then reset
+ */
+ snd_azf3328_mixer_set_mute(chip, IDX_MIXER_PLAY_MASTER, 1);
+ snd_azf3328_mixer_outw(chip, IDX_MIXER_RESET, 0x0000);
+
+ snd_azf3328_timer_stop(chip->timer);
+ snd_azf3328_gameport_free(chip);
+
+ if (chip->irq >= 0)
+ synchronize_irq(chip->irq);
+__end_hw:
+ if (chip->irq >= 0)
+ free_irq(chip->irq, chip);
+ pci_release_regions(chip->pci);
+ pci_disable_device(chip->pci);
+
+ kfree(chip);
+ return 0;
+}
+
+static int
+snd_azf3328_dev_free(struct snd_device *device)
+{
+ struct snd_azf3328 *chip = device->device_data;
+ return snd_azf3328_free(chip);
+}
+
#if 0
/* check whether a bit can be modified */
static void
-snd_azf3328_test_bit(unsigned int reg, int bit)
+snd_azf3328_test_bit(unsigned unsigned reg, int bit)
{
unsigned char val, valoff, valon;
@@ -1659,42 +2032,74 @@ snd_azf3328_test_bit(unsigned int reg, int bit)
outb(val|(1 << bit), reg);
valon = inb(reg);
-
+
outb(val, reg);
- printk(KERN_ERR "reg %04x bit %d: %02x %02x %02x\n", reg, bit, val, valoff, valon);
+ printk(KERN_ERR "reg %04x bit %d: %02x %02x %02x\n",
+ reg, bit, val, valoff, valon
+ );
}
#endif
-#if DEBUG_MISC
-static void
+static inline void
snd_azf3328_debug_show_ports(const struct snd_azf3328 *chip)
{
+#if DEBUG_MISC
u16 tmp;
- snd_azf3328_dbgmisc("codec_port 0x%lx, io2_port 0x%lx, mpu_port 0x%lx, synth_port 0x%lx, mixer_port 0x%lx, irq %d\n", chip->codec_port, chip->io2_port, chip->mpu_port, chip->synth_port, chip->mixer_port, chip->irq);
-
- snd_azf3328_dbgmisc("io2 %02x %02x %02x %02x %02x %02x\n", snd_azf3328_io2_inb(chip, 0), snd_azf3328_io2_inb(chip, 1), snd_azf3328_io2_inb(chip, 2), snd_azf3328_io2_inb(chip, 3), snd_azf3328_io2_inb(chip, 4), snd_azf3328_io2_inb(chip, 5));
-
- for (tmp=0; tmp <= 0x01; tmp += 1)
- snd_azf3328_dbgmisc("0x%02x: opl 0x%04x, mpu300 0x%04x, mpu310 0x%04x, mpu320 0x%04x, mpu330 0x%04x\n", tmp, inb(0x388 + tmp), inb(0x300 + tmp), inb(0x310 + tmp), inb(0x320 + tmp), inb(0x330 + tmp));
+ snd_azf3328_dbgmisc(
+ "codec_io 0x%lx, game_io 0x%lx, mpu_io 0x%lx, "
+ "opl3_io 0x%lx, mixer_io 0x%lx, irq %d\n",
+ chip->codec_io, chip->game_io, chip->mpu_io,
+ chip->opl3_io, chip->mixer_io, chip->irq
+ );
+
+ snd_azf3328_dbgmisc("game %02x %02x %02x %02x %02x %02x\n",
+ snd_azf3328_game_inb(chip, 0),
+ snd_azf3328_game_inb(chip, 1),
+ snd_azf3328_game_inb(chip, 2),
+ snd_azf3328_game_inb(chip, 3),
+ snd_azf3328_game_inb(chip, 4),
+ snd_azf3328_game_inb(chip, 5)
+ );
+
+ for (tmp = 0; tmp < 0x07; tmp += 1)
+ snd_azf3328_dbgmisc("mpu_io 0x%04x\n", inb(chip->mpu_io + tmp));
+
+ for (tmp = 0; tmp <= 0x07; tmp += 1)
+ snd_azf3328_dbgmisc("0x%02x: game200 0x%04x, game208 0x%04x\n",
+ tmp, inb(0x200 + tmp), inb(0x208 + tmp));
+
+ for (tmp = 0; tmp <= 0x01; tmp += 1)
+ snd_azf3328_dbgmisc(
+ "0x%02x: mpu300 0x%04x, mpu310 0x%04x, mpu320 0x%04x, "
+ "mpu330 0x%04x opl388 0x%04x opl38c 0x%04x\n",
+ tmp,
+ inb(0x300 + tmp),
+ inb(0x310 + tmp),
+ inb(0x320 + tmp),
+ inb(0x330 + tmp),
+ inb(0x388 + tmp),
+ inb(0x38c + tmp)
+ );
for (tmp = 0; tmp < AZF_IO_SIZE_CODEC; tmp += 2)
- snd_azf3328_dbgmisc("codec 0x%02x: 0x%04x\n", tmp, snd_azf3328_codec_inw(chip, tmp));
+ snd_azf3328_dbgmisc("codec 0x%02x: 0x%04x\n",
+ tmp, snd_azf3328_codec_inw(chip, tmp)
+ );
for (tmp = 0; tmp < AZF_IO_SIZE_MIXER; tmp += 2)
- snd_azf3328_dbgmisc("mixer 0x%02x: 0x%04x\n", tmp, snd_azf3328_mixer_inw(chip, tmp));
+ snd_azf3328_dbgmisc("mixer 0x%02x: 0x%04x\n",
+ tmp, snd_azf3328_mixer_inw(chip, tmp)
+ );
+#endif /* DEBUG_MISC */
}
-#else
-static inline void
-snd_azf3328_debug_show_ports(const struct snd_azf3328 *chip) {}
-#endif
static int __devinit
snd_azf3328_create(struct snd_card *card,
- struct pci_dev *pci,
- unsigned long device_type,
- struct snd_azf3328 ** rchip)
+ struct pci_dev *pci,
+ unsigned long device_type,
+ struct snd_azf3328 **rchip)
{
struct snd_azf3328 *chip;
int err;
@@ -1705,7 +2110,8 @@ snd_azf3328_create(struct snd_card *card,
*rchip = NULL;
- if ((err = pci_enable_device(pci)) < 0)
+ err = pci_enable_device(pci);
+ if (err < 0)
return err;
chip = kzalloc(sizeof(*chip), GFP_KERNEL);
@@ -1721,20 +2127,25 @@ snd_azf3328_create(struct snd_card *card,
/* check if we can restrict PCI DMA transfers to 24 bits */
if (pci_set_dma_mask(pci, DMA_24BIT_MASK) < 0 ||
pci_set_consistent_dma_mask(pci, DMA_24BIT_MASK) < 0) {
- snd_printk(KERN_ERR "architecture does not support 24bit PCI busmaster DMA\n");
+ snd_printk(KERN_ERR "architecture does not support "
+ "24bit PCI busmaster DMA\n"
+ );
err = -ENXIO;
goto out_err;
}
- if ((err = pci_request_regions(pci, "Aztech AZF3328")) < 0) {
+ err = pci_request_regions(pci, "Aztech AZF3328");
+ if (err < 0)
goto out_err;
- }
- chip->codec_port = pci_resource_start(pci, 0);
- chip->io2_port = pci_resource_start(pci, 1);
- chip->mpu_port = pci_resource_start(pci, 2);
- chip->synth_port = pci_resource_start(pci, 3);
- chip->mixer_port = pci_resource_start(pci, 4);
+ chip->codec_io = pci_resource_start(pci, 0);
+ chip->game_io = pci_resource_start(pci, 1);
+ chip->mpu_io = pci_resource_start(pci, 2);
+ chip->opl3_io = pci_resource_start(pci, 3);
+ chip->mixer_io = pci_resource_start(pci, 4);
+
+ chip->audio_stream[AZF_PLAYBACK].portbase = chip->codec_io + 0x00;
+ chip->audio_stream[AZF_CAPTURE].portbase = chip->codec_io + 0x20;
if (request_irq(pci->irq, snd_azf3328_interrupt,
IRQF_SHARED, card->shortname, chip)) {
@@ -1747,29 +2158,29 @@ snd_azf3328_create(struct snd_card *card,
synchronize_irq(chip->irq);
snd_azf3328_debug_show_ports(chip);
-
- 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)
goto out_err;
- }
/* create mixer interface & switches */
- if ((err = snd_azf3328_mixer_new(chip)) < 0)
+ err = snd_azf3328_mixer_new(chip);
+ if (err < 0)
goto out_err;
-#if 0
- /* set very low bitrate to reduce noise and power consumption? */
- snd_azf3328_setfmt(chip, IDX_IO_PLAY_SOUNDFORMAT, 5512, 8, 1);
-#endif
+ /* shutdown codecs to save power */
+ /* have snd_azf3328_codec_activity() act properly */
+ chip->audio_stream[AZF_PLAYBACK].running = 1;
+ snd_azf3328_codec_activity(chip, AZF_PLAYBACK, 0);
/* standard chip init stuff */
- /* default IRQ init value */
+ /* default IRQ init value */
tmp = DMA_PLAY_SOMETHING2|DMA_EPILOGUE_SOMETHING|DMA_SOMETHING_ELSE;
spin_lock_irq(&chip->reg_lock);
snd_azf3328_codec_outb(chip, IDX_IO_PLAY_FLAGS, tmp);
snd_azf3328_codec_outb(chip, IDX_IO_REC_FLAGS, tmp);
snd_azf3328_codec_outb(chip, IDX_IO_SOMETHING_FLAGS, tmp);
- snd_azf3328_codec_outb(chip, IDX_IO_TIMER_VALUE + 3, 0x00); /* disable timer */
spin_unlock_irq(&chip->reg_lock);
snd_card_set_dev(card, &pci->dev);
@@ -1805,52 +2216,61 @@ snd_azf3328_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
return -ENOENT;
}
- card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0 );
+ card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
if (card == NULL)
return -ENOMEM;
strcpy(card->driver, "AZF3328");
strcpy(card->shortname, "Aztech AZF3328 (PCI168)");
- if ((err = snd_azf3328_create(card, pci, pci_id->driver_data, &chip)) < 0) {
+ err = snd_azf3328_create(card, pci, pci_id->driver_data, &chip);
+ if (err < 0)
goto out_err;
- }
card->private_data = chip;
- if ((err = snd_mpu401_uart_new( card, 0, MPU401_HW_MPU401,
- chip->mpu_port, MPU401_INFO_INTEGRATED,
- pci->irq, 0, &chip->rmidi)) < 0) {
- snd_printk(KERN_ERR "azf3328: no MPU-401 device at 0x%lx?\n", chip->mpu_port);
+ err = snd_mpu401_uart_new(
+ card, 0, MPU401_HW_MPU401, chip->mpu_io, MPU401_INFO_INTEGRATED,
+ pci->irq, 0, &chip->rmidi
+ );
+ if (err < 0) {
+ snd_printk(KERN_ERR "azf3328: no MPU-401 device at 0x%lx?\n",
+ chip->mpu_io
+ );
goto out_err;
}
- if ((err = snd_azf3328_timer(chip, 0)) < 0) {
+ err = snd_azf3328_timer(chip, 0);
+ if (err < 0)
goto out_err;
- }
- if ((err = snd_azf3328_pcm(chip, 0)) < 0) {
+ err = snd_azf3328_pcm(chip, 0);
+ if (err < 0)
goto out_err;
- }
- if (snd_opl3_create(card, chip->synth_port, chip->synth_port+2,
+ if (snd_opl3_create(card, chip->opl3_io, chip->opl3_io+2,
OPL3_HW_AUTO, 1, &opl3) < 0) {
snd_printk(KERN_ERR "azf3328: no OPL3 device at 0x%lx-0x%lx?\n",
- chip->synth_port, chip->synth_port+2 );
+ chip->opl3_io, chip->opl3_io+2
+ );
} else {
- if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) {
+ /* need to use IDs 1, 2 since ID 0 is snd_azf3328_timer above */
+ err = snd_opl3_timer_new(opl3, 1, 2);
+ if (err < 0)
+ goto out_err;
+ err = snd_opl3_hwdep_new(opl3, 0, 1, NULL);
+ if (err < 0)
goto out_err;
- }
}
opl3->private_data = chip;
sprintf(card->longname, "%s at 0x%lx, irq %i",
- card->shortname, chip->codec_port, chip->irq);
+ card->shortname, chip->codec_io, chip->irq);
- if ((err = snd_card_register(card)) < 0) {
+ err = snd_card_register(card);
+ if (err < 0)
goto out_err;
- }
#ifdef MODULE
printk(
@@ -1861,19 +2281,18 @@ snd_azf3328_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
1024000 / seqtimer_scaling, seqtimer_scaling);
#endif
- if (snd_azf3328_config_joystick(chip, dev) < 0)
- snd_azf3328_io2_outb(chip, IDX_IO2_LEGACY_ADDR,
- snd_azf3328_io2_inb(chip, IDX_IO2_LEGACY_ADDR) & ~LEGACY_JOY);
+ snd_azf3328_gameport(chip, dev);
pci_set_drvdata(pci, card);
dev++;
err = 0;
goto out;
-
+
out_err:
+ snd_printk(KERN_ERR "azf3328: something failed, exiting\n");
snd_card_free(card);
-
+
out:
snd_azf3328_dbgcallleave();
return err;
@@ -1894,27 +2313,31 @@ snd_azf3328_suspend(struct pci_dev *pci, pm_message_t state)
{
struct snd_card *card = pci_get_drvdata(pci);
struct snd_azf3328 *chip = card->private_data;
- int reg;
+ unsigned reg;
snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
-
+
snd_pcm_suspend_all(chip->pcm);
- for (reg = 0; reg < AZF_IO_SIZE_MIXER_PM / 2; reg++)
- chip->saved_regs_mixer[reg] = inw(chip->mixer_port + reg * 2);
+ for (reg = 0; reg < AZF_IO_SIZE_MIXER_PM / 2; ++reg)
+ chip->saved_regs_mixer[reg] = inw(chip->mixer_io + reg * 2);
/* make sure to disable master volume etc. to prevent looping sound */
snd_azf3328_mixer_set_mute(chip, IDX_MIXER_PLAY_MASTER, 1);
snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 1);
-
- for (reg = 0; reg < AZF_IO_SIZE_CODEC_PM / 2; reg++)
- chip->saved_regs_codec[reg] = inw(chip->codec_port + reg * 2);
- for (reg = 0; reg < AZF_IO_SIZE_IO2_PM / 2; reg++)
- chip->saved_regs_io2[reg] = inw(chip->io2_port + reg * 2);
- for (reg = 0; reg < AZF_IO_SIZE_MPU_PM / 2; reg++)
- chip->saved_regs_mpu[reg] = inw(chip->mpu_port + reg * 2);
- for (reg = 0; reg < AZF_IO_SIZE_SYNTH_PM / 2; reg++)
- chip->saved_regs_synth[reg] = inw(chip->synth_port + reg * 2);
+
+ for (reg = 0; reg < AZF_IO_SIZE_CODEC_PM / 2; ++reg)
+ chip->saved_regs_codec[reg] = inw(chip->codec_io + reg * 2);
+
+ /* manually store the one currently relevant write-only reg, too */
+ chip->saved_regs_codec[IDX_IO_6AH / 2] = chip->shadow_reg_codec_6AH;
+
+ for (reg = 0; reg < AZF_IO_SIZE_GAME_PM / 2; ++reg)
+ chip->saved_regs_game[reg] = inw(chip->game_io + reg * 2);
+ for (reg = 0; reg < AZF_IO_SIZE_MPU_PM / 2; ++reg)
+ chip->saved_regs_mpu[reg] = inw(chip->mpu_io + reg * 2);
+ for (reg = 0; reg < AZF_IO_SIZE_OPL3_PM / 2; ++reg)
+ chip->saved_regs_opl3[reg] = inw(chip->opl3_io + reg * 2);
pci_disable_device(pci);
pci_save_state(pci);
@@ -1927,7 +2350,7 @@ snd_azf3328_resume(struct pci_dev *pci)
{
struct snd_card *card = pci_get_drvdata(pci);
struct snd_azf3328 *chip = card->private_data;
- int reg;
+ unsigned reg;
pci_set_power_state(pci, PCI_D0);
pci_restore_state(pci);
@@ -1939,23 +2362,21 @@ snd_azf3328_resume(struct pci_dev *pci)
}
pci_set_master(pci);
- for (reg = 0; reg < AZF_IO_SIZE_IO2_PM / 2; reg++)
- outw(chip->saved_regs_io2[reg], chip->io2_port + reg * 2);
- for (reg = 0; reg < AZF_IO_SIZE_MPU_PM / 2; reg++)
- outw(chip->saved_regs_mpu[reg], chip->mpu_port + reg * 2);
- for (reg = 0; reg < AZF_IO_SIZE_SYNTH_PM / 2; reg++)
- outw(chip->saved_regs_synth[reg], chip->synth_port + reg * 2);
- for (reg = 0; reg < AZF_IO_SIZE_MIXER_PM / 2; reg++)
- outw(chip->saved_regs_mixer[reg], chip->mixer_port + reg * 2);
- for (reg = 0; reg < AZF_IO_SIZE_CODEC_PM / 2; reg++)
- outw(chip->saved_regs_codec[reg], chip->codec_port + reg * 2);
+ for (reg = 0; reg < AZF_IO_SIZE_GAME_PM / 2; ++reg)
+ outw(chip->saved_regs_game[reg], chip->game_io + reg * 2);
+ for (reg = 0; reg < AZF_IO_SIZE_MPU_PM / 2; ++reg)
+ outw(chip->saved_regs_mpu[reg], chip->mpu_io + reg * 2);
+ for (reg = 0; reg < AZF_IO_SIZE_OPL3_PM / 2; ++reg)
+ outw(chip->saved_regs_opl3[reg], chip->opl3_io + reg * 2);
+ for (reg = 0; reg < AZF_IO_SIZE_MIXER_PM / 2; ++reg)
+ outw(chip->saved_regs_mixer[reg], chip->mixer_io + reg * 2);
+ for (reg = 0; reg < AZF_IO_SIZE_CODEC_PM / 2; ++reg)
+ outw(chip->saved_regs_codec[reg], chip->codec_io + reg * 2);
snd_power_change_state(card, SNDRV_CTL_POWER_D0);
return 0;
}
-#endif
-
-
+#endif /* CONFIG_PM */
static struct pci_driver driver = {
diff --git a/sound/pci/azt3328.h b/sound/pci/azt3328.h
index 679fa992e2bc..974e05122f00 100644
--- a/sound/pci/azt3328.h
+++ b/sound/pci/azt3328.h
@@ -1,7 +1,8 @@
#ifndef __SOUND_AZT3328_H
#define __SOUND_AZT3328_H
-/* "PU" == "power-up value", as tested on PCI168 PCI rev. 10 */
+/* "PU" == "power-up value", as tested on PCI168 PCI rev. 10
+ * "WRITE_ONLY" == register does not indicate actual bit values */
/*** main I/O area port indices ***/
/* (only 0x70 of 0x80 bytes saved/restored by Windows driver) */
@@ -54,7 +55,10 @@
#define SOUNDFORMAT_XTAL1 0x00
#define SOUNDFORMAT_XTAL2 0x01
/* all _SUSPECTED_ values are not used by Windows drivers, so we don't
- * have any hard facts, only rough measurements */
+ * have any hard facts, only rough measurements.
+ * All we know is that the crystal used on the board has 24.576MHz,
+ * like many soundcards (which results in the frequencies below when
+ * using certain divider values selected by the values below) */
#define SOUNDFORMAT_FREQ_SUSPECTED_4000 0x0c | SOUNDFORMAT_XTAL1
#define SOUNDFORMAT_FREQ_SUSPECTED_4800 0x0a | SOUNDFORMAT_XTAL1
#define SOUNDFORMAT_FREQ_5510 0x0c | SOUNDFORMAT_XTAL2
@@ -72,6 +76,26 @@
#define SOUNDFORMAT_FLAG_16BIT 0x0010
#define SOUNDFORMAT_FLAG_2CHANNELS 0x0020
+/* define frequency helpers, for maximum value safety */
+enum azf_freq_t {
+#define AZF_FREQ(rate) AZF_FREQ_##rate = rate
+ AZF_FREQ(4000),
+ AZF_FREQ(4800),
+ AZF_FREQ(5512),
+ AZF_FREQ(6620),
+ AZF_FREQ(8000),
+ AZF_FREQ(9600),
+ AZF_FREQ(11025),
+ AZF_FREQ(13240),
+ AZF_FREQ(16000),
+ AZF_FREQ(22050),
+ AZF_FREQ(32000),
+ AZF_FREQ(44100),
+ AZF_FREQ(48000),
+ AZF_FREQ(66200),
+#undef AZF_FREQ
+};
+
/** recording area (see also: playback bit flag definitions) **/
#define IDX_IO_REC_FLAGS 0x20 /* ??, PU:0x0000 */
#define IDX_IO_REC_IRQTYPE 0x22 /* ??, PU:0x0000 */
@@ -97,40 +121,171 @@
/** DirectX timer, main interrupt area (FIXME: and something else?) **/
#define IDX_IO_TIMER_VALUE 0x60 /* found this timer area by pure luck :-) */
- #define TIMER_VALUE_MASK 0x000fffffUL /* timer countdown value; triggers IRQ when timer is finished */
- #define TIMER_ENABLE_COUNTDOWN 0x01000000UL /* activate the timer countdown */
- #define TIMER_ENABLE_IRQ 0x02000000UL /* trigger timer IRQ on zero transition */
- #define TIMER_ACK_IRQ 0x04000000UL /* being set in IRQ handler in case port 0x00 (hmm, not port 0x64!?!?) had 0x0020 set upon IRQ handler */
+ /* timer countdown value; triggers IRQ when timer is finished */
+ #define TIMER_VALUE_MASK 0x000fffffUL
+ /* activate timer countdown */
+ #define TIMER_COUNTDOWN_ENABLE 0x01000000UL
+ /* trigger timer IRQ on zero transition */
+ #define TIMER_IRQ_ENABLE 0x02000000UL
+ /* being set in IRQ handler in case port 0x00 (hmm, not port 0x64!?!?)
+ * had 0x0020 set upon IRQ handler */
+ #define TIMER_IRQ_ACK 0x04000000UL
#define IDX_IO_IRQSTATUS 0x64
- #define IRQ_PLAYBACK 0x0001
- #define IRQ_RECORDING 0x0002
- #define IRQ_MPU401 0x0010
- #define IRQ_TIMER 0x0020 /* DirectX timer */
- #define IRQ_UNKNOWN1 0x0040 /* probably unused, or possibly I2S port? or gameport IRQ? */
- #define IRQ_UNKNOWN2 0x0080 /* probably unused, or possibly I2S port? or gameport IRQ? */
+ /* some IRQ bit in here might also be used to signal a power-management timer
+ * timeout, to request shutdown of the chip (e.g. AD1815JS has such a thing).
+ * Some OPL3 hardware (e.g. in LM4560) has some special timer hardware which
+ * can trigger an OPL3 timer IRQ, so maybe there's such a thing as well... */
+
+ #define IRQ_PLAYBACK 0x0001
+ #define IRQ_RECORDING 0x0002
+ #define IRQ_UNKNOWN1 0x0004 /* most probably I2S port */
+ #define IRQ_GAMEPORT 0x0008 /* Interrupt of Digital(ly) Enhanced Game Port */
+ #define IRQ_MPU401 0x0010
+ #define IRQ_TIMER 0x0020 /* DirectX timer */
+ #define IRQ_UNKNOWN2 0x0040 /* probably unused, or possibly I2S port? */
+ #define IRQ_UNKNOWN3 0x0080 /* probably unused, or possibly I2S port? */
#define IDX_IO_66H 0x66 /* writing 0xffff returns 0x0000 */
-#define IDX_IO_SOME_VALUE 0x68 /* this is set to e.g. 0x3ff or 0x300, and writable; maybe some buffer limit, but I couldn't find out more, PU:0x00ff */
-#define IDX_IO_6AH 0x6A /* this WORD can be set to have bits 0x0028 activated (FIXME: correct??); actually inhibits PCM playback!!! maybe power management?? */
- #define IO_6A_PAUSE_PLAYBACK 0x0200 /* bit 9; sure, this pauses playback, but what the heck is this really about?? */
-#define IDX_IO_6CH 0x6C
-#define IDX_IO_6EH 0x6E /* writing 0xffff returns 0x83fe */
-/* further I/O indices not saved/restored, so probably not used */
+ /* this is set to e.g. 0x3ff or 0x300, and writable;
+ * maybe some buffer limit, but I couldn't find out more, PU:0x00ff: */
+#define IDX_IO_SOME_VALUE 0x68
+ #define IO_68_RANDOM_TOGGLE1 0x0100 /* toggles randomly */
+ #define IO_68_RANDOM_TOGGLE2 0x0200 /* toggles randomly */
+ /* umm, nope, behaviour of these bits changes depending on what we wrote
+ * to 0x6b!!
+ * And they change upon playback/stop, too:
+ * Writing a value to 0x68 will display this exact value during playback,
+ * too but when stopped it can fall back to a rather different
+ * seemingly random value). Hmm, possibly this is a register which
+ * has a remote shadow which needs proper device supply which only exists
+ * in case playback is active? Or is this driver-induced?
+ */
+
+/* this WORD can be set to have bits 0x0028 activated (FIXME: correct??);
+ * actually inhibits PCM playback!!! maybe power management??: */
+#define IDX_IO_6AH 0x6A /* WRITE_ONLY! */
+ /* bit 5: enabling this will activate permanent counting of bytes 2/3
+ * at gameport I/O (0xb402/3) (equal values each) and cause
+ * gameport legacy I/O at 0x0200 to be _DISABLED_!
+ * Is this Digital Enhanced Game Port Enable??? Or maybe it's Testmode
+ * for Enhanced Digital Gameport (see 4D Wave DX card): */
+ #define IO_6A_SOMETHING1_GAMEPORT 0x0020
+ /* bit 8; sure, this _pauses_ playback (later resumes at same spot!),
+ * but what the heck is this really about??: */
+ #define IO_6A_PAUSE_PLAYBACK_BIT8 0x0100
+ /* bit 9; sure, this _pauses_ playback (later resumes at same spot!),
+ * but what the heck is this really about??: */
+ #define IO_6A_PAUSE_PLAYBACK_BIT9 0x0200
+ /* BIT8 and BIT9 are _NOT_ able to affect OPL3 MIDI playback,
+ * thus it suggests influence on PCM only!!
+ * However OTOH there seems to be no bit anywhere around here
+ * which is able to disable OPL3... */
+ /* bit 10: enabling this actually changes values at legacy gameport
+ * I/O address (0x200); is this enabling of the Digital Enhanced Game Port???
+ * Or maybe this simply switches off the NE558 circuit, since enabling this
+ * still lets us evaluate button states, but not axis states */
+ #define IO_6A_SOMETHING2_GAMEPORT 0x0400
+ /* writing 0x0300: causes quite some crackling during
+ * PC activity such as switching windows (PCI traffic??
+ * --> FIFO/timing settings???) */
+ /* writing 0x0100 plus/or 0x0200 inhibits playback */
+ /* since the Windows .INF file has Flag_Enable_JoyStick and
+ * Flag_Enable_SB_DOS_Emulation directly together, it stands to reason
+ * that some other bit in this same register might be responsible
+ * for SB DOS Emulation activation (note that the file did NOT define
+ * a switch for OPL3!) */
+#define IDX_IO_6CH 0x6C /* unknown; fully read-writable */
+#define IDX_IO_6EH 0x6E
+ /* writing 0xffff returns 0x83fe (or 0x03fe only).
+ * writing 0x83 (and only 0x83!!) to 0x6f will cause 0x6c to switch
+ * from 0000 to ffff. */
+/* further I/O indices not saved/restored and not readable after writing,
+ * so probably not used */
-/*** I/O 2 area port indices ***/
+
+/*** Gameport area port indices ***/
/* (only 0x06 of 0x08 bytes saved/restored by Windows driver) */
-#define AZF_IO_SIZE_IO2 0x08
-#define AZF_IO_SIZE_IO2_PM 0x06
+#define AZF_IO_SIZE_GAME 0x08
+#define AZF_IO_SIZE_GAME_PM 0x06
+
+enum {
+ AZF_GAME_LEGACY_IO_PORT = 0x200
+};
+
+#define IDX_GAME_LEGACY_COMPATIBLE 0x00
+ /* in some operation mode, writing anything to this port
+ * triggers an interrupt:
+ * yup, that's in case IDX_GAME_01H has one of the
+ * axis measurement bits enabled
+ * (and of course one needs to have GAME_HWCFG_IRQ_ENABLE, too) */
+
+#define IDX_GAME_AXES_CONFIG 0x01
+ /* NOTE: layout of this register awfully similar (read: "identical??")
+ * to AD1815JS.pdf (p.29) */
+
+ /* enables axis 1 (X axis) measurement: */
+ #define GAME_AXES_ENABLE_1 0x01
+ /* enables axis 2 (Y axis) measurement: */
+ #define GAME_AXES_ENABLE_2 0x02
+ /* enables axis 3 (X axis) measurement: */
+ #define GAME_AXES_ENABLE_3 0x04
+ /* enables axis 4 (Y axis) measurement: */
+ #define GAME_AXES_ENABLE_4 0x08
+ /* selects the current axis to read the measured value of
+ * (at IDX_GAME_AXIS_VALUE):
+ * 00 = axis 1, 01 = axis 2, 10 = axis 3, 11 = axis 4: */
+ #define GAME_AXES_READ_MASK 0x30
+ /* enable to have the latch continuously accept ADC values
+ * (and continuously cause interrupts in case interrupts are enabled);
+ * AD1815JS.pdf says it's ~16ms interval there: */
+ #define GAME_AXES_LATCH_ENABLE 0x40
+ /* joystick data (measured axes) ready for reading: */
+ #define GAME_AXES_SAMPLING_READY 0x80
+
+ /* NOTE: other card specs (SiS960 and others!) state that the
+ * game position latches should be frozen when reading and be freed
+ * (== reset?) after reading!!!
+ * Freezing most likely means disabling 0x40 (GAME_AXES_LATCH_ENABLE),
+ * but how to free the value? */
+ /* An internet search for "gameport latch ADC" should provide some insight
+ * into how to program such a gameport system. */
+
+ /* writing 0xf0 to 01H once reset both counters to 0, in some special mode!?
+ * yup, in case 6AH 0x20 is not enabled
+ * (and 0x40 is sufficient, 0xf0 is not needed) */
+
+#define IDX_GAME_AXIS_VALUE 0x02
+ /* R: value of currently configured axis (word value!);
+ * W: trigger axis measurement */
+
+#define IDX_GAME_HWCONFIG 0x04
+ /* note: bits 4 to 7 are never set (== 0) when reading!
+ * --> reserved bits? */
+ /* enables IRQ notification upon axes measurement ready: */
+ #define GAME_HWCFG_IRQ_ENABLE 0x01
+ /* these bits choose a different frequency for the
+ * internal ADC counter increment.
+ * hmm, seems to be a combo of bits:
+ * 00 --> standard frequency
+ * 10 --> 1/2
+ * 01 --> 1/20
+ * 11 --> 1/200: */
+ #define GAME_HWCFG_ADC_COUNTER_FREQ_MASK 0x06
-#define IDX_IO2_LEGACY_ADDR 0x04
- #define LEGACY_SOMETHING 0x01 /* OPL3?? */
- #define LEGACY_JOY 0x08
+ /* enable gameport legacy I/O address (0x200)
+ * I was unable to locate any configurability for a different address: */
+ #define GAME_HWCFG_LEGACY_ADDRESS_ENABLE 0x08
+/*** MPU401 ***/
#define AZF_IO_SIZE_MPU 0x04
#define AZF_IO_SIZE_MPU_PM 0x04
-#define AZF_IO_SIZE_SYNTH 0x08
-#define AZF_IO_SIZE_SYNTH_PM 0x06
+/*** OPL3 synth ***/
+#define AZF_IO_SIZE_OPL3 0x08
+#define AZF_IO_SIZE_OPL3_PM 0x06
+/* hmm, given that a standard OPL3 has 4 registers only,
+ * there might be some enhanced functionality lurking at the end
+ * (especially since register 0x04 has a "non-empty" value 0xfe) */
/*** mixer I/O area port indices ***/
/* (only 0x22 of 0x40 bytes saved/restored by Windows driver)
diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c
index 4ecdd635ed1d..3aa8d973540a 100644
--- a/sound/pci/bt87x.c
+++ b/sound/pci/bt87x.c
@@ -227,7 +227,6 @@ static inline void snd_bt87x_writel(struct snd_bt87x *chip, u32 reg, u32 value)
static int snd_bt87x_create_risc(struct snd_bt87x *chip, struct snd_pcm_substream *substream,
unsigned int periods, unsigned int period_bytes)
{
- struct snd_sg_buf *sgbuf = snd_pcm_substream_sgbuf(substream);
unsigned int i, offset;
u32 *risc;
@@ -246,6 +245,7 @@ static int snd_bt87x_create_risc(struct snd_bt87x *chip, struct snd_pcm_substrea
rest = period_bytes;
do {
u32 cmd, len;
+ unsigned int addr;
len = PAGE_SIZE - (offset % PAGE_SIZE);
if (len > rest)
@@ -260,7 +260,8 @@ static int snd_bt87x_create_risc(struct snd_bt87x *chip, struct snd_pcm_substrea
if (len == rest)
cmd |= RISC_EOL | RISC_IRQ;
*risc++ = cpu_to_le32(cmd);
- *risc++ = cpu_to_le32((u32)snd_pcm_sgbuf_get_addr(sgbuf, offset));
+ addr = snd_pcm_sgbuf_get_addr(substream, offset);
+ *risc++ = cpu_to_le32(addr);
offset += len;
rest -= len;
} while (rest > 0);
diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c
index ecbe79b67e43..a7d89662acf6 100644
--- a/sound/pci/ca0106/ca0106_main.c
+++ b/sound/pci/ca0106/ca0106_main.c
@@ -249,6 +249,12 @@ static struct snd_ca0106_details ca0106_chip_details[] = {
.name = "MSI K8N Diamond MB [SB0438]",
.gpio_type = 2,
.i2c_adc = 1 } ,
+ /* MSI K8N Diamond PLUS MB */
+ { .serial = 0x10091102,
+ .name = "MSI K8N Diamond MB",
+ .gpio_type = 2,
+ .i2c_adc = 1,
+ .spi_dac = 2 } ,
/* Shuttle XPC SD31P which has an onboard Creative Labs
* Sound Blaster Live! 24-bit EAX
* high-definition 7.1 audio processor".
diff --git a/sound/pci/ca0106/ca_midi.c b/sound/pci/ca0106/ca_midi.c
index 893ee4f1ea77..c7885117da33 100644
--- a/sound/pci/ca0106/ca_midi.c
+++ b/sound/pci/ca0106/ca_midi.c
@@ -125,7 +125,8 @@ static int ca_midi_input_open(struct snd_rawmidi_substream *substream)
struct snd_ca_midi *midi = substream->rmidi->private_data;
unsigned long flags;
- snd_assert(midi->dev_id, return -ENXIO);
+ if (snd_BUG_ON(!midi->dev_id))
+ return -ENXIO;
spin_lock_irqsave(&midi->open_lock, flags);
midi->midi_mode |= CA_MIDI_MODE_INPUT;
midi->substream_input = substream;
@@ -144,7 +145,8 @@ static int ca_midi_output_open(struct snd_rawmidi_substream *substream)
struct snd_ca_midi *midi = substream->rmidi->private_data;
unsigned long flags;
- snd_assert(midi->dev_id, return -ENXIO);
+ if (snd_BUG_ON(!midi->dev_id))
+ return -ENXIO;
spin_lock_irqsave(&midi->open_lock, flags);
midi->midi_mode |= CA_MIDI_MODE_OUTPUT;
midi->substream_output = substream;
@@ -163,7 +165,8 @@ static int ca_midi_input_close(struct snd_rawmidi_substream *substream)
struct snd_ca_midi *midi = substream->rmidi->private_data;
unsigned long flags;
- snd_assert(midi->dev_id, return -ENXIO);
+ if (snd_BUG_ON(!midi->dev_id))
+ return -ENXIO;
spin_lock_irqsave(&midi->open_lock, flags);
midi->interrupt_disable(midi,midi->rx_enable);
midi->midi_mode &= ~CA_MIDI_MODE_INPUT;
@@ -181,7 +184,9 @@ static int ca_midi_output_close(struct snd_rawmidi_substream *substream)
{
struct snd_ca_midi *midi = substream->rmidi->private_data;
unsigned long flags;
- snd_assert(midi->dev_id, return -ENXIO);
+
+ if (snd_BUG_ON(!midi->dev_id))
+ return -ENXIO;
spin_lock_irqsave(&midi->open_lock, flags);
@@ -201,7 +206,9 @@ static int ca_midi_output_close(struct snd_rawmidi_substream *substream)
static void ca_midi_input_trigger(struct snd_rawmidi_substream *substream, int up)
{
struct snd_ca_midi *midi = substream->rmidi->private_data;
- snd_assert(midi->dev_id, return);
+
+ if (snd_BUG_ON(!midi->dev_id))
+ return;
if (up) {
midi->interrupt_enable(midi,midi->rx_enable);
@@ -215,7 +222,8 @@ static void ca_midi_output_trigger(struct snd_rawmidi_substream *substream, int
struct snd_ca_midi *midi = substream->rmidi->private_data;
unsigned long flags;
- snd_assert(midi->dev_id, return);
+ if (snd_BUG_ON(!midi->dev_id))
+ return;
if (up) {
int max = 4;
diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c
index 9971b5b7735b..1a74ca62c314 100644
--- a/sound/pci/cmipci.c
+++ b/sound/pci/cmipci.c
@@ -2357,7 +2357,8 @@ static int snd_cmipci_uswitch_get(struct snd_kcontrol *kcontrol,
{
struct cmipci_switch_args *args;
args = (struct cmipci_switch_args *)kcontrol->private_value;
- snd_assert(args != NULL, return -EINVAL);
+ if (snd_BUG_ON(!args))
+ return -EINVAL;
return _snd_cmipci_uswitch_get(kcontrol, ucontrol, args);
}
@@ -2401,7 +2402,8 @@ static int snd_cmipci_uswitch_put(struct snd_kcontrol *kcontrol,
{
struct cmipci_switch_args *args;
args = (struct cmipci_switch_args *)kcontrol->private_value;
- snd_assert(args != NULL, return -EINVAL);
+ if (snd_BUG_ON(!args))
+ return -EINVAL;
return _snd_cmipci_uswitch_put(kcontrol, ucontrol, args);
}
@@ -2662,7 +2664,8 @@ static int __devinit snd_cmipci_mixer_new(struct cmipci *cm, int pcm_spdif_devic
unsigned int idx;
int err;
- snd_assert(cm != NULL && cm->card != NULL, return -EINVAL);
+ if (snd_BUG_ON(!cm || !cm->card))
+ return -EINVAL;
card = cm->card;
diff --git a/sound/pci/cs4281.c b/sound/pci/cs4281.c
index 7556fd90d0eb..ef9308f7c45b 100644
--- a/sound/pci/cs4281.c
+++ b/sound/pci/cs4281.c
@@ -766,13 +766,13 @@ static void snd_cs4281_mode(struct cs4281 *chip, struct cs4281_dma *dma,
if (!capture) {
if (dma->left_slot == chip->src_left_play_slot) {
unsigned int val = snd_cs4281_rate(runtime->rate, NULL);
- snd_assert(dma->right_slot == chip->src_right_play_slot, );
+ snd_BUG_ON(dma->right_slot != chip->src_right_play_slot);
snd_cs4281_pokeBA0(chip, BA0_DACSR, val);
}
} else {
if (dma->left_slot == chip->src_left_rec_slot) {
unsigned int val = snd_cs4281_rate(runtime->rate, NULL);
- snd_assert(dma->right_slot == chip->src_right_rec_slot, );
+ snd_BUG_ON(dma->right_slot != chip->src_right_rec_slot);
snd_cs4281_pokeBA0(chip, BA0_ADCSR, val);
}
}
@@ -1209,7 +1209,8 @@ static void snd_cs4281_gameport_trigger(struct gameport *gameport)
{
struct cs4281 *chip = gameport_get_port_data(gameport);
- snd_assert(chip, return);
+ if (snd_BUG_ON(!chip))
+ return;
snd_cs4281_pokeBA0(chip, BA0_JSPT, 0xff);
}
@@ -1217,7 +1218,8 @@ static unsigned char snd_cs4281_gameport_read(struct gameport *gameport)
{
struct cs4281 *chip = gameport_get_port_data(gameport);
- snd_assert(chip, return 0);
+ if (snd_BUG_ON(!chip))
+ return 0;
return snd_cs4281_peekBA0(chip, BA0_JSPT);
}
@@ -1228,7 +1230,8 @@ static int snd_cs4281_gameport_cooked_read(struct gameport *gameport,
struct cs4281 *chip = gameport_get_port_data(gameport);
unsigned js1, js2, jst;
- snd_assert(chip, return 0);
+ if (snd_BUG_ON(!chip))
+ return 0;
js1 = snd_cs4281_peekBA0(chip, BA0_JSC1);
js2 = snd_cs4281_peekBA0(chip, BA0_JSC2);
diff --git a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c
index e214e567dec8..fb6dc3980257 100644
--- a/sound/pci/cs46xx/cs46xx_lib.c
+++ b/sound/pci/cs46xx/cs46xx_lib.c
@@ -90,9 +90,10 @@ static unsigned short snd_cs46xx_codec_read(struct snd_cs46xx *chip,
int count;
unsigned short result,tmp;
u32 offset = 0;
- snd_assert ( (codec_index == CS46XX_PRIMARY_CODEC_INDEX) ||
- (codec_index == CS46XX_SECONDARY_CODEC_INDEX),
- return -EINVAL);
+
+ if (snd_BUG_ON(codec_index != CS46XX_PRIMARY_CODEC_INDEX &&
+ codec_index != CS46XX_SECONDARY_CODEC_INDEX))
+ return -EINVAL;
chip->active_ctrl(chip, 1);
@@ -212,9 +213,9 @@ static unsigned short snd_cs46xx_ac97_read(struct snd_ac97 * ac97,
unsigned short val;
int codec_index = ac97->num;
- snd_assert(codec_index == CS46XX_PRIMARY_CODEC_INDEX ||
- codec_index == CS46XX_SECONDARY_CODEC_INDEX,
- return 0xffff);
+ if (snd_BUG_ON(codec_index != CS46XX_PRIMARY_CODEC_INDEX &&
+ codec_index != CS46XX_SECONDARY_CODEC_INDEX))
+ return 0xffff;
val = snd_cs46xx_codec_read(chip, reg, codec_index);
@@ -229,9 +230,9 @@ static void snd_cs46xx_codec_write(struct snd_cs46xx *chip,
{
int count;
- snd_assert ((codec_index == CS46XX_PRIMARY_CODEC_INDEX) ||
- (codec_index == CS46XX_SECONDARY_CODEC_INDEX),
- return);
+ if (snd_BUG_ON(codec_index != CS46XX_PRIMARY_CODEC_INDEX &&
+ codec_index != CS46XX_SECONDARY_CODEC_INDEX))
+ return;
chip->active_ctrl(chip, 1);
@@ -294,9 +295,9 @@ static void snd_cs46xx_ac97_write(struct snd_ac97 *ac97,
struct snd_cs46xx *chip = ac97->private_data;
int codec_index = ac97->num;
- snd_assert(codec_index == CS46XX_PRIMARY_CODEC_INDEX ||
- codec_index == CS46XX_SECONDARY_CODEC_INDEX,
- return);
+ if (snd_BUG_ON(codec_index != CS46XX_PRIMARY_CODEC_INDEX &&
+ codec_index != CS46XX_SECONDARY_CODEC_INDEX))
+ return;
snd_cs46xx_codec_write(chip, reg, val, codec_index);
}
@@ -315,7 +316,8 @@ int snd_cs46xx_download(struct snd_cs46xx *chip,
unsigned int bank = offset >> 16;
offset = offset & 0xffff;
- snd_assert(!(offset & 3) && !(len & 3), return -EINVAL);
+ if (snd_BUG_ON((offset & 3) || (len & 3)))
+ return -EINVAL;
dst = chip->region.idx[bank+1].remap_addr + offset;
len /= sizeof(u32);
@@ -343,7 +345,8 @@ int snd_cs46xx_clear_BA1(struct snd_cs46xx *chip,
unsigned int bank = offset >> 16;
offset = offset & 0xffff;
- snd_assert(!(offset & 3) && !(len & 3), return -EINVAL);
+ if (snd_BUG_ON((offset & 3) || (len & 3)))
+ return -EINVAL;
dst = chip->region.idx[bank+1].remap_addr + offset;
len /= sizeof(u32);
@@ -722,7 +725,9 @@ static snd_pcm_uframes_t snd_cs46xx_playback_direct_pointer(struct snd_pcm_subst
struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
size_t ptr;
struct snd_cs46xx_pcm *cpcm = substream->runtime->private_data;
- snd_assert (cpcm->pcm_channel,return -ENXIO);
+
+ if (snd_BUG_ON(!cpcm->pcm_channel))
+ return -ENXIO;
#ifdef CONFIG_SND_CS46XX_NEW_DSP
ptr = snd_cs46xx_peek(chip, (cpcm->pcm_channel->pcm_reader_scb->address + 2) << 2);
@@ -740,7 +745,8 @@ static snd_pcm_uframes_t snd_cs46xx_playback_indirect_pointer(struct snd_pcm_sub
struct snd_cs46xx_pcm *cpcm = substream->runtime->private_data;
#ifdef CONFIG_SND_CS46XX_NEW_DSP
- snd_assert (cpcm->pcm_channel,return -ENXIO);
+ if (snd_BUG_ON(!cpcm->pcm_channel))
+ return -ENXIO;
ptr = snd_cs46xx_peek(chip, (cpcm->pcm_channel->pcm_reader_scb->address + 2) << 2);
#else
ptr = snd_cs46xx_peek(chip, BA1_PBA);
@@ -908,7 +914,8 @@ static int snd_cs46xx_playback_hw_params(struct snd_pcm_substream *substream,
cpcm = runtime->private_data;
#ifdef CONFIG_SND_CS46XX_NEW_DSP
- snd_assert (sample_rate != 0, return -ENXIO);
+ if (snd_BUG_ON(!sample_rate))
+ return -ENXIO;
mutex_lock(&chip->spos_mutex);
@@ -917,7 +924,7 @@ static int snd_cs46xx_playback_hw_params(struct snd_pcm_substream *substream,
return -ENXIO;
}
- snd_assert (cpcm->pcm_channel != NULL);
+ snd_BUG_ON(!cpcm->pcm_channel);
if (!cpcm->pcm_channel) {
mutex_unlock(&chip->spos_mutex);
return -ENXIO;
@@ -952,7 +959,7 @@ static int snd_cs46xx_playback_hw_params(struct snd_pcm_substream *substream,
} else if (cpcm->pcm_channel_id == DSP_IEC958_CHANNEL) {
substream->ops = &snd_cs46xx_playback_iec958_ops;
} else {
- snd_assert(0);
+ snd_BUG();
}
#else
substream->ops = &snd_cs46xx_playback_ops;
@@ -981,7 +988,7 @@ static int snd_cs46xx_playback_hw_params(struct snd_pcm_substream *substream,
} else if (cpcm->pcm_channel_id == DSP_IEC958_CHANNEL) {
substream->ops = &snd_cs46xx_playback_indirect_iec958_ops;
} else {
- snd_assert(0);
+ snd_BUG();
}
#else
substream->ops = &snd_cs46xx_playback_indirect_ops;
@@ -1029,7 +1036,8 @@ static int snd_cs46xx_playback_prepare(struct snd_pcm_substream *substream)
cpcm = runtime->private_data;
#ifdef CONFIG_SND_CS46XX_NEW_DSP
- snd_assert (cpcm->pcm_channel != NULL, return -ENXIO);
+ if (snd_BUG_ON(!cpcm->pcm_channel))
+ return -ENXIO;
pfie = snd_cs46xx_peek(chip, (cpcm->pcm_channel->pcm_reader_scb->address + 1) << 2 );
pfie &= ~0x0000f03f;
@@ -1714,9 +1722,9 @@ static void snd_cs46xx_mixer_free_ac97(struct snd_ac97 *ac97)
{
struct snd_cs46xx *chip = ac97->private_data;
- snd_assert ((ac97 == chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]) ||
- (ac97 == chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]),
- return);
+ if (snd_BUG_ON(ac97 != chip->ac97[CS46XX_PRIMARY_CODEC_INDEX] &&
+ ac97 != chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]))
+ return;
if (ac97 == chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]) {
chip->ac97[CS46XX_PRIMARY_CODEC_INDEX] = NULL;
@@ -1864,7 +1872,7 @@ static int snd_cs46xx_iec958_put(struct snd_kcontrol *kcontrol,
break;
default:
res = -EINVAL;
- snd_assert(0, (void)0);
+ snd_BUG(); /* should never happen ... */
}
return res;
@@ -2236,7 +2244,7 @@ static void snd_cs46xx_codec_reset (struct snd_ac97 * ac97)
snd_printdd("cs46xx: CODOEC2 mode %04x\n",0x3);
snd_cs46xx_ac97_write(ac97,AC97_CSR_ACMODE,0x3);
} else {
- snd_assert(0); /* should never happen ... */
+ snd_BUG(); /* should never happen ... */
}
udelay(50);
@@ -2553,7 +2561,8 @@ static void snd_cs46xx_gameport_trigger(struct gameport *gameport)
{
struct snd_cs46xx *chip = gameport_get_port_data(gameport);
- snd_assert(chip, return);
+ if (snd_BUG_ON(!chip))
+ return;
snd_cs46xx_pokeBA0(chip, BA0_JSPT, 0xFF); //outb(gameport->io, 0xFF);
}
@@ -2561,7 +2570,8 @@ static unsigned char snd_cs46xx_gameport_read(struct gameport *gameport)
{
struct snd_cs46xx *chip = gameport_get_port_data(gameport);
- snd_assert(chip, return 0);
+ if (snd_BUG_ON(!chip))
+ return 0;
return snd_cs46xx_peekBA0(chip, BA0_JSPT); //inb(gameport->io);
}
@@ -2570,7 +2580,8 @@ static int snd_cs46xx_gameport_cooked_read(struct gameport *gameport, int *axes,
struct snd_cs46xx *chip = gameport_get_port_data(gameport);
unsigned js1, js2, jst;
- snd_assert(chip, return 0);
+ if (snd_BUG_ON(!chip))
+ return 0;
js1 = snd_cs46xx_peekBA0(chip, BA0_JSC1);
js2 = snd_cs46xx_peekBA0(chip, BA0_JSC2);
@@ -2754,7 +2765,8 @@ static int snd_cs46xx_free(struct snd_cs46xx *chip)
{
int idx;
- snd_assert(chip != NULL, return -EINVAL);
+ if (snd_BUG_ON(!chip))
+ return -EINVAL;
if (chip->active_ctrl)
chip->active_ctrl(chip, 1);
@@ -3489,8 +3501,9 @@ static struct cs_card_type __devinitdata cards[] = {
.name = "Mitac MI6020/21",
.amp = amp_voyetra,
},
+ /* Hercules Game Theatre XP */
{
- .vendor = 0x14AF,
+ .vendor = 0x14af, /* Guillemot Corporation */
.id = 0x0050,
.name = "Hercules Game Theatre XP",
.amp = amp_hercules,
@@ -3532,9 +3545,25 @@ static struct cs_card_type __devinitdata cards[] = {
.amp = amp_hercules,
.mixer_init = hercules_mixer_init,
},
+ /* Herculess Fortissimo */
+ {
+ .vendor = 0x1681,
+ .id = 0xa010,
+ .name = "Hercules Gamesurround Fortissimo II",
+ },
+ {
+ .vendor = 0x1681,
+ .id = 0xa011,
+ .name = "Hercules Gamesurround Fortissimo III 7.1",
+ },
/* Teratec */
{
.vendor = 0x153b,
+ .id = 0x112e,
+ .name = "Terratec DMX XFire 1024",
+ },
+ {
+ .vendor = 0x153b,
.id = 0x1136,
.name = "Terratec SiXPack 5.1",
},
diff --git a/sound/pci/cs46xx/dsp_spos.c b/sound/pci/cs46xx/dsp_spos.c
index ccc8bedb5b1a..f4f0c8f5dad7 100644
--- a/sound/pci/cs46xx/dsp_spos.c
+++ b/sound/pci/cs46xx/dsp_spos.c
@@ -63,7 +63,8 @@ static int shadow_and_reallocate_code (struct snd_cs46xx * chip, u32 * data, u32
u32 mop_operands,mop_type,wide_op;
struct dsp_spos_instance * ins = chip->dsp_spos_instance;
- snd_assert( ((size % 2) == 0), return -EINVAL);
+ if (snd_BUG_ON(size %2))
+ return -EINVAL;
while (i < size) {
loval = data[i++];
@@ -289,7 +290,8 @@ void cs46xx_dsp_spos_destroy (struct snd_cs46xx * chip)
int i;
struct dsp_spos_instance * ins = chip->dsp_spos_instance;
- snd_assert(ins != NULL, return);
+ if (snd_BUG_ON(!ins))
+ return;
mutex_lock(&chip->spos_mutex);
for (i = 0; i < ins->nscb; ++i) {
@@ -404,7 +406,8 @@ int cs46xx_dsp_load_module (struct snd_cs46xx * chip, struct dsp_module_desc * m
/* if module has a code segment it must have
symbol table */
- snd_assert(module->symbol_table.symbols != NULL ,return -ENOMEM);
+ if (snd_BUG_ON(!module->symbol_table.symbols))
+ return -ENOMEM;
if (add_symbols(chip,module)) {
snd_printk(KERN_ERR "dsp_spos: failed to load symbol table\n");
return -ENOMEM;
@@ -1369,7 +1372,8 @@ int cs46xx_dsp_scb_and_task_init (struct snd_cs46xx *chip)
valid_slots = snd_cs46xx_peekBA0(chip, BA0_ACOSV);
- snd_assert (chip->nr_ac97_codecs == 1 || chip->nr_ac97_codecs == 2);
+ if (snd_BUG_ON(chip->nr_ac97_codecs != 1 && chip->nr_ac97_codecs != 2))
+ goto _fail_end;
if (chip->nr_ac97_codecs == 1) {
/* output on slot 5 and 11
@@ -1609,11 +1613,14 @@ static int cs46xx_dsp_async_init (struct snd_cs46xx *chip,
spdifo_scb_desc = cs46xx_dsp_create_scb(chip,"SPDIFOSCB",(u32 *)&spdifo_scb,SPDIFO_SCB_INST);
- snd_assert(spdifo_scb_desc, return -EIO);
+ if (snd_BUG_ON(!spdifo_scb_desc))
+ return -EIO;
spdifi_scb_desc = cs46xx_dsp_create_scb(chip,"SPDIFISCB",(u32 *)&spdifi_scb,SPDIFI_SCB_INST);
- snd_assert(spdifi_scb_desc, return -EIO);
+ if (snd_BUG_ON(!spdifi_scb_desc))
+ return -EIO;
async_codec_scb_desc = cs46xx_dsp_create_scb(chip,"AsynCodecInputSCB",(u32 *)&async_codec_input_scb, HFG_TREE_SCB);
- snd_assert(async_codec_scb_desc, return -EIO);
+ if (snd_BUG_ON(!async_codec_scb_desc))
+ return -EIO;
async_codec_scb_desc->parent_scb_ptr = NULL;
async_codec_scb_desc->next_scb_ptr = spdifi_scb_desc;
@@ -1698,8 +1705,10 @@ int cs46xx_dsp_enable_spdif_in (struct snd_cs46xx *chip)
chip->active_ctrl(chip, 1);
chip->amplifier_ctrl(chip, 1);
- snd_assert (ins->asynch_rx_scb == NULL,return -EINVAL);
- snd_assert (ins->spdif_in_src != NULL,return -EINVAL);
+ if (snd_BUG_ON(ins->asynch_rx_scb))
+ return -EINVAL;
+ if (snd_BUG_ON(!ins->spdif_in_src))
+ return -EINVAL;
mutex_lock(&chip->spos_mutex);
@@ -1754,8 +1763,10 @@ int cs46xx_dsp_disable_spdif_in (struct snd_cs46xx *chip)
{
struct dsp_spos_instance * ins = chip->dsp_spos_instance;
- snd_assert (ins->asynch_rx_scb != NULL, return -EINVAL);
- snd_assert (ins->spdif_in_src != NULL,return -EINVAL);
+ if (snd_BUG_ON(!ins->asynch_rx_scb))
+ return -EINVAL;
+ if (snd_BUG_ON(!ins->spdif_in_src))
+ return -EINVAL;
mutex_lock(&chip->spos_mutex);
@@ -1780,8 +1791,10 @@ int cs46xx_dsp_enable_pcm_capture (struct snd_cs46xx *chip)
{
struct dsp_spos_instance * ins = chip->dsp_spos_instance;
- snd_assert (ins->pcm_input == NULL,return -EINVAL);
- snd_assert (ins->ref_snoop_scb != NULL,return -EINVAL);
+ if (snd_BUG_ON(ins->pcm_input))
+ return -EINVAL;
+ if (snd_BUG_ON(!ins->ref_snoop_scb))
+ return -EINVAL;
mutex_lock(&chip->spos_mutex);
ins->pcm_input = cs46xx_add_record_source(chip,ins->ref_snoop_scb,PCMSERIALIN_PCM_SCB_ADDR,
@@ -1795,7 +1808,8 @@ int cs46xx_dsp_disable_pcm_capture (struct snd_cs46xx *chip)
{
struct dsp_spos_instance * ins = chip->dsp_spos_instance;
- snd_assert (ins->pcm_input != NULL,return -EINVAL);
+ if (snd_BUG_ON(!ins->pcm_input))
+ return -EINVAL;
mutex_lock(&chip->spos_mutex);
cs46xx_dsp_remove_scb (chip,ins->pcm_input);
@@ -1809,8 +1823,10 @@ int cs46xx_dsp_enable_adc_capture (struct snd_cs46xx *chip)
{
struct dsp_spos_instance * ins = chip->dsp_spos_instance;
- snd_assert (ins->adc_input == NULL,return -EINVAL);
- snd_assert (ins->codec_in_scb != NULL,return -EINVAL);
+ if (snd_BUG_ON(ins->adc_input))
+ return -EINVAL;
+ if (snd_BUG_ON(!ins->codec_in_scb))
+ return -EINVAL;
mutex_lock(&chip->spos_mutex);
ins->adc_input = cs46xx_add_record_source(chip,ins->codec_in_scb,PCMSERIALIN_SCB_ADDR,
@@ -1824,7 +1840,8 @@ int cs46xx_dsp_disable_adc_capture (struct snd_cs46xx *chip)
{
struct dsp_spos_instance * ins = chip->dsp_spos_instance;
- snd_assert (ins->adc_input != NULL,return -EINVAL);
+ if (snd_BUG_ON(!ins->adc_input))
+ return -EINVAL;
mutex_lock(&chip->spos_mutex);
cs46xx_dsp_remove_scb (chip,ins->adc_input);
diff --git a/sound/pci/cs46xx/dsp_spos_scb_lib.c b/sound/pci/cs46xx/dsp_spos_scb_lib.c
index 2873cfe48c33..dd7c41b037b4 100644
--- a/sound/pci/cs46xx/dsp_spos_scb_lib.c
+++ b/sound/pci/cs46xx/dsp_spos_scb_lib.c
@@ -46,8 +46,11 @@ static void remove_symbol (struct snd_cs46xx * chip, struct dsp_symbol_entry * s
struct dsp_spos_instance * ins = chip->dsp_spos_instance;
int symbol_index = (int)(symbol - ins->symbol_table.symbols);
- snd_assert(ins->symbol_table.nsymbols > 0,return);
- snd_assert(symbol_index >= 0 && symbol_index < ins->symbol_table.nsymbols, return);
+ if (snd_BUG_ON(ins->symbol_table.nsymbols <= 0))
+ return;
+ if (snd_BUG_ON(symbol_index < 0 ||
+ symbol_index >= ins->symbol_table.nsymbols))
+ return;
ins->symbol_table.symbols[symbol_index].deleted = 1;
@@ -116,8 +119,9 @@ static void _dsp_unlink_scb (struct snd_cs46xx *chip, struct dsp_scb_descriptor
if ( scb->parent_scb_ptr ) {
/* unlink parent SCB */
- snd_assert ((scb->parent_scb_ptr->sub_list_ptr == scb ||
- scb->parent_scb_ptr->next_scb_ptr == scb),return);
+ if (snd_BUG_ON(scb->parent_scb_ptr->sub_list_ptr != scb &&
+ scb->parent_scb_ptr->next_scb_ptr != scb))
+ return;
if (scb->parent_scb_ptr->sub_list_ptr == scb) {
@@ -140,7 +144,6 @@ static void _dsp_unlink_scb (struct snd_cs46xx *chip, struct dsp_scb_descriptor
scb->next_scb_ptr = ins->the_null_scb;
}
} else {
- /* snd_assert ( (scb->sub_list_ptr == ins->the_null_scb), return); */
scb->parent_scb_ptr->next_scb_ptr = scb->next_scb_ptr;
if (scb->next_scb_ptr != ins->the_null_scb) {
@@ -181,16 +184,17 @@ void cs46xx_dsp_remove_scb (struct snd_cs46xx *chip, struct dsp_scb_descriptor *
unsigned long flags;
/* check integrety */
- snd_assert ( (scb->index >= 0 &&
- scb->index < ins->nscb &&
- (ins->scbs + scb->index) == scb), return );
+ if (snd_BUG_ON(scb->index < 0 ||
+ scb->index >= ins->nscb ||
+ (ins->scbs + scb->index) != scb))
+ return;
#if 0
/* can't remove a SCB with childs before
removing childs first */
- snd_assert ( (scb->sub_list_ptr == ins->the_null_scb &&
- scb->next_scb_ptr == ins->the_null_scb),
- goto _end);
+ if (snd_BUG_ON(scb->sub_list_ptr != ins->the_null_scb ||
+ scb->next_scb_ptr != ins->the_null_scb))
+ goto _end;
#endif
spin_lock_irqsave(&scb->lock, flags);
@@ -198,7 +202,8 @@ void cs46xx_dsp_remove_scb (struct snd_cs46xx *chip, struct dsp_scb_descriptor *
spin_unlock_irqrestore(&scb->lock, flags);
cs46xx_dsp_proc_free_scb_desc(scb);
- snd_assert (scb->scb_symbol != NULL, return );
+ if (snd_BUG_ON(!scb->scb_symbol))
+ return;
remove_symbol (chip,scb->scb_symbol);
ins->scbs[scb->index].deleted = 1;
@@ -234,7 +239,6 @@ void cs46xx_dsp_proc_free_scb_desc (struct dsp_scb_descriptor * scb)
snd_info_free_entry(scb->proc_info);
scb->proc_info = NULL;
- snd_assert (scb_info != NULL, return);
kfree (scb_info);
}
}
@@ -291,7 +295,8 @@ _dsp_create_generic_scb (struct snd_cs46xx *chip, char * name, u32 * scb_data, u
unsigned long flags;
- snd_assert (ins->the_null_scb != NULL,return NULL);
+ if (snd_BUG_ON(!ins->the_null_scb))
+ return NULL;
/* fill the data that will be wroten to DSP */
scb_data[SCBsubListPtr] =
@@ -321,18 +326,20 @@ _dsp_create_generic_scb (struct snd_cs46xx *chip, char * name, u32 * scb_data, u
#endif
/* link to parent SCB */
if (scb_child_type == SCB_ON_PARENT_NEXT_SCB) {
- snd_assert ( (scb->parent_scb_ptr->next_scb_ptr == ins->the_null_scb),
- return NULL);
+ if (snd_BUG_ON(scb->parent_scb_ptr->next_scb_ptr !=
+ ins->the_null_scb))
+ return NULL;
scb->parent_scb_ptr->next_scb_ptr = scb;
} else if (scb_child_type == SCB_ON_PARENT_SUBLIST_SCB) {
- snd_assert ( (scb->parent_scb_ptr->sub_list_ptr == ins->the_null_scb),
- return NULL);
+ if (snd_BUG_ON(scb->parent_scb_ptr->sub_list_ptr !=
+ ins->the_null_scb))
+ return NULL;
scb->parent_scb_ptr->sub_list_ptr = scb;
} else {
- snd_assert (0,return NULL);
+ snd_BUG();
}
spin_lock_irqsave(&chip->reg_lock, flags);
@@ -675,7 +682,7 @@ cs46xx_dsp_create_src_task_scb(struct snd_cs46xx * chip, char * scb_name,
if (pass_through) {
/* wont work with any other rate than
the native DSP rate */
- snd_assert (rate == 48000);
+ snd_BUG_ON(rate != 48000);
scb = cs46xx_dsp_create_generic_scb(chip,scb_name,(u32 *)&src_task_scb,
dest,"DMAREADER",parent_scb,
@@ -1142,7 +1149,8 @@ find_next_free_scb (struct snd_cs46xx * chip, struct dsp_scb_descriptor * from)
struct dsp_scb_descriptor * scb = from;
while (scb->next_scb_ptr != ins->the_null_scb) {
- snd_assert (scb->next_scb_ptr != NULL, return NULL);
+ if (snd_BUG_ON(!scb->next_scb_ptr))
+ return NULL;
scb = scb->next_scb_ptr;
}
@@ -1246,10 +1254,11 @@ cs46xx_dsp_create_pcm_channel (struct snd_cs46xx * chip,
break;
case DSP_PCM_S71_CHANNEL:
/* TODO */
- snd_assert(0);
+ snd_BUG();
break;
case DSP_IEC958_CHANNEL:
- snd_assert (ins->asynch_tx_scb != NULL, return NULL);
+ if (snd_BUG_ON(!ins->asynch_tx_scb))
+ return NULL;
mixer_scb = ins->asynch_tx_scb;
/* if sample rate is set to 48khz we pass
@@ -1262,7 +1271,7 @@ cs46xx_dsp_create_pcm_channel (struct snd_cs46xx * chip,
}
break;
default:
- snd_assert (0);
+ snd_BUG();
return NULL;
}
/* default sample rate is 44100 */
@@ -1308,7 +1317,8 @@ cs46xx_dsp_create_pcm_channel (struct snd_cs46xx * chip,
break;
}
}
- snd_assert (src_index != -1,return NULL);
+ if (snd_BUG_ON(src_index == -1))
+ return NULL;
/* we need to create a new SRC SCB */
if (mixer_scb->sub_list_ptr == ins->the_null_scb) {
@@ -1462,9 +1472,10 @@ void cs46xx_dsp_destroy_pcm_channel (struct snd_cs46xx * chip,
struct dsp_spos_instance * ins = chip->dsp_spos_instance;
unsigned long flags;
- snd_assert(pcm_channel->active, return );
- snd_assert(ins->npcm_channels > 0, return );
- snd_assert(pcm_channel->src_scb->ref_count > 0, return );
+ if (snd_BUG_ON(!pcm_channel->active ||
+ ins->npcm_channels <= 0 ||
+ pcm_channel->src_scb->ref_count <= 0))
+ return;
spin_lock_irqsave(&chip->reg_lock, flags);
pcm_channel->unlinked = 1;
@@ -1479,8 +1490,9 @@ 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,
- return );
+ if (snd_BUG_ON(pcm_channel->src_slot < 0 ||
+ pcm_channel->src_slot >= DSP_MAX_SRC_NR))
+ return;
ins->src_scb_slots[pcm_channel->src_slot] = 0;
ins->nsrc_scb --;
@@ -1490,11 +1502,11 @@ void cs46xx_dsp_destroy_pcm_channel (struct snd_cs46xx * chip,
int cs46xx_dsp_pcm_unlink (struct snd_cs46xx * chip,
struct dsp_pcm_channel_descriptor * pcm_channel)
{
- struct dsp_spos_instance * ins = chip->dsp_spos_instance;
unsigned long flags;
- snd_assert(pcm_channel->active,return -EIO);
- snd_assert(ins->npcm_channels > 0,return -EIO);
+ if (snd_BUG_ON(!pcm_channel->active ||
+ chip->dsp_spos_instance->npcm_channels <= 0))
+ return -EIO;
spin_lock(&pcm_channel->src_scb->lock);
@@ -1537,7 +1549,7 @@ int cs46xx_dsp_pcm_link (struct snd_cs46xx * chip,
src_scb->sub_list_ptr = pcm_channel->pcm_reader_scb;
- snd_assert (pcm_channel->pcm_reader_scb->parent_scb_ptr == NULL, ; );
+ snd_BUG_ON(pcm_channel->pcm_reader_scb->parent_scb_ptr);
pcm_channel->pcm_reader_scb->parent_scb_ptr = parent_scb;
spin_lock_irqsave(&chip->reg_lock, flags);
@@ -1564,7 +1576,8 @@ cs46xx_add_record_source (struct snd_cs46xx *chip, struct dsp_scb_descriptor * s
struct dsp_scb_descriptor * pcm_input;
int insert_point;
- snd_assert (ins->record_mixer_scb != NULL,return NULL);
+ if (snd_BUG_ON(!ins->record_mixer_scb))
+ return NULL;
if (ins->record_mixer_scb->sub_list_ptr != ins->the_null_scb) {
parent = find_next_free_scb (chip,ins->record_mixer_scb->sub_list_ptr);
@@ -1583,7 +1596,8 @@ cs46xx_add_record_source (struct snd_cs46xx *chip, struct dsp_scb_descriptor * s
int cs46xx_src_unlink(struct snd_cs46xx *chip, struct dsp_scb_descriptor * src)
{
- snd_assert (src->parent_scb_ptr != NULL, return -EINVAL );
+ if (snd_BUG_ON(!src->parent_scb_ptr))
+ return -EINVAL;
/* mute SCB */
cs46xx_dsp_scb_set_volume (chip,src,0,0);
@@ -1598,8 +1612,10 @@ int cs46xx_src_link(struct snd_cs46xx *chip, struct dsp_scb_descriptor * src)
struct dsp_spos_instance * ins = chip->dsp_spos_instance;
struct dsp_scb_descriptor * parent_scb;
- snd_assert (src->parent_scb_ptr == NULL, return -EINVAL );
- snd_assert(ins->master_mix_scb !=NULL, return -EINVAL );
+ if (snd_BUG_ON(src->parent_scb_ptr))
+ return -EINVAL;
+ if (snd_BUG_ON(!ins->master_mix_scb))
+ return -EINVAL;
if (ins->master_mix_scb->sub_list_ptr != ins->the_null_scb) {
parent_scb = find_next_free_scb (chip,ins->master_mix_scb->sub_list_ptr);
@@ -1635,8 +1651,11 @@ int cs46xx_dsp_enable_spdif_out (struct snd_cs46xx *chip)
return -EBUSY;
}
- snd_assert (ins->asynch_tx_scb == NULL, return -EINVAL);
- snd_assert (ins->master_mix_scb->next_scb_ptr == ins->the_null_scb, return -EINVAL);
+ if (snd_BUG_ON(ins->asynch_tx_scb))
+ return -EINVAL;
+ if (snd_BUG_ON(ins->master_mix_scb->next_scb_ptr !=
+ ins->the_null_scb))
+ return -EINVAL;
/* reset output snooper sample buffer pointer */
snd_cs46xx_poke (chip, (ins->ref_snoop_scb->address + 2) << 2,
@@ -1676,10 +1695,15 @@ int cs46xx_dsp_disable_spdif_out (struct snd_cs46xx *chip)
}
/* check integrety */
- snd_assert (ins->asynch_tx_scb != NULL, return -EINVAL);
- snd_assert (ins->spdif_pcm_input_scb != NULL,return -EINVAL);
- snd_assert (ins->master_mix_scb->next_scb_ptr == ins->asynch_tx_scb, return -EINVAL);
- snd_assert (ins->asynch_tx_scb->parent_scb_ptr == ins->master_mix_scb, return -EINVAL);
+ if (snd_BUG_ON(!ins->asynch_tx_scb))
+ return -EINVAL;
+ if (snd_BUG_ON(!ins->spdif_pcm_input_scb))
+ return -EINVAL;
+ if (snd_BUG_ON(ins->master_mix_scb->next_scb_ptr != ins->asynch_tx_scb))
+ return -EINVAL;
+ if (snd_BUG_ON(ins->asynch_tx_scb->parent_scb_ptr !=
+ ins->master_mix_scb))
+ return -EINVAL;
cs46xx_dsp_remove_scb (chip,ins->spdif_pcm_input_scb);
cs46xx_dsp_remove_scb (chip,ins->asynch_tx_scb);
@@ -1734,7 +1758,8 @@ int cs46xx_iec958_post_close (struct snd_cs46xx *chip)
{
struct dsp_spos_instance * ins = chip->dsp_spos_instance;
- snd_assert (ins->asynch_tx_scb != NULL, return -EINVAL);
+ if (snd_BUG_ON(!ins->asynch_tx_scb))
+ return -EINVAL;
ins->spdif_status_out &= ~DSP_SPDIF_STATUS_PLAYBACK_OPEN;
diff --git a/sound/pci/echoaudio/darla20_dsp.c b/sound/pci/echoaudio/darla20_dsp.c
index 4159e3bc186f..29043301ebb8 100644
--- a/sound/pci/echoaudio/darla20_dsp.c
+++ b/sound/pci/echoaudio/darla20_dsp.c
@@ -34,7 +34,8 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
int err;
DE_INIT(("init_hw() - Darla20\n"));
- snd_assert((subdevice_id & 0xfff0) == DARLA20, return -ENODEV);
+ if (snd_BUG_ON((subdevice_id & 0xfff0) != DARLA20))
+ return -ENODEV;
if ((err = init_dsp_comm_page(chip))) {
DE_INIT(("init_hw - could not initialize DSP comm page\n"));
diff --git a/sound/pci/echoaudio/darla24_dsp.c b/sound/pci/echoaudio/darla24_dsp.c
index 79938eed7e9c..60228731841f 100644
--- a/sound/pci/echoaudio/darla24_dsp.c
+++ b/sound/pci/echoaudio/darla24_dsp.c
@@ -34,7 +34,8 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
int err;
DE_INIT(("init_hw() - Darla24\n"));
- snd_assert((subdevice_id & 0xfff0) == DARLA24, return -ENODEV);
+ if (snd_BUG_ON((subdevice_id & 0xfff0) != DARLA24))
+ return -ENODEV;
if ((err = init_dsp_comm_page(chip))) {
DE_INIT(("init_hw - could not initialize DSP comm page\n"));
@@ -148,8 +149,9 @@ static int set_sample_rate(struct echoaudio *chip, u32 rate)
static int set_input_clock(struct echoaudio *chip, u16 clock)
{
- snd_assert(clock == ECHO_CLOCK_INTERNAL ||
- clock == ECHO_CLOCK_ESYNC, return -EINVAL);
+ if (snd_BUG_ON(clock != ECHO_CLOCK_INTERNAL &&
+ clock != ECHO_CLOCK_ESYNC))
+ return -EINVAL;
chip->input_clock = clock;
return set_sample_rate(chip, chip->sample_rate);
}
diff --git a/sound/pci/echoaudio/echo3g_dsp.c b/sound/pci/echoaudio/echo3g_dsp.c
index 48eb7c599111..417e25add82b 100644
--- a/sound/pci/echoaudio/echo3g_dsp.c
+++ b/sound/pci/echoaudio/echo3g_dsp.c
@@ -47,7 +47,8 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
local_irq_enable();
DE_INIT(("init_hw() - Echo3G\n"));
- snd_assert((subdevice_id & 0xfff0) == ECHO3G, return -ENODEV);
+ if (snd_BUG_ON((subdevice_id & 0xfff0) != ECHO3G))
+ return -ENODEV;
if ((err = init_dsp_comm_page(chip))) {
DE_INIT(("init_hw - could not initialize DSP comm page\n"));
@@ -104,9 +105,11 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
if ((err = init_line_levels(chip)) < 0)
return err;
err = set_digital_mode(chip, DIGITAL_MODE_SPDIF_RCA);
- snd_assert(err >= 0, return err);
+ if (err < 0)
+ return err;
err = set_phantom_power(chip, 0);
- snd_assert(err >= 0, return err);
+ if (err < 0)
+ return err;
err = set_professional_spdif(chip, TRUE);
DE_INIT(("init_hw done\n"));
diff --git a/sound/pci/echoaudio/echoaudio.c b/sound/pci/echoaudio/echoaudio.c
index e16dc92e82fb..8dbc5c4ba421 100644
--- a/sound/pci/echoaudio/echoaudio.c
+++ b/sound/pci/echoaudio/echoaudio.c
@@ -490,7 +490,6 @@ static int init_engine(struct snd_pcm_substream *substream,
{
struct echoaudio *chip;
int err, per, rest, page, edge, offs;
- struct snd_sg_buf *sgbuf;
struct audiopipe *pipe;
chip = snd_pcm_substream_chip(substream);
@@ -503,7 +502,7 @@ static int init_engine(struct snd_pcm_substream *substream,
if (pipe->index >= 0) {
DE_HWP(("hwp_ie free(%d)\n", pipe->index));
err = free_pipes(chip, pipe);
- snd_assert(!err);
+ snd_BUG_ON(err);
chip->substream[pipe->index] = NULL;
}
@@ -531,10 +530,6 @@ static int init_engine(struct snd_pcm_substream *substream,
return err;
}
- sgbuf = snd_pcm_substream_sgbuf(substream);
-
- DE_HWP(("pcm_hw_params table size=%d pages=%d\n",
- sgbuf->size, sgbuf->pages));
sglist_init(chip, pipe);
edge = PAGE_SIZE;
for (offs = page = per = 0; offs < params_buffer_bytes(hw_params);
@@ -543,16 +538,15 @@ static int init_engine(struct snd_pcm_substream *substream,
if (offs + rest > params_buffer_bytes(hw_params))
rest = params_buffer_bytes(hw_params) - offs;
while (rest) {
+ dma_addr_t addr;
+ addr = snd_pcm_sgbuf_get_addr(substream, offs);
if (rest <= edge - offs) {
- sglist_add_mapping(chip, pipe,
- snd_sgbuf_get_addr(sgbuf, offs),
- rest);
+ sglist_add_mapping(chip, pipe, addr, rest);
sglist_add_irq(chip, pipe);
offs += rest;
rest = 0;
} else {
- sglist_add_mapping(chip, pipe,
- snd_sgbuf_get_addr(sgbuf, offs),
+ sglist_add_mapping(chip, pipe, addr,
edge - offs);
rest -= edge - offs;
offs = edge;
@@ -690,8 +684,10 @@ static int pcm_prepare(struct snd_pcm_substream *substream)
return -EINVAL;
}
- snd_assert(pipe_index < px_num(chip), return -EINVAL);
- snd_assert(is_pipe_allocated(chip, pipe_index), return -EINVAL);
+ if (snd_BUG_ON(pipe_index >= px_num(chip)))
+ return -EINVAL;
+ if (snd_BUG_ON(!is_pipe_allocated(chip, pipe_index)))
+ return -EINVAL;
set_audio_format(chip, pipe_index, &format);
return 0;
}
diff --git a/sound/pci/echoaudio/echoaudio_3g.c b/sound/pci/echoaudio/echoaudio_3g.c
index 52a933189576..c3736bbd819e 100644
--- a/sound/pci/echoaudio/echoaudio_3g.c
+++ b/sound/pci/echoaudio/echoaudio_3g.c
@@ -103,9 +103,11 @@ static int set_digital_mode(struct echoaudio *chip, u8 mode)
int err, i, o;
/* All audio channels must be closed before changing the digital mode */
- snd_assert(!chip->pipe_alloc_mask, return -EAGAIN);
+ if (snd_BUG_ON(chip->pipe_alloc_mask))
+ return -EAGAIN;
- snd_assert(chip->digital_modes & (1 << mode), return -EINVAL);
+ if (snd_BUG_ON(!(chip->digital_modes & (1 << mode))))
+ return -EINVAL;
previous_mode = chip->digital_mode;
err = dsp_set_digital_mode(chip, mode);
@@ -267,8 +269,9 @@ static int set_sample_rate(struct echoaudio *chip, u32 rate)
return 0;
}
- snd_assert(rate < 50000 || chip->digital_mode != DIGITAL_MODE_ADAT,
- return -EINVAL);
+ if (snd_BUG_ON(rate >= 50000 &&
+ chip->digital_mode == DIGITAL_MODE_ADAT))
+ return -EINVAL;
clock = 0;
control_reg = le32_to_cpu(chip->comm_page->control_register);
diff --git a/sound/pci/echoaudio/echoaudio_dsp.c b/sound/pci/echoaudio/echoaudio_dsp.c
index e6c100770392..be0e18192de3 100644
--- a/sound/pci/echoaudio/echoaudio_dsp.c
+++ b/sound/pci/echoaudio/echoaudio_dsp.c
@@ -474,7 +474,8 @@ static int load_firmware(struct echoaudio *chip)
const struct firmware *fw;
int box_type, err;
- snd_assert(chip->dsp_code_to_load && chip->comm_page, return -EPERM);
+ if (snd_BUG_ON(!chip->dsp_code_to_load || !chip->comm_page))
+ return -EPERM;
/* See if the ASIC is present and working - only if the DSP is already loaded */
if (chip->dsp_code) {
@@ -512,8 +513,8 @@ static int load_firmware(struct echoaudio *chip)
/* Set the nominal level for an input or output bus (true = -10dBV, false = +4dBu) */
static int set_nominal_level(struct echoaudio *chip, u16 index, char consumer)
{
- snd_assert(index < num_busses_out(chip) + num_busses_in(chip),
- return -EINVAL);
+ if (snd_BUG_ON(index >= num_busses_out(chip) + num_busses_in(chip)))
+ return -EINVAL;
/* Wait for the handshake (OK even if ASIC is not loaded) */
if (wait_handshake(chip))
@@ -536,7 +537,8 @@ static int set_nominal_level(struct echoaudio *chip, u16 index, char consumer)
/* Set the gain for a single physical output channel (dB). */
static int set_output_gain(struct echoaudio *chip, u16 channel, s8 gain)
{
- snd_assert(channel < num_busses_out(chip), return -EINVAL);
+ if (snd_BUG_ON(channel >= num_busses_out(chip)))
+ return -EINVAL;
if (wait_handshake(chip))
return -EIO;
@@ -554,8 +556,9 @@ static int set_output_gain(struct echoaudio *chip, u16 channel, s8 gain)
static int set_monitor_gain(struct echoaudio *chip, u16 output, u16 input,
s8 gain)
{
- snd_assert(output < num_busses_out(chip) &&
- input < num_busses_in(chip), return -EINVAL);
+ if (snd_BUG_ON(output >= num_busses_out(chip) ||
+ input >= num_busses_in(chip)))
+ return -EINVAL;
if (wait_handshake(chip))
return -EIO;
@@ -1065,8 +1068,10 @@ static int free_pipes(struct echoaudio *chip, struct audiopipe *pipe)
int i;
DE_ACT(("free_pipes: Pipe %d\n", pipe->index));
- snd_assert(is_pipe_allocated(chip, pipe->index), return -EINVAL);
- snd_assert(pipe->state == PIPE_STATE_STOPPED, return -EINVAL);
+ if (snd_BUG_ON(!is_pipe_allocated(chip, pipe->index)))
+ return -EINVAL;
+ if (snd_BUG_ON(pipe->state != PIPE_STATE_STOPPED))
+ return -EINVAL;
for (channel_mask = i = 0; i < pipe->interleave; i++)
channel_mask |= 1 << (pipe->index + i);
diff --git a/sound/pci/echoaudio/echoaudio_gml.c b/sound/pci/echoaudio/echoaudio_gml.c
index 3aa37e76ebab..afa273330e8a 100644
--- a/sound/pci/echoaudio/echoaudio_gml.c
+++ b/sound/pci/echoaudio/echoaudio_gml.c
@@ -112,9 +112,11 @@ static int set_digital_mode(struct echoaudio *chip, u8 mode)
return -EIO;
/* All audio channels must be closed before changing the digital mode */
- snd_assert(!chip->pipe_alloc_mask, return -EAGAIN);
+ if (snd_BUG_ON(chip->pipe_alloc_mask))
+ return -EAGAIN;
- snd_assert(chip->digital_modes & (1 << mode), return -EINVAL);
+ if (snd_BUG_ON(!(chip->digital_modes & (1 << mode))))
+ return -EINVAL;
previous_mode = chip->digital_mode;
err = dsp_set_digital_mode(chip, mode);
diff --git a/sound/pci/echoaudio/gina20_dsp.c b/sound/pci/echoaudio/gina20_dsp.c
index 2757c8960843..db6c952e9d7f 100644
--- a/sound/pci/echoaudio/gina20_dsp.c
+++ b/sound/pci/echoaudio/gina20_dsp.c
@@ -38,7 +38,8 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
int err;
DE_INIT(("init_hw() - Gina20\n"));
- snd_assert((subdevice_id & 0xfff0) == GINA20, return -ENODEV);
+ if (snd_BUG_ON((subdevice_id & 0xfff0) != GINA20))
+ return -ENODEV;
if ((err = init_dsp_comm_page(chip))) {
DE_INIT(("init_hw - could not initialize DSP comm page\n"));
@@ -177,7 +178,8 @@ static int set_input_clock(struct echoaudio *chip, u16 clock)
/* Set input bus gain (one unit is 0.5dB !) */
static int set_input_gain(struct echoaudio *chip, u16 input, int gain)
{
- snd_assert(input < num_busses_in(chip), return -EINVAL);
+ if (snd_BUG_ON(input >= num_busses_in(chip)))
+ return -EINVAL;
if (wait_handshake(chip))
return -EIO;
diff --git a/sound/pci/echoaudio/gina24_dsp.c b/sound/pci/echoaudio/gina24_dsp.c
index 144fc567becf..2fef37a2a5b9 100644
--- a/sound/pci/echoaudio/gina24_dsp.c
+++ b/sound/pci/echoaudio/gina24_dsp.c
@@ -43,7 +43,8 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
int err;
DE_INIT(("init_hw() - Gina24\n"));
- snd_assert((subdevice_id & 0xfff0) == GINA24, return -ENODEV);
+ if (snd_BUG_ON((subdevice_id & 0xfff0) != GINA24))
+ return -ENODEV;
if ((err = init_dsp_comm_page(chip))) {
DE_INIT(("init_hw - could not initialize DSP comm page\n"));
@@ -84,7 +85,8 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
if ((err = init_line_levels(chip)) < 0)
return err;
err = set_digital_mode(chip, DIGITAL_MODE_SPDIF_RCA);
- snd_assert(err >= 0, return err);
+ if (err < 0)
+ return err;
err = set_professional_spdif(chip, TRUE);
DE_INIT(("init_hw done\n"));
@@ -163,8 +165,9 @@ static int set_sample_rate(struct echoaudio *chip, u32 rate)
{
u32 control_reg, clock;
- snd_assert(rate < 50000 || chip->digital_mode != DIGITAL_MODE_ADAT,
- return -EINVAL);
+ if (snd_BUG_ON(rate >= 50000 &&
+ chip->digital_mode == DIGITAL_MODE_ADAT))
+ return -EINVAL;
/* Only set the clock for internal mode. */
if (chip->input_clock != ECHO_CLOCK_INTERNAL) {
diff --git a/sound/pci/echoaudio/indigo_dsp.c b/sound/pci/echoaudio/indigo_dsp.c
index d6ac7734609e..f05e39f7aad9 100644
--- a/sound/pci/echoaudio/indigo_dsp.c
+++ b/sound/pci/echoaudio/indigo_dsp.c
@@ -39,7 +39,8 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
int err;
DE_INIT(("init_hw() - Indigo\n"));
- snd_assert((subdevice_id & 0xfff0) == INDIGO, return -ENODEV);
+ if (snd_BUG_ON((subdevice_id & 0xfff0) != INDIGO))
+ return -ENODEV;
if ((err = init_dsp_comm_page(chip))) {
DE_INIT(("init_hw - could not initialize DSP comm page\n"));
@@ -143,8 +144,9 @@ static int set_vmixer_gain(struct echoaudio *chip, u16 output, u16 pipe,
{
int index;
- snd_assert(pipe < num_pipes_out(chip) &&
- output < num_busses_out(chip), return -EINVAL);
+ if (snd_BUG_ON(pipe >= num_pipes_out(chip) ||
+ output >= num_busses_out(chip)))
+ return -EINVAL;
if (wait_handshake(chip))
return -EIO;
diff --git a/sound/pci/echoaudio/indigodj_dsp.c b/sound/pci/echoaudio/indigodj_dsp.c
index 500e150b49fc..90730a5ecb42 100644
--- a/sound/pci/echoaudio/indigodj_dsp.c
+++ b/sound/pci/echoaudio/indigodj_dsp.c
@@ -39,7 +39,8 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
int err;
DE_INIT(("init_hw() - Indigo DJ\n"));
- snd_assert((subdevice_id & 0xfff0) == INDIGO_DJ, return -ENODEV);
+ if (snd_BUG_ON((subdevice_id & 0xfff0) != INDIGO_DJ))
+ return -ENODEV;
if ((err = init_dsp_comm_page(chip))) {
DE_INIT(("init_hw - could not initialize DSP comm page\n"));
@@ -143,8 +144,9 @@ static int set_vmixer_gain(struct echoaudio *chip, u16 output, u16 pipe,
{
int index;
- snd_assert(pipe < num_pipes_out(chip) &&
- output < num_busses_out(chip), return -EINVAL);
+ if (snd_BUG_ON(pipe >= num_pipes_out(chip) ||
+ output >= num_busses_out(chip)))
+ return -EINVAL;
if (wait_handshake(chip))
return -EIO;
diff --git a/sound/pci/echoaudio/indigoio_dsp.c b/sound/pci/echoaudio/indigoio_dsp.c
index f3ad13d06be0..a7e09ec21079 100644
--- a/sound/pci/echoaudio/indigoio_dsp.c
+++ b/sound/pci/echoaudio/indigoio_dsp.c
@@ -39,7 +39,8 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
int err;
DE_INIT(("init_hw() - Indigo IO\n"));
- snd_assert((subdevice_id & 0xfff0) == INDIGO_IO, return -ENODEV);
+ if (snd_BUG_ON((subdevice_id & 0xfff0) != INDIGO_IO))
+ return -ENODEV;
if ((err = init_dsp_comm_page(chip))) {
DE_INIT(("init_hw - could not initialize DSP comm page\n"));
@@ -114,8 +115,9 @@ static int set_vmixer_gain(struct echoaudio *chip, u16 output, u16 pipe,
{
int index;
- snd_assert(pipe < num_pipes_out(chip) &&
- output < num_busses_out(chip), return -EINVAL);
+ if (snd_BUG_ON(pipe >= num_pipes_out(chip) ||
+ output >= num_busses_out(chip)))
+ return -EINVAL;
if (wait_handshake(chip))
return -EIO;
diff --git a/sound/pci/echoaudio/layla20_dsp.c b/sound/pci/echoaudio/layla20_dsp.c
index 990c9a60a0a8..ede75c6ca0fb 100644
--- a/sound/pci/echoaudio/layla20_dsp.c
+++ b/sound/pci/echoaudio/layla20_dsp.c
@@ -42,7 +42,8 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
int err;
DE_INIT(("init_hw() - Layla20\n"));
- snd_assert((subdevice_id & 0xfff0) == LAYLA20, return -ENODEV);
+ if (snd_BUG_ON((subdevice_id & 0xfff0) != LAYLA20))
+ return -ENODEV;
if ((err = init_dsp_comm_page(chip))) {
DE_INIT(("init_hw - could not initialize DSP comm page\n"));
@@ -155,7 +156,8 @@ static int load_asic(struct echoaudio *chip)
static int set_sample_rate(struct echoaudio *chip, u32 rate)
{
- snd_assert(rate >= 8000 && rate <= 50000, return -EINVAL);
+ if (snd_BUG_ON(rate < 8000 || rate > 50000))
+ return -EINVAL;
/* Only set the clock for internal mode. Do not return failure,
simply treat it as a non-event. */
@@ -252,7 +254,8 @@ static int set_output_clock(struct echoaudio *chip, u16 clock)
/* Set input bus gain (one unit is 0.5dB !) */
static int set_input_gain(struct echoaudio *chip, u16 input, int gain)
{
- snd_assert(input < num_busses_in(chip), return -EINVAL);
+ if (snd_BUG_ON(input >= num_busses_in(chip)))
+ return -EINVAL;
if (wait_handshake(chip))
return -EIO;
diff --git a/sound/pci/echoaudio/layla24_dsp.c b/sound/pci/echoaudio/layla24_dsp.c
index 97e42e115147..d61b5cbcccad 100644
--- a/sound/pci/echoaudio/layla24_dsp.c
+++ b/sound/pci/echoaudio/layla24_dsp.c
@@ -42,7 +42,8 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
int err;
DE_INIT(("init_hw() - Layla24\n"));
- snd_assert((subdevice_id & 0xfff0) == LAYLA24, return -ENODEV);
+ if (snd_BUG_ON((subdevice_id & 0xfff0) != LAYLA24))
+ return -ENODEV;
if ((err = init_dsp_comm_page(chip))) {
DE_INIT(("init_hw - could not initialize DSP comm page\n"));
@@ -73,7 +74,8 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
return err;
err = set_digital_mode(chip, DIGITAL_MODE_SPDIF_RCA);
- snd_assert(err >= 0, return err);
+ if (err < 0)
+ return err;
err = set_professional_spdif(chip, TRUE);
DE_INIT(("init_hw done\n"));
@@ -158,8 +160,9 @@ static int set_sample_rate(struct echoaudio *chip, u32 rate)
{
u32 control_reg, clock, base_rate;
- snd_assert(rate < 50000 || chip->digital_mode != DIGITAL_MODE_ADAT,
- return -EINVAL);
+ if (snd_BUG_ON(rate >= 50000 &&
+ chip->digital_mode == DIGITAL_MODE_ADAT))
+ return -EINVAL;
/* Only set the clock for internal mode. */
if (chip->input_clock != ECHO_CLOCK_INTERNAL) {
diff --git a/sound/pci/echoaudio/mia_dsp.c b/sound/pci/echoaudio/mia_dsp.c
index 891c70519096..227386602f9b 100644
--- a/sound/pci/echoaudio/mia_dsp.c
+++ b/sound/pci/echoaudio/mia_dsp.c
@@ -42,7 +42,8 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
int err;
DE_INIT(("init_hw() - Mia\n"));
- snd_assert((subdevice_id & 0xfff0) == MIA, return -ENODEV);
+ if (snd_BUG_ON((subdevice_id & 0xfff0) != MIA))
+ return -ENODEV;
if ((err = init_dsp_comm_page(chip))) {
DE_INIT(("init_hw - could not initialize DSP comm page\n"));
@@ -161,8 +162,9 @@ static int set_sample_rate(struct echoaudio *chip, u32 rate)
static int set_input_clock(struct echoaudio *chip, u16 clock)
{
DE_ACT(("set_input_clock(%d)\n", clock));
- snd_assert(clock == ECHO_CLOCK_INTERNAL || clock == ECHO_CLOCK_SPDIF,
- return -EINVAL);
+ if (snd_BUG_ON(clock != ECHO_CLOCK_INTERNAL &&
+ clock != ECHO_CLOCK_SPDIF))
+ return -EINVAL;
chip->input_clock = clock;
return set_sample_rate(chip, chip->sample_rate);
@@ -176,8 +178,9 @@ static int set_vmixer_gain(struct echoaudio *chip, u16 output, u16 pipe,
{
int index;
- snd_assert(pipe < num_pipes_out(chip) &&
- output < num_busses_out(chip), return -EINVAL);
+ if (snd_BUG_ON(pipe >= num_pipes_out(chip) ||
+ output >= num_busses_out(chip)))
+ return -EINVAL;
if (wait_handshake(chip))
return -EIO;
diff --git a/sound/pci/echoaudio/midi.c b/sound/pci/echoaudio/midi.c
index 91f5bff66d3f..77bf2a83d997 100644
--- a/sound/pci/echoaudio/midi.c
+++ b/sound/pci/echoaudio/midi.c
@@ -59,7 +59,8 @@ static int enable_midi_input(struct echoaudio *chip, char enable)
Returns how many actually written or < 0 on error */
static int write_midi(struct echoaudio *chip, u8 *data, int bytes)
{
- snd_assert(bytes > 0 && bytes < MIDI_OUT_BUFFER_SIZE, return -EINVAL);
+ if (snd_BUG_ON(bytes <= 0 || bytes >= MIDI_OUT_BUFFER_SIZE))
+ return -EINVAL;
if (wait_handshake(chip))
return -EIO;
@@ -119,7 +120,8 @@ static int midi_service_irq(struct echoaudio *chip)
/* The count is at index 0, followed by actual data */
count = le16_to_cpu(chip->comm_page->midi_input[0]);
- snd_assert(count < MIDI_IN_BUFFER_SIZE, return 0);
+ if (snd_BUG_ON(count >= MIDI_IN_BUFFER_SIZE))
+ return 0;
/* Get the MIDI data from the comm page */
i = 1;
diff --git a/sound/pci/echoaudio/mona_dsp.c b/sound/pci/echoaudio/mona_dsp.c
index c0b4bf0be7d1..eaa619bd2a03 100644
--- a/sound/pci/echoaudio/mona_dsp.c
+++ b/sound/pci/echoaudio/mona_dsp.c
@@ -43,7 +43,8 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
int err;
DE_INIT(("init_hw() - Mona\n"));
- snd_assert((subdevice_id & 0xfff0) == MONA, return -ENODEV);
+ if (snd_BUG_ON((subdevice_id & 0xfff0) != MONA))
+ return -ENODEV;
if ((err = init_dsp_comm_page(chip))) {
DE_INIT(("init_hw - could not initialize DSP comm page\n"));
@@ -79,7 +80,8 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
return err;
err = set_digital_mode(chip, DIGITAL_MODE_SPDIF_RCA);
- snd_assert(err >= 0, return err);
+ if (err < 0)
+ return err;
err = set_professional_spdif(chip, TRUE);
DE_INIT(("init_hw done\n"));
diff --git a/sound/pci/emu10k1/emu10k1_callback.c b/sound/pci/emu10k1/emu10k1_callback.c
index 45088ebcce50..0e649dcdbf64 100644
--- a/sound/pci/emu10k1/emu10k1_callback.c
+++ b/sound/pci/emu10k1/emu10k1_callback.c
@@ -145,7 +145,8 @@ terminate_voice(struct snd_emux_voice *vp)
{
struct snd_emu10k1 *hw;
- snd_assert(vp, return);
+ if (snd_BUG_ON(!vp))
+ return;
hw = vp->hw;
snd_emu10k1_ptr_write(hw, DCYSUSV, vp->ch, 0x807f | DCYSUSV_CHANNELENABLE_MASK);
if (vp->block) {
@@ -325,7 +326,8 @@ start_voice(struct snd_emux_voice *vp)
hw = vp->hw;
ch = vp->ch;
- snd_assert(ch >= 0, return -EINVAL);
+ if (snd_BUG_ON(ch < 0))
+ return -EINVAL;
chan = vp->chan;
emem = (struct snd_emu10k1_memblk *)vp->block;
diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c
index 548c9cc81af5..2f283ea6ad9a 100644
--- a/sound/pci/emu10k1/emu10k1_main.c
+++ b/sound/pci/emu10k1/emu10k1_main.c
@@ -1528,6 +1528,7 @@ static struct snd_emu_chip_details emu_chip_details[] = {
.ca0151_chip = 1,
.spk71 = 1,
.spdif_bug = 1,
+ .invert_shared_spdif = 1, /* digital/analog switch swapped */
.adc_1361t = 1, /* 24 bit capture instead of 16bit. Fixes ALSA bug#324 */
.ac97_chip = 1} ,
{.vendor = 0x1102, .device = 0x0004, .revision = 0x04,
diff --git a/sound/pci/emu10k1/emu10k1_patch.c b/sound/pci/emu10k1/emu10k1_patch.c
index 42bae6f7e9a4..e10f027bde03 100644
--- a/sound/pci/emu10k1/emu10k1_patch.c
+++ b/sound/pci/emu10k1/emu10k1_patch.c
@@ -46,8 +46,8 @@ snd_emu10k1_sample_new(struct snd_emux *rec, struct snd_sf_sample *sp,
struct snd_emu10k1 *emu;
emu = rec->hw;
- snd_assert(sp != NULL, return -EINVAL);
- snd_assert(hdr != NULL, return -EINVAL);
+ if (snd_BUG_ON(!sp || !hdr))
+ return -EINVAL;
if (sp->v.size == 0) {
snd_printd("emu: rom font for sample %d\n", sp->v.sample);
@@ -104,7 +104,8 @@ snd_emu10k1_sample_new(struct snd_emux *rec, struct snd_sf_sample *sp,
size = BLANK_HEAD_SIZE;
if (! (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_8BITS))
size *= 2;
- snd_assert(offset + size <= blocksize, return -EINVAL);
+ if (offset + size > blocksize)
+ return -EINVAL;
snd_emu10k1_synth_bzero(emu, sp->block, offset, size);
offset += size;
@@ -112,7 +113,8 @@ snd_emu10k1_sample_new(struct snd_emux *rec, struct snd_sf_sample *sp,
size = loopend;
if (! (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_8BITS))
size *= 2;
- snd_assert(offset + size <= blocksize, return -EINVAL);
+ if (offset + size > blocksize)
+ return -EINVAL;
if (snd_emu10k1_synth_copy_from_user(emu, sp->block, offset, data, size)) {
snd_emu10k1_synth_free(emu, sp->block);
sp->block = NULL;
@@ -129,12 +131,14 @@ snd_emu10k1_sample_new(struct snd_emux *rec, struct snd_sf_sample *sp,
int woffset;
unsigned short *wblock = (unsigned short*)block;
woffset = offset / 2;
- snd_assert(offset + loopsize*2 <= blocksize, return -EINVAL);
+ if (offset + loopsize * 2 > blocksize)
+ return -EINVAL;
for (i = 0; i < loopsize; i++)
wblock[woffset + i] = wblock[woffset - i -1];
offset += loopsize * 2;
} else {
- snd_assert(offset + loopsize <= blocksize, return -EINVAL);
+ if (offset + loopsize > blocksize)
+ return -EINVAL;
for (i = 0; i < loopsize; i++)
block[offset + i] = block[offset - i -1];
offset += loopsize;
@@ -154,7 +158,8 @@ snd_emu10k1_sample_new(struct snd_emux *rec, struct snd_sf_sample *sp,
/* loopend -> sample end */
size = sp->v.size - loopend;
- snd_assert(size >= 0, return -EINVAL);
+ if (size < 0)
+ return -EINVAL;
if (! (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_8BITS))
size *= 2;
if (snd_emu10k1_synth_copy_from_user(emu, sp->block, offset, data, size)) {
@@ -212,8 +217,8 @@ snd_emu10k1_sample_free(struct snd_emux *rec, struct snd_sf_sample *sp,
struct snd_emu10k1 *emu;
emu = rec->hw;
- snd_assert(sp != NULL, return -EINVAL);
- snd_assert(hdr != NULL, return -EINVAL);
+ if (snd_BUG_ON(!sp || !hdr))
+ return -EINVAL;
if (sp->block) {
snd_emu10k1_synth_free(emu, sp->block);
diff --git a/sound/pci/emu10k1/emu10k1x.c b/sound/pci/emu10k1/emu10k1x.c
index 491a4a50f869..5ff4dbb62dad 100644
--- a/sound/pci/emu10k1/emu10k1x.c
+++ b/sound/pci/emu10k1/emu10k1x.c
@@ -1319,7 +1319,8 @@ static int snd_emu10k1x_midi_input_open(struct snd_rawmidi_substream *substream)
unsigned long flags;
emu = midi->emu;
- snd_assert(emu, return -ENXIO);
+ if (snd_BUG_ON(!emu))
+ return -ENXIO;
spin_lock_irqsave(&midi->open_lock, flags);
midi->midi_mode |= EMU10K1X_MIDI_MODE_INPUT;
midi->substream_input = substream;
@@ -1345,7 +1346,8 @@ static int snd_emu10k1x_midi_output_open(struct snd_rawmidi_substream *substream
unsigned long flags;
emu = midi->emu;
- snd_assert(emu, return -ENXIO);
+ if (snd_BUG_ON(!emu))
+ return -ENXIO;
spin_lock_irqsave(&midi->open_lock, flags);
midi->midi_mode |= EMU10K1X_MIDI_MODE_OUTPUT;
midi->substream_output = substream;
@@ -1372,7 +1374,8 @@ static int snd_emu10k1x_midi_input_close(struct snd_rawmidi_substream *substream
int err = 0;
emu = midi->emu;
- snd_assert(emu, return -ENXIO);
+ if (snd_BUG_ON(!emu))
+ return -ENXIO;
spin_lock_irqsave(&midi->open_lock, flags);
snd_emu10k1x_intr_disable(emu, midi->rx_enable);
midi->midi_mode &= ~EMU10K1X_MIDI_MODE_INPUT;
@@ -1394,7 +1397,8 @@ static int snd_emu10k1x_midi_output_close(struct snd_rawmidi_substream *substrea
int err = 0;
emu = midi->emu;
- snd_assert(emu, return -ENXIO);
+ if (snd_BUG_ON(!emu))
+ return -ENXIO;
spin_lock_irqsave(&midi->open_lock, flags);
snd_emu10k1x_intr_disable(emu, midi->tx_enable);
midi->midi_mode &= ~EMU10K1X_MIDI_MODE_OUTPUT;
@@ -1413,7 +1417,8 @@ static void snd_emu10k1x_midi_input_trigger(struct snd_rawmidi_substream *substr
struct emu10k1x *emu;
struct emu10k1x_midi *midi = substream->rmidi->private_data;
emu = midi->emu;
- snd_assert(emu, return);
+ if (snd_BUG_ON(!emu))
+ return;
if (up)
snd_emu10k1x_intr_enable(emu, midi->rx_enable);
@@ -1428,7 +1433,8 @@ static void snd_emu10k1x_midi_output_trigger(struct snd_rawmidi_substream *subst
unsigned long flags;
emu = midi->emu;
- snd_assert(emu, return);
+ if (snd_BUG_ON(!emu))
+ return;
if (up) {
int max = 4;
diff --git a/sound/pci/emu10k1/emufx.c b/sound/pci/emu10k1/emufx.c
index 71dc4c8865b8..7dba08f0ab8e 100644
--- a/sound/pci/emu10k1/emufx.c
+++ b/sound/pci/emu10k1/emufx.c
@@ -487,7 +487,8 @@ static void snd_emu10k1_write_op(struct snd_emu10k1_fx8010_code *icode,
u32 op, u32 r, u32 a, u32 x, u32 y)
{
u_int32_t *code;
- snd_assert(*ptr < 512, return);
+ if (snd_BUG_ON(*ptr >= 512))
+ return;
code = (u_int32_t __force *)icode->code + (*ptr) * 2;
set_bit(*ptr, icode->code_valid);
code[0] = ((x & 0x3ff) << 10) | (y & 0x3ff);
@@ -503,7 +504,8 @@ static void snd_emu10k1_audigy_write_op(struct snd_emu10k1_fx8010_code *icode,
u32 op, u32 r, u32 a, u32 x, u32 y)
{
u_int32_t *code;
- snd_assert(*ptr < 1024, return);
+ if (snd_BUG_ON(*ptr >= 1024))
+ return;
code = (u_int32_t __force *)icode->code + (*ptr) * 2;
set_bit(*ptr, icode->code_valid);
code[0] = ((x & 0x7ff) << 12) | (y & 0x7ff);
diff --git a/sound/pci/emu10k1/emumixer.c b/sound/pci/emu10k1/emumixer.c
index fd221209abcb..f34bbfb705f5 100644
--- a/sound/pci/emu10k1/emumixer.c
+++ b/sound/pci/emu10k1/emumixer.c
@@ -1578,6 +1578,10 @@ static int snd_emu10k1_shared_spdif_get(struct snd_kcontrol *kcontrol,
ucontrol->value.integer.value[0] = inl(emu->port + A_IOCFG) & A_IOCFG_GPOUT0 ? 1 : 0;
else
ucontrol->value.integer.value[0] = inl(emu->port + HCFG) & HCFG_GPOUT0 ? 1 : 0;
+ if (emu->card_capabilities->invert_shared_spdif)
+ ucontrol->value.integer.value[0] =
+ !ucontrol->value.integer.value[0];
+
return 0;
}
@@ -1586,15 +1590,18 @@ static int snd_emu10k1_shared_spdif_put(struct snd_kcontrol *kcontrol,
{
unsigned long flags;
struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
- unsigned int reg, val;
+ unsigned int reg, val, sw;
int change = 0;
+ sw = ucontrol->value.integer.value[0];
+ if (emu->card_capabilities->invert_shared_spdif)
+ sw = !sw;
spin_lock_irqsave(&emu->reg_lock, flags);
if ( emu->card_capabilities->i2c_adc) {
/* Do nothing for Audigy 2 ZS Notebook */
} else if (emu->audigy) {
reg = inl(emu->port + A_IOCFG);
- val = ucontrol->value.integer.value[0] ? A_IOCFG_GPOUT0 : 0;
+ val = sw ? A_IOCFG_GPOUT0 : 0;
change = (reg & A_IOCFG_GPOUT0) != val;
if (change) {
reg &= ~A_IOCFG_GPOUT0;
@@ -1603,7 +1610,7 @@ static int snd_emu10k1_shared_spdif_put(struct snd_kcontrol *kcontrol,
}
}
reg = inl(emu->port + HCFG);
- val = ucontrol->value.integer.value[0] ? HCFG_GPOUT0 : 0;
+ val = sw ? HCFG_GPOUT0 : 0;
change |= (reg & HCFG_GPOUT0) != val;
if (change) {
reg &= ~HCFG_GPOUT0;
diff --git a/sound/pci/emu10k1/emumpu401.c b/sound/pci/emu10k1/emumpu401.c
index c4d76d16661e..8578c70c61f2 100644
--- a/sound/pci/emu10k1/emumpu401.c
+++ b/sound/pci/emu10k1/emumpu401.c
@@ -157,7 +157,8 @@ static int snd_emu10k1_midi_input_open(struct snd_rawmidi_substream *substream)
unsigned long flags;
emu = midi->emu;
- snd_assert(emu, return -ENXIO);
+ if (snd_BUG_ON(!emu))
+ return -ENXIO;
spin_lock_irqsave(&midi->open_lock, flags);
midi->midi_mode |= EMU10K1_MIDI_MODE_INPUT;
midi->substream_input = substream;
@@ -183,7 +184,8 @@ static int snd_emu10k1_midi_output_open(struct snd_rawmidi_substream *substream)
unsigned long flags;
emu = midi->emu;
- snd_assert(emu, return -ENXIO);
+ if (snd_BUG_ON(!emu))
+ return -ENXIO;
spin_lock_irqsave(&midi->open_lock, flags);
midi->midi_mode |= EMU10K1_MIDI_MODE_OUTPUT;
midi->substream_output = substream;
@@ -210,7 +212,8 @@ static int snd_emu10k1_midi_input_close(struct snd_rawmidi_substream *substream)
int err = 0;
emu = midi->emu;
- snd_assert(emu, return -ENXIO);
+ if (snd_BUG_ON(!emu))
+ return -ENXIO;
spin_lock_irqsave(&midi->open_lock, flags);
snd_emu10k1_intr_disable(emu, midi->rx_enable);
midi->midi_mode &= ~EMU10K1_MIDI_MODE_INPUT;
@@ -232,7 +235,8 @@ static int snd_emu10k1_midi_output_close(struct snd_rawmidi_substream *substream
int err = 0;
emu = midi->emu;
- snd_assert(emu, return -ENXIO);
+ if (snd_BUG_ON(!emu))
+ return -ENXIO;
spin_lock_irqsave(&midi->open_lock, flags);
snd_emu10k1_intr_disable(emu, midi->tx_enable);
midi->midi_mode &= ~EMU10K1_MIDI_MODE_OUTPUT;
@@ -251,7 +255,8 @@ static void snd_emu10k1_midi_input_trigger(struct snd_rawmidi_substream *substre
struct snd_emu10k1 *emu;
struct snd_emu10k1_midi *midi = (struct snd_emu10k1_midi *)substream->rmidi->private_data;
emu = midi->emu;
- snd_assert(emu, return);
+ if (snd_BUG_ON(!emu))
+ return;
if (up)
snd_emu10k1_intr_enable(emu, midi->rx_enable);
@@ -266,7 +271,8 @@ static void snd_emu10k1_midi_output_trigger(struct snd_rawmidi_substream *substr
unsigned long flags;
emu = midi->emu;
- snd_assert(emu, return);
+ if (snd_BUG_ON(!emu))
+ return;
if (up) {
int max = 4;
diff --git a/sound/pci/emu10k1/memory.c b/sound/pci/emu10k1/memory.c
index 916c1dbcd53c..6a47672f930a 100644
--- a/sound/pci/emu10k1/memory.c
+++ b/sound/pci/emu10k1/memory.c
@@ -107,7 +107,8 @@ static int search_empty_map_area(struct snd_emu10k1 *emu, int npages, struct lis
list_for_each (pos, &emu->mapped_link_head) {
struct snd_emu10k1_memblk *blk = get_emu10k1_memblk(pos, mapped_link);
- snd_assert(blk->mapped_page >= 0, continue);
+ if (blk->mapped_page < 0)
+ continue;
size = blk->mapped_page - page;
if (size == npages) {
*nextp = pos;
@@ -295,15 +296,18 @@ struct snd_util_memblk *
snd_emu10k1_alloc_pages(struct snd_emu10k1 *emu, struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_sg_buf *sgbuf = snd_pcm_substream_sgbuf(substream);
struct snd_util_memhdr *hdr;
struct snd_emu10k1_memblk *blk;
int page, err, idx;
- snd_assert(emu, return NULL);
- snd_assert(runtime->dma_bytes > 0 && runtime->dma_bytes < MAXPAGES * EMUPAGESIZE, return NULL);
+ if (snd_BUG_ON(!emu))
+ return NULL;
+ if (snd_BUG_ON(runtime->dma_bytes <= 0 ||
+ runtime->dma_bytes >= MAXPAGES * EMUPAGESIZE))
+ return NULL;
hdr = emu->memhdr;
- snd_assert(hdr, return NULL);
+ if (snd_BUG_ON(!hdr))
+ return NULL;
mutex_lock(&hdr->block_mutex);
blk = search_empty(emu, runtime->dma_bytes);
@@ -316,16 +320,9 @@ snd_emu10k1_alloc_pages(struct snd_emu10k1 *emu, struct snd_pcm_substream *subst
*/
idx = 0;
for (page = blk->first_page; page <= blk->last_page; page++, idx++) {
+ unsigned long ofs = idx << PAGE_SHIFT;
dma_addr_t addr;
-#ifdef CONFIG_SND_DEBUG
- if (idx >= sgbuf->pages) {
- printk(KERN_ERR "emu: pages overflow! (%d-%d) for %d\n",
- blk->first_page, blk->last_page, sgbuf->pages);
- mutex_unlock(&hdr->block_mutex);
- return NULL;
- }
-#endif
- addr = sgbuf->table[idx].addr;
+ addr = snd_pcm_sgbuf_get_addr(substream, ofs);
if (! is_valid_page(emu, addr)) {
printk(KERN_ERR "emu: failure page = %d\n", idx);
mutex_unlock(&hdr->block_mutex);
@@ -353,7 +350,8 @@ snd_emu10k1_alloc_pages(struct snd_emu10k1 *emu, struct snd_pcm_substream *subst
*/
int snd_emu10k1_free_pages(struct snd_emu10k1 *emu, struct snd_util_memblk *blk)
{
- snd_assert(emu && blk, return -EINVAL);
+ if (snd_BUG_ON(!emu || !blk))
+ return -EINVAL;
return snd_emu10k1_synth_free(emu, blk);
}
@@ -437,43 +435,49 @@ static void get_single_page_range(struct snd_util_memhdr *hdr,
*last_page_ret = last_page;
}
+/* release allocated pages */
+static void __synth_free_pages(struct snd_emu10k1 *emu, int first_page,
+ int last_page)
+{
+ int page;
+
+ for (page = first_page; page <= last_page; page++) {
+ free_page((unsigned long)emu->page_ptr_table[page]);
+ emu->page_addr_table[page] = 0;
+ emu->page_ptr_table[page] = NULL;
+ }
+}
+
/*
* allocate kernel pages
*/
static int synth_alloc_pages(struct snd_emu10k1 *emu, struct snd_emu10k1_memblk *blk)
{
int page, first_page, last_page;
- struct snd_dma_buffer dmab;
emu10k1_memblk_init(blk);
get_single_page_range(emu->memhdr, blk, &first_page, &last_page);
/* allocate kernel pages */
for (page = first_page; page <= last_page; page++) {
- if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(emu->pci),
- PAGE_SIZE, &dmab) < 0)
- goto __fail;
- if (! is_valid_page(emu, dmab.addr)) {
- snd_dma_free_pages(&dmab);
- goto __fail;
+ /* first try to allocate from <4GB zone */
+ struct page *p = alloc_page(GFP_KERNEL | GFP_DMA32 |
+ __GFP_NOWARN);
+ if (!p || (page_to_pfn(p) & ~(emu->dma_mask >> PAGE_SHIFT))) {
+ if (p)
+ __free_page(p);
+ /* try to allocate from <16MB zone */
+ p = alloc_page(GFP_ATOMIC | GFP_DMA |
+ __GFP_NORETRY | /* no OOM-killer */
+ __GFP_NOWARN);
+ }
+ if (!p) {
+ __synth_free_pages(emu, first_page, page - 1);
+ return -ENOMEM;
}
- emu->page_addr_table[page] = dmab.addr;
- emu->page_ptr_table[page] = dmab.area;
+ emu->page_addr_table[page] = page_to_phys(p);
+ emu->page_ptr_table[page] = page_address(p);
}
return 0;
-
-__fail:
- /* release allocated pages */
- last_page = page - 1;
- for (page = first_page; page <= last_page; page++) {
- dmab.area = emu->page_ptr_table[page];
- dmab.addr = emu->page_addr_table[page];
- dmab.bytes = PAGE_SIZE;
- snd_dma_free_pages(&dmab);
- emu->page_addr_table[page] = 0;
- emu->page_ptr_table[page] = NULL;
- }
-
- return -ENOMEM;
}
/*
@@ -481,23 +485,10 @@ __fail:
*/
static int synth_free_pages(struct snd_emu10k1 *emu, struct snd_emu10k1_memblk *blk)
{
- int page, first_page, last_page;
- struct snd_dma_buffer dmab;
+ int first_page, last_page;
get_single_page_range(emu->memhdr, blk, &first_page, &last_page);
- dmab.dev.type = SNDRV_DMA_TYPE_DEV;
- dmab.dev.dev = snd_dma_pci_data(emu->pci);
- for (page = first_page; page <= last_page; page++) {
- if (emu->page_ptr_table[page] == NULL)
- continue;
- dmab.area = emu->page_ptr_table[page];
- dmab.addr = emu->page_addr_table[page];
- dmab.bytes = PAGE_SIZE;
- snd_dma_free_pages(&dmab);
- emu->page_addr_table[page] = 0;
- emu->page_ptr_table[page] = NULL;
- }
-
+ __synth_free_pages(emu, first_page, last_page);
return 0;
}
@@ -505,7 +496,8 @@ static int synth_free_pages(struct snd_emu10k1 *emu, struct snd_emu10k1_memblk *
static inline void *offset_ptr(struct snd_emu10k1 *emu, int page, int offset)
{
char *ptr;
- snd_assert(page >= 0 && page < emu->max_cache_pages, return NULL);
+ if (snd_BUG_ON(page < 0 || page >= emu->max_cache_pages))
+ return NULL;
ptr = emu->page_ptr_table[page];
if (! ptr) {
printk(KERN_ERR "emu10k1: access to NULL ptr: page = %d\n", page);
diff --git a/sound/pci/emu10k1/voice.c b/sound/pci/emu10k1/voice.c
index 958cb2a65a4e..d7300a1aa262 100644
--- a/sound/pci/emu10k1/voice.c
+++ b/sound/pci/emu10k1/voice.c
@@ -111,8 +111,10 @@ int snd_emu10k1_voice_alloc(struct snd_emu10k1 *emu, int type, int number,
unsigned long flags;
int result;
- snd_assert(rvoice != NULL, return -EINVAL);
- snd_assert(number, return -EINVAL);
+ if (snd_BUG_ON(!rvoice))
+ return -EINVAL;
+ if (snd_BUG_ON(!number))
+ return -EINVAL;
spin_lock_irqsave(&emu->voice_lock, flags);
for (;;) {
@@ -145,7 +147,8 @@ int snd_emu10k1_voice_free(struct snd_emu10k1 *emu,
{
unsigned long flags;
- snd_assert(pvoice != NULL, return -EINVAL);
+ if (snd_BUG_ON(!pvoice))
+ return -EINVAL;
spin_lock_irqsave(&emu->voice_lock, flags);
pvoice->interrupt = NULL;
pvoice->use = pvoice->pcm = pvoice->synth = pvoice->midi = pvoice->efx = 0;
diff --git a/sound/pci/ens1370.c b/sound/pci/ens1370.c
index fbf1124f7c79..9bf95367c882 100644
--- a/sound/pci/ens1370.c
+++ b/sound/pci/ens1370.c
@@ -522,7 +522,7 @@ static unsigned int snd_es1371_wait_src_ready(struct ensoniq * ensoniq)
return r;
cond_resched();
}
- snd_printk(KERN_ERR "wait source ready timeout 0x%lx [0x%x]\n",
+ snd_printk(KERN_ERR "wait src ready timeout 0x%lx [0x%x]\n",
ES_REG(ensoniq, 1371_SMPRATE), r);
return 0;
}
@@ -1629,6 +1629,7 @@ static int __devinit snd_ensoniq_1371_mixer(struct ensoniq *ensoniq,
memset(&ac97, 0, sizeof(ac97));
ac97.private_data = ensoniq;
ac97.private_free = snd_ensoniq_mixer_free_ac97;
+ ac97.pci = ensoniq->pci;
ac97.scaps = AC97_SCAP_AUDIO;
if ((err = snd_ac97_mixer(pbus, &ac97, &ensoniq->u.es1371.ac97)) < 0)
return err;
diff --git a/sound/pci/es1938.c b/sound/pci/es1938.c
index 84fac1fbf103..4cd9a1faaecc 100644
--- a/sound/pci/es1938.c
+++ b/sound/pci/es1938.c
@@ -860,7 +860,8 @@ static int snd_es1938_capture_copy(struct snd_pcm_substream *substream,
struct es1938 *chip = snd_pcm_substream_chip(substream);
pos <<= chip->dma1_shift;
count <<= chip->dma1_shift;
- snd_assert(pos + count <= chip->dma1_size, return -EINVAL);
+ if (snd_BUG_ON(pos + count > chip->dma1_size))
+ return -EINVAL;
if (pos + count < chip->dma1_size) {
if (copy_to_user(dst, runtime->dma_area + pos + 1, count))
return -EFAULT;
diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c
index 1bf298d214b9..20ee7599600b 100644
--- a/sound/pci/es1968.c
+++ b/sound/pci/es1968.c
@@ -692,7 +692,8 @@ static void apu_data_set(struct es1968 *chip, u16 data)
/* no spinlock */
static void __apu_set_register(struct es1968 *chip, u16 channel, u8 reg, u16 data)
{
- snd_assert(channel < NR_APUS, return);
+ if (snd_BUG_ON(channel >= NR_APUS))
+ return;
#ifdef CONFIG_PM
chip->apu_map[channel][reg] = data;
#endif
@@ -711,7 +712,8 @@ static void apu_set_register(struct es1968 *chip, u16 channel, u8 reg, u16 data)
static u16 __apu_get_register(struct es1968 *chip, u16 channel, u8 reg)
{
- snd_assert(channel < NR_APUS, return 0);
+ if (snd_BUG_ON(channel >= NR_APUS))
+ return 0;
reg |= (channel << 4);
apu_index_set(chip, reg);
return __maestro_read(chip, IDR0_DATA_PORT);
diff --git a/sound/pci/hda/Makefile b/sound/pci/hda/Makefile
index ab0c726d648e..1980c6d207e7 100644
--- a/sound/pci/hda/Makefile
+++ b/sound/pci/hda/Makefile
@@ -5,6 +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_INPUT_BEEP) += hda_beep.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
@@ -14,5 +15,6 @@ 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
+snd-hda-intel-$(CONFIG_SND_HDA_CODEC_NVHDMI) += patch_nvhdmi.o
obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-intel.o
diff --git a/sound/pci/hda/hda_beep.c b/sound/pci/hda/hda_beep.c
new file mode 100644
index 000000000000..9b77b3e0fa98
--- /dev/null
+++ b/sound/pci/hda/hda_beep.c
@@ -0,0 +1,134 @@
+/*
+ * Digital Beep Input Interface for HD-audio codec
+ *
+ * Author: Matthew Ranostay <mranostay@embeddedalley.com>
+ * Copyright (c) 2008 Embedded Alley Solutions Inc
+ *
+ * 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 <linux/input.h>
+#include <linux/pci.h>
+#include <linux/workqueue.h>
+#include <sound/core.h>
+#include "hda_beep.h"
+
+enum {
+ DIGBEEP_HZ_STEP = 46875, /* 46.875 Hz */
+ DIGBEEP_HZ_MIN = 93750, /* 93.750 Hz */
+ DIGBEEP_HZ_MAX = 12000000, /* 12 KHz */
+};
+
+static void snd_hda_generate_beep(struct work_struct *work)
+{
+ struct hda_beep *beep =
+ container_of(work, struct hda_beep, beep_work);
+ struct hda_codec *codec = beep->codec;
+
+ /* generate tone */
+ snd_hda_codec_write_cache(codec, beep->nid, 0,
+ AC_VERB_SET_BEEP_CONTROL, beep->tone);
+}
+
+static int snd_hda_beep_event(struct input_dev *dev, unsigned int type,
+ unsigned int code, int hz)
+{
+ struct hda_beep *beep = input_get_drvdata(dev);
+
+ switch (code) {
+ case SND_BELL:
+ if (hz)
+ hz = 1000;
+ case SND_TONE:
+ hz *= 1000; /* fixed point */
+ hz = hz - DIGBEEP_HZ_MIN;
+ if (hz < 0)
+ hz = 0; /* turn off PC beep*/
+ else if (hz >= (DIGBEEP_HZ_MAX - DIGBEEP_HZ_MIN))
+ hz = 0xff;
+ else {
+ hz /= DIGBEEP_HZ_STEP;
+ hz++;
+ }
+ break;
+ default:
+ return -1;
+ }
+ beep->tone = hz;
+
+ /* schedule beep event */
+ schedule_work(&beep->beep_work);
+ return 0;
+}
+
+int snd_hda_attach_beep_device(struct hda_codec *codec, int nid)
+{
+ struct input_dev *input_dev;
+ struct hda_beep *beep;
+ int err;
+
+ beep = kzalloc(sizeof(*beep), GFP_KERNEL);
+ if (beep == NULL)
+ return -ENOMEM;
+ snprintf(beep->phys, sizeof(beep->phys),
+ "card%d/codec#%d/beep0", codec->bus->card->number, codec->addr);
+ input_dev = input_allocate_device();
+
+ /* setup digital beep device */
+ input_dev->name = "HDA Digital PCBeep";
+ input_dev->phys = beep->phys;
+ input_dev->id.bustype = BUS_PCI;
+
+ input_dev->id.vendor = codec->vendor_id >> 16;
+ input_dev->id.product = codec->vendor_id & 0xffff;
+ input_dev->id.version = 0x01;
+
+ input_dev->evbit[0] = BIT_MASK(EV_SND);
+ input_dev->sndbit[0] = BIT_MASK(SND_BELL) | BIT_MASK(SND_TONE);
+ input_dev->event = snd_hda_beep_event;
+ input_dev->dev.parent = &codec->bus->pci->dev;
+ input_set_drvdata(input_dev, beep);
+
+ err = input_register_device(input_dev);
+ if (err < 0) {
+ input_free_device(input_dev);
+ kfree(beep);
+ return err;
+ }
+
+ /* enable linear scale */
+ snd_hda_codec_write(codec, nid, 0,
+ AC_VERB_SET_DIGI_CONVERT_2, 0x01);
+
+ beep->nid = nid;
+ beep->dev = input_dev;
+ beep->codec = codec;
+ codec->beep = beep;
+
+ INIT_WORK(&beep->beep_work, &snd_hda_generate_beep);
+ return 0;
+}
+
+void snd_hda_detach_beep_device(struct hda_codec *codec)
+{
+ struct hda_beep *beep = codec->beep;
+ if (beep) {
+ cancel_work_sync(&beep->beep_work);
+ flush_scheduled_work();
+
+ input_unregister_device(beep->dev);
+ kfree(beep);
+ }
+}
diff --git a/sound/pci/hda/hda_beep.h b/sound/pci/hda/hda_beep.h
new file mode 100644
index 000000000000..de4036e6e710
--- /dev/null
+++ b/sound/pci/hda/hda_beep.h
@@ -0,0 +1,44 @@
+/*
+ * Digital Beep Input Interface for HD-audio codec
+ *
+ * Author: Matthew Ranostay <mranostay@embeddedalley.com>
+ * Copyright (c) 2008 Embedded Alley Solutions Inc
+ *
+ * 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
+ */
+
+#ifndef __SOUND_HDA_BEEP_H
+#define __SOUND_HDA_BEEP_H
+
+#include "hda_codec.h"
+
+/* beep information */
+struct hda_beep {
+ struct input_dev *dev;
+ struct hda_codec *codec;
+ char phys[32];
+ int tone;
+ int nid;
+ struct work_struct beep_work; /* scheduled task for beep event */
+};
+
+#ifdef CONFIG_SND_HDA_INPUT_BEEP
+int snd_hda_attach_beep_device(struct hda_codec *codec, int nid);
+void snd_hda_detach_beep_device(struct hda_codec *codec);
+#else
+#define snd_hda_attach_beep_device(...)
+#define snd_hda_detach_beep_device(...)
+#endif
+#endif
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index a6be6e3e8716..6447754ae56e 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -94,6 +94,9 @@ static const struct hda_codec_preset *hda_preset_tables[] = {
#ifdef CONFIG_SND_HDA_CODEC_VIA
snd_hda_preset_via,
#endif
+#ifdef CONFIG_SND_HDA_CODEC_NVHDMI
+ snd_hda_preset_nvhdmi,
+#endif
NULL
};
@@ -211,7 +214,8 @@ int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid,
unsigned int shift, num_elems, mask;
hda_nid_t prev_nid;
- snd_assert(conn_list && max_conns > 0, return -EINVAL);
+ if (snd_BUG_ON(!conn_list || max_conns <= 0))
+ return -EINVAL;
parm = snd_hda_param_read(codec, nid, AC_PAR_CONNLIST_LEN);
if (parm & AC_CLIST_LONG) {
@@ -313,7 +317,7 @@ int snd_hda_queue_unsol_event(struct hda_bus *bus, u32 res, u32 res_ex)
}
/*
- * process queueud unsolicited events
+ * process queued unsolicited events
*/
static void process_unsol_events(struct work_struct *work)
{
@@ -407,8 +411,10 @@ int __devinit snd_hda_bus_new(struct snd_card *card,
.dev_free = snd_hda_bus_dev_free,
};
- snd_assert(temp, return -EINVAL);
- snd_assert(temp->ops.command && temp->ops.get_response, return -EINVAL);
+ if (snd_BUG_ON(!temp))
+ return -EINVAL;
+ if (snd_BUG_ON(!temp->ops.command || !temp->ops.get_response))
+ return -EINVAL;
if (busp)
*busp = NULL;
@@ -585,11 +591,13 @@ int __devinit snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr,
struct hda_codec **codecp)
{
struct hda_codec *codec;
- char component[13];
+ char component[31];
int err;
- snd_assert(bus, return -EINVAL);
- snd_assert(codec_addr <= HDA_MAX_CODEC_ADDRESS, return -EINVAL);
+ if (snd_BUG_ON(!bus))
+ return -EINVAL;
+ if (snd_BUG_ON(codec_addr > HDA_MAX_CODEC_ADDRESS))
+ return -EINVAL;
if (bus->caddr_tbl[codec_addr]) {
snd_printk(KERN_ERR "hda_codec: "
@@ -688,7 +696,7 @@ int __devinit snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr,
snd_hda_create_hwdep(codec);
#endif
- sprintf(component, "HDA:%08x", codec->vendor_id);
+ sprintf(component, "HDA:%08x,%08x,%08x", codec->vendor_id, codec->subsystem_id, codec->revision_id);
snd_component_add(codec->bus->card, component);
if (codecp)
@@ -956,15 +964,6 @@ void snd_hda_codec_resume_amp(struct hda_codec *codec)
}
#endif /* SND_HDA_NEEDS_RESUME */
-/*
- * AMP control callbacks
- */
-/* retrieve parameters from private_value */
-#define get_amp_nid(kc) ((kc)->private_value & 0xffff)
-#define get_amp_channels(kc) (((kc)->private_value >> 16) & 0x3)
-#define get_amp_direction(kc) (((kc)->private_value >> 18) & 0x1)
-#define get_amp_index(kc) (((kc)->private_value >> 19) & 0xf)
-
/* volume */
int snd_hda_mixer_amp_volume_info(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *uinfo)
@@ -1430,6 +1429,29 @@ static unsigned int convert_to_spdif_status(unsigned short val)
return sbits;
}
+/* set digital convert verbs both for the given NID and its slaves */
+static void set_dig_out(struct hda_codec *codec, hda_nid_t nid,
+ int verb, int val)
+{
+ hda_nid_t *d;
+
+ snd_hda_codec_write(codec, nid, 0, verb, val);
+ d = codec->slave_dig_outs;
+ if (!d)
+ return;
+ for (; *d; d++)
+ snd_hda_codec_write(codec, *d, 0, verb, val);
+}
+
+static inline void set_dig_out_convert(struct hda_codec *codec, hda_nid_t nid,
+ int dig1, int dig2)
+{
+ if (dig1 != -1)
+ set_dig_out(codec, nid, AC_VERB_SET_DIGI_CONVERT_1, dig1);
+ if (dig2 != -1)
+ set_dig_out(codec, nid, AC_VERB_SET_DIGI_CONVERT_2, dig2);
+}
+
static int snd_hda_spdif_default_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
@@ -1448,14 +1470,8 @@ static int snd_hda_spdif_default_put(struct snd_kcontrol *kcontrol,
change = codec->spdif_ctls != val;
codec->spdif_ctls = val;
- 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);
- }
+ if (change)
+ set_dig_out_convert(codec, nid, val & 0xff, (val >> 8) & 0xff);
mutex_unlock(&codec->spdif_mutex);
return change;
@@ -1487,9 +1503,7 @@ static int snd_hda_spdif_out_switch_put(struct snd_kcontrol *kcontrol,
change = codec->spdif_ctls != val;
if (change) {
codec->spdif_ctls = val;
- snd_hda_codec_write_cache(codec, nid, 0,
- AC_VERB_SET_DIGI_CONVERT_1,
- val & 0xff);
+ set_dig_out_convert(codec, nid, val & 0xff, -1);
/* unmute amp switch (if any) */
if ((get_wcaps(codec, nid) & AC_WCAP_OUT_AMP) &&
(val & AC_DIG1_ENABLE))
@@ -2236,11 +2250,13 @@ static int __devinit set_pcm_default_values(struct hda_codec *codec,
if (info->ops.close == NULL)
info->ops.close = hda_pcm_default_open_close;
if (info->ops.prepare == NULL) {
- snd_assert(info->nid, return -EINVAL);
+ if (snd_BUG_ON(!info->nid))
+ return -EINVAL;
info->ops.prepare = hda_pcm_default_prepare;
}
if (info->ops.cleanup == NULL) {
- snd_assert(info->nid, return -EINVAL);
+ if (snd_BUG_ON(!info->nid))
+ return -EINVAL;
info->ops.cleanup = hda_pcm_default_cleanup;
}
return 0;
@@ -2335,7 +2351,7 @@ int snd_hda_check_board_config(struct hda_codec *codec,
if (!tbl)
return -1;
if (tbl->value >= 0 && tbl->value < num_configs) {
-#ifdef CONFIG_SND_DEBUG_DETECT
+#ifdef CONFIG_SND_DEBUG_VERBOSE
char tmp[10];
const char *model = NULL;
if (models)
@@ -2583,14 +2599,31 @@ static void setup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid,
unsigned int stream_tag, unsigned int format)
{
/* turn off SPDIF once; otherwise the IEC958 bits won't be updated */
- if (codec->spdif_ctls & AC_DIG1_ENABLE)
- snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
- codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff);
+ if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE))
+ set_dig_out_convert(codec, nid,
+ codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff,
+ -1);
snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format);
+ if (codec->slave_dig_outs) {
+ hda_nid_t *d;
+ for (d = codec->slave_dig_outs; *d; d++)
+ snd_hda_codec_setup_stream(codec, *d, stream_tag, 0,
+ format);
+ }
/* turn on again (if needed) */
- if (codec->spdif_ctls & AC_DIG1_ENABLE)
- snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
- codec->spdif_ctls & 0xff);
+ if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE))
+ set_dig_out_convert(codec, nid,
+ codec->spdif_ctls & 0xff, -1);
+}
+
+static void cleanup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid)
+{
+ snd_hda_codec_cleanup_stream(codec, nid);
+ if (codec->slave_dig_outs) {
+ hda_nid_t *d;
+ for (d = codec->slave_dig_outs; *d; d++)
+ snd_hda_codec_cleanup_stream(codec, *d);
+ }
}
/*
@@ -2602,7 +2635,7 @@ int snd_hda_multi_out_dig_open(struct hda_codec *codec,
mutex_lock(&codec->spdif_mutex);
if (mout->dig_out_used == HDA_DIG_ANALOG_DUP)
/* already opened as analog dup; reset it once */
- snd_hda_codec_cleanup_stream(codec, mout->dig_out_nid);
+ cleanup_dig_out_stream(codec, mout->dig_out_nid);
mout->dig_out_used = HDA_DIG_EXCLUSIVE;
mutex_unlock(&codec->spdif_mutex);
return 0;
@@ -2697,7 +2730,7 @@ int snd_hda_multi_out_analog_prepare(struct hda_codec *codec,
stream_tag, format);
} else {
mout->dig_out_used = 0;
- snd_hda_codec_cleanup_stream(codec, mout->dig_out_nid);
+ cleanup_dig_out_stream(codec, mout->dig_out_nid);
}
}
mutex_unlock(&codec->spdif_mutex);
@@ -2748,7 +2781,7 @@ int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec,
mout->extra_out_nid[i]);
mutex_lock(&codec->spdif_mutex);
if (mout->dig_out_nid && mout->dig_out_used == HDA_DIG_ANALOG_DUP) {
- snd_hda_codec_cleanup_stream(codec, mout->dig_out_nid);
+ cleanup_dig_out_stream(codec, mout->dig_out_nid);
mout->dig_out_used = 0;
}
mutex_unlock(&codec->spdif_mutex);
@@ -2756,7 +2789,7 @@ int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec,
}
/*
- * Helper for automatic ping configuration
+ * Helper for automatic pin configuration
*/
static int is_in_nid_list(hda_nid_t nid, hda_nid_t *list)
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index dcd390b2bbaa..60468f562400 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -78,7 +78,7 @@ enum {
#define AC_VERB_GET_BEEP_CONTROL 0x0f0a
#define AC_VERB_GET_EAPD_BTLENABLE 0x0f0c
#define AC_VERB_GET_DIGI_CONVERT_1 0x0f0d
-#define AC_VERB_GET_DIGI_CONVERT_2 0x0f0e
+#define AC_VERB_GET_DIGI_CONVERT_2 0x0f0e /* unused */
#define AC_VERB_GET_VOLUME_KNOB_CONTROL 0x0f0f
/* f10-f1a: GPIO */
#define AC_VERB_GET_GPIO_DATA 0x0f15
@@ -90,6 +90,14 @@ enum {
#define AC_VERB_GET_CONFIG_DEFAULT 0x0f1c
/* f20: AFG/MFG */
#define AC_VERB_GET_SUBSYSTEM_ID 0x0f20
+#define AC_VERB_GET_CVT_CHAN_COUNT 0x0f2d
+#define AC_VERB_GET_HDMI_DIP_SIZE 0x0f2e
+#define AC_VERB_GET_HDMI_ELDD 0x0f2f
+#define AC_VERB_GET_HDMI_DIP_INDEX 0x0f30
+#define AC_VERB_GET_HDMI_DIP_DATA 0x0f31
+#define AC_VERB_GET_HDMI_DIP_XMIT 0x0f32
+#define AC_VERB_GET_HDMI_CP_CTRL 0x0f33
+#define AC_VERB_GET_HDMI_CHAN_SLOT 0x0f34
/*
* SET verbs
@@ -121,7 +129,14 @@ enum {
#define AC_VERB_SET_CONFIG_DEFAULT_BYTES_1 0x71d
#define AC_VERB_SET_CONFIG_DEFAULT_BYTES_2 0x71e
#define AC_VERB_SET_CONFIG_DEFAULT_BYTES_3 0x71f
+#define AC_VERB_SET_EAPD 0x788
#define AC_VERB_SET_CODEC_RESET 0x7ff
+#define AC_VERB_SET_CVT_CHAN_COUNT 0x72d
+#define AC_VERB_SET_HDMI_DIP_INDEX 0x730
+#define AC_VERB_SET_HDMI_DIP_DATA 0x731
+#define AC_VERB_SET_HDMI_DIP_XMIT 0x732
+#define AC_VERB_SET_HDMI_CP_CTRL 0x733
+#define AC_VERB_SET_HDMI_CHAN_SLOT 0x734
/*
* Parameter IDs
@@ -143,6 +158,7 @@ enum {
#define AC_PAR_GPIO_CAP 0x11
#define AC_PAR_AMP_OUT_CAP 0x12
#define AC_PAR_VOL_KNB_CAP 0x13
+#define AC_PAR_HDMI_LPCM_CAP 0x20
/*
* AC_VERB_PARAMETERS results (32bit)
@@ -171,6 +187,8 @@ enum {
#define AC_WCAP_DIGITAL (1<<9) /* digital I/O */
#define AC_WCAP_POWER (1<<10) /* power control */
#define AC_WCAP_LR_SWAP (1<<11) /* L/R swap */
+#define AC_WCAP_CP_CAPS (1<<12) /* content protection */
+#define AC_WCAP_CHAN_CNT_EXT (7<<13) /* channel count ext */
#define AC_WCAP_DELAY (0xf<<16)
#define AC_WCAP_DELAY_SHIFT 16
#define AC_WCAP_TYPE (0xf<<20)
@@ -206,9 +224,20 @@ enum {
/* Input converter SDI select */
#define AC_SDI_SELECT (0xf<<0)
-/* Unsolicited response */
+/* Unsolicited response control */
#define AC_UNSOL_TAG (0x3f<<0)
#define AC_UNSOL_ENABLED (1<<7)
+#define AC_USRSP_EN AC_UNSOL_ENABLED
+
+/* Unsolicited responses */
+#define AC_UNSOL_RES_TAG (0x3f<<26)
+#define AC_UNSOL_RES_TAG_SHIFT 26
+#define AC_UNSOL_RES_SUBTAG (0x1f<<21)
+#define AC_UNSOL_RES_SUBTAG_SHIFT 21
+#define AC_UNSOL_RES_ELDV (1<<1) /* ELD Data valid (for HDMI) */
+#define AC_UNSOL_RES_PD (1<<0) /* pinsense detect */
+#define AC_UNSOL_RES_CP_STATE (1<<1) /* content protection */
+#define AC_UNSOL_RES_CP_READY (1<<0) /* content protection */
/* Pin widget capabilies */
#define AC_PINCAP_IMP_SENSE (1<<0) /* impedance sense capable */
@@ -222,6 +251,10 @@ enum {
* but is marked reserved in the Intel HDA specification.
*/
#define AC_PINCAP_LR_SWAP (1<<7) /* L/R swap */
+/* Note: The same bit as LR_SWAP is newly defined as HDMI capability
+ * in HD-audio specification
+ */
+#define AC_PINCAP_HDMI (1<<7) /* HDMI pin */
#define AC_PINCAP_VREF (0x37<<8)
#define AC_PINCAP_VREF_SHIFT 8
#define AC_PINCAP_EAPD (1<<16) /* EAPD capable */
@@ -272,6 +305,22 @@ enum {
#define AC_KNBCAP_NUM_STEPS (0x7f<<0)
#define AC_KNBCAP_DELTA (1<<7)
+/* HDMI LPCM capabilities */
+#define AC_LPCMCAP_48K_CP_CHNS (0x0f<<0) /* max channels w/ CP-on */
+#define AC_LPCMCAP_48K_NO_CHNS (0x0f<<4) /* max channels w/o CP-on */
+#define AC_LPCMCAP_48K_20BIT (1<<8) /* 20b bitrate supported */
+#define AC_LPCMCAP_48K_24BIT (1<<9) /* 24b bitrate supported */
+#define AC_LPCMCAP_96K_CP_CHNS (0x0f<<10) /* max channels w/ CP-on */
+#define AC_LPCMCAP_96K_NO_CHNS (0x0f<<14) /* max channels w/o CP-on */
+#define AC_LPCMCAP_96K_20BIT (1<<18) /* 20b bitrate supported */
+#define AC_LPCMCAP_96K_24BIT (1<<19) /* 24b bitrate supported */
+#define AC_LPCMCAP_192K_CP_CHNS (0x0f<<20) /* max channels w/ CP-on */
+#define AC_LPCMCAP_192K_NO_CHNS (0x0f<<24) /* max channels w/o CP-on */
+#define AC_LPCMCAP_192K_20BIT (1<<28) /* 20b bitrate supported */
+#define AC_LPCMCAP_192K_24BIT (1<<29) /* 24b bitrate supported */
+#define AC_LPCMCAP_44K (1<<30) /* 44.1kHz support */
+#define AC_LPCMCAP_44K_MS (1<<31) /* 44.1kHz-multiplies support */
+
/*
* Control Parameters
*/
@@ -317,18 +366,44 @@ enum {
#define AC_PINCTL_OUT_EN (1<<6)
#define AC_PINCTL_HP_EN (1<<7)
-/* Unsolicited response - 8bit */
-#define AC_USRSP_EN (1<<7)
-
/* Pin sense - 32bit */
#define AC_PINSENSE_IMPEDANCE_MASK (0x7fffffff)
#define AC_PINSENSE_PRESENCE (1<<31)
+#define AC_PINSENSE_ELDV (1<<30) /* ELD valid (HDMI) */
/* EAPD/BTL enable - 32bit */
#define AC_EAPDBTL_BALANCED (1<<0)
#define AC_EAPDBTL_EAPD (1<<1)
#define AC_EAPDBTL_LR_SWAP (1<<2)
+/* HDMI ELD data */
+#define AC_ELDD_ELD_VALID (1<<31)
+#define AC_ELDD_ELD_DATA 0xff
+
+/* HDMI DIP size */
+#define AC_DIPSIZE_ELD_BUF (1<<3) /* ELD buf size of packet size */
+#define AC_DIPSIZE_PACK_IDX (0x07<<0) /* packet index */
+
+/* HDMI DIP index */
+#define AC_DIPIDX_PACK_IDX (0x07<<5) /* packet idnex */
+#define AC_DIPIDX_BYTE_IDX (0x1f<<0) /* byte index */
+
+/* HDMI DIP xmit (transmit) control */
+#define AC_DIPXMIT_MASK (0x3<<6)
+#define AC_DIPXMIT_DISABLE (0x0<<6) /* disable xmit */
+#define AC_DIPXMIT_ONCE (0x2<<6) /* xmit once then disable */
+#define AC_DIPXMIT_BEST (0x3<<6) /* best effort */
+
+/* HDMI content protection (CP) control */
+#define AC_CPCTRL_CES (1<<9) /* current encryption state */
+#define AC_CPCTRL_READY (1<<8) /* ready bit */
+#define AC_CPCTRL_SUBTAG (0x1f<<3) /* subtag for unsol-resp */
+#define AC_CPCTRL_STATE (3<<0) /* current CP request state */
+
+/* Converter channel <-> HDMI slot mapping */
+#define AC_CVTMAP_HDMI_SLOT (0xf<<0) /* HDMI slot number */
+#define AC_CVTMAP_CHAN (0xf<<4) /* converter channel number */
+
/* configuration default - 32bit */
#define AC_DEFCFG_SEQUENCE (0xf<<0)
#define AC_DEFCFG_DEF_ASSOC (0xf<<4)
@@ -449,6 +524,7 @@ enum {
*/
struct hda_bus;
+struct hda_beep;
struct hda_codec;
struct hda_pcm;
struct hda_pcm_stream;
@@ -634,6 +710,9 @@ struct hda_codec {
/* codec specific info */
void *spec;
+ /* beep device */
+ struct hda_beep *beep;
+
/* widget capabilities cache */
unsigned int num_nodes;
hda_nid_t start_nid;
@@ -646,9 +725,15 @@ 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? */
+ hda_nid_t *slave_dig_outs; /* optional digital out slave widgets */
struct snd_hwdep *hwdep; /* assigned hwdep device */
+ /* misc flags */
+ unsigned int spdif_status_reset :1; /* needs to toggle SPDIF for each
+ * status change
+ * (e.g. Realtek codecs)
+ */
#ifdef CONFIG_SND_HDA_POWER_SAVE
unsigned int power_on :1; /* current (global) power-state */
unsigned int power_transition :1; /* power-state in transition */
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
index 59e4389c94a4..0ca30894f7c6 100644
--- a/sound/pci/hda/hda_generic.c
+++ b/sound/pci/hda/hda_generic.c
@@ -174,7 +174,8 @@ static int build_afg_tree(struct hda_codec *codec)
int i, nodes, err;
hda_nid_t nid;
- snd_assert(spec, return -EINVAL);
+ if (snd_BUG_ON(!spec))
+ return -EINVAL;
spec->def_amp_out_caps = snd_hda_param_read(codec, codec->afg, AC_PAR_AMP_OUT_CAP);
spec->def_amp_in_caps = snd_hda_param_read(codec, codec->afg, AC_PAR_AMP_IN_CAP);
diff --git a/sound/pci/hda/hda_hwdep.c b/sound/pci/hda/hda_hwdep.c
index 2177d9af5334..6e18a422d993 100644
--- a/sound/pci/hda/hda_hwdep.c
+++ b/sound/pci/hda/hda_hwdep.c
@@ -88,7 +88,7 @@ static int hda_hwdep_ioctl_compat(struct snd_hwdep *hw, struct file *file,
static int hda_hwdep_open(struct snd_hwdep *hw, struct file *file)
{
-#ifndef CONFIG_SND_DEBUG_DETECT
+#ifndef CONFIG_SND_DEBUG_VERBOSE
if (!capable(CAP_SYS_RAWIO))
return -EACCES;
#endif
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index b3a618eb42cd..9f316c1b2790 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -55,6 +55,7 @@ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
static char *model[SNDRV_CARDS];
static int position_fix[SNDRV_CARDS];
+static int bdl_pos_adj[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = -1};
static int probe_mask[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = -1};
static int single_cmd;
static int enable_msi;
@@ -69,7 +70,9 @@ module_param_array(model, charp, NULL, 0444);
MODULE_PARM_DESC(model, "Use the given board model.");
module_param_array(position_fix, int, NULL, 0444);
MODULE_PARM_DESC(position_fix, "Fix DMA pointer "
- "(0 = auto, 1 = none, 2 = POSBUF, 3 = FIFO size).");
+ "(0 = auto, 1 = none, 2 = POSBUF).");
+module_param_array(bdl_pos_adj, int, NULL, 0644);
+MODULE_PARM_DESC(bdl_pos_adj, "BDL position adjustment offset.");
module_param_array(probe_mask, int, NULL, 0444);
MODULE_PARM_DESC(probe_mask, "Bitmask to probe codecs (default = -1).");
module_param(single_cmd, bool, 0444);
@@ -98,6 +101,7 @@ MODULE_SUPPORTED_DEVICE("{{Intel, ICH6},"
"{Intel, ICH8},"
"{Intel, ICH9},"
"{Intel, ICH10},"
+ "{Intel, PCH},"
"{Intel, SCH},"
"{ATI, SB450},"
"{ATI, SB600},"
@@ -197,6 +201,10 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 };
#define ATIHDMI_NUM_CAPTURE 0
#define ATIHDMI_NUM_PLAYBACK 1
+/* TERA has 4 playback and 3 capture */
+#define TERA_NUM_CAPTURE 3
+#define TERA_NUM_PLAYBACK 4
+
/* this number is statically defined for simplicity */
#define MAX_AZX_DEV 16
@@ -214,9 +222,9 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 };
#define RIRB_INT_OVERRUN 0x04
#define RIRB_INT_MASK 0x05
-/* STATESTS int mask: SD2,SD1,SD0 */
-#define AZX_MAX_CODECS 3
-#define STATESTS_INT_MASK 0x07
+/* STATESTS int mask: S3,SD2,SD1,SD0 */
+#define AZX_MAX_CODECS 4
+#define STATESTS_INT_MASK 0x0f
/* SD_CTL bits */
#define SD_CTL_STREAM_RESET 0x01 /* stream reset bit */
@@ -259,9 +267,8 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 };
/* position fix mode */
enum {
POS_FIX_AUTO,
- POS_FIX_NONE,
+ POS_FIX_LPIB,
POS_FIX_POSBUF,
- POS_FIX_FIFO,
};
/* Defines for ATI HD Audio support in SB450 south bridge */
@@ -271,11 +278,19 @@ enum {
/* Defines for Nvidia HDA support */
#define NVIDIA_HDA_TRANSREG_ADDR 0x4e
#define NVIDIA_HDA_ENABLE_COHBITS 0x0f
+#define NVIDIA_HDA_ISTRM_COH 0x4d
+#define NVIDIA_HDA_OSTRM_COH 0x4c
+#define NVIDIA_HDA_ENABLE_COHBIT 0x01
/* Defines for Intel SCH HDA snoop control */
#define INTEL_SCH_HDA_DEVC 0x78
#define INTEL_SCH_HDA_DEVC_NOSNOOP (0x1<<11)
+/* Define IN stream 0 FIFO size offset in VIA controller */
+#define VIA_IN_STREAM0_FIFO_SIZE_OFFSET 0x90
+/* Define VIA HD Audio Device ID*/
+#define VIA_HDAC_DEVICE_ID 0x3288
+
/*
*/
@@ -285,6 +300,7 @@ struct azx_dev {
u32 *posbuf; /* position buffer pointer */
unsigned int bufsize; /* size of the play buffer in bytes */
+ unsigned int period_bytes; /* size of the period in bytes */
unsigned int frags; /* number for period in the play buffer */
unsigned int fifo_size; /* FIFO size */
@@ -301,11 +317,17 @@ struct azx_dev {
*/
unsigned char stream_tag; /* assigned stream */
unsigned char index; /* stream index */
- /* for sanity check of position buffer */
- unsigned int period_intr;
unsigned int opened :1;
unsigned int running :1;
+ unsigned int irq_pending :1;
+ unsigned int irq_ignore :1;
+ /*
+ * For VIA:
+ * A flag to ensure DMA position is 0
+ * when link position is not greater than FIFO size
+ */
+ unsigned int insufficient :1;
};
/* CORB/RIRB */
@@ -323,6 +345,7 @@ struct azx_rb {
struct azx {
struct snd_card *card;
struct pci_dev *pci;
+ int dev_index;
/* chip type specific */
int driver_type;
@@ -366,9 +389,14 @@ struct azx {
unsigned int single_cmd :1;
unsigned int polling_mode :1;
unsigned int msi :1;
+ unsigned int irq_pending_warned :1;
+ unsigned int via_dmapos_patch :1; /* enable DMA-position fix for VIA */
/* for debugging */
unsigned int last_cmd; /* last issued command (to sync) */
+
+ /* for pending irqs */
+ struct work_struct irq_pending_work;
};
/* driver types */
@@ -381,6 +409,8 @@ enum {
AZX_DRIVER_SIS,
AZX_DRIVER_ULI,
AZX_DRIVER_NVIDIA,
+ AZX_DRIVER_TERA,
+ AZX_NUM_DRIVERS, /* keep this as last entry */
};
static char *driver_short_names[] __devinitdata = {
@@ -392,6 +422,7 @@ static char *driver_short_names[] __devinitdata = {
[AZX_DRIVER_SIS] = "HDA SIS966",
[AZX_DRIVER_ULI] = "HDA ULI M5461",
[AZX_DRIVER_NVIDIA] = "HDA NVidia",
+ [AZX_DRIVER_TERA] = "HDA Teradici",
};
/*
@@ -426,11 +457,6 @@ static char *driver_short_names[] __devinitdata = {
/* for pcm support */
#define get_azx_dev(substream) (substream->runtime->private_data)
-/* Get the upper 32bit of the given dma_addr_t
- * Compiler should optimize and eliminate the code if dma_addr_t is 32bit
- */
-#define upper_32bit(addr) (sizeof(addr) > 4 ? (u32)((addr) >> 32) : (u32)0)
-
static int azx_acquire_irq(struct azx *chip, int do_disconnect);
/*
@@ -461,7 +487,7 @@ static void azx_init_cmd_io(struct azx *chip)
chip->corb.addr = chip->rb.addr;
chip->corb.buf = (u32 *)chip->rb.area;
azx_writel(chip, CORBLBASE, (u32)chip->corb.addr);
- azx_writel(chip, CORBUBASE, upper_32bit(chip->corb.addr));
+ azx_writel(chip, CORBUBASE, upper_32_bits(chip->corb.addr));
/* set the corb size to 256 entries (ULI requires explicitly) */
azx_writeb(chip, CORBSIZE, 0x02);
@@ -476,7 +502,7 @@ static void azx_init_cmd_io(struct azx *chip)
chip->rirb.addr = chip->rb.addr + 2048;
chip->rirb.buf = (u32 *)(chip->rb.area + 2048);
azx_writel(chip, RIRBLBASE, (u32)chip->rirb.addr);
- azx_writel(chip, RIRBUBASE, upper_32bit(chip->rirb.addr));
+ azx_writel(chip, RIRBUBASE, upper_32_bits(chip->rirb.addr));
/* set the rirb size to 256 entries (ULI requires explicitly) */
azx_writeb(chip, RIRBSIZE, 0x02);
@@ -805,6 +831,11 @@ static void azx_int_clear(struct azx *chip)
/* start a stream */
static void azx_stream_start(struct azx *chip, struct azx_dev *azx_dev)
{
+ /*
+ * Before stream start, initialize parameter
+ */
+ azx_dev->insufficient = 1;
+
/* enable SIE */
azx_writeb(chip, INTCTL,
azx_readb(chip, INTCTL) | (1 << azx_dev->index));
@@ -847,7 +878,7 @@ static void azx_init_chip(struct azx *chip)
/* program the position buffer */
azx_writel(chip, DPLBASE, (u32)chip->posbuf.addr);
- azx_writel(chip, DPUBASE, upper_32bit(chip->posbuf.addr));
+ azx_writel(chip, DPUBASE, upper_32_bits(chip->posbuf.addr));
chip->initialized = 1;
}
@@ -890,6 +921,12 @@ static void azx_init_pci(struct azx *chip)
update_pci_byte(chip->pci,
NVIDIA_HDA_TRANSREG_ADDR,
0x0f, NVIDIA_HDA_ENABLE_COHBITS);
+ update_pci_byte(chip->pci,
+ NVIDIA_HDA_ISTRM_COH,
+ 0x01, NVIDIA_HDA_ENABLE_COHBIT);
+ update_pci_byte(chip->pci,
+ NVIDIA_HDA_OSTRM_COH,
+ 0x01, NVIDIA_HDA_ENABLE_COHBIT);
break;
case AZX_DRIVER_SCH:
pci_read_config_word(chip->pci, INTEL_SCH_HDA_DEVC, &snoop);
@@ -908,6 +945,8 @@ static void azx_init_pci(struct azx *chip)
}
+static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev);
+
/*
* interrupt handler
*/
@@ -930,11 +969,23 @@ static irqreturn_t azx_interrupt(int irq, void *dev_id)
azx_dev = &chip->azx_dev[i];
if (status & azx_dev->sd_int_sta_mask) {
azx_sd_writeb(azx_dev, SD_STS, SD_INT_MASK);
- if (azx_dev->substream && azx_dev->running) {
- azx_dev->period_intr++;
+ if (!azx_dev->substream || !azx_dev->running)
+ continue;
+ /* ignore the first dummy IRQ (due to pos_adj) */
+ if (azx_dev->irq_ignore) {
+ azx_dev->irq_ignore = 0;
+ continue;
+ }
+ /* check whether this IRQ is really acceptable */
+ if (azx_position_ok(chip, azx_dev)) {
+ azx_dev->irq_pending = 0;
spin_unlock(&chip->reg_lock);
snd_pcm_period_elapsed(azx_dev->substream);
spin_lock(&chip->reg_lock);
+ } else {
+ /* bogus IRQ, process it later */
+ azx_dev->irq_pending = 1;
+ schedule_work(&chip->irq_pending_work);
}
}
}
@@ -959,59 +1010,108 @@ static irqreturn_t azx_interrupt(int irq, void *dev_id)
/*
+ * set up a BDL entry
+ */
+static int setup_bdle(struct snd_pcm_substream *substream,
+ struct azx_dev *azx_dev, u32 **bdlp,
+ int ofs, int size, int with_ioc)
+{
+ u32 *bdl = *bdlp;
+
+ while (size > 0) {
+ dma_addr_t addr;
+ int chunk;
+
+ if (azx_dev->frags >= AZX_MAX_BDL_ENTRIES)
+ return -EINVAL;
+
+ addr = snd_pcm_sgbuf_get_addr(substream, ofs);
+ /* program the address field of the BDL entry */
+ bdl[0] = cpu_to_le32((u32)addr);
+ bdl[1] = cpu_to_le32(upper_32_bits(addr));
+ /* program the size field of the BDL entry */
+ chunk = snd_pcm_sgbuf_get_chunk_size(substream, ofs, size);
+ bdl[2] = cpu_to_le32(chunk);
+ /* program the IOC to enable interrupt
+ * only when the whole fragment is processed
+ */
+ size -= chunk;
+ bdl[3] = (size || !with_ioc) ? 0 : cpu_to_le32(0x01);
+ bdl += 4;
+ azx_dev->frags++;
+ ofs += chunk;
+ }
+ *bdlp = bdl;
+ return ofs;
+}
+
+/*
* set up BDL entries
*/
-static int azx_setup_periods(struct snd_pcm_substream *substream,
+static int azx_setup_periods(struct azx *chip,
+ struct snd_pcm_substream *substream,
struct azx_dev *azx_dev)
{
- struct snd_sg_buf *sgbuf = snd_pcm_substream_sgbuf(substream);
u32 *bdl;
int i, ofs, periods, period_bytes;
+ int pos_adj;
/* reset BDL address */
azx_sd_writel(azx_dev, SD_BDLPL, 0);
azx_sd_writel(azx_dev, SD_BDLPU, 0);
period_bytes = snd_pcm_lib_period_bytes(substream);
+ azx_dev->period_bytes = period_bytes;
periods = azx_dev->bufsize / period_bytes;
/* program the initial BDL entries */
bdl = (u32 *)azx_dev->bdl.area;
ofs = 0;
azx_dev->frags = 0;
- for (i = 0; i < periods; i++) {
- int size, rest;
- if (i >= AZX_MAX_BDL_ENTRIES) {
- snd_printk(KERN_ERR "Too many BDL entries: "
- "buffer=%d, period=%d\n",
- azx_dev->bufsize, period_bytes);
- /* reset */
- azx_sd_writel(azx_dev, SD_BDLPL, 0);
- azx_sd_writel(azx_dev, SD_BDLPU, 0);
- return -EINVAL;
+ azx_dev->irq_ignore = 0;
+ pos_adj = bdl_pos_adj[chip->dev_index];
+ if (pos_adj > 0) {
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ int pos_align = pos_adj;
+ pos_adj = (pos_adj * runtime->rate + 47999) / 48000;
+ if (!pos_adj)
+ pos_adj = pos_align;
+ else
+ pos_adj = ((pos_adj + pos_align - 1) / pos_align) *
+ pos_align;
+ pos_adj = frames_to_bytes(runtime, pos_adj);
+ if (pos_adj >= period_bytes) {
+ snd_printk(KERN_WARNING "Too big adjustment %d\n",
+ bdl_pos_adj[chip->dev_index]);
+ pos_adj = 0;
+ } else {
+ ofs = setup_bdle(substream, azx_dev,
+ &bdl, ofs, pos_adj, 1);
+ if (ofs < 0)
+ goto error;
+ azx_dev->irq_ignore = 1;
}
- rest = period_bytes;
- do {
- dma_addr_t addr = snd_pcm_sgbuf_get_addr(sgbuf, ofs);
- /* program the address field of the BDL entry */
- bdl[0] = cpu_to_le32((u32)addr);
- bdl[1] = cpu_to_le32(upper_32bit(addr));
- /* program the size field of the BDL entry */
- size = PAGE_SIZE - (ofs % PAGE_SIZE);
- if (rest < size)
- size = rest;
- bdl[2] = cpu_to_le32(size);
- /* program the IOC to enable interrupt
- * only when the whole fragment is processed
- */
- rest -= size;
- bdl[3] = rest ? 0 : cpu_to_le32(0x01);
- bdl += 4;
- azx_dev->frags++;
- ofs += size;
- } while (rest > 0);
+ } else
+ pos_adj = 0;
+ for (i = 0; i < periods; i++) {
+ if (i == periods - 1 && pos_adj)
+ ofs = setup_bdle(substream, azx_dev, &bdl, ofs,
+ period_bytes - pos_adj, 0);
+ else
+ ofs = setup_bdle(substream, azx_dev, &bdl, ofs,
+ period_bytes, 1);
+ if (ofs < 0)
+ goto error;
}
return 0;
+
+ error:
+ snd_printk(KERN_ERR "Too many BDL entries: buffer=%d, period=%d\n",
+ azx_dev->bufsize, period_bytes);
+ /* reset */
+ azx_sd_writel(azx_dev, SD_BDLPL, 0);
+ azx_sd_writel(azx_dev, SD_BDLPU, 0);
+ return -EINVAL;
}
/*
@@ -1062,11 +1162,12 @@ static int azx_setup_controller(struct azx *chip, struct azx_dev *azx_dev)
/* lower BDL address */
azx_sd_writel(azx_dev, SD_BDLPL, (u32)azx_dev->bdl.addr);
/* upper BDL address */
- azx_sd_writel(azx_dev, SD_BDLPU, upper_32bit(azx_dev->bdl.addr));
+ azx_sd_writel(azx_dev, SD_BDLPU, upper_32_bits(azx_dev->bdl.addr));
/* enable the position buffer */
if (chip->position_fix == POS_FIX_POSBUF ||
- chip->position_fix == POS_FIX_AUTO) {
+ chip->position_fix == POS_FIX_AUTO ||
+ chip->via_dmapos_patch) {
if (!(azx_readl(chip, DPLBASE) & ICH6_DPLBASE_ENABLE))
azx_writel(chip, DPLBASE,
(u32)chip->posbuf.addr | ICH6_DPLBASE_ENABLE);
@@ -1084,15 +1185,18 @@ static int azx_setup_controller(struct azx *chip, struct azx_dev *azx_dev)
* Codec initialization
*/
-static unsigned int azx_max_codecs[] __devinitdata = {
+/* number of codec slots for each chipset: 0 = default slots (i.e. 4) */
+static unsigned int azx_max_codecs[AZX_NUM_DRIVERS] __devinitdata = {
+ [AZX_DRIVER_TERA] = 1,
+};
+
+/* number of slots to probe as default
+ * this can be different from azx_max_codecs[] -- e.g. some boards
+ * report wrongly the non-existing 4th slot availability
+ */
+static unsigned int azx_default_codecs[AZX_NUM_DRIVERS] __devinitdata = {
[AZX_DRIVER_ICH] = 3,
- [AZX_DRIVER_SCH] = 3,
- [AZX_DRIVER_ATI] = 4,
- [AZX_DRIVER_ATIHDMI] = 4,
- [AZX_DRIVER_VIA] = 3, /* FIXME: correct? */
- [AZX_DRIVER_SIS] = 3, /* FIXME: correct? */
- [AZX_DRIVER_ULI] = 3, /* FIXME: correct? */
- [AZX_DRIVER_NVIDIA] = 3, /* FIXME: correct? */
+ [AZX_DRIVER_ATI] = 3,
};
static int __devinit azx_codec_create(struct azx *chip, const char *model,
@@ -1100,6 +1204,7 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model,
{
struct hda_bus_template bus_temp;
int c, codecs, audio_codecs, err;
+ int def_slots, max_slots;
memset(&bus_temp, 0, sizeof(bus_temp));
bus_temp.private_data = chip;
@@ -1115,8 +1220,17 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model,
if (err < 0)
return err;
+ if (chip->driver_type == AZX_DRIVER_NVIDIA)
+ chip->bus->needs_damn_long_delay = 1;
+
codecs = audio_codecs = 0;
- for (c = 0; c < AZX_MAX_CODECS; c++) {
+ max_slots = azx_max_codecs[chip->driver_type];
+ if (!max_slots)
+ max_slots = AZX_MAX_CODECS;
+ def_slots = azx_default_codecs[chip->driver_type];
+ if (!def_slots)
+ def_slots = max_slots;
+ for (c = 0; c < def_slots; c++) {
if ((chip->codec_mask & (1 << c)) & codec_probe_mask) {
struct hda_codec *codec;
err = snd_hda_codec_new(chip->bus, c, &codec);
@@ -1129,7 +1243,7 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model,
}
if (!audio_codecs) {
/* probe additional slots if no codec is found */
- for (; c < azx_max_codecs[chip->driver_type]; c++) {
+ for (; c < max_slots; c++) {
if ((chip->codec_mask & (1 << c)) & codec_probe_mask) {
err = snd_hda_codec_new(chip->bus, c, NULL);
if (err < 0)
@@ -1316,7 +1430,7 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream)
snd_printdd("azx_pcm_prepare: bufsize=0x%x, format=0x%x\n",
azx_dev->bufsize, azx_dev->format_val);
- if (azx_setup_periods(substream, azx_dev) < 0)
+ if (azx_setup_periods(chip, substream, azx_dev) < 0)
return -EINVAL;
azx_setup_controller(chip, azx_dev);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
@@ -1421,35 +1535,173 @@ static int azx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
return 0;
}
+/* get the current DMA position with correction on VIA chips */
+static unsigned int azx_via_get_position(struct azx *chip,
+ struct azx_dev *azx_dev)
+{
+ unsigned int link_pos, mini_pos, bound_pos;
+ unsigned int mod_link_pos, mod_dma_pos, mod_mini_pos;
+ unsigned int fifo_size;
+
+ link_pos = azx_sd_readl(azx_dev, SD_LPIB);
+ if (azx_dev->index >= 4) {
+ /* Playback, no problem using link position */
+ return link_pos;
+ }
+
+ /* Capture */
+ /* For new chipset,
+ * use mod to get the DMA position just like old chipset
+ */
+ mod_dma_pos = le32_to_cpu(*azx_dev->posbuf);
+ mod_dma_pos %= azx_dev->period_bytes;
+
+ /* azx_dev->fifo_size can't get FIFO size of in stream.
+ * Get from base address + offset.
+ */
+ fifo_size = readw(chip->remap_addr + VIA_IN_STREAM0_FIFO_SIZE_OFFSET);
+
+ if (azx_dev->insufficient) {
+ /* Link position never gather than FIFO size */
+ if (link_pos <= fifo_size)
+ return 0;
+
+ azx_dev->insufficient = 0;
+ }
+
+ if (link_pos <= fifo_size)
+ mini_pos = azx_dev->bufsize + link_pos - fifo_size;
+ else
+ mini_pos = link_pos - fifo_size;
+
+ /* Find nearest previous boudary */
+ mod_mini_pos = mini_pos % azx_dev->period_bytes;
+ mod_link_pos = link_pos % azx_dev->period_bytes;
+ if (mod_link_pos >= fifo_size)
+ bound_pos = link_pos - mod_link_pos;
+ else if (mod_dma_pos >= mod_mini_pos)
+ bound_pos = mini_pos - mod_mini_pos;
+ else {
+ bound_pos = mini_pos - mod_mini_pos + azx_dev->period_bytes;
+ if (bound_pos >= azx_dev->bufsize)
+ bound_pos = 0;
+ }
+
+ /* Calculate real DMA position we want */
+ return bound_pos + mod_dma_pos;
+}
+
+static unsigned int azx_get_position(struct azx *chip,
+ struct azx_dev *azx_dev)
+{
+ unsigned int pos;
+
+ if (chip->via_dmapos_patch)
+ pos = azx_via_get_position(chip, azx_dev);
+ else if (chip->position_fix == POS_FIX_POSBUF ||
+ chip->position_fix == POS_FIX_AUTO) {
+ /* use the position buffer */
+ pos = le32_to_cpu(*azx_dev->posbuf);
+ } else {
+ /* read LPIB */
+ pos = azx_sd_readl(azx_dev, SD_LPIB);
+ }
+ if (pos >= azx_dev->bufsize)
+ pos = 0;
+ return pos;
+}
+
static snd_pcm_uframes_t azx_pcm_pointer(struct snd_pcm_substream *substream)
{
struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
struct azx *chip = apcm->chip;
struct azx_dev *azx_dev = get_azx_dev(substream);
+ return bytes_to_frames(substream->runtime,
+ azx_get_position(chip, azx_dev));
+}
+
+/*
+ * Check whether the current DMA position is acceptable for updating
+ * periods. Returns non-zero if it's OK.
+ *
+ * Many HD-audio controllers appear pretty inaccurate about
+ * the update-IRQ timing. The IRQ is issued before actually the
+ * data is processed. So, we need to process it afterwords in a
+ * workqueue.
+ */
+static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev)
+{
unsigned int pos;
- if (chip->position_fix == POS_FIX_POSBUF ||
- chip->position_fix == POS_FIX_AUTO) {
- /* use the position buffer */
- pos = le32_to_cpu(*azx_dev->posbuf);
- if (chip->position_fix == POS_FIX_AUTO &&
- azx_dev->period_intr == 1 && !pos) {
+ pos = azx_get_position(chip, azx_dev);
+ if (chip->position_fix == POS_FIX_AUTO) {
+ if (!pos) {
printk(KERN_WARNING
"hda-intel: Invalid position buffer, "
"using LPIB read method instead.\n");
- chip->position_fix = POS_FIX_NONE;
- goto read_lpib;
+ chip->position_fix = POS_FIX_LPIB;
+ pos = azx_get_position(chip, azx_dev);
+ } else
+ chip->position_fix = POS_FIX_POSBUF;
+ }
+
+ if (!bdl_pos_adj[chip->dev_index])
+ return 1; /* no delayed ack */
+ if (pos % azx_dev->period_bytes > azx_dev->period_bytes / 2)
+ return 0; /* NG - it's below the period boundary */
+ return 1; /* OK, it's fine */
+}
+
+/*
+ * The work for pending PCM period updates.
+ */
+static void azx_irq_pending_work(struct work_struct *work)
+{
+ struct azx *chip = container_of(work, struct azx, irq_pending_work);
+ int i, pending;
+
+ if (!chip->irq_pending_warned) {
+ printk(KERN_WARNING
+ "hda-intel: IRQ timing workaround is activated "
+ "for card #%d. Suggest a bigger bdl_pos_adj.\n",
+ chip->card->number);
+ chip->irq_pending_warned = 1;
+ }
+
+ for (;;) {
+ pending = 0;
+ spin_lock_irq(&chip->reg_lock);
+ for (i = 0; i < chip->num_streams; i++) {
+ struct azx_dev *azx_dev = &chip->azx_dev[i];
+ if (!azx_dev->irq_pending ||
+ !azx_dev->substream ||
+ !azx_dev->running)
+ continue;
+ if (azx_position_ok(chip, azx_dev)) {
+ azx_dev->irq_pending = 0;
+ spin_unlock(&chip->reg_lock);
+ snd_pcm_period_elapsed(azx_dev->substream);
+ spin_lock(&chip->reg_lock);
+ } else
+ pending++;
}
- } else {
- read_lpib:
- /* read LPIB */
- pos = azx_sd_readl(azx_dev, SD_LPIB);
- if (chip->position_fix == POS_FIX_FIFO)
- pos += azx_dev->fifo_size;
+ spin_unlock_irq(&chip->reg_lock);
+ if (!pending)
+ return;
+ cond_resched();
}
- if (pos >= azx_dev->bufsize)
- pos = 0;
- return bytes_to_frames(substream->runtime, pos);
+}
+
+/* clear irq_pending flags and assure no on-going workq */
+static void azx_clear_irq_pending(struct azx *chip)
+{
+ int i;
+
+ spin_lock_irq(&chip->reg_lock);
+ for (i = 0; i < chip->num_streams; i++)
+ chip->azx_dev[i].irq_pending = 0;
+ spin_unlock_irq(&chip->reg_lock);
+ flush_scheduled_work();
}
static struct snd_pcm_ops azx_pcm_ops = {
@@ -1482,7 +1734,8 @@ static int __devinit create_codec_pcm(struct azx *chip, struct hda_codec *codec,
if (!cpcm->stream[0].substreams && !cpcm->stream[1].substreams)
return 0;
- snd_assert(cpcm->name, return -EINVAL);
+ if (snd_BUG_ON(!cpcm->name))
+ return -EINVAL;
err = snd_pcm_new(chip->card, cpcm->name, cpcm->device,
cpcm->stream[0].substreams,
@@ -1506,7 +1759,7 @@ static int __devinit create_codec_pcm(struct azx *chip, struct hda_codec *codec,
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &azx_pcm_ops);
snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
snd_dma_pci_data(chip->pci),
- 1024 * 64, 1024 * 1024);
+ 1024 * 64, 32 * 1024 * 1024);
chip->pcm[cpcm->device] = pcm;
return 0;
}
@@ -1676,6 +1929,7 @@ static int azx_suspend(struct pci_dev *pci, pm_message_t state)
int i;
snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
+ azx_clear_irq_pending(chip);
for (i = 0; i < AZX_MAX_PCMS; i++)
snd_pcm_suspend_all(chip->pcm[i]);
if (chip->initialized)
@@ -1732,6 +1986,7 @@ static int azx_free(struct azx *chip)
int i;
if (chip->initialized) {
+ azx_clear_irq_pending(chip);
for (i = 0; i < chip->num_streams; i++)
azx_stream_stop(chip, &chip->azx_dev[i]);
azx_stop_chip(chip);
@@ -1770,9 +2025,9 @@ static int azx_dev_free(struct snd_device *device)
* white/black-listing for position_fix
*/
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),
- SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_NONE),
+ SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_LPIB),
+ SND_PCI_QUIRK(0x1028, 0x01de, "Dell Precision 390", POS_FIX_LPIB),
+ SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB),
{}
};
@@ -1780,6 +2035,15 @@ static int __devinit check_position_fix(struct azx *chip, int fix)
{
const struct snd_pci_quirk *q;
+ /* Check VIA HD Audio Controller exist */
+ if (chip->pci->vendor == PCI_VENDOR_ID_VIA &&
+ chip->pci->device == VIA_HDAC_DEVICE_ID) {
+ chip->via_dmapos_patch = 1;
+ /* Use link position directly, avoid any transfer problem. */
+ return POS_FIX_LPIB;
+ }
+ chip->via_dmapos_patch = 0;
+
if (fix == POS_FIX_AUTO) {
q = snd_pci_quirk_lookup(chip->pci, position_fix_list);
if (q) {
@@ -1857,12 +2121,25 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
chip->irq = -1;
chip->driver_type = driver_type;
chip->msi = enable_msi;
+ chip->dev_index = dev;
+ INIT_WORK(&chip->irq_pending_work, azx_irq_pending_work);
chip->position_fix = check_position_fix(chip, position_fix[dev]);
check_probe_mask(chip, dev);
chip->single_cmd = single_cmd;
+ if (bdl_pos_adj[dev] < 0) {
+ switch (chip->driver_type) {
+ case AZX_DRIVER_ICH:
+ bdl_pos_adj[dev] = 1;
+ break;
+ default:
+ bdl_pos_adj[dev] = 32;
+ break;
+ }
+ }
+
#if BITS_PER_LONG != 64
/* Fix up base address on ULI M5461 */
if (chip->driver_type == AZX_DRIVER_ULI) {
@@ -2089,10 +2366,13 @@ static struct pci_device_id azx_ids[] = {
{ PCI_DEVICE(0x8086, 0x27d8), .driver_data = AZX_DRIVER_ICH },
{ PCI_DEVICE(0x8086, 0x269a), .driver_data = AZX_DRIVER_ICH },
{ PCI_DEVICE(0x8086, 0x284b), .driver_data = AZX_DRIVER_ICH },
+ { PCI_DEVICE(0x8086, 0x2911), .driver_data = AZX_DRIVER_ICH },
{ PCI_DEVICE(0x8086, 0x293e), .driver_data = AZX_DRIVER_ICH },
{ PCI_DEVICE(0x8086, 0x293f), .driver_data = AZX_DRIVER_ICH },
{ PCI_DEVICE(0x8086, 0x3a3e), .driver_data = AZX_DRIVER_ICH },
{ PCI_DEVICE(0x8086, 0x3a6e), .driver_data = AZX_DRIVER_ICH },
+ /* PCH */
+ { PCI_DEVICE(0x8086, 0x3b56), .driver_data = AZX_DRIVER_ICH },
/* SCH */
{ PCI_DEVICE(0x8086, 0x811b), .driver_data = AZX_DRIVER_SCH },
/* ATI SB 450/600 */
@@ -2102,6 +2382,7 @@ static struct pci_device_id azx_ids[] = {
{ PCI_DEVICE(0x1002, 0x793b), .driver_data = AZX_DRIVER_ATIHDMI },
{ PCI_DEVICE(0x1002, 0x7919), .driver_data = AZX_DRIVER_ATIHDMI },
{ PCI_DEVICE(0x1002, 0x960f), .driver_data = AZX_DRIVER_ATIHDMI },
+ { PCI_DEVICE(0x1002, 0x970f), .driver_data = AZX_DRIVER_ATIHDMI },
{ PCI_DEVICE(0x1002, 0xaa00), .driver_data = AZX_DRIVER_ATIHDMI },
{ PCI_DEVICE(0x1002, 0xaa08), .driver_data = AZX_DRIVER_ATIHDMI },
{ PCI_DEVICE(0x1002, 0xaa10), .driver_data = AZX_DRIVER_ATIHDMI },
@@ -2141,6 +2422,8 @@ static struct pci_device_id azx_ids[] = {
{ PCI_DEVICE(0x10de, 0x0bd5), .driver_data = AZX_DRIVER_NVIDIA },
{ PCI_DEVICE(0x10de, 0x0bd6), .driver_data = AZX_DRIVER_NVIDIA },
{ PCI_DEVICE(0x10de, 0x0bd7), .driver_data = AZX_DRIVER_NVIDIA },
+ /* Teradici */
+ { PCI_DEVICE(0x6549, 0x1200), .driver_data = AZX_DRIVER_TERA },
{ 0, }
};
MODULE_DEVICE_TABLE(pci, azx_ids);
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h
index 5c9e578f7f2d..7957fefda730 100644
--- a/sound/pci/hda/hda_local.h
+++ b/sound/pci/hda/hda_local.h
@@ -368,12 +368,15 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec,
#define AMP_OUT_UNMUTE 0xb000
#define AMP_OUT_ZERO 0xb000
/* pinctl values */
-#define PIN_IN 0x20
-#define PIN_VREF80 0x24
-#define PIN_VREF50 0x21
-#define PIN_OUT 0x40
-#define PIN_HP 0xc0
-#define PIN_HP_AMP 0x80
+#define PIN_IN (AC_PINCTL_IN_EN)
+#define PIN_VREFHIZ (AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ)
+#define PIN_VREF50 (AC_PINCTL_IN_EN | AC_PINCTL_VREF_50)
+#define PIN_VREFGRD (AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD)
+#define PIN_VREF80 (AC_PINCTL_IN_EN | AC_PINCTL_VREF_80)
+#define PIN_VREF100 (AC_PINCTL_IN_EN | AC_PINCTL_VREF_100)
+#define PIN_OUT (AC_PINCTL_OUT_EN)
+#define PIN_HP (AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN)
+#define PIN_HP_AMP (AC_PINCTL_HP_EN)
/*
* get widget capabilities
@@ -418,4 +421,13 @@ int snd_hda_check_amp_list_power(struct hda_codec *codec,
hda_nid_t nid);
#endif /* CONFIG_SND_HDA_POWER_SAVE */
+/*
+ * AMP control callbacks
+ */
+/* retrieve parameters from private_value */
+#define get_amp_nid(kc) ((kc)->private_value & 0xffff)
+#define get_amp_channels(kc) (((kc)->private_value >> 16) & 0x3)
+#define get_amp_direction(kc) (((kc)->private_value >> 18) & 0x1)
+#define get_amp_index(kc) (((kc)->private_value >> 19) & 0xf)
+
#endif /* __SOUND_HDA_LOCAL_H */
diff --git a/sound/pci/hda/hda_patch.h b/sound/pci/hda/hda_patch.h
index 2fdf2358dbc2..dfbcfa88da44 100644
--- a/sound/pci/hda/hda_patch.h
+++ b/sound/pci/hda/hda_patch.h
@@ -18,3 +18,5 @@ extern struct hda_codec_preset snd_hda_preset_atihdmi[];
extern struct hda_codec_preset snd_hda_preset_conexant[];
/* VIA codecs */
extern struct hda_codec_preset snd_hda_preset_via[];
+/* NVIDIA HDMI codecs */
+extern struct hda_codec_preset snd_hda_preset_nvhdmi[];
diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c
index 5633f77f8f3b..743d77922bce 100644
--- a/sound/pci/hda/hda_proc.c
+++ b/sound/pci/hda/hda_proc.c
@@ -216,7 +216,7 @@ static void print_pin_caps(struct snd_info_buffer *buffer,
unsigned int caps, val;
caps = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP);
- snd_iprintf(buffer, " Pincap 0x08%x:", caps);
+ snd_iprintf(buffer, " Pincap 0x%08x:", caps);
if (caps & AC_PINCAP_IN)
snd_iprintf(buffer, " IN");
if (caps & AC_PINCAP_OUT)
@@ -229,8 +229,13 @@ static void print_pin_caps(struct snd_info_buffer *buffer,
snd_iprintf(buffer, " Detect");
if (caps & AC_PINCAP_BALANCE)
snd_iprintf(buffer, " Balanced");
- if (caps & AC_PINCAP_LR_SWAP)
- snd_iprintf(buffer, " R/L");
+ if (caps & AC_PINCAP_HDMI) {
+ /* Realtek uses this bit as a different meaning */
+ if ((codec->vendor_id >> 16) == 0x10ec)
+ snd_iprintf(buffer, " R/L");
+ else
+ snd_iprintf(buffer, " HDMI");
+ }
if (caps & AC_PINCAP_TRIG_REQ)
snd_iprintf(buffer, " Trigger");
if (caps & AC_PINCAP_IMP_SENSE)
@@ -366,8 +371,6 @@ static void print_digital_conv(struct snd_info_buffer *buffer,
{
unsigned int digi1 = snd_hda_codec_read(codec, nid, 0,
AC_VERB_GET_DIGI_CONVERT_1, 0);
- unsigned int digi2 = snd_hda_codec_read(codec, nid, 0,
- AC_VERB_GET_DIGI_CONVERT_2, 0);
snd_iprintf(buffer, " Digital:");
if (digi1 & AC_DIG1_ENABLE)
snd_iprintf(buffer, " Enabled");
@@ -386,7 +389,8 @@ static void print_digital_conv(struct snd_info_buffer *buffer,
if (digi1 & AC_DIG1_LEVEL)
snd_iprintf(buffer, " GenLevel");
snd_iprintf(buffer, "\n");
- snd_iprintf(buffer, " Digital category: 0x%x\n", digi2 & AC_DIG2_CC);
+ snd_iprintf(buffer, " Digital category: 0x%x\n",
+ (digi1 >> 8) & AC_DIG2_CC);
}
static const char *get_pwr_state(u32 state)
@@ -553,9 +557,15 @@ static void print_codec_info(struct snd_info_entry *entry,
snd_iprintf(buffer, "Node 0x%02x [%s] wcaps 0x%x:", nid,
get_wid_type_name(wid_type), wid_caps);
- if (wid_caps & AC_WCAP_STEREO)
- snd_iprintf(buffer, " Stereo");
- else
+ if (wid_caps & AC_WCAP_STEREO) {
+ unsigned int chans;
+ chans = (wid_caps & AC_WCAP_CHAN_CNT_EXT) >> 13;
+ chans = ((chans << 1) | 1) + 1;
+ if (chans == 2)
+ snd_iprintf(buffer, " Stereo");
+ else
+ snd_iprintf(buffer, " %d-Channels", chans);
+ } else
snd_iprintf(buffer, " Mono");
if (wid_caps & AC_WCAP_DIGITAL)
snd_iprintf(buffer, " Digital");
@@ -567,6 +577,8 @@ static void print_codec_info(struct snd_info_entry *entry,
snd_iprintf(buffer, " Stripe");
if (wid_caps & AC_WCAP_LR_SWAP)
snd_iprintf(buffer, " R/L");
+ if (wid_caps & AC_WCAP_CP_CAPS)
+ snd_iprintf(buffer, " CP");
snd_iprintf(buffer, "\n");
/* volume knob is a special widget that always have connection
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index a99e86d74278..2b00c4afdf97 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -23,7 +23,6 @@
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/pci.h>
-#include <linux/mutex.h>
#include <sound/core.h>
#include "hda_codec.h"
@@ -64,7 +63,6 @@ struct ad198x_spec {
/* PCM information */
struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
- struct mutex amp_mutex; /* PCM volume/mute control mutex */
unsigned int spdif_route;
/* dynamic controls, init_verbs and input_mux */
@@ -1618,6 +1616,7 @@ static const char *ad1981_models[AD1981_MODELS] = {
static struct snd_pci_quirk ad1981_cfg_tbl[] = {
SND_PCI_QUIRK(0x1014, 0x0597, "Lenovo Z60", AD1981_THINKPAD),
+ SND_PCI_QUIRK(0x1014, 0x05b7, "Lenovo Z60m", AD1981_THINKPAD),
/* All HP models */
SND_PCI_QUIRK(0x103c, 0, "HP nx", AD1981_HP),
SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba U205", AD1981_TOSHIBA),
@@ -1827,9 +1826,14 @@ static hda_nid_t ad1988_capsrc_nids[3] = {
0x0c, 0x0d, 0x0e
};
-#define AD1988_SPDIF_OUT 0x02
+#define AD1988_SPDIF_OUT 0x02
+#define AD1988_SPDIF_OUT_HDMI 0x0b
#define AD1988_SPDIF_IN 0x07
+static hda_nid_t ad1989b_slave_dig_outs[2] = {
+ AD1988_SPDIF_OUT, AD1988_SPDIF_OUT_HDMI
+};
+
static struct hda_input_mux ad1988_6stack_capture_source = {
.num_items = 5,
.items = {
@@ -2144,6 +2148,7 @@ static struct snd_kcontrol_new ad1988_spdif_in_mixers[] = {
static struct snd_kcontrol_new ad1989_spdif_out_mixers[] = {
HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
+ HDA_CODEC_VOLUME("HDMI Playback Volume", 0x1d, 0x0, HDA_OUTPUT),
{ } /* end */
};
@@ -2208,6 +2213,8 @@ static struct hda_verb ad1988_6stack_init_verbs[] = {
{0x34, AC_VERB_SET_CONNECT_SEL, 0x0},
/* Analog CD Input */
{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
+ /* Analog Mix output amp */
+ {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */
{ }
};
@@ -2248,8 +2255,12 @@ static struct hda_verb ad1988_spdif_init_verbs[] = {
/* AD1989 has no ADC -> SPDIF route */
static struct hda_verb ad1989_spdif_init_verbs[] = {
- /* SPDIF out pin */
+ /* SPDIF-1 out pin */
+ {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
+ /* SPDIF-2/HDMI out pin */
+ {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
+ {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
{ }
};
@@ -2337,6 +2348,8 @@ static struct hda_verb ad1988_3stack_init_verbs[] = {
{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+ /* Analog Mix output amp */
+ {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */
{ }
};
@@ -2410,6 +2423,8 @@ static struct hda_verb ad1988_laptop_init_verbs[] = {
{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+ /* Analog Mix output amp */
+ {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */
{ }
};
@@ -2623,7 +2638,7 @@ static int ad1988_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
{
struct ad198x_spec *spec = codec->spec;
hda_nid_t nid;
- int idx, err;
+ int i, idx, err;
char name[32];
if (! pin)
@@ -2631,16 +2646,26 @@ static int ad1988_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
idx = ad1988_pin_idx(pin);
nid = ad1988_idx_to_dac(codec, idx);
- /* specify the DAC as the extra output */
- if (! spec->multiout.hp_nid)
- spec->multiout.hp_nid = nid;
- else
- spec->multiout.extra_out_nid[0] = nid;
- /* control HP volume/switch on the output mixer amp */
- sprintf(name, "%s Playback Volume", pfx);
- if ((err = add_control(spec, AD_CTL_WIDGET_VOL, name,
- HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
- return err;
+ /* check whether the corresponding DAC was already taken */
+ for (i = 0; i < spec->autocfg.line_outs; i++) {
+ hda_nid_t pin = spec->autocfg.line_out_pins[i];
+ hda_nid_t dac = ad1988_idx_to_dac(codec, ad1988_pin_idx(pin));
+ if (dac == nid)
+ break;
+ }
+ if (i >= spec->autocfg.line_outs) {
+ /* specify the DAC as the extra output */
+ if (!spec->multiout.hp_nid)
+ spec->multiout.hp_nid = nid;
+ else
+ spec->multiout.extra_out_nid[0] = nid;
+ /* control HP volume/switch on the output mixer amp */
+ sprintf(name, "%s Playback Volume", pfx);
+ err = add_control(spec, AD_CTL_WIDGET_VOL, name,
+ HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
+ if (err < 0)
+ return err;
+ }
nid = ad1988_mixer_nids[idx];
sprintf(name, "%s Playback Switch", pfx);
if ((err = add_control(spec, AD_CTL_BIND_MUTE, name,
@@ -2859,6 +2884,7 @@ static struct snd_pci_quirk ad1988_cfg_tbl[] = {
SND_PCI_QUIRK(0x1043, 0x81ec, "Asus P5B-DLX", AD1988_6STACK_DIG),
SND_PCI_QUIRK(0x1043, 0x81f6, "Asus M2N-SLI", AD1988_6STACK_DIG),
SND_PCI_QUIRK(0x1043, 0x8277, "Asus P5K-E/WIFI-AP", AD1988_6STACK_DIG),
+ SND_PCI_QUIRK(0x1043, 0x8311, "Asus P5Q-Premium/Pro", AD1988_6STACK_DIG),
{}
};
@@ -2966,6 +2992,7 @@ static int patch_ad1988(struct hda_codec *codec)
ad1989_spdif_out_mixers;
spec->init_verbs[spec->num_init_verbs++] =
ad1989_spdif_init_verbs;
+ codec->slave_dig_outs = ad1989b_slave_dig_outs;
} else {
spec->mixers[spec->num_mixers++] =
ad1988_spdif_out_mixers;
@@ -3177,7 +3204,6 @@ static int patch_ad1884(struct hda_codec *codec)
if (spec == NULL)
return -ENOMEM;
- mutex_init(&spec->amp_mutex);
codec->spec = spec;
spec->multiout.max_channels = 2;
@@ -3847,7 +3873,6 @@ static int patch_ad1884a(struct hda_codec *codec)
if (spec == NULL)
return -ENOMEM;
- mutex_init(&spec->amp_mutex);
codec->spec = spec;
spec->multiout.max_channels = 2;
@@ -3904,7 +3929,7 @@ static int patch_ad1884a(struct hda_codec *codec)
/*
- * AD1882
+ * AD1882 / AD1882A
*
* port-A - front hp-out
* port-B - front mic-in
@@ -3941,6 +3966,18 @@ static struct hda_input_mux ad1882_capture_source = {
},
};
+/* list: 0x11, 0x39, 0x3a, 0x3c, 0x18, 0x1f, 0x12, 0x20 */
+static struct hda_input_mux ad1882a_capture_source = {
+ .num_items = 5,
+ .items = {
+ { "Front Mic", 0x1 },
+ { "Mic", 0x4},
+ { "Line", 0x2 },
+ { "Digital Mic", 0x06 },
+ { "Mix", 0x7 },
+ },
+};
+
static struct snd_kcontrol_new ad1882_base_mixers[] = {
HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
@@ -3950,16 +3987,7 @@ static struct snd_kcontrol_new ad1882_base_mixers[] = {
HDA_CODEC_MUTE("Front Playback Switch", 0x12, 0x0, HDA_OUTPUT),
HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT),
HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
- HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x01, HDA_INPUT),
- HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
- HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x04, HDA_INPUT),
- HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x04, HDA_INPUT),
- HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x06, HDA_INPUT),
- HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x06, HDA_INPUT),
- HDA_CODEC_VOLUME("Beep Playback Volume", 0x20, 0x07, HDA_INPUT),
- HDA_CODEC_MUTE("Beep Playback Switch", 0x20, 0x07, HDA_INPUT),
+
HDA_CODEC_VOLUME("Mic Boost", 0x3c, 0x0, HDA_OUTPUT),
HDA_CODEC_VOLUME("Front Mic Boost", 0x39, 0x0, HDA_OUTPUT),
HDA_CODEC_VOLUME("Line-In Boost", 0x3a, 0x0, HDA_OUTPUT),
@@ -3992,6 +4020,35 @@ static struct snd_kcontrol_new ad1882_base_mixers[] = {
{ } /* end */
};
+static struct snd_kcontrol_new ad1882_loopback_mixers[] = {
+ HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
+ HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
+ HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x01, HDA_INPUT),
+ HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
+ HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x04, HDA_INPUT),
+ HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x04, HDA_INPUT),
+ HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x06, HDA_INPUT),
+ HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x06, HDA_INPUT),
+ HDA_CODEC_VOLUME("Beep Playback Volume", 0x20, 0x07, HDA_INPUT),
+ HDA_CODEC_MUTE("Beep Playback Switch", 0x20, 0x07, HDA_INPUT),
+ { } /* end */
+};
+
+static struct snd_kcontrol_new ad1882a_loopback_mixers[] = {
+ HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
+ HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
+ HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x04, HDA_INPUT),
+ HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x04, HDA_INPUT),
+ HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x01, HDA_INPUT),
+ HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x01, HDA_INPUT),
+ HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x06, HDA_INPUT),
+ HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x06, HDA_INPUT),
+ HDA_CODEC_VOLUME("Beep Playback Volume", 0x20, 0x07, HDA_INPUT),
+ HDA_CODEC_MUTE("Beep Playback Switch", 0x20, 0x07, HDA_INPUT),
+ HDA_CODEC_VOLUME("Digital Mic Boost", 0x1f, 0x0, HDA_INPUT),
+ { } /* end */
+};
+
static struct snd_kcontrol_new ad1882_3stack_mixers[] = {
HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT),
HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x17, 1, 0x0, HDA_OUTPUT),
@@ -4152,7 +4209,6 @@ static int patch_ad1882(struct hda_codec *codec)
if (spec == NULL)
return -ENOMEM;
- mutex_init(&spec->amp_mutex);
codec->spec = spec;
spec->multiout.max_channels = 6;
@@ -4162,9 +4218,16 @@ static int patch_ad1882(struct hda_codec *codec)
spec->num_adc_nids = ARRAY_SIZE(ad1882_adc_nids);
spec->adc_nids = ad1882_adc_nids;
spec->capsrc_nids = ad1882_capsrc_nids;
- spec->input_mux = &ad1882_capture_source;
- spec->num_mixers = 1;
+ if (codec->vendor_id == 0x11d1882)
+ spec->input_mux = &ad1882_capture_source;
+ else
+ spec->input_mux = &ad1882a_capture_source;
+ spec->num_mixers = 2;
spec->mixers[0] = ad1882_base_mixers;
+ if (codec->vendor_id == 0x11d1882)
+ spec->mixers[1] = ad1882_loopback_mixers;
+ else
+ spec->mixers[1] = ad1882a_loopback_mixers;
spec->num_init_verbs = 1;
spec->init_verbs[0] = ad1882_init_verbs;
spec->spdif_route = 0;
@@ -4181,8 +4244,8 @@ static int patch_ad1882(struct hda_codec *codec)
switch (board_config) {
default:
case AD1882_3STACK:
- spec->num_mixers = 2;
- spec->mixers[1] = ad1882_3stack_mixers;
+ spec->num_mixers = 3;
+ spec->mixers[2] = ad1882_3stack_mixers;
spec->channel_mode = ad1882_modes;
spec->num_channel_mode = ARRAY_SIZE(ad1882_modes);
spec->need_dac_fix = 1;
@@ -4190,8 +4253,8 @@ static int patch_ad1882(struct hda_codec *codec)
spec->multiout.num_dacs = 1;
break;
case AD1882_6STACK:
- spec->num_mixers = 2;
- spec->mixers[1] = ad1882_6stack_mixers;
+ spec->num_mixers = 3;
+ spec->mixers[2] = ad1882_6stack_mixers;
break;
}
return 0;
@@ -4214,6 +4277,7 @@ struct hda_codec_preset snd_hda_preset_analog[] = {
{ .id = 0x11d41986, .name = "AD1986A", .patch = patch_ad1986a },
{ .id = 0x11d41988, .name = "AD1988", .patch = patch_ad1988 },
{ .id = 0x11d4198b, .name = "AD1988B", .patch = patch_ad1988 },
+ { .id = 0x11d4882a, .name = "AD1882A", .patch = patch_ad1882 },
{ .id = 0x11d4989a, .name = "AD1989A", .patch = patch_ad1988 },
{ .id = 0x11d4989b, .name = "AD1989B", .patch = patch_ad1988 },
{} /* terminator */
diff --git a/sound/pci/hda/patch_atihdmi.c b/sound/pci/hda/patch_atihdmi.c
index 12272508b112..ba61575983fd 100644
--- a/sound/pci/hda/patch_atihdmi.c
+++ b/sound/pci/hda/patch_atihdmi.c
@@ -35,6 +35,9 @@ struct atihdmi_spec {
struct hda_pcm pcm_rec;
};
+#define CVT_NID 0x02 /* audio converter */
+#define PIN_NID 0x03 /* HDMI output pin */
+
static struct hda_verb atihdmi_basic_init[] = {
/* enable digital output on pin widget */
{ 0x03, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
@@ -60,8 +63,9 @@ static int atihdmi_init(struct hda_codec *codec)
{
snd_hda_sequence_write(codec, atihdmi_basic_init);
/* SI codec requires to unmute the pin */
- if (get_wcaps(codec, 0x03) & AC_WCAP_OUT_AMP)
- snd_hda_codec_write(codec, 0x03, 0, AC_VERB_SET_AMP_GAIN_MUTE,
+ if (get_wcaps(codec, PIN_NID) & AC_WCAP_OUT_AMP)
+ snd_hda_codec_write(codec, PIN_NID, 0,
+ AC_VERB_SET_AMP_GAIN_MUTE,
AMP_OUT_UNMUTE);
return 0;
}
@@ -92,15 +96,29 @@ static int atihdmi_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
struct snd_pcm_substream *substream)
{
struct atihdmi_spec *spec = codec->spec;
- return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag,
- format, substream);
+ int chans = substream->runtime->channels;
+ int i, err;
+
+ err = snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag,
+ format, substream);
+ if (err < 0)
+ return err;
+ snd_hda_codec_write(codec, CVT_NID, 0, AC_VERB_SET_CVT_CHAN_COUNT,
+ chans - 1);
+ /* FIXME: XXX */
+ for (i = 0; i < chans; i++) {
+ snd_hda_codec_write(codec, CVT_NID, 0,
+ AC_VERB_SET_HDMI_CHAN_SLOT,
+ (i << 4) | i);
+ }
+ return 0;
}
static struct hda_pcm_stream atihdmi_pcm_digital_playback = {
.substreams = 1,
.channels_min = 2,
.channels_max = 2,
- .nid = 0x2, /* NID to query formats and rates and setup streams */
+ .nid = CVT_NID, /* NID to query formats and rates and setup streams */
.ops = {
.open = atihdmi_dig_playback_pcm_open,
.close = atihdmi_dig_playback_pcm_close,
@@ -112,6 +130,7 @@ static int atihdmi_build_pcms(struct hda_codec *codec)
{
struct atihdmi_spec *spec = codec->spec;
struct hda_pcm *info = &spec->pcm_rec;
+ unsigned int chans;
codec->num_pcms = 1;
codec->pcm_info = info;
@@ -120,6 +139,13 @@ static int atihdmi_build_pcms(struct hda_codec *codec)
info->pcm_type = HDA_PCM_TYPE_HDMI;
info->stream[SNDRV_PCM_STREAM_PLAYBACK] = atihdmi_pcm_digital_playback;
+ /* FIXME: we must check ELD and change the PCM parameters dynamically
+ */
+ chans = get_wcaps(codec, CVT_NID);
+ chans = (chans & AC_WCAP_CHAN_CNT_EXT) >> 13;
+ chans = ((chans << 1) | 1) + 1;
+ info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = chans;
+
return 0;
}
@@ -147,9 +173,11 @@ static int patch_atihdmi(struct hda_codec *codec)
spec->multiout.num_dacs = 0; /* no analog */
spec->multiout.max_channels = 2;
- spec->multiout.dig_out_nid = 0x2; /* NID for copying analog to digital,
- * seems to be unused in pure-digital
- * case. */
+ /* NID for copying analog to digital,
+ * seems to be unused in pure-digital
+ * case.
+ */
+ spec->multiout.dig_out_nid = CVT_NID;
codec->patch_ops = atihdmi_patch_ops;
@@ -164,6 +192,7 @@ struct hda_codec_preset snd_hda_preset_atihdmi[] = {
{ .id = 0x10027919, .name = "ATI RS600 HDMI", .patch = patch_atihdmi },
{ .id = 0x1002791a, .name = "ATI RS690/780 HDMI", .patch = patch_atihdmi },
{ .id = 0x1002aa01, .name = "ATI R6xx HDMI", .patch = patch_atihdmi },
+ { .id = 0x10951390, .name = "SiI1390 HDMI", .patch = patch_atihdmi },
{ .id = 0x10951392, .name = "SiI1392 HDMI", .patch = patch_atihdmi },
{ .id = 0x17e80047, .name = "Chrontel HDMI", .patch = patch_atihdmi },
{} /* terminator */
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index 36fd85260035..7c1eb23f0cec 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -82,7 +82,6 @@ struct conexant_spec {
/* PCM information */
struct hda_pcm pcm_rec[2]; /* used in build_pcms() */
- struct mutex amp_mutex; /* PCM volume/mute control mutex */
unsigned int spdif_route;
/* dynamic controls, init_verbs and input_mux */
@@ -687,7 +686,7 @@ static struct snd_kcontrol_new cxt5045_mixers_hp530[] = {
static struct hda_verb cxt5045_init_verbs[] = {
/* Line in, Mic */
- {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
+ {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 },
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 },
/* HP, Amp */
{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
@@ -907,10 +906,12 @@ static struct snd_pci_quirk cxt5045_cfg_tbl[] = {
SND_PCI_QUIRK(0x103c, 0x30cf, "HP DV9533EG", CXT5045_LAPTOP_HPSENSE),
SND_PCI_QUIRK(0x103c, 0x30d5, "HP 530", CXT5045_LAPTOP_HP530),
SND_PCI_QUIRK(0x103c, 0x30d9, "HP Spartan", CXT5045_LAPTOP_HPSENSE),
+ SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba P105", CXT5045_LAPTOP_MICSENSE),
SND_PCI_QUIRK(0x152d, 0x0753, "Benq R55E", CXT5045_BENQ),
SND_PCI_QUIRK(0x1734, 0x10ad, "Fujitsu Si1520", CXT5045_LAPTOP_MICSENSE),
SND_PCI_QUIRK(0x1734, 0x10cb, "Fujitsu Si3515", CXT5045_LAPTOP_HPMICSENSE),
- SND_PCI_QUIRK(0x1734, 0x110e, "Fujitsu V5505", CXT5045_LAPTOP_HPSENSE),
+ SND_PCI_QUIRK(0x1734, 0x110e, "Fujitsu V5505",
+ CXT5045_LAPTOP_HPMICSENSE),
SND_PCI_QUIRK(0x1509, 0x1e40, "FIC", CXT5045_LAPTOP_HPMICSENSE),
SND_PCI_QUIRK(0x1509, 0x2f05, "FIC", CXT5045_LAPTOP_HPMICSENSE),
SND_PCI_QUIRK(0x1509, 0x2f06, "FIC", CXT5045_LAPTOP_HPMICSENSE),
@@ -928,7 +929,6 @@ static int patch_cxt5045(struct hda_codec *codec)
spec = kzalloc(sizeof(*spec), GFP_KERNEL);
if (!spec)
return -ENOMEM;
- mutex_init(&spec->amp_mutex);
codec->spec = spec;
spec->multiout.max_channels = 2;
@@ -963,6 +963,7 @@ static int patch_cxt5045(struct hda_codec *codec)
codec->patch_ops.init = cxt5045_init;
break;
case CXT5045_LAPTOP_MICSENSE:
+ codec->patch_ops.unsol_event = cxt5045_hp_unsol_event;
spec->input_mux = &cxt5045_capture_source;
spec->num_init_verbs = 2;
spec->init_verbs[1] = cxt5045_mic_sense_init_verbs;
@@ -1007,15 +1008,19 @@ static int patch_cxt5045(struct hda_codec *codec)
#endif
}
- /*
- * Fix max PCM level to 0 dB
- * (originall it has 0x2b steps with 0dB offset 0x14)
- */
- snd_hda_override_amp_caps(codec, 0x17, HDA_INPUT,
- (0x14 << AC_AMPCAP_OFFSET_SHIFT) |
- (0x14 << AC_AMPCAP_NUM_STEPS_SHIFT) |
- (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
- (1 << AC_AMPCAP_MUTE_SHIFT));
+ switch (codec->subsystem_id >> 16) {
+ case 0x103c:
+ /* HP laptop has a really bad sound over 0dB on NID 0x17.
+ * Fix max PCM level to 0 dB
+ * (originall it has 0x2b steps with 0dB offset 0x14)
+ */
+ snd_hda_override_amp_caps(codec, 0x17, HDA_INPUT,
+ (0x14 << AC_AMPCAP_OFFSET_SHIFT) |
+ (0x14 << AC_AMPCAP_NUM_STEPS_SHIFT) |
+ (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
+ (1 << AC_AMPCAP_MUTE_SHIFT));
+ break;
+ }
return 0;
}
@@ -1477,7 +1482,6 @@ static int patch_cxt5047(struct hda_codec *codec)
spec = kzalloc(sizeof(*spec), GFP_KERNEL);
if (!spec)
return -ENOMEM;
- mutex_init(&spec->amp_mutex);
codec->spec = spec;
spec->multiout.max_channels = 2;
@@ -1736,7 +1740,6 @@ static int patch_cxt5051(struct hda_codec *codec)
spec = kzalloc(sizeof(*spec), GFP_KERNEL);
if (!spec)
return -ENOMEM;
- mutex_init(&spec->amp_mutex);
codec->spec = spec;
codec->patch_ops = conexant_patch_ops;
diff --git a/sound/pci/hda/patch_nvhdmi.c b/sound/pci/hda/patch_nvhdmi.c
new file mode 100644
index 000000000000..1a65775d28e1
--- /dev/null
+++ b/sound/pci/hda/patch_nvhdmi.c
@@ -0,0 +1,164 @@
+/*
+ * Universal Interface for Intel High Definition Audio Codec
+ *
+ * HD audio interface patch for NVIDIA HDMI codecs
+ *
+ * Copyright (c) 2008 NVIDIA Corp. All rights reserved.
+ * Copyright (c) 2008 Wei Ni <wni@nvidia.com>
+ *
+ *
+ * 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 <linux/init.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <sound/core.h>
+#include "hda_codec.h"
+#include "hda_local.h"
+
+struct nvhdmi_spec {
+ struct hda_multi_out multiout;
+
+ struct hda_pcm pcm_rec;
+};
+
+static struct hda_verb nvhdmi_basic_init[] = {
+ /* enable digital output on pin widget */
+ { 0x05, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
+ {} /* terminator */
+};
+
+/*
+ * Controls
+ */
+static int nvhdmi_build_controls(struct hda_codec *codec)
+{
+ struct nvhdmi_spec *spec = codec->spec;
+ int err;
+
+ err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid);
+ if (err < 0)
+ return err;
+
+ return 0;
+}
+
+static int nvhdmi_init(struct hda_codec *codec)
+{
+ snd_hda_sequence_write(codec, nvhdmi_basic_init);
+ return 0;
+}
+
+/*
+ * Digital out
+ */
+static int nvhdmi_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
+ struct hda_codec *codec,
+ struct snd_pcm_substream *substream)
+{
+ struct nvhdmi_spec *spec = codec->spec;
+ return snd_hda_multi_out_dig_open(codec, &spec->multiout);
+}
+
+static int nvhdmi_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
+ struct hda_codec *codec,
+ struct snd_pcm_substream *substream)
+{
+ struct nvhdmi_spec *spec = codec->spec;
+ return snd_hda_multi_out_dig_close(codec, &spec->multiout);
+}
+
+static int nvhdmi_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
+ struct hda_codec *codec,
+ unsigned int stream_tag,
+ unsigned int format,
+ struct snd_pcm_substream *substream)
+{
+ struct nvhdmi_spec *spec = codec->spec;
+ return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag,
+ format, substream);
+}
+
+static struct hda_pcm_stream nvhdmi_pcm_digital_playback = {
+ .substreams = 1,
+ .channels_min = 2,
+ .channels_max = 2,
+ .nid = 0x4, /* NID to query formats and rates and setup streams */
+ .rates = SNDRV_PCM_RATE_48000,
+ .maxbps = 16,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ .ops = {
+ .open = nvhdmi_dig_playback_pcm_open,
+ .close = nvhdmi_dig_playback_pcm_close,
+ .prepare = nvhdmi_dig_playback_pcm_prepare
+ },
+};
+
+static int nvhdmi_build_pcms(struct hda_codec *codec)
+{
+ struct nvhdmi_spec *spec = codec->spec;
+ struct hda_pcm *info = &spec->pcm_rec;
+
+ codec->num_pcms = 1;
+ codec->pcm_info = info;
+
+ info->name = "NVIDIA HDMI";
+ info->stream[SNDRV_PCM_STREAM_PLAYBACK] = nvhdmi_pcm_digital_playback;
+
+ return 0;
+}
+
+static void nvhdmi_free(struct hda_codec *codec)
+{
+ kfree(codec->spec);
+}
+
+static struct hda_codec_ops nvhdmi_patch_ops = {
+ .build_controls = nvhdmi_build_controls,
+ .build_pcms = nvhdmi_build_pcms,
+ .init = nvhdmi_init,
+ .free = nvhdmi_free,
+};
+
+static int patch_nvhdmi(struct hda_codec *codec)
+{
+ struct nvhdmi_spec *spec;
+
+ spec = kzalloc(sizeof(*spec), GFP_KERNEL);
+ if (spec == NULL)
+ return -ENOMEM;
+
+ codec->spec = spec;
+
+ spec->multiout.num_dacs = 0; /* no analog */
+ spec->multiout.max_channels = 2;
+ spec->multiout.dig_out_nid = 0x4; /* NID for copying analog to digital,
+ * seems to be unused in pure-digital
+ * case. */
+
+ codec->patch_ops = nvhdmi_patch_ops;
+
+ return 0;
+}
+
+/*
+ * patch entries
+ */
+struct hda_codec_preset snd_hda_preset_nvhdmi[] = {
+ { .id = 0x10de0002, .name = "NVIDIA MCP78 HDMI", .patch = patch_nvhdmi },
+ { .id = 0x10de0007, .name = "NVIDIA MCP7A HDMI", .patch = patch_nvhdmi },
+ {} /* terminator */
+};
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index b0a2a262ece2..0b6e682c46d0 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -72,6 +72,7 @@ enum {
enum {
ALC260_BASIC,
ALC260_HP,
+ ALC260_HP_DC7600,
ALC260_HP_3013,
ALC260_FUJITSU_S702X,
ALC260_ACER,
@@ -100,6 +101,9 @@ enum {
ALC262_BENQ_T31,
ALC262_ULTRA,
ALC262_LENOVO_3000,
+ ALC262_NEC,
+ ALC262_TOSHIBA_S06,
+ ALC262_TOSHIBA_RX1,
ALC262_AUTO,
ALC262_MODEL_LAST /* last tag */
};
@@ -110,6 +114,7 @@ enum {
ALC268_3ST,
ALC268_TOSHIBA,
ALC268_ACER,
+ ALC268_ACER_ASPIRE_ONE,
ALC268_DELL,
ALC268_ZEPTO,
#ifdef CONFIG_SND_DEBUG
@@ -122,6 +127,9 @@ enum {
/* ALC269 models */
enum {
ALC269_BASIC,
+ ALC269_QUANTA_FL1,
+ ALC269_ASUS_EEEPC_P703,
+ ALC269_ASUS_EEEPC_P901,
ALC269_AUTO,
ALC269_MODEL_LAST /* last tag */
};
@@ -163,6 +171,17 @@ enum {
ALC662_LENOVO_101E,
ALC662_ASUS_EEEPC_P701,
ALC662_ASUS_EEEPC_EP20,
+ ALC663_ASUS_M51VA,
+ ALC663_ASUS_G71V,
+ ALC663_ASUS_H13,
+ ALC663_ASUS_G50V,
+ ALC662_ECS,
+ ALC663_ASUS_MODE1,
+ ALC662_ASUS_MODE2,
+ ALC663_ASUS_MODE3,
+ ALC663_ASUS_MODE4,
+ ALC663_ASUS_MODE5,
+ ALC663_ASUS_MODE6,
ALC662_AUTO,
ALC662_MODEL_LAST,
};
@@ -194,17 +213,21 @@ enum {
ALC883_ACER,
ALC883_ACER_ASPIRE,
ALC883_MEDION,
- ALC883_MEDION_MD2,
+ ALC883_MEDION_MD2,
ALC883_LAPTOP_EAPD,
ALC883_LENOVO_101E_2ch,
ALC883_LENOVO_NB0763,
ALC888_LENOVO_MS7195_DIG,
- ALC883_HAIER_W66,
+ ALC888_LENOVO_SKY,
+ ALC883_HAIER_W66,
ALC888_3ST_HP,
ALC888_6ST_DELL,
ALC883_MITAC,
ALC883_CLEVO_M720,
ALC883_FUJITSU_PI2515,
+ ALC883_3ST_6ch_INTEL,
+ ALC888_ASUS_M90V,
+ ALC888_ASUS_EEE1601,
ALC883_AUTO,
ALC883_MODEL_LAST,
};
@@ -280,6 +303,10 @@ struct alc_spec {
#ifdef CONFIG_SND_HDA_POWER_SAVE
struct hda_loopback_check loopback;
#endif
+
+ /* for PLL fix */
+ hda_nid_t pll_nid;
+ unsigned int pll_coef_idx, pll_coef_bit;
};
/*
@@ -387,7 +414,7 @@ static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
/*
* Control the mode of pin widget settings via the mixer. "pc" is used
- * instead of "%" to avoid consequences of accidently treating the % as
+ * instead of "%" to avoid consequences of accidently treating the % as
* being part of a format specifier. Maximum allowed length of a value is
* 63 characters plus NULL terminator.
*
@@ -418,7 +445,7 @@ static unsigned char alc_pin_mode_values[] = {
#define ALC_PIN_DIR_IN_NOMICBIAS 0x03
#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
-/* Info about the pin modes supported by the different pin direction modes.
+/* Info about the pin modes supported by the different pin direction modes.
* For each direction the minimum and maximum values are given.
*/
static signed char alc_pin_mode_dir_info[5][2] = {
@@ -491,7 +518,7 @@ static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
AC_VERB_SET_PIN_WIDGET_CONTROL,
alc_pin_mode_values[val]);
- /* Also enable the retasking pin's input/output as required
+ /* Also enable the retasking pin's input/output as required
* for the requested pin mode. Enum values of 2 or less are
* input modes.
*
@@ -696,7 +723,7 @@ static void setup_preset(struct alc_spec *spec,
i++)
spec->init_verbs[spec->num_init_verbs++] =
preset->init_verbs[i];
-
+
spec->channel_mode = preset->channel_mode;
spec->num_channel_mode = preset->num_channel_mode;
spec->need_dac_fix = preset->need_dac_fix;
@@ -707,7 +734,7 @@ static void setup_preset(struct alc_spec *spec,
spec->multiout.dac_nids = preset->dac_nids;
spec->multiout.dig_out_nid = preset->dig_out_nid;
spec->multiout.hp_nid = preset->hp_nid;
-
+
spec->num_mux_defs = preset->num_mux_defs;
if (!spec->num_mux_defs)
spec->num_mux_defs = 1;
@@ -747,6 +774,38 @@ static struct hda_verb alc_gpio3_init_verbs[] = {
{ }
};
+/*
+ * Fix hardware PLL issue
+ * On some codecs, the analog PLL gating control must be off while
+ * the default value is 1.
+ */
+static void alc_fix_pll(struct hda_codec *codec)
+{
+ struct alc_spec *spec = codec->spec;
+ unsigned int val;
+
+ if (!spec->pll_nid)
+ return;
+ snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
+ spec->pll_coef_idx);
+ val = snd_hda_codec_read(codec, spec->pll_nid, 0,
+ AC_VERB_GET_PROC_COEF, 0);
+ snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
+ spec->pll_coef_idx);
+ snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
+ val & ~(1 << spec->pll_coef_bit));
+}
+
+static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
+ unsigned int coef_idx, unsigned int coef_bit)
+{
+ struct alc_spec *spec = codec->spec;
+ spec->pll_nid = nid;
+ spec->pll_coef_idx = coef_idx;
+ spec->pll_coef_bit = coef_bit;
+ alc_fix_pll(codec);
+}
+
static void alc_sku_automute(struct hda_codec *codec)
{
struct alc_spec *spec = codec->spec;
@@ -776,6 +835,24 @@ static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
alc_sku_automute(codec);
}
+/* additional initialization for ALC888 variants */
+static void alc888_coef_init(struct hda_codec *codec)
+{
+ unsigned int tmp;
+
+ snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
+ 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);
+ if ((tmp & 0xf0) == 2)
+ /* alc888S-VC */
+ snd_hda_codec_read(codec, 0x20, 0,
+ AC_VERB_SET_PROC_COEF, 0x830);
+ else
+ /* alc888-VB */
+ snd_hda_codec_read(codec, 0x20, 0,
+ AC_VERB_SET_PROC_COEF, 0x3030);
+}
+
/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
* 31 ~ 16 : Manufacture ID
* 15 ~ 8 : SKU ID
@@ -794,7 +871,7 @@ static void alc_subsystem_id(struct hda_codec *codec,
if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
goto do_sku;
- /*
+ /*
* 31~30 : port conetcivity
* 29~21 : reserve
* 20 : PCBEEP input
@@ -851,8 +928,10 @@ do_sku:
case 0x10ec0267:
case 0x10ec0268:
case 0x10ec0269:
+ case 0x10ec0660:
+ case 0x10ec0662:
+ case 0x10ec0663:
case 0x10ec0862:
- case 0x10ec0662:
case 0x10ec0889:
snd_hda_codec_write(codec, 0x14, 0,
AC_VERB_SET_EAPD_BTLENABLE, 2);
@@ -877,18 +956,20 @@ do_sku:
case 0x10ec0882:
case 0x10ec0883:
case 0x10ec0885:
- case 0x10ec0888:
case 0x10ec0889:
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);
+ AC_VERB_SET_COEF_INDEX, 7);
snd_hda_codec_write(codec, 0x20, 0,
AC_VERB_SET_PROC_COEF,
tmp | 0x2010);
break;
+ case 0x10ec0888:
+ /*alc888_coef_init(codec);*/ /* called in alc_init() */
+ break;
case 0x10ec0267:
case 0x10ec0268:
snd_hda_codec_write(codec, 0x20, 0,
@@ -896,7 +977,7 @@ do_sku:
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);
+ AC_VERB_SET_COEF_INDEX, 7);
snd_hda_codec_write(codec, 0x20, 0,
AC_VERB_SET_PROC_COEF,
tmp | 0x3000);
@@ -905,7 +986,7 @@ do_sku:
default:
break;
}
-
+
/* is laptop or Desktop and enable the function "Mute internal speaker
* when the external headphone out jack is plugged"
*/
@@ -941,6 +1022,7 @@ do_sku:
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;
}
@@ -1231,7 +1313,7 @@ static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
*
* The system also has a pair of internal speakers, and a headphone jack.
* These are both connected to Line2 on the codec, hence to DAC 02.
- *
+ *
* There is a variable resistor to control the speaker or headphone
* volume. This is a hardware-only device without a software API.
*
@@ -1759,7 +1841,7 @@ static struct hda_verb alc880_pin_6stack_init_verbs[] = {
{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-
+
{ }
};
@@ -1804,7 +1886,7 @@ static struct hda_verb alc880_uniwill_init_verbs[] = {
/*
* Uniwill P53
-* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
+* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
*/
static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
@@ -1903,7 +1985,7 @@ static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec)
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);
present &= HDA_AMP_VOLMASK;
@@ -1985,7 +2067,7 @@ static struct hda_verb alc880_pin_asus_init_verbs[] = {
{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-
+
{ }
};
@@ -2373,6 +2455,10 @@ static int alc_init(struct hda_codec *codec)
struct alc_spec *spec = codec->spec;
unsigned int i;
+ alc_fix_pll(codec);
+ if (codec->vendor_id == 0x10ec0888)
+ alc888_coef_init(codec);
+
for (i = 0; i < spec->num_init_verbs; i++)
snd_hda_sequence_write(codec, spec->init_verbs[i]);
@@ -2563,12 +2649,14 @@ static int alc_build_pcms(struct hda_codec *codec)
info->name = spec->stream_name_analog;
if (spec->stream_analog_playback) {
- snd_assert(spec->multiout.dac_nids, return -EINVAL);
+ if (snd_BUG_ON(!spec->multiout.dac_nids))
+ return -EINVAL;
info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
}
if (spec->stream_analog_capture) {
- snd_assert(spec->adc_nids, return -EINVAL);
+ if (snd_BUG_ON(!spec->adc_nids))
+ return -EINVAL;
info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
}
@@ -2598,6 +2686,8 @@ static int alc_build_pcms(struct hda_codec *codec)
info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
}
+ /* FIXME: do we need this for all Realtek codec models? */
+ codec->spdif_status_reset = 1;
}
/* If the use of more than one ADC is requested for the current
@@ -3009,6 +3099,7 @@ static struct snd_pci_quirk alc880_cfg_tbl[] = {
SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
+ SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
@@ -3613,7 +3704,7 @@ static void alc880_auto_init_multi_out(struct hda_codec *codec)
{
struct alc_spec *spec = codec->spec;
int i;
-
+
alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
for (i = 0; i < spec->autocfg.line_outs; i++) {
hda_nid_t nid = spec->autocfg.line_out_pins[i];
@@ -4054,6 +4145,33 @@ static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
{ } /* end */
};
+static struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
+ .ops = &snd_hda_bind_vol,
+ .values = {
+ HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
+ HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
+ HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
+ 0
+ },
+};
+
+static struct hda_bind_ctls alc260_dc7600_bind_switch = {
+ .ops = &snd_hda_bind_sw,
+ .values = {
+ HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
+ HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
+ 0
+ },
+};
+
+static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
+ HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
+ HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
+ HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
+ HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
+ { } /* end */
+};
+
static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
{},
@@ -4077,7 +4195,30 @@ static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
alc260_hp_3013_automute(codec);
}
-/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
+static void alc260_hp_3012_automute(struct hda_codec *codec)
+{
+ unsigned int present, bits;
+
+ present = snd_hda_codec_read(codec, 0x10, 0,
+ AC_VERB_GET_PIN_SENSE, 0) & AC_PINSENSE_PRESENCE;
+
+ bits = present ? 0 : PIN_OUT;
+ snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
+ bits);
+ snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
+ bits);
+ snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
+ bits);
+}
+
+static void alc260_hp_3012_unsol_event(struct hda_codec *codec,
+ unsigned int res)
+{
+ if ((res >> 26) == ALC880_HP_EVENT)
+ alc260_hp_3012_automute(codec);
+}
+
+/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
* HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
*/
static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
@@ -4408,7 +4549,7 @@ static struct hda_verb alc260_fujitsu_init_verbs[] = {
{0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
{0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
- /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
+ /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
* when acting as an output.
*/
{0x0d, AC_VERB_SET_CONNECT_SEL, 0},
@@ -4433,14 +4574,14 @@ static struct hda_verb alc260_fujitsu_init_verbs[] = {
* stage.
*/
{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- /* Unmute input buffer of pin widget used for Line-in (no equiv
+ /* Unmute input buffer of pin widget used for Line-in (no equiv
* mixer ctrl)
*/
{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
/* Mute capture amp left and right */
{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
- /* Set ADC connection select to match default mixer setting - line
+ /* Set ADC connection select to match default mixer setting - line
* in (on mic1 pin)
*/
{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
@@ -4494,7 +4635,7 @@ static struct hda_verb alc260_acer_init_verbs[] = {
{0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
{0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
- /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
+ /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
* bus when acting as outputs.
*/
{0x0b, AC_VERB_SET_CONNECT_SEL, 0},
@@ -4605,6 +4746,20 @@ static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
alc260_replacer_672v_automute(codec);
}
+static struct hda_verb alc260_hp_dc7600_verbs[] = {
+ {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
+ {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
+ {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+ {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+ {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+ {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+ {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
+ {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
+ {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
+ {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
+ {}
+};
+
/* Test configuration for debugging, modelled after the ALC880 test
* configuration.
*/
@@ -4616,7 +4771,7 @@ static hda_nid_t alc260_test_adc_nids[2] = {
0x04, 0x05,
};
/* For testing the ALC260, each input MUX needs its own definition since
- * the signal assignments are different. This assumes that the first ADC
+ * the signal assignments are different. This assumes that the first ADC
* is NID 0x04.
*/
static struct hda_input_mux alc260_test_capture_sources[2] = {
@@ -4699,7 +4854,7 @@ static struct snd_kcontrol_new alc260_test_mixer[] = {
/* Switches to allow the digital IO pins to be enabled. The datasheet
* is ambigious as to which NID is which; testing on laptops which
- * make this output available should provide clarification.
+ * make this output available should provide clarification.
*/
ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
@@ -4735,7 +4890,7 @@ static struct hda_verb alc260_test_init_verbs[] = {
{0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
{0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
- /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
+ /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
* OUT1 sum bus when acting as an output.
*/
{0x0b, AC_VERB_SET_CONNECT_SEL, 0},
@@ -4827,7 +4982,7 @@ static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
} else
return 0; /* N/A */
-
+
snprintf(name, sizeof(name), "%s Playback Volume", pfx);
err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
if (err < 0)
@@ -4933,7 +5088,7 @@ static void alc260_auto_init_multi_out(struct hda_codec *codec)
int pin_type = get_pin_type(spec->autocfg.line_out_type);
alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
}
-
+
nid = spec->autocfg.speaker_pins[0];
if (nid)
alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
@@ -4975,7 +5130,7 @@ static struct hda_verb alc260_volume_init_verbs[] = {
{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-
+
/* Unmute 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
@@ -5004,7 +5159,7 @@ static struct hda_verb alc260_volume_init_verbs[] = {
{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-
+
{ }
};
@@ -5085,6 +5240,7 @@ static const char *alc260_models[ALC260_MODEL_LAST] = {
[ALC260_BASIC] = "basic",
[ALC260_HP] = "hp",
[ALC260_HP_3013] = "hp-3013",
+ [ALC260_HP_DC7600] = "hp-dc7600",
[ALC260_FUJITSU_S702X] = "fujitsu",
[ALC260_ACER] = "acer",
[ALC260_WILL] = "will",
@@ -5101,8 +5257,8 @@ static struct snd_pci_quirk alc260_cfg_tbl[] = {
SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013),
SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
- SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP),
- SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_3013),
+ SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
+ SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
@@ -5148,6 +5304,22 @@ static struct alc_config_preset alc260_presets[] = {
.unsol_event = alc260_hp_unsol_event,
.init_hook = alc260_hp_automute,
},
+ [ALC260_HP_DC7600] = {
+ .mixers = { alc260_hp_dc7600_mixer,
+ alc260_input_mixer,
+ alc260_capture_alt_mixer },
+ .init_verbs = { alc260_init_verbs,
+ alc260_hp_dc7600_verbs },
+ .num_dacs = ARRAY_SIZE(alc260_dac_nids),
+ .dac_nids = alc260_dac_nids,
+ .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
+ .adc_nids = alc260_hp_adc_nids,
+ .num_channel_mode = ARRAY_SIZE(alc260_modes),
+ .channel_mode = alc260_modes,
+ .input_mux = &alc260_capture_source,
+ .unsol_event = alc260_hp_3012_unsol_event,
+ .init_hook = alc260_hp_3012_automute,
+ },
[ALC260_HP_3013] = {
.mixers = { alc260_hp_3013_mixer,
alc260_input_mixer,
@@ -5863,7 +6035,7 @@ static struct hda_verb alc882_targa_verbs[] = {
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-
+
{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 */
@@ -5879,7 +6051,7 @@ static struct hda_verb alc882_targa_verbs[] = {
static void alc882_targa_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, 0x1b, HDA_OUTPUT, 0,
@@ -5905,7 +6077,7 @@ static struct hda_verb alc882_asus_a7j_verbs[] = {
{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 */
@@ -5923,7 +6095,7 @@ static struct hda_verb alc882_asus_a7m_verbs[] = {
{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 */
@@ -6249,7 +6421,7 @@ static struct alc_config_preset alc882_presets[] = {
.channel_mode = alc882_3ST_6ch_modes,
.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,
@@ -6262,14 +6434,14 @@ static struct alc_config_preset alc882_presets[] = {
.channel_mode = alc880_threestack_modes,
.need_dac_fix = 1,
.input_mux = &alc882_capture_source,
- },
+ },
};
/*
* Pin config fixes
*/
-enum {
+enum {
PINFIX_ABIT_AW9D_MAX
};
@@ -6353,7 +6525,9 @@ static void alc882_auto_init_analog_input(struct hda_codec *codec)
continue;
vref = PIN_IN;
if (1 /*i <= AUTO_PIN_FRONT_MIC*/) {
- if (snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP) &
+ unsigned int pincap;
+ pincap = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP);
+ if ((pincap >> AC_PINCAP_VREF_SHIFT) &
AC_PINCAP_VREF_80)
vref = PIN_VREF80;
}
@@ -6366,6 +6540,39 @@ static void alc882_auto_init_analog_input(struct hda_codec *codec)
}
}
+static void alc882_auto_init_input_src(struct hda_codec *codec)
+{
+ struct alc_spec *spec = codec->spec;
+ const struct hda_input_mux *imux = spec->input_mux;
+ int c;
+
+ for (c = 0; c < spec->num_adc_nids; c++) {
+ hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
+ hda_nid_t nid = spec->capsrc_nids[c];
+ int conns, mute, idx, item;
+
+ conns = snd_hda_get_connections(codec, nid, conn_list,
+ ARRAY_SIZE(conn_list));
+ if (conns < 0)
+ continue;
+ for (idx = 0; idx < conns; idx++) {
+ /* if the current connection is the selected one,
+ * unmute it as default - otherwise mute it
+ */
+ mute = AMP_IN_MUTE(idx);
+ for (item = 0; item < imux->num_items; item++) {
+ if (imux->items[item].index == idx) {
+ if (spec->cur_mux[c] == item)
+ mute = AMP_IN_UNMUTE(idx);
+ break;
+ }
+ }
+ snd_hda_codec_write(codec, nid, 0,
+ AC_VERB_SET_AMP_GAIN_MUTE, mute);
+ }
+ }
+}
+
/* add mic boosts if needed */
static int alc_auto_add_mic_boost(struct hda_codec *codec)
{
@@ -6420,6 +6627,7 @@ static void alc882_auto_init(struct hda_codec *codec)
alc882_auto_init_multi_out(codec);
alc882_auto_init_hp_out(codec);
alc882_auto_init_analog_input(codec);
+ alc882_auto_init_input_src(codec);
if (spec->unsol_event)
alc_sku_automute(codec);
}
@@ -6448,15 +6656,19 @@ static int patch_alc882(struct hda_codec *codec)
board_config = ALC885_MACPRO;
break;
case 0x106b1000: /* iMac 24 */
+ case 0x106b2800: /* AppleTV */
board_config = ALC885_IMAC24;
break;
- case 0x106b00a1: /* Macbook */
+ case 0x106b00a1: /* Macbook (might be wrong - PCI SSID?) */
+ case 0x106b00a4: /* MacbookPro4,1 */
case 0x106b2c00: /* Macbook Pro rev3 */
+ case 0x106b3600: /* Macbook 3.1 */
board_config = ALC885_MBP3;
break;
default:
/* ALC889A is handled better as ALC888-compatible */
- if (codec->revision_id == 0x100103) {
+ if (codec->revision_id == 0x100101 ||
+ codec->revision_id == 0x100103) {
alc_free(codec);
return patch_alc883(codec);
}
@@ -6485,14 +6697,20 @@ static int patch_alc882(struct hda_codec *codec)
if (board_config != ALC882_AUTO)
setup_preset(spec, &alc882_presets[board_config]);
- spec->stream_name_analog = "ALC882 Analog";
+ if (codec->vendor_id == 0x10ec0885) {
+ spec->stream_name_analog = "ALC885 Analog";
+ spec->stream_name_digital = "ALC885 Digital";
+ } else {
+ spec->stream_name_analog = "ALC882 Analog";
+ spec->stream_name_digital = "ALC882 Digital";
+ }
+
spec->stream_analog_playback = &alc882_pcm_analog_playback;
spec->stream_analog_capture = &alc882_pcm_analog_capture;
/* FIXME: setup DAC5 */
/*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
- spec->stream_name_digital = "ALC882 Digital";
spec->stream_digital_playback = &alc882_pcm_digital_playback;
spec->stream_digital_capture = &alc882_pcm_digital_capture;
@@ -6569,6 +6787,16 @@ static struct hda_input_mux alc883_capture_source = {
},
};
+static struct hda_input_mux alc883_3stack_6ch_intel = {
+ .num_items = 4,
+ .items = {
+ { "Mic", 0x1 },
+ { "Front Mic", 0x0 },
+ { "Line", 0x2 },
+ { "CD", 0x4 },
+ },
+};
+
static struct hda_input_mux alc883_lenovo_101e_capture_source = {
.num_items = 2,
.items = {
@@ -6595,6 +6823,23 @@ static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
},
};
+static struct hda_input_mux alc883_lenovo_sky_capture_source = {
+ .num_items = 3,
+ .items = {
+ { "Mic", 0x0 },
+ { "Front Mic", 0x1 },
+ { "Line", 0x4 },
+ },
+};
+
+static struct hda_input_mux alc883_asus_eee1601_capture_source = {
+ .num_items = 2,
+ .items = {
+ { "Mic", 0x0 },
+ { "Line", 0x2 },
+ },
+};
+
#define alc883_mux_enum_info alc_mux_enum_info
#define alc883_mux_enum_get alc_mux_enum_get
/* ALC883 has the ALC882-type input selection */
@@ -6650,6 +6895,48 @@ static struct hda_channel_mode alc883_3ST_6ch_modes[3] = {
};
/*
+ * 2ch mode
+ */
+static struct hda_verb alc883_3ST_ch2_intel_init[] = {
+ { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
+ { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
+ { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
+ { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
+ { } /* end */
+};
+
+/*
+ * 4ch mode
+ */
+static struct hda_verb alc883_3ST_ch4_intel_init[] = {
+ { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
+ { 0x19, 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
+ */
+static struct hda_verb alc883_3ST_ch6_intel_init[] = {
+ { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
+ { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
+ { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
+ { 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 */
+};
+
+static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
+ { 2, alc883_3ST_ch2_intel_init },
+ { 4, alc883_3ST_ch4_intel_init },
+ { 6, alc883_3ST_ch6_intel_init },
+};
+
+/*
* 6ch mode
*/
static struct hda_verb alc883_sixstack_ch6_init[] = {
@@ -6867,6 +7154,43 @@ static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ /* .name = "Capture Source", */
+ .name = "Input Source",
+ .count = 1,
+ .info = alc883_mux_enum_info,
+ .get = alc883_mux_enum_get,
+ .put = alc883_mux_enum_put,
+ },
+ { } /* end */
+};
+
+static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
+ HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
+ HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
+ HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
+ HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
+ HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
+ HDA_OUTPUT),
+ HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
+ HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
+ HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 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, 0x1, HDA_INPUT),
+ HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
+ HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
+ HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
+ HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
+ HDA_CODEC_MUTE("Front 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),
+ 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),
{
@@ -6883,13 +7207,13 @@ static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
+ HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT),
+ HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x16, 1, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
+ HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
+ HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
@@ -7052,7 +7376,7 @@ static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
.put = alc883_mux_enum_put,
},
{ } /* end */
-};
+};
static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
@@ -7079,6 +7403,87 @@ static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
{ } /* end */
};
+static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
+ HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
+ HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
+ HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
+ HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
+ HDA_CODEC_VOLUME_MONO("Center Playback Volume",
+ 0x0d, 1, 0x0, HDA_OUTPUT),
+ HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
+ HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
+ HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
+ HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
+ HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
+ HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
+ HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x1a, 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("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
+ HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
+ HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, 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 hda_bind_ctls alc883_bind_cap_vol = {
+ .ops = &snd_hda_bind_vol,
+ .values = {
+ HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
+ HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
+ 0
+ },
+};
+
+static struct hda_bind_ctls alc883_bind_cap_switch = {
+ .ops = &snd_hda_bind_sw,
+ .values = {
+ HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
+ HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
+ 0
+ },
+};
+
+static struct snd_kcontrol_new alc883_asus_eee1601_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", 0x14, 0x0, HDA_OUTPUT),
+ 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_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
+ HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ /* .name = "Capture Source", */
+ .name = "Input Source",
+ .count = 1,
+ .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,
@@ -7092,7 +7497,7 @@ static struct snd_kcontrol_new alc883_chmode_mixer[] = {
static struct hda_verb alc883_init_verbs[] = {
/* ADC1: mute amp left and right */
- {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+ {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
/* ADC2: mute amp left and right */
{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
@@ -7157,14 +7562,14 @@ static struct hda_verb alc883_init_verbs[] = {
/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
/* Input mixer2 */
{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)},
+ {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
+ {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_UNMUTE(1)},
- {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
- {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
+ {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
+ {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
+ {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
{ }
};
@@ -7264,7 +7669,7 @@ static struct hda_verb alc883_tagra_verbs[] = {
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-
+
{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 */
@@ -7314,6 +7719,18 @@ static struct hda_verb alc883_haier_w66_verbs[] = {
{ } /* end */
};
+static struct hda_verb alc888_lenovo_sky_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)},
+ {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+ {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+ {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+ {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
+ {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
+ { } /* end */
+};
+
static struct hda_verb alc888_3st_hp_verbs[] = {
{0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
{0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
@@ -7351,7 +7768,7 @@ static struct hda_channel_mode alc888_3st_hp_modes[2] = {
static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
{
unsigned int present;
-
+
present = snd_hda_codec_read(codec, 0x1b, 0,
AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
@@ -7364,7 +7781,7 @@ static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
static void alc888_lenovo_ms7195_rca_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,
@@ -7394,7 +7811,7 @@ static struct hda_verb alc883_medion_md2_verbs[] = {
static void alc883_medion_md2_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,
@@ -7549,7 +7966,7 @@ static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
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,
@@ -7586,7 +8003,7 @@ static struct hda_verb alc883_acer_eapd_verbs[] = {
static void alc888_6st_dell_front_automute(struct hda_codec *codec)
{
unsigned int present;
-
+
present = snd_hda_codec_read(codec, 0x1b, 0,
AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
@@ -7610,6 +8027,50 @@ static void alc888_6st_dell_unsol_event(struct hda_codec *codec,
}
}
+static void alc888_lenovo_sky_front_automute(struct hda_codec *codec)
+{
+ unsigned int mute;
+ unsigned int 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_stereo(codec, 0x14, HDA_OUTPUT, 0,
+ HDA_AMP_MUTE, HDA_AMP_MUTE);
+ snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
+ HDA_AMP_MUTE, HDA_AMP_MUTE);
+ snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
+ HDA_AMP_MUTE, HDA_AMP_MUTE);
+ snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
+ HDA_AMP_MUTE, HDA_AMP_MUTE);
+ snd_hda_codec_amp_stereo(codec, 0x1a, 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_stereo(codec, 0x14, HDA_OUTPUT, 0,
+ HDA_AMP_MUTE, mute);
+ snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
+ HDA_AMP_MUTE, mute);
+ snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
+ HDA_AMP_MUTE, mute);
+ snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
+ HDA_AMP_MUTE, mute);
+ snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
+ HDA_AMP_MUTE, mute);
+ }
+}
+
+static void alc883_lenovo_sky_unsol_event(struct hda_codec *codec,
+ unsigned int res)
+{
+ if ((res >> 26) == ALC880_HP_EVENT)
+ alc888_lenovo_sky_front_automute(codec);
+}
+
/*
* generic initialization of ADC, input mixers and output mixers
*/
@@ -7694,6 +8155,105 @@ static struct snd_kcontrol_new alc883_capture_mixer[] = {
{ } /* end */
};
+static struct hda_verb alc888_asus_m90v_verbs[] = {
+ {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+ {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+ {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+ /* enable unsolicited event */
+ {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
+ {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
+ { } /* end */
+};
+
+static void alc883_nb_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, 0x23, 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 | (0x01 << 8) | (present ? 0x80 : 0));
+}
+
+static void alc883_M90V_speaker_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)
+ & AC_PINSENSE_PRESENCE;
+ bits = present ? 0 : PIN_OUT;
+ snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
+ bits);
+ snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
+ bits);
+ snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
+ bits);
+}
+
+static void alc883_mode2_unsol_event(struct hda_codec *codec,
+ unsigned int res)
+{
+ switch (res >> 26) {
+ case ALC880_HP_EVENT:
+ alc883_M90V_speaker_automute(codec);
+ break;
+ case ALC880_MIC_EVENT:
+ alc883_nb_mic_automute(codec);
+ break;
+ }
+}
+
+static void alc883_mode2_inithook(struct hda_codec *codec)
+{
+ alc883_M90V_speaker_automute(codec);
+ alc883_nb_mic_automute(codec);
+}
+
+static struct hda_verb alc888_asus_eee1601_verbs[] = {
+ {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+ {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+ {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+ {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+ {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
+ {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
+ {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
+ /* enable unsolicited event */
+ {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
+ { } /* end */
+};
+
+static void alc883_eee1601_speaker_automute(struct hda_codec *codec)
+{
+ unsigned int present;
+ unsigned char bits;
+
+ present = snd_hda_codec_read(codec, 0x14, 0,
+ AC_VERB_GET_PIN_SENSE, 0)
+ & AC_PINSENSE_PRESENCE;
+ bits = present ? 0 : PIN_OUT;
+ snd_hda_codec_write(codec, 0x1b, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
+ bits);
+}
+
+static void alc883_eee1601_unsol_event(struct hda_codec *codec,
+ unsigned int res)
+{
+ switch (res >> 26) {
+ case ALC880_HP_EVENT:
+ alc883_eee1601_speaker_automute(codec);
+ break;
+ }
+}
+
+static void alc883_eee1601_inithook(struct hda_codec *codec)
+{
+ alc883_eee1601_speaker_automute(codec);
+}
+
#ifdef CONFIG_SND_HDA_POWER_SAVE
#define alc883_loopbacks alc880_loopbacks
#endif
@@ -7723,12 +8283,14 @@ 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",
+ [ALC888_LENOVO_SKY] = "lenovo-sky",
[ALC883_HAIER_W66] = "haier-w66",
[ALC888_3ST_HP] = "3stack-hp",
[ALC888_6ST_DELL] = "6stack-dell",
[ALC883_MITAC] = "mitac",
[ALC883_CLEVO_M720] = "clevo-m720",
[ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
+ [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
[ALC883_AUTO] = "auto",
};
@@ -7737,6 +8299,7 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = {
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, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER), /* default Acer */
SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
@@ -7744,10 +8307,13 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = {
SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
+ SND_PCI_QUIRK(0x1043, 0x8317, "Asus M90V", ALC888_ASUS_M90V),
+ SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG),
SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
+ SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG),
SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
@@ -7783,9 +8349,12 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = {
SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
+ SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
+ SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
+ SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
{}
};
@@ -7824,6 +8393,18 @@ static struct alc_config_preset alc883_presets[] = {
.need_dac_fix = 1,
.input_mux = &alc883_capture_source,
},
+ [ALC883_3ST_6ch_INTEL] = {
+ .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
+ .init_verbs = { alc883_init_verbs },
+ .num_dacs = ARRAY_SIZE(alc883_dac_nids),
+ .dac_nids = alc883_dac_nids,
+ .dig_out_nid = ALC883_DIGOUT_NID,
+ .dig_in_nid = ALC883_DIGIN_NID,
+ .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
+ .channel_mode = alc883_3ST_6ch_intel_modes,
+ .need_dac_fix = 1,
+ .input_mux = &alc883_3stack_6ch_intel,
+ },
[ALC883_6ST_DIG] = {
.mixers = { alc883_base_mixer, alc883_chmode_mixer },
.init_verbs = { alc883_init_verbs },
@@ -7908,7 +8489,7 @@ static struct alc_config_preset alc883_presets[] = {
.input_mux = &alc883_capture_source,
.unsol_event = alc883_medion_md2_unsol_event,
.init_hook = alc883_medion_md2_automute,
- },
+ },
[ALC883_LAPTOP_EAPD] = {
.mixers = { alc883_base_mixer },
.init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
@@ -8025,6 +8606,49 @@ static struct alc_config_preset alc883_presets[] = {
.unsol_event = alc883_2ch_fujitsu_pi2515_unsol_event,
.init_hook = alc883_2ch_fujitsu_pi2515_automute,
},
+ [ALC888_LENOVO_SKY] = {
+ .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
+ .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_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_sixstack_modes),
+ .channel_mode = alc883_sixstack_modes,
+ .need_dac_fix = 1,
+ .input_mux = &alc883_lenovo_sky_capture_source,
+ .unsol_event = alc883_lenovo_sky_unsol_event,
+ .init_hook = alc888_lenovo_sky_front_automute,
+ },
+ [ALC888_ASUS_M90V] = {
+ .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
+ .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
+ .num_dacs = ARRAY_SIZE(alc883_dac_nids),
+ .dac_nids = alc883_dac_nids,
+ .dig_out_nid = ALC883_DIGOUT_NID,
+ .dig_in_nid = ALC883_DIGIN_NID,
+ .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
+ .channel_mode = alc883_3ST_6ch_modes,
+ .need_dac_fix = 1,
+ .input_mux = &alc883_fujitsu_pi2515_capture_source,
+ .unsol_event = alc883_mode2_unsol_event,
+ .init_hook = alc883_mode2_inithook,
+ },
+ [ALC888_ASUS_EEE1601] = {
+ .mixers = { alc883_asus_eee1601_mixer },
+ .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
+ .num_dacs = ARRAY_SIZE(alc883_dac_nids),
+ .dac_nids = alc883_dac_nids,
+ .dig_out_nid = ALC883_DIGOUT_NID,
+ .dig_in_nid = ALC883_DIGIN_NID,
+ .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
+ .channel_mode = alc883_3ST_2ch_modes,
+ .need_dac_fix = 1,
+ .input_mux = &alc883_asus_eee1601_capture_source,
+ .unsol_event = alc883_eee1601_unsol_event,
+ .init_hook = alc883_eee1601_inithook,
+ },
};
@@ -8100,6 +8724,8 @@ static void alc883_auto_init_analog_input(struct hda_codec *codec)
}
}
+#define alc883_auto_init_input_src alc882_auto_init_input_src
+
/* almost identical with ALC880 parser... */
static int alc883_parse_auto_config(struct hda_codec *codec)
{
@@ -8130,6 +8756,7 @@ static void alc883_auto_init(struct hda_codec *codec)
alc883_auto_init_multi_out(codec);
alc883_auto_init_hp_out(codec);
alc883_auto_init_analog_input(codec);
+ alc883_auto_init_input_src(codec);
if (spec->unsol_event)
alc_sku_automute(codec);
}
@@ -8145,6 +8772,8 @@ static int patch_alc883(struct hda_codec *codec)
codec->spec = spec;
+ alc_fix_pll_init(codec, 0x20, 0x0a, 10);
+
board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST,
alc883_models,
alc883_cfg_tbl);
@@ -8171,12 +8800,25 @@ static int patch_alc883(struct hda_codec *codec)
if (board_config != ALC883_AUTO)
setup_preset(spec, &alc883_presets[board_config]);
- spec->stream_name_analog = "ALC883 Analog";
+ switch (codec->vendor_id) {
+ case 0x10ec0888:
+ spec->stream_name_analog = "ALC888 Analog";
+ spec->stream_name_digital = "ALC888 Digital";
+ break;
+ case 0x10ec0889:
+ spec->stream_name_analog = "ALC889 Analog";
+ spec->stream_name_digital = "ALC889 Digital";
+ break;
+ default:
+ spec->stream_name_analog = "ALC883 Analog";
+ spec->stream_name_digital = "ALC883 Digital";
+ break;
+ }
+
spec->stream_analog_playback = &alc883_pcm_analog_playback;
spec->stream_analog_capture = &alc883_pcm_analog_capture;
spec->stream_analog_alt_capture = &alc883_pcm_analog_alt_capture;
- spec->stream_name_digital = "ALC883 Digital";
spec->stream_digital_playback = &alc883_pcm_digital_playback;
spec->stream_digital_capture = &alc883_pcm_digital_capture;
@@ -8189,6 +8831,7 @@ 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;
@@ -8213,6 +8856,13 @@ static int patch_alc883(struct hda_codec *codec)
#define alc262_modes alc260_modes
#define alc262_capture_source alc882_capture_source
+static hda_nid_t alc262_dmic_adc_nids[1] = {
+ /* ADC0 */
+ 0x09
+};
+
+static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
+
static struct snd_kcontrol_new alc262_base_mixer[] = {
HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
@@ -8594,10 +9244,10 @@ static struct hda_verb alc262_init_verbs[] = {
{0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
{0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
-
+
{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
{0x15, 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 */
@@ -8619,6 +9269,12 @@ static struct hda_verb alc262_init_verbs[] = {
{ }
};
+static struct hda_verb alc262_eapd_verbs[] = {
+ {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
+ {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
+ { }
+};
+
static struct hda_verb alc262_hippo_unsol_verbs[] = {
{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
@@ -8645,6 +9301,91 @@ static struct hda_verb alc262_sony_unsol_verbs[] = {
{}
};
+static struct hda_input_mux alc262_dmic_capture_source = {
+ .num_items = 2,
+ .items = {
+ { "Int DMic", 0x9 },
+ { "Mic", 0x0 },
+ },
+};
+
+static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
+ HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
+ HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
+ HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, 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("Capture Volume", 0x09, 0x0, HDA_INPUT),
+ HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ /* The multiple "Capture Source" controls confuse alsamixer
+ * So call somewhat different..
+ */
+ /* .name = "Capture Source", */
+ .name = "Input Source",
+ .count = 1,
+ .info = alc_mux_enum_info,
+ .get = alc_mux_enum_get,
+ .put = alc_mux_enum_put,
+ },
+ { } /* end */
+};
+
+static struct hda_verb alc262_toshiba_s06_verbs[] = {
+ {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
+ {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+ {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+ {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
+ {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
+ {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
+ {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
+ {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
+ {}
+};
+
+static void alc262_dmic_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_CONNECT_SEL, present ? 0x0 : 0x09);
+}
+
+/* toggle speaker-output according to the hp-jack state */
+static void alc262_toshiba_s06_speaker_automute(struct hda_codec *codec)
+{
+ unsigned int present;
+ unsigned char bits;
+
+ present = snd_hda_codec_read(codec, 0x15, 0,
+ AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
+ bits = present ? 0 : PIN_OUT;
+ snd_hda_codec_write(codec, 0x14, 0,
+ AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
+}
+
+
+
+/* unsolicited event for HP jack sensing */
+static void alc262_toshiba_s06_unsol_event(struct hda_codec *codec,
+ unsigned int res)
+{
+ if ((res >> 26) == ALC880_HP_EVENT)
+ alc262_toshiba_s06_speaker_automute(codec);
+ if ((res >> 26) == ALC880_MIC_EVENT)
+ alc262_dmic_automute(codec);
+
+}
+
+static void alc262_toshiba_s06_init_hook(struct hda_codec *codec)
+{
+ alc262_toshiba_s06_speaker_automute(codec);
+ alc262_dmic_automute(codec);
+}
+
/* mute/unmute internal speaker according to the hp jack and mute state */
static void alc262_hippo_automute(struct hda_codec *codec)
{
@@ -8709,6 +9450,41 @@ static void alc262_hippo1_unsol_event(struct hda_codec *codec,
}
/*
+ * nec model
+ * 0x15 = headphone
+ * 0x16 = internal speaker
+ * 0x18 = external mic
+ */
+
+static struct snd_kcontrol_new alc262_nec_mixer[] = {
+ HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
+ HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, 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("Mic Boost", 0x18, 0, HDA_INPUT),
+
+ HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
+ HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
+ { } /* end */
+};
+
+static struct hda_verb alc262_nec_verbs[] = {
+ /* Unmute Speaker */
+ {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+
+ /* Headphone */
+ {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
+ {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+
+ /* External mic to headphone */
+ {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+ /* External mic to speaker */
+ {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+ {}
+};
+
+/*
* fujitsu model
* 0x14 = headphone/spdif-out, 0x15 = internal speaker,
* 0x1b = port replicator headphone out
@@ -8940,6 +9716,25 @@ static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
{ } /* end */
};
+static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
+ HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_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 = 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("Mic Boost", 0x18, 0, HDA_INPUT),
+ HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
+ HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
+ HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
+ { } /* end */
+};
+
/* additional init verbs for Benq laptops */
static struct hda_verb alc262_EAPD_verbs[] = {
{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
@@ -9188,7 +9983,7 @@ static struct hda_verb alc262_volume_init_verbs[] = {
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
-
+
/* set up input amps for analog loopback */
/* Amp Indices: DAC = 0, mixer = 1 */
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
@@ -9243,7 +10038,7 @@ static struct hda_verb alc262_HP_BPC_init_verbs[] = {
{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)
*/
@@ -9404,6 +10199,24 @@ static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
{ }
};
+static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
+
+ {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
+ {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
+ {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
+
+ {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
+ {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
+ {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
+ {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
+
+ {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
+ {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
+ {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
+ {}
+};
+
+
#ifdef CONFIG_SND_HDA_POWER_SAVE
#define alc262_loopbacks alc880_loopbacks
#endif
@@ -9460,6 +10273,7 @@ static int alc262_parse_auto_config(struct hda_codec *codec)
#define alc262_auto_init_multi_out alc882_auto_init_multi_out
#define alc262_auto_init_hp_out alc882_auto_init_hp_out
#define alc262_auto_init_analog_input alc882_auto_init_analog_input
+#define alc262_auto_init_input_src alc882_auto_init_input_src
/* init callback for auto-configuration model -- overriding the default init */
@@ -9469,6 +10283,7 @@ static void alc262_auto_init(struct hda_codec *codec)
alc262_auto_init_multi_out(codec);
alc262_auto_init_hp_out(codec);
alc262_auto_init_analog_input(codec);
+ alc262_auto_init_input_src(codec);
if (spec->unsol_event)
alc_sku_automute(codec);
}
@@ -9488,13 +10303,17 @@ static const char *alc262_models[ALC262_MODEL_LAST] = {
[ALC262_BENQ_ED8] = "benq",
[ALC262_BENQ_T31] = "benq-t31",
[ALC262_SONY_ASSAMD] = "sony-assamd",
+ [ALC262_TOSHIBA_S06] = "toshiba-s06",
+ [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
[ALC262_ULTRA] = "ultra",
[ALC262_LENOVO_3000] = "lenovo-3000",
+ [ALC262_NEC] = "nec",
[ALC262_AUTO] = "auto",
};
static struct snd_pci_quirk alc262_cfg_tbl[] = {
SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
+ SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
SND_PCI_QUIRK(0x103c, 0x12fe, "HP xw9400", ALC262_HP_BPC),
SND_PCI_QUIRK(0x103c, 0x12ff, "HP xw4550", ALC262_HP_BPC),
SND_PCI_QUIRK(0x103c, 0x1306, "HP xw8600", ALC262_HP_BPC),
@@ -9522,6 +10341,9 @@ static struct snd_pci_quirk alc262_cfg_tbl[] = {
SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD),
SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD),
+ SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
+ ALC262_TOSHIBA_RX1),
+ SND_PCI_QUIRK(0x1179, 0x0268, "Toshiba S06", ALC262_TOSHIBA_S06),
SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
SND_PCI_QUIRK(0x144d, 0xc032, "Samsung Q1 Ultra", ALC262_ULTRA),
@@ -9675,7 +10497,7 @@ static struct alc_config_preset alc262_presets[] = {
.input_mux = &alc262_capture_source,
.unsol_event = alc262_hippo_unsol_event,
.init_hook = alc262_hippo_automute,
- },
+ },
[ALC262_ULTRA] = {
.mixers = { alc262_ultra_mixer, alc262_ultra_capture_mixer },
.init_verbs = { alc262_ultra_verbs },
@@ -9703,6 +10525,43 @@ static struct alc_config_preset alc262_presets[] = {
.input_mux = &alc262_fujitsu_capture_source,
.unsol_event = alc262_lenovo_3000_unsol_event,
},
+ [ALC262_NEC] = {
+ .mixers = { alc262_nec_mixer },
+ .init_verbs = { alc262_nec_verbs },
+ .num_dacs = ARRAY_SIZE(alc262_dac_nids),
+ .dac_nids = alc262_dac_nids,
+ .hp_nid = 0x03,
+ .num_channel_mode = ARRAY_SIZE(alc262_modes),
+ .channel_mode = alc262_modes,
+ .input_mux = &alc262_capture_source,
+ },
+ [ALC262_TOSHIBA_S06] = {
+ .mixers = { alc262_toshiba_s06_mixer },
+ .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
+ alc262_eapd_verbs },
+ .num_dacs = ARRAY_SIZE(alc262_dac_nids),
+ .capsrc_nids = alc262_dmic_capsrc_nids,
+ .dac_nids = alc262_dac_nids,
+ .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
+ .dig_out_nid = ALC262_DIGOUT_NID,
+ .num_channel_mode = ARRAY_SIZE(alc262_modes),
+ .channel_mode = alc262_modes,
+ .input_mux = &alc262_dmic_capture_source,
+ .unsol_event = alc262_toshiba_s06_unsol_event,
+ .init_hook = alc262_toshiba_s06_init_hook,
+ },
+ [ALC262_TOSHIBA_RX1] = {
+ .mixers = { alc262_toshiba_rx1_mixer },
+ .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
+ .num_dacs = ARRAY_SIZE(alc262_dac_nids),
+ .dac_nids = alc262_dac_nids,
+ .hp_nid = 0x03,
+ .num_channel_mode = ARRAY_SIZE(alc262_modes),
+ .channel_mode = alc262_modes,
+ .input_mux = &alc262_capture_source,
+ .unsol_event = alc262_hippo_unsol_event,
+ .init_hook = alc262_hippo_automute,
+ },
};
static int patch_alc262(struct hda_codec *codec)
@@ -9729,6 +10588,8 @@ static int patch_alc262(struct hda_codec *codec)
}
#endif
+ alc_fix_pll_init(codec, 0x20, 0x0a, 10);
+
board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
alc262_models,
alc262_cfg_tbl);
@@ -9759,7 +10620,7 @@ static int patch_alc262(struct hda_codec *codec)
spec->stream_name_analog = "ALC262 Analog";
spec->stream_analog_playback = &alc262_pcm_analog_playback;
spec->stream_analog_capture = &alc262_pcm_analog_capture;
-
+
spec->stream_name_digital = "ALC262 Digital";
spec->stream_digital_playback = &alc262_pcm_digital_playback;
spec->stream_digital_capture = &alc262_pcm_digital_capture;
@@ -9795,7 +10656,7 @@ static int patch_alc262(struct hda_codec *codec)
if (!spec->loopback.amplist)
spec->loopback.amplist = alc262_loopbacks;
#endif
-
+
return 0;
}
@@ -9804,7 +10665,7 @@ static int patch_alc262(struct hda_codec *codec)
*/
#define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
#define alc268_modes alc260_modes
-
+
static hda_nid_t alc268_dac_nids[2] = {
/* front, hp */
0x02, 0x03
@@ -9864,6 +10725,14 @@ static struct hda_verb alc268_toshiba_verbs[] = {
{ } /* end */
};
+static struct hda_input_mux alc268_acer_lc_capture_source = {
+ .num_items = 2,
+ .items = {
+ { "i-Mic", 0x6 },
+ { "E-Mic", 0x0 },
+ },
+};
+
/* Acer specific */
/* bind volumes of both NID 0x02 and 0x03 */
static struct hda_bind_ctls alc268_acer_bind_master_vol = {
@@ -9916,6 +10785,21 @@ static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
return change;
}
+static struct snd_kcontrol_new alc268_acer_aspire_one_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),
+ },
+ HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
+ { }
+};
+
static struct snd_kcontrol_new alc268_acer_mixer[] = {
/* output mixer control */
HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
@@ -9933,6 +10817,16 @@ static struct snd_kcontrol_new alc268_acer_mixer[] = {
{ }
};
+static struct hda_verb alc268_acer_aspire_one_verbs[] = {
+ {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
+ {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+ {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
+ {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
+ {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
+ {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
+ { }
+};
+
static struct hda_verb alc268_acer_verbs[] = {
{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
@@ -9940,7 +10834,6 @@ static struct hda_verb alc268_acer_verbs[] = {
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
-
{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
{ }
};
@@ -9967,6 +10860,47 @@ static void alc268_acer_init_hook(struct hda_codec *codec)
alc268_acer_automute(codec, 1);
}
+/* toggle speaker-output according to the hp-jack state */
+static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)
+{
+ unsigned int present;
+ unsigned char bits;
+
+ present = snd_hda_codec_read(codec, 0x15, 0,
+ AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
+ bits = present ? AMP_IN_MUTE(0) : 0;
+ snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0,
+ AMP_IN_MUTE(0), bits);
+ snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1,
+ AMP_IN_MUTE(0), bits);
+}
+
+
+static void alc268_acer_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, 0x23, 0, AC_VERB_SET_CONNECT_SEL,
+ present ? 0x0 : 0x6);
+}
+
+static void alc268_acer_lc_unsol_event(struct hda_codec *codec,
+ unsigned int res)
+{
+ if ((res >> 26) == ALC880_HP_EVENT)
+ alc268_aspire_one_speaker_automute(codec);
+ if ((res >> 26) == ALC880_MIC_EVENT)
+ alc268_acer_mic_automute(codec);
+}
+
+static void alc268_acer_lc_init_hook(struct hda_codec *codec)
+{
+ alc268_aspire_one_speaker_automute(codec);
+ alc268_acer_mic_automute(codec);
+}
+
static struct snd_kcontrol_new alc268_dell_mixer[] = {
/* output mixer control */
HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
@@ -10115,7 +11049,7 @@ static struct hda_verb alc268_base_init_verbs[] = {
{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
/* Unmute Selector 23h,24h and set the default input to mic-in */
-
+
{0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
{0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
@@ -10314,7 +11248,7 @@ static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
nid = cfg->line_out_pins[0];
if (nid)
- alc268_new_analog_output(spec, nid, "Front", 0);
+ alc268_new_analog_output(spec, nid, "Front", 0);
nid = cfg->speaker_pins[0];
if (nid == 0x1d) {
@@ -10336,7 +11270,7 @@ static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
if (err < 0)
return err;
}
- return 0;
+ return 0;
}
/* create playback/capture controls for input pins */
@@ -10357,7 +11291,7 @@ static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec,
case 0x1a:
idx1 = 2; /* Line In */
break;
- case 0x1c:
+ case 0x1c:
idx1 = 3; /* CD */
break;
case 0x12:
@@ -10369,7 +11303,7 @@ static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec,
}
imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
imux->items[imux->num_items].index = idx1;
- imux->num_items++;
+ imux->num_items++;
}
return 0;
}
@@ -10399,11 +11333,11 @@ static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
}
dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
- if (line_nid == 0x14)
+ if (line_nid == 0x14)
dac_vol2 = AMP_OUT_ZERO;
else if (line_nid == 0x15)
dac_vol1 = AMP_OUT_ZERO;
- if (hp_nid == 0x14)
+ if (hp_nid == 0x14)
dac_vol2 = AMP_OUT_ZERO;
else if (hp_nid == 0x15)
dac_vol1 = AMP_OUT_ZERO;
@@ -10494,6 +11428,7 @@ static const char *alc268_models[ALC268_MODEL_LAST] = {
[ALC268_3ST] = "3stack",
[ALC268_TOSHIBA] = "toshiba",
[ALC268_ACER] = "acer",
+ [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
[ALC268_DELL] = "dell",
[ALC268_ZEPTO] = "zepto",
#ifdef CONFIG_SND_DEBUG
@@ -10508,11 +11443,14 @@ static struct snd_pci_quirk alc268_cfg_tbl[] = {
SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
+ SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
+ ALC268_ACER_ASPIRE_ONE),
SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA),
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(0x1179, 0xff64, "TOSHIBA L305", ALC268_TOSHIBA),
SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
@@ -10585,6 +11523,23 @@ static struct alc_config_preset alc268_presets[] = {
.unsol_event = alc268_acer_unsol_event,
.init_hook = alc268_acer_init_hook,
},
+ [ALC268_ACER_ASPIRE_ONE] = {
+ .mixers = { alc268_acer_aspire_one_mixer,
+ alc268_capture_alt_mixer },
+ .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
+ alc268_acer_aspire_one_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,
+ .capsrc_nids = alc268_capsrc_nids,
+ .hp_nid = 0x03,
+ .num_channel_mode = ARRAY_SIZE(alc268_modes),
+ .channel_mode = alc268_modes,
+ .input_mux = &alc268_acer_lc_capture_source,
+ .unsol_event = alc268_acer_lc_unsol_event,
+ .init_hook = alc268_acer_lc_init_hook,
+ },
[ALC268_DELL] = {
.mixers = { alc268_dell_mixer, alc268_beep_mixer },
.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
@@ -10674,12 +11629,18 @@ static int patch_alc268(struct hda_codec *codec)
if (board_config != ALC268_AUTO)
setup_preset(spec, &alc268_presets[board_config]);
- spec->stream_name_analog = "ALC268 Analog";
+ if (codec->vendor_id == 0x10ec0267) {
+ spec->stream_name_analog = "ALC267 Analog";
+ spec->stream_name_digital = "ALC267 Digital";
+ } else {
+ spec->stream_name_analog = "ALC268 Analog";
+ spec->stream_name_digital = "ALC268 Digital";
+ }
+
spec->stream_analog_playback = &alc268_pcm_analog_playback;
spec->stream_analog_capture = &alc268_pcm_analog_capture;
spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
- spec->stream_name_digital = "ALC268 Digital";
spec->stream_digital_playback = &alc268_pcm_digital_playback;
if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
@@ -10723,7 +11684,7 @@ static int patch_alc268(struct hda_codec *codec)
codec->patch_ops = alc_patch_ops;
if (board_config == ALC268_AUTO)
spec->init_hook = alc268_auto_init;
-
+
return 0;
}
@@ -10736,7 +11697,31 @@ static int patch_alc268(struct hda_codec *codec)
static hda_nid_t alc269_adc_nids[1] = {
/* ADC1 */
- 0x07,
+ 0x08,
+};
+
+static hda_nid_t alc269_capsrc_nids[1] = {
+ 0x23,
+};
+
+/* NOTE: ADC2 (0x07) is connected from a recording *MIXER* (0x24),
+ * not a mux!
+ */
+
+static struct hda_input_mux alc269_eeepc_dmic_capture_source = {
+ .num_items = 2,
+ .items = {
+ { "i-Mic", 0x5 },
+ { "e-Mic", 0x0 },
+ },
+};
+
+static struct hda_input_mux alc269_eeepc_amic_capture_source = {
+ .num_items = 2,
+ .items = {
+ { "i-Mic", 0x1 },
+ { "e-Mic", 0x0 },
+ },
};
#define alc269_modes alc260_modes
@@ -10749,6 +11734,8 @@ static struct snd_kcontrol_new alc269_base_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("Beep Playback Volume", 0x0b, 0x4, HDA_INPUT),
+ HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x4, HDA_INPUT),
HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
@@ -10758,10 +11745,49 @@ static struct snd_kcontrol_new alc269_base_mixer[] = {
{ } /* end */
};
+static struct snd_kcontrol_new alc269_quanta_fl1_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),
+ },
+ 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("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
+ HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
+ HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
+ HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x04, HDA_INPUT),
+ HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x04, HDA_INPUT),
+ { }
+};
+
+/* bind volumes of both NID 0x0c and 0x0d */
+static struct hda_bind_ctls alc269_epc_bind_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
+ },
+};
+
+static struct snd_kcontrol_new alc269_eeepc_mixer[] = {
+ HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
+ HDA_BIND_VOL("LineOut Playback Volume", &alc269_epc_bind_vol),
+ HDA_CODEC_MUTE("LineOut Playback Switch", 0x15, 0x0, HDA_OUTPUT),
+ { } /* end */
+};
+
/* capture mixer elements */
static struct snd_kcontrol_new alc269_capture_mixer[] = {
- HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
- HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
+ HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
+ HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
/* The multiple "Capture Source" controls confuse alsamixer
@@ -10777,6 +11803,172 @@ static struct snd_kcontrol_new alc269_capture_mixer[] = {
{ } /* end */
};
+/* capture mixer elements */
+static struct snd_kcontrol_new alc269_epc_capture_mixer[] = {
+ HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
+ HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
+ { } /* end */
+};
+
+/* beep control */
+static struct snd_kcontrol_new alc269_beep_mixer[] = {
+ HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x4, HDA_INPUT),
+ HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x4, HDA_INPUT),
+ { } /* end */
+};
+
+static struct hda_verb alc269_quanta_fl1_verbs[] = {
+ {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
+ {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
+ {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+ {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
+ {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
+ {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
+ { }
+};
+
+/* toggle speaker-output according to the hp-jack state */
+static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
+{
+ unsigned int present;
+ unsigned char bits;
+
+ present = snd_hda_codec_read(codec, 0x15, 0,
+ AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
+ bits = present ? AMP_IN_MUTE(0) : 0;
+ snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
+ AMP_IN_MUTE(0), bits);
+ snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
+ AMP_IN_MUTE(0), bits);
+
+ snd_hda_codec_write(codec, 0x20, 0,
+ AC_VERB_SET_COEF_INDEX, 0x0c);
+ snd_hda_codec_write(codec, 0x20, 0,
+ AC_VERB_SET_PROC_COEF, 0x680);
+
+ snd_hda_codec_write(codec, 0x20, 0,
+ AC_VERB_SET_COEF_INDEX, 0x0c);
+ snd_hda_codec_write(codec, 0x20, 0,
+ AC_VERB_SET_PROC_COEF, 0x480);
+}
+
+static void alc269_quanta_fl1_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, 0x23, 0,
+ AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x1);
+}
+
+static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
+ unsigned int res)
+{
+ if ((res >> 26) == ALC880_HP_EVENT)
+ alc269_quanta_fl1_speaker_automute(codec);
+ if ((res >> 26) == ALC880_MIC_EVENT)
+ alc269_quanta_fl1_mic_automute(codec);
+}
+
+static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
+{
+ alc269_quanta_fl1_speaker_automute(codec);
+ alc269_quanta_fl1_mic_automute(codec);
+}
+
+static struct hda_verb alc269_eeepc_dmic_init_verbs[] = {
+ {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
+ {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
+ {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
+ {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
+ {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
+ {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
+ {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
+ {}
+};
+
+static struct hda_verb alc269_eeepc_amic_init_verbs[] = {
+ {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
+ {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
+ {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
+ {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
+ {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
+ {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
+ {}
+};
+
+/* toggle speaker-output according to the hp-jack state */
+static void alc269_speaker_automute(struct hda_codec *codec)
+{
+ unsigned int present;
+ unsigned char bits;
+
+ present = snd_hda_codec_read(codec, 0x15, 0,
+ AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
+ bits = present ? AMP_IN_MUTE(0) : 0;
+ snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
+ AMP_IN_MUTE(0), bits);
+ snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
+ AMP_IN_MUTE(0), bits);
+}
+
+static void alc269_eeepc_dmic_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, 0x23, 0,
+ AC_VERB_SET_CONNECT_SEL, (present ? 0 : 5));
+}
+
+static void alc269_eeepc_amic_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, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
+ 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
+ snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
+ 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
+}
+
+/* unsolicited event for HP jack sensing */
+static void alc269_eeepc_dmic_unsol_event(struct hda_codec *codec,
+ unsigned int res)
+{
+ if ((res >> 26) == ALC880_HP_EVENT)
+ alc269_speaker_automute(codec);
+
+ if ((res >> 26) == ALC880_MIC_EVENT)
+ alc269_eeepc_dmic_automute(codec);
+}
+
+static void alc269_eeepc_dmic_inithook(struct hda_codec *codec)
+{
+ alc269_speaker_automute(codec);
+ alc269_eeepc_dmic_automute(codec);
+}
+
+/* unsolicited event for HP jack sensing */
+static void alc269_eeepc_amic_unsol_event(struct hda_codec *codec,
+ unsigned int res)
+{
+ if ((res >> 26) == ALC880_HP_EVENT)
+ alc269_speaker_automute(codec);
+
+ if ((res >> 26) == ALC880_MIC_EVENT)
+ alc269_eeepc_amic_automute(codec);
+}
+
+static void alc269_eeepc_amic_inithook(struct hda_codec *codec)
+{
+ alc269_speaker_automute(codec);
+ alc269_eeepc_amic_automute(codec);
+}
+
/*
* generic initialization of ADC, input mixers and output mixers
*/
@@ -10836,8 +12028,8 @@ static struct hda_verb alc269_init_verbs[] = {
/* FIXME: use matrix-type input source selection */
/* Mixer elements: 0x18, 19, 1a, 1b, 1d, 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(1)},
+ {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+ {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
@@ -10947,7 +12139,7 @@ static int alc269_auto_create_multi_out_ctls(struct alc_spec *spec,
static int alc269_parse_auto_config(struct hda_codec *codec)
{
struct alc_spec *spec = codec->spec;
- int err;
+ int i, err;
static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
@@ -10970,14 +12162,28 @@ static int alc269_parse_auto_config(struct hda_codec *codec)
if (spec->kctl_alloc)
spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
+ /* create a beep mixer control if the pin 0x1d isn't assigned */
+ for (i = 0; i < ARRAY_SIZE(spec->autocfg.input_pins); i++)
+ if (spec->autocfg.input_pins[i] == 0x1d)
+ break;
+ if (i >= ARRAY_SIZE(spec->autocfg.input_pins))
+ spec->mixers[spec->num_mixers++] = alc269_beep_mixer;
+
spec->init_verbs[spec->num_init_verbs++] = alc269_init_verbs;
spec->num_mux_defs = 1;
spec->input_mux = &spec->private_imux;
+ /* set default input source */
+ snd_hda_codec_write_cache(codec, alc269_capsrc_nids[0],
+ 0, AC_VERB_SET_CONNECT_SEL,
+ spec->input_mux->items[0].index);
err = alc_auto_add_mic_boost(codec);
if (err < 0)
return err;
+ spec->mixers[spec->num_mixers] = alc269_capture_mixer;
+ spec->num_mixers++;
+
return 1;
}
@@ -11001,16 +12207,26 @@ static void alc269_auto_init(struct hda_codec *codec)
* configuration and preset
*/
static const char *alc269_models[ALC269_MODEL_LAST] = {
- [ALC269_BASIC] = "basic",
+ [ALC269_BASIC] = "basic",
+ [ALC269_QUANTA_FL1] = "quanta",
+ [ALC269_ASUS_EEEPC_P703] = "eeepc-p703",
+ [ALC269_ASUS_EEEPC_P901] = "eeepc-p901"
};
static struct snd_pci_quirk alc269_cfg_tbl[] = {
+ SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
+ SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
+ ALC269_ASUS_EEEPC_P703),
+ SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
+ ALC269_ASUS_EEEPC_P901),
+ SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
+ ALC269_ASUS_EEEPC_P901),
{}
};
static struct alc_config_preset alc269_presets[] = {
[ALC269_BASIC] = {
- .mixers = { alc269_base_mixer },
+ .mixers = { alc269_base_mixer, alc269_capture_mixer },
.init_verbs = { alc269_init_verbs },
.num_dacs = ARRAY_SIZE(alc269_dac_nids),
.dac_nids = alc269_dac_nids,
@@ -11019,6 +12235,44 @@ static struct alc_config_preset alc269_presets[] = {
.channel_mode = alc269_modes,
.input_mux = &alc269_capture_source,
},
+ [ALC269_QUANTA_FL1] = {
+ .mixers = { alc269_quanta_fl1_mixer },
+ .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
+ .num_dacs = ARRAY_SIZE(alc269_dac_nids),
+ .dac_nids = alc269_dac_nids,
+ .hp_nid = 0x03,
+ .num_channel_mode = ARRAY_SIZE(alc269_modes),
+ .channel_mode = alc269_modes,
+ .input_mux = &alc269_capture_source,
+ .unsol_event = alc269_quanta_fl1_unsol_event,
+ .init_hook = alc269_quanta_fl1_init_hook,
+ },
+ [ALC269_ASUS_EEEPC_P703] = {
+ .mixers = { alc269_eeepc_mixer, alc269_epc_capture_mixer },
+ .init_verbs = { alc269_init_verbs,
+ alc269_eeepc_amic_init_verbs },
+ .num_dacs = ARRAY_SIZE(alc269_dac_nids),
+ .dac_nids = alc269_dac_nids,
+ .hp_nid = 0x03,
+ .num_channel_mode = ARRAY_SIZE(alc269_modes),
+ .channel_mode = alc269_modes,
+ .input_mux = &alc269_eeepc_amic_capture_source,
+ .unsol_event = alc269_eeepc_amic_unsol_event,
+ .init_hook = alc269_eeepc_amic_inithook,
+ },
+ [ALC269_ASUS_EEEPC_P901] = {
+ .mixers = { alc269_eeepc_mixer, alc269_epc_capture_mixer},
+ .init_verbs = { alc269_init_verbs,
+ alc269_eeepc_dmic_init_verbs },
+ .num_dacs = ARRAY_SIZE(alc269_dac_nids),
+ .dac_nids = alc269_dac_nids,
+ .hp_nid = 0x03,
+ .num_channel_mode = ARRAY_SIZE(alc269_modes),
+ .channel_mode = alc269_modes,
+ .input_mux = &alc269_eeepc_dmic_capture_source,
+ .unsol_event = alc269_eeepc_dmic_unsol_event,
+ .init_hook = alc269_eeepc_dmic_inithook,
+ },
};
static int patch_alc269(struct hda_codec *codec)
@@ -11033,6 +12287,8 @@ static int patch_alc269(struct hda_codec *codec)
codec->spec = spec;
+ alc_fix_pll_init(codec, 0x20, 0x04, 15);
+
board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
alc269_models,
alc269_cfg_tbl);
@@ -11070,8 +12326,7 @@ static int patch_alc269(struct hda_codec *codec)
spec->adc_nids = alc269_adc_nids;
spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
- spec->mixers[spec->num_mixers] = alc269_capture_mixer;
- spec->num_mixers++;
+ spec->capsrc_nids = alc269_capsrc_nids;
codec->patch_ops = alc_patch_ops;
if (board_config == ALC269_AUTO)
@@ -11273,7 +12528,7 @@ static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
-
+
/*Capture mixer control */
HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
@@ -11416,20 +12671,20 @@ static struct hda_verb alc861_base_init_verbs[] = {
/* route front mic to ADC1*/
{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-
+
/* Unmute DAC0~3 & spdif out*/
{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-
+
/* Unmute Mixer 14 (mic) 1c (Line in)*/
{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-
+
/* Unmute Stereo Mixer 15 */
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
@@ -11485,13 +12740,13 @@ static struct hda_verb alc861_threestack_init_verbs[] = {
{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-
+
/* Unmute Mixer 14 (mic) 1c (Line in)*/
{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-
+
/* Unmute Stereo Mixer 15 */
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
@@ -11547,13 +12802,13 @@ static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-
+
/* Unmute Mixer 14 (mic) 1c (Line in)*/
{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-
+
/* Unmute Stereo Mixer 15 */
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
@@ -11618,7 +12873,7 @@ static struct hda_verb alc861_asus_init_verbs[] = {
{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-
+
/* Unmute Stereo Mixer 15 */
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
@@ -11655,20 +12910,20 @@ static struct hda_verb alc861_auto_init_verbs[] = {
*/
/* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-
+
/* Unmute DAC0~3 & spdif out*/
{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-
+
/* Unmute Mixer 14 (mic) 1c (Line in)*/
{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-
+
/* Unmute Stereo Mixer 15 */
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
@@ -12243,7 +13498,7 @@ static int patch_alc861(struct hda_codec *codec)
if (!spec->loopback.amplist)
spec->loopback.amplist = alc861_loopbacks;
#endif
-
+
return 0;
}
@@ -12497,7 +13752,7 @@ static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
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 */
};
@@ -12631,12 +13886,18 @@ static struct hda_verb alc861vd_eapd_verbs[] = {
{ }
};
+static struct hda_verb alc660vd_eapd_verbs[] = {
+ {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
+ {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
+ { }
+};
+
static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
- {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
+ {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
{}
};
@@ -12698,7 +13959,7 @@ static struct hda_verb alc861vd_dallas_verbs[] = {
{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-
+
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
@@ -12723,7 +13984,7 @@ static struct hda_verb alc861vd_dallas_verbs[] = {
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
- {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
+ {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
{ } /* end */
@@ -12776,6 +14037,7 @@ static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
+ SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC861VD_LENOVO),
SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
@@ -12786,6 +14048,7 @@ static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO),
SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO),
+ SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 N200", ALC861VD_LENOVO),
SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
{}
};
@@ -12880,7 +14143,7 @@ static struct alc_config_preset alc861vd_presets[] = {
.input_mux = &alc861vd_hp_capture_source,
.unsol_event = alc861vd_dallas_unsol_event,
.init_hook = alc861vd_dallas_automute,
- },
+ },
};
/*
@@ -12944,6 +14207,8 @@ static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
}
}
+#define alc861vd_auto_init_input_src alc882_auto_init_input_src
+
#define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
#define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
@@ -13126,6 +14391,7 @@ static void alc861vd_auto_init(struct hda_codec *codec)
alc861vd_auto_init_multi_out(codec);
alc861vd_auto_init_hp_out(codec);
alc861vd_auto_init_analog_input(codec);
+ alc861vd_auto_init_input_src(codec);
if (spec->unsol_event)
alc_sku_automute(codec);
}
@@ -13168,11 +14434,19 @@ static int patch_alc861vd(struct hda_codec *codec)
if (board_config != ALC861VD_AUTO)
setup_preset(spec, &alc861vd_presets[board_config]);
- spec->stream_name_analog = "ALC861VD Analog";
+ if (codec->vendor_id == 0x10ec0660) {
+ spec->stream_name_analog = "ALC660-VD Analog";
+ spec->stream_name_digital = "ALC660-VD Digital";
+ /* always turn on EAPD */
+ spec->init_verbs[spec->num_init_verbs++] = alc660vd_eapd_verbs;
+ } else {
+ spec->stream_name_analog = "ALC861VD Analog";
+ spec->stream_name_digital = "ALC861VD Digital";
+ }
+
spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
- spec->stream_name_digital = "ALC861VD Digital";
spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
@@ -13251,6 +14525,23 @@ static struct hda_input_mux alc662_eeepc_capture_source = {
},
};
+static struct hda_input_mux alc663_capture_source = {
+ .num_items = 3,
+ .items = {
+ { "Mic", 0x0 },
+ { "Front Mic", 0x1 },
+ { "Line", 0x2 },
+ },
+};
+
+static struct hda_input_mux alc663_m51va_capture_source = {
+ .num_items = 2,
+ .items = {
+ { "Ext-Mic", 0x0 },
+ { "D-Mic", 0x9 },
+ },
+};
+
#define alc662_mux_enum_info alc_mux_enum_info
#define alc662_mux_enum_get alc_mux_enum_get
#define alc662_mux_enum_put alc882_mux_enum_put
@@ -13431,6 +14722,151 @@ static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
{ } /* end */
};
+static struct hda_bind_ctls alc663_asus_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
+ },
+};
+
+static struct hda_bind_ctls alc663_asus_one_bind_switch = {
+ .ops = &snd_hda_bind_sw,
+ .values = {
+ HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
+ HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
+ 0
+ },
+};
+
+static struct snd_kcontrol_new alc663_m51va_mixer[] = {
+ HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
+ HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
+ HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
+ HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
+ { } /* end */
+};
+
+static struct hda_bind_ctls alc663_asus_tree_bind_switch = {
+ .ops = &snd_hda_bind_sw,
+ .values = {
+ HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
+ HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
+ HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
+ 0
+ },
+};
+
+static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
+ HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
+ HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
+ HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
+ HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
+ HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
+ HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
+
+ { } /* end */
+};
+
+static struct hda_bind_ctls alc663_asus_four_bind_switch = {
+ .ops = &snd_hda_bind_sw,
+ .values = {
+ HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
+ HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
+ HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
+ 0
+ },
+};
+
+static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
+ HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
+ HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
+ HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
+ HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
+ HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
+ HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
+ { } /* end */
+};
+
+static struct snd_kcontrol_new alc662_1bjd_mixer[] = {
+ HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
+ HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
+ HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, 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("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
+ HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
+ { } /* end */
+};
+
+static struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
+ .ops = &snd_hda_bind_vol,
+ .values = {
+ HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
+ HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
+ 0
+ },
+};
+
+static struct hda_bind_ctls alc663_asus_two_bind_switch = {
+ .ops = &snd_hda_bind_sw,
+ .values = {
+ HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
+ HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
+ 0
+ },
+};
+
+static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
+ HDA_BIND_VOL("Master Playback Volume",
+ &alc663_asus_two_bind_master_vol),
+ HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
+ HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
+ HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
+ HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
+ HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
+ { } /* end */
+};
+
+static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
+ HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
+ HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
+ HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
+ HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
+ HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
+ HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
+ { } /* end */
+};
+
+static struct snd_kcontrol_new alc663_g71v_mixer[] = {
+ HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
+ HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
+ HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
+ HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
+ HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, 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("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 alc663_g50v_mixer[] = {
+ HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
+ HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
+ HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, 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("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
+ HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
+ HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
+ HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
+ { } /* end */
+};
+
static struct snd_kcontrol_new alc662_chmode_mixer[] = {
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -13501,6 +14937,11 @@ static struct hda_verb alc662_init_verbs[] = {
{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)},
+
+ /* always trun on EAPD */
+ {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
+ {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
+
{ }
};
@@ -13571,6 +15012,125 @@ static struct hda_verb alc662_auto_init_verbs[] = {
{ }
};
+/* additional verbs for ALC663 */
+static struct hda_verb alc663_auto_init_verbs[] = {
+ {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+ {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+ { }
+};
+
+static struct hda_verb alc663_m51va_init_verbs[] = {
+ {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
+ {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
+ {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+ {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+ {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
+ {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+ {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
+ {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
+ {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
+ {}
+};
+
+static struct hda_verb alc663_21jd_amic_init_verbs[] = {
+ {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+ {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+ {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
+ {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+ {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+ {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
+ {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
+ {}
+};
+
+static struct hda_verb alc662_1bjd_amic_init_verbs[] = {
+ {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
+ {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+ {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+ {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
+ {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+ {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+ {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
+ {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
+ {}
+};
+
+static struct hda_verb alc663_15jd_amic_init_verbs[] = {
+ {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+ {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+ {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
+ {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+ {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+ {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
+ {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
+ {}
+};
+
+static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
+ {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
+ {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+ {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+ {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
+ {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+ {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+ {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
+ {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+ {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+ {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
+ {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
+ {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
+ {}
+};
+
+static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
+ {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
+ {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+ {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+ {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
+ {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+ {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+ {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
+ {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+ {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+ {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
+ {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
+ {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
+ {}
+};
+
+static struct hda_verb alc663_g71v_init_verbs[] = {
+ {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+ /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
+ /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
+
+ {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+ {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+ {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
+
+ {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
+ {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
+ {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
+ {}
+};
+
+static struct hda_verb alc663_g50v_init_verbs[] = {
+ {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+ {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+ {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
+
+ {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
+ {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
+ {}
+};
+
+static struct hda_verb alc662_ecs_init_verbs[] = {
+ {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
+ {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+ {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
+ {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
+ {}
+};
+
/* capture mixer elements */
static struct snd_kcontrol_new alc662_capture_mixer[] = {
HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
@@ -13590,6 +15150,12 @@ static struct snd_kcontrol_new alc662_capture_mixer[] = {
{ } /* end */
};
+static struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
+ HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
+ HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
+ { } /* end */
+};
+
static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
{
unsigned int present;
@@ -13670,12 +15236,12 @@ static void alc662_eeepc_ep20_automute(struct hda_codec *codec)
if (present) {
/* mute internal speaker */
snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
- HDA_AMP_MUTE, HDA_AMP_MUTE);
+ 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_stereo(codec, 0x1b, HDA_OUTPUT, 0,
- HDA_AMP_MUTE, mute);
+ HDA_AMP_MUTE, mute);
}
}
@@ -13692,6 +15258,377 @@ static void alc662_eeepc_ep20_inithook(struct hda_codec *codec)
alc662_eeepc_ep20_automute(codec);
}
+static void alc663_m51va_speaker_automute(struct hda_codec *codec)
+{
+ unsigned int present;
+ unsigned char bits;
+
+ present = snd_hda_codec_read(codec, 0x21, 0,
+ AC_VERB_GET_PIN_SENSE, 0)
+ & AC_PINSENSE_PRESENCE;
+ bits = present ? HDA_AMP_MUTE : 0;
+ snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
+ AMP_IN_MUTE(0), bits);
+ snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
+ AMP_IN_MUTE(0), bits);
+}
+
+static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)
+{
+ unsigned int present;
+ unsigned char bits;
+
+ present = snd_hda_codec_read(codec, 0x21, 0,
+ AC_VERB_GET_PIN_SENSE, 0)
+ & AC_PINSENSE_PRESENCE;
+ bits = present ? HDA_AMP_MUTE : 0;
+ snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
+ AMP_IN_MUTE(0), bits);
+ snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
+ AMP_IN_MUTE(0), bits);
+ snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
+ AMP_IN_MUTE(0), bits);
+ snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
+ AMP_IN_MUTE(0), bits);
+}
+
+static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
+{
+ unsigned int present;
+ unsigned char bits;
+
+ present = snd_hda_codec_read(codec, 0x15, 0,
+ AC_VERB_GET_PIN_SENSE, 0)
+ & AC_PINSENSE_PRESENCE;
+ bits = present ? HDA_AMP_MUTE : 0;
+ snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
+ AMP_IN_MUTE(0), bits);
+ snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
+ AMP_IN_MUTE(0), bits);
+ snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
+ AMP_IN_MUTE(0), bits);
+ snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
+ AMP_IN_MUTE(0), bits);
+}
+
+static void alc662_f5z_speaker_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)
+ & AC_PINSENSE_PRESENCE;
+ bits = present ? 0 : PIN_OUT;
+ snd_hda_codec_write(codec, 0x14, 0,
+ AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
+}
+
+static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec)
+{
+ unsigned int present1, present2;
+
+ present1 = snd_hda_codec_read(codec, 0x21, 0,
+ AC_VERB_GET_PIN_SENSE, 0)
+ & AC_PINSENSE_PRESENCE;
+ present2 = snd_hda_codec_read(codec, 0x15, 0,
+ AC_VERB_GET_PIN_SENSE, 0)
+ & AC_PINSENSE_PRESENCE;
+
+ if (present1 || present2) {
+ snd_hda_codec_write_cache(codec, 0x14, 0,
+ AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
+ } else {
+ snd_hda_codec_write_cache(codec, 0x14, 0,
+ AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
+ }
+}
+
+static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec)
+{
+ unsigned int present1, present2;
+
+ present1 = snd_hda_codec_read(codec, 0x1b, 0,
+ AC_VERB_GET_PIN_SENSE, 0)
+ & AC_PINSENSE_PRESENCE;
+ present2 = snd_hda_codec_read(codec, 0x15, 0,
+ AC_VERB_GET_PIN_SENSE, 0)
+ & AC_PINSENSE_PRESENCE;
+
+ if (present1 || present2) {
+ snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
+ AMP_IN_MUTE(0), AMP_IN_MUTE(0));
+ snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
+ AMP_IN_MUTE(0), AMP_IN_MUTE(0));
+ } else {
+ snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
+ AMP_IN_MUTE(0), 0);
+ snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
+ AMP_IN_MUTE(0), 0);
+ }
+}
+
+static void alc663_m51va_mic_automute(struct hda_codec *codec)
+{
+ unsigned int present;
+
+ present = snd_hda_codec_read(codec, 0x18, 0,
+ AC_VERB_GET_PIN_SENSE, 0)
+ & AC_PINSENSE_PRESENCE;
+ snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
+ 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
+ snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
+ 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
+ snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
+ 0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
+ snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
+ 0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
+}
+
+static void alc663_m51va_unsol_event(struct hda_codec *codec,
+ unsigned int res)
+{
+ switch (res >> 26) {
+ case ALC880_HP_EVENT:
+ alc663_m51va_speaker_automute(codec);
+ break;
+ case ALC880_MIC_EVENT:
+ alc663_m51va_mic_automute(codec);
+ break;
+ }
+}
+
+static void alc663_m51va_inithook(struct hda_codec *codec)
+{
+ alc663_m51va_speaker_automute(codec);
+ alc663_m51va_mic_automute(codec);
+}
+
+/* ***************** Mode1 ******************************/
+static void alc663_mode1_unsol_event(struct hda_codec *codec,
+ unsigned int res)
+{
+ switch (res >> 26) {
+ case ALC880_HP_EVENT:
+ alc663_m51va_speaker_automute(codec);
+ break;
+ case ALC880_MIC_EVENT:
+ alc662_eeepc_mic_automute(codec);
+ break;
+ }
+}
+
+static void alc663_mode1_inithook(struct hda_codec *codec)
+{
+ alc663_m51va_speaker_automute(codec);
+ alc662_eeepc_mic_automute(codec);
+}
+/* ***************** Mode2 ******************************/
+static void alc662_mode2_unsol_event(struct hda_codec *codec,
+ unsigned int res)
+{
+ switch (res >> 26) {
+ case ALC880_HP_EVENT:
+ alc662_f5z_speaker_automute(codec);
+ break;
+ case ALC880_MIC_EVENT:
+ alc662_eeepc_mic_automute(codec);
+ break;
+ }
+}
+
+static void alc662_mode2_inithook(struct hda_codec *codec)
+{
+ alc662_f5z_speaker_automute(codec);
+ alc662_eeepc_mic_automute(codec);
+}
+/* ***************** Mode3 ******************************/
+static void alc663_mode3_unsol_event(struct hda_codec *codec,
+ unsigned int res)
+{
+ switch (res >> 26) {
+ case ALC880_HP_EVENT:
+ alc663_two_hp_m1_speaker_automute(codec);
+ break;
+ case ALC880_MIC_EVENT:
+ alc662_eeepc_mic_automute(codec);
+ break;
+ }
+}
+
+static void alc663_mode3_inithook(struct hda_codec *codec)
+{
+ alc663_two_hp_m1_speaker_automute(codec);
+ alc662_eeepc_mic_automute(codec);
+}
+/* ***************** Mode4 ******************************/
+static void alc663_mode4_unsol_event(struct hda_codec *codec,
+ unsigned int res)
+{
+ switch (res >> 26) {
+ case ALC880_HP_EVENT:
+ alc663_21jd_two_speaker_automute(codec);
+ break;
+ case ALC880_MIC_EVENT:
+ alc662_eeepc_mic_automute(codec);
+ break;
+ }
+}
+
+static void alc663_mode4_inithook(struct hda_codec *codec)
+{
+ alc663_21jd_two_speaker_automute(codec);
+ alc662_eeepc_mic_automute(codec);
+}
+/* ***************** Mode5 ******************************/
+static void alc663_mode5_unsol_event(struct hda_codec *codec,
+ unsigned int res)
+{
+ switch (res >> 26) {
+ case ALC880_HP_EVENT:
+ alc663_15jd_two_speaker_automute(codec);
+ break;
+ case ALC880_MIC_EVENT:
+ alc662_eeepc_mic_automute(codec);
+ break;
+ }
+}
+
+static void alc663_mode5_inithook(struct hda_codec *codec)
+{
+ alc663_15jd_two_speaker_automute(codec);
+ alc662_eeepc_mic_automute(codec);
+}
+/* ***************** Mode6 ******************************/
+static void alc663_mode6_unsol_event(struct hda_codec *codec,
+ unsigned int res)
+{
+ switch (res >> 26) {
+ case ALC880_HP_EVENT:
+ alc663_two_hp_m2_speaker_automute(codec);
+ break;
+ case ALC880_MIC_EVENT:
+ alc662_eeepc_mic_automute(codec);
+ break;
+ }
+}
+
+static void alc663_mode6_inithook(struct hda_codec *codec)
+{
+ alc663_two_hp_m2_speaker_automute(codec);
+ alc662_eeepc_mic_automute(codec);
+}
+
+static void alc663_g71v_hp_automute(struct hda_codec *codec)
+{
+ unsigned int present;
+ unsigned char bits;
+
+ present = snd_hda_codec_read(codec, 0x21, 0,
+ AC_VERB_GET_PIN_SENSE, 0)
+ & AC_PINSENSE_PRESENCE;
+ 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 alc663_g71v_front_automute(struct hda_codec *codec)
+{
+ unsigned int present;
+ unsigned char bits;
+
+ present = snd_hda_codec_read(codec, 0x15, 0,
+ AC_VERB_GET_PIN_SENSE, 0)
+ & AC_PINSENSE_PRESENCE;
+ bits = present ? HDA_AMP_MUTE : 0;
+ snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
+ HDA_AMP_MUTE, bits);
+}
+
+static void alc663_g71v_unsol_event(struct hda_codec *codec,
+ unsigned int res)
+{
+ switch (res >> 26) {
+ case ALC880_HP_EVENT:
+ alc663_g71v_hp_automute(codec);
+ break;
+ case ALC880_FRONT_EVENT:
+ alc663_g71v_front_automute(codec);
+ break;
+ case ALC880_MIC_EVENT:
+ alc662_eeepc_mic_automute(codec);
+ break;
+ }
+}
+
+static void alc663_g71v_inithook(struct hda_codec *codec)
+{
+ alc663_g71v_front_automute(codec);
+ alc663_g71v_hp_automute(codec);
+ alc662_eeepc_mic_automute(codec);
+}
+
+static void alc663_g50v_unsol_event(struct hda_codec *codec,
+ unsigned int res)
+{
+ switch (res >> 26) {
+ case ALC880_HP_EVENT:
+ alc663_m51va_speaker_automute(codec);
+ break;
+ case ALC880_MIC_EVENT:
+ alc662_eeepc_mic_automute(codec);
+ break;
+ }
+}
+
+static void alc663_g50v_inithook(struct hda_codec *codec)
+{
+ alc663_m51va_speaker_automute(codec);
+ alc662_eeepc_mic_automute(codec);
+}
+
+/* bind hp and internal speaker mute (with plug check) */
+static int alc662_ecs_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, 0x1b, 0, HDA_OUTPUT, 0,
+ HDA_AMP_MUTE,
+ valp[0] ? 0 : HDA_AMP_MUTE);
+ change |= snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0,
+ HDA_AMP_MUTE,
+ valp[1] ? 0 : HDA_AMP_MUTE);
+ if (change)
+ alc262_hippo1_automute(codec);
+ return change;
+}
+
+static struct snd_kcontrol_new alc662_ecs_mixer[] = {
+ HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 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 = alc662_ecs_master_sw_put,
+ .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
+ },
+
+ HDA_CODEC_VOLUME("e-Mic/LineIn Boost", 0x18, 0, HDA_INPUT),
+ HDA_CODEC_VOLUME("e-Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
+ HDA_CODEC_MUTE("e-Mic/LineIn 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 */
+};
+
#ifdef CONFIG_SND_HDA_POWER_SAVE
#define alc662_loopbacks alc880_loopbacks
#endif
@@ -13714,14 +15651,70 @@ static const char *alc662_models[ALC662_MODEL_LAST] = {
[ALC662_LENOVO_101E] = "lenovo-101e",
[ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
[ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
+ [ALC662_ECS] = "ecs",
+ [ALC663_ASUS_M51VA] = "m51va",
+ [ALC663_ASUS_G71V] = "g71v",
+ [ALC663_ASUS_H13] = "h13",
+ [ALC663_ASUS_G50V] = "g50v",
+ [ALC663_ASUS_MODE1] = "asus-mode1",
+ [ALC662_ASUS_MODE2] = "asus-mode2",
+ [ALC663_ASUS_MODE3] = "asus-mode3",
+ [ALC663_ASUS_MODE4] = "asus-mode4",
+ [ALC663_ASUS_MODE5] = "asus-mode5",
+ [ALC663_ASUS_MODE6] = "asus-mode6",
[ALC662_AUTO] = "auto",
};
static struct snd_pci_quirk alc662_cfg_tbl[] = {
+ SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
+ SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS M51VA", ALC663_ASUS_G50V),
SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
+ SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
+ SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),
+ SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
+ SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
+ SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
+ SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),
+ SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
+ SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
+ SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
+ SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
+ SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
+ SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
+ SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
+ SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
+ SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
+ SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
+ SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
+ SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
+ SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
+ SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
+ SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
+ SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
+ SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
+ SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
+ SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
+ SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
+ SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
+ SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
+ SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
+ SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
+ SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
+ SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
+ ALC662_3ST_6ch_DIG),
SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
+ SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
+ SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
+ SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
+ ALC662_3ST_6ch_DIG),
+ SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
+ SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
+ ALC662_3ST_6ch_DIG),
+ SND_PCI_QUIRK(0x1854, 0x2000, "ASUS H13-2000", ALC663_ASUS_H13),
+ SND_PCI_QUIRK(0x1854, 0x2001, "ASUS H13-2001", ALC663_ASUS_H13),
+ SND_PCI_QUIRK(0x1854, 0x2002, "ASUS H13-2002", ALC663_ASUS_H13),
{}
};
@@ -13809,7 +15802,150 @@ static struct alc_config_preset alc662_presets[] = {
.unsol_event = alc662_eeepc_ep20_unsol_event,
.init_hook = alc662_eeepc_ep20_inithook,
},
-
+ [ALC662_ECS] = {
+ .mixers = { alc662_ecs_mixer, alc662_capture_mixer },
+ .init_verbs = { alc662_init_verbs,
+ alc662_ecs_init_verbs },
+ .num_dacs = ARRAY_SIZE(alc662_dac_nids),
+ .dac_nids = alc662_dac_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,
+ },
+ [ALC663_ASUS_M51VA] = {
+ .mixers = { alc663_m51va_mixer, alc662_capture_mixer},
+ .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
+ .num_dacs = ARRAY_SIZE(alc662_dac_nids),
+ .dac_nids = alc662_dac_nids,
+ .dig_out_nid = ALC662_DIGOUT_NID,
+ .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
+ .channel_mode = alc662_3ST_2ch_modes,
+ .input_mux = &alc663_m51va_capture_source,
+ .unsol_event = alc663_m51va_unsol_event,
+ .init_hook = alc663_m51va_inithook,
+ },
+ [ALC663_ASUS_G71V] = {
+ .mixers = { alc663_g71v_mixer, alc662_capture_mixer},
+ .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs },
+ .num_dacs = ARRAY_SIZE(alc662_dac_nids),
+ .dac_nids = alc662_dac_nids,
+ .dig_out_nid = ALC662_DIGOUT_NID,
+ .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
+ .channel_mode = alc662_3ST_2ch_modes,
+ .input_mux = &alc662_eeepc_capture_source,
+ .unsol_event = alc663_g71v_unsol_event,
+ .init_hook = alc663_g71v_inithook,
+ },
+ [ALC663_ASUS_H13] = {
+ .mixers = { alc663_m51va_mixer, alc662_capture_mixer},
+ .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
+ .num_dacs = ARRAY_SIZE(alc662_dac_nids),
+ .dac_nids = alc662_dac_nids,
+ .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
+ .channel_mode = alc662_3ST_2ch_modes,
+ .input_mux = &alc663_m51va_capture_source,
+ .unsol_event = alc663_m51va_unsol_event,
+ .init_hook = alc663_m51va_inithook,
+ },
+ [ALC663_ASUS_G50V] = {
+ .mixers = { alc663_g50v_mixer, alc662_capture_mixer},
+ .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs },
+ .num_dacs = ARRAY_SIZE(alc662_dac_nids),
+ .dac_nids = alc662_dac_nids,
+ .dig_out_nid = ALC662_DIGOUT_NID,
+ .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
+ .channel_mode = alc662_3ST_6ch_modes,
+ .input_mux = &alc663_capture_source,
+ .unsol_event = alc663_g50v_unsol_event,
+ .init_hook = alc663_g50v_inithook,
+ },
+ [ALC663_ASUS_MODE1] = {
+ .mixers = { alc663_m51va_mixer, alc662_auto_capture_mixer },
+ .init_verbs = { alc662_init_verbs,
+ alc663_21jd_amic_init_verbs },
+ .num_dacs = ARRAY_SIZE(alc662_dac_nids),
+ .hp_nid = 0x03,
+ .dac_nids = alc662_dac_nids,
+ .dig_out_nid = ALC662_DIGOUT_NID,
+ .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
+ .channel_mode = alc662_3ST_2ch_modes,
+ .input_mux = &alc662_eeepc_capture_source,
+ .unsol_event = alc663_mode1_unsol_event,
+ .init_hook = alc663_mode1_inithook,
+ },
+ [ALC662_ASUS_MODE2] = {
+ .mixers = { alc662_1bjd_mixer, alc662_auto_capture_mixer },
+ .init_verbs = { alc662_init_verbs,
+ alc662_1bjd_amic_init_verbs },
+ .num_dacs = ARRAY_SIZE(alc662_dac_nids),
+ .dac_nids = alc662_dac_nids,
+ .dig_out_nid = ALC662_DIGOUT_NID,
+ .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
+ .channel_mode = alc662_3ST_2ch_modes,
+ .input_mux = &alc662_eeepc_capture_source,
+ .unsol_event = alc662_mode2_unsol_event,
+ .init_hook = alc662_mode2_inithook,
+ },
+ [ALC663_ASUS_MODE3] = {
+ .mixers = { alc663_two_hp_m1_mixer, alc662_auto_capture_mixer },
+ .init_verbs = { alc662_init_verbs,
+ alc663_two_hp_amic_m1_init_verbs },
+ .num_dacs = ARRAY_SIZE(alc662_dac_nids),
+ .hp_nid = 0x03,
+ .dac_nids = alc662_dac_nids,
+ .dig_out_nid = ALC662_DIGOUT_NID,
+ .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
+ .channel_mode = alc662_3ST_2ch_modes,
+ .input_mux = &alc662_eeepc_capture_source,
+ .unsol_event = alc663_mode3_unsol_event,
+ .init_hook = alc663_mode3_inithook,
+ },
+ [ALC663_ASUS_MODE4] = {
+ .mixers = { alc663_asus_21jd_clfe_mixer,
+ alc662_auto_capture_mixer},
+ .init_verbs = { alc662_init_verbs,
+ alc663_21jd_amic_init_verbs},
+ .num_dacs = ARRAY_SIZE(alc662_dac_nids),
+ .hp_nid = 0x03,
+ .dac_nids = alc662_dac_nids,
+ .dig_out_nid = ALC662_DIGOUT_NID,
+ .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
+ .channel_mode = alc662_3ST_2ch_modes,
+ .input_mux = &alc662_eeepc_capture_source,
+ .unsol_event = alc663_mode4_unsol_event,
+ .init_hook = alc663_mode4_inithook,
+ },
+ [ALC663_ASUS_MODE5] = {
+ .mixers = { alc663_asus_15jd_clfe_mixer,
+ alc662_auto_capture_mixer },
+ .init_verbs = { alc662_init_verbs,
+ alc663_15jd_amic_init_verbs },
+ .num_dacs = ARRAY_SIZE(alc662_dac_nids),
+ .hp_nid = 0x03,
+ .dac_nids = alc662_dac_nids,
+ .dig_out_nid = ALC662_DIGOUT_NID,
+ .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
+ .channel_mode = alc662_3ST_2ch_modes,
+ .input_mux = &alc662_eeepc_capture_source,
+ .unsol_event = alc663_mode5_unsol_event,
+ .init_hook = alc663_mode5_inithook,
+ },
+ [ALC663_ASUS_MODE6] = {
+ .mixers = { alc663_two_hp_m2_mixer, alc662_auto_capture_mixer },
+ .init_verbs = { alc662_init_verbs,
+ alc663_two_hp_amic_m2_init_verbs },
+ .num_dacs = ARRAY_SIZE(alc662_dac_nids),
+ .hp_nid = 0x03,
+ .dac_nids = alc662_dac_nids,
+ .dig_out_nid = ALC662_DIGOUT_NID,
+ .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
+ .channel_mode = alc662_3ST_2ch_modes,
+ .input_mux = &alc662_eeepc_capture_source,
+ .unsol_event = alc663_mode6_unsol_event,
+ .init_hook = alc663_mode6_inithook,
+ },
};
@@ -13846,15 +15982,15 @@ static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
HDA_OUTPUT));
if (err < 0)
return err;
- err = add_control(spec, ALC_CTL_BIND_MUTE,
+ err = add_control(spec, ALC_CTL_WIDGET_MUTE,
"Center Playback Switch",
- HDA_COMPOSE_AMP_VAL(nid, 1, 2,
+ HDA_COMPOSE_AMP_VAL(0x0e, 1, 0,
HDA_INPUT));
if (err < 0)
return err;
- err = add_control(spec, ALC_CTL_BIND_MUTE,
+ err = add_control(spec, ALC_CTL_WIDGET_MUTE,
"LFE Playback Switch",
- HDA_COMPOSE_AMP_VAL(nid, 2, 2,
+ HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
HDA_INPUT));
if (err < 0)
return err;
@@ -13866,9 +16002,9 @@ static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
if (err < 0)
return err;
sprintf(name, "%s Playback Switch", chname[i]);
- err = add_control(spec, ALC_CTL_BIND_MUTE, name,
- HDA_COMPOSE_AMP_VAL(nid, 3, 2,
- HDA_INPUT));
+ err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
+ HDA_COMPOSE_AMP_VAL(alc880_idx_to_mixer(i),
+ 3, 0, HDA_INPUT));
if (err < 0)
return err;
}
@@ -13887,6 +16023,14 @@ static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
if (!pin)
return 0;
+ if (pin == 0x17) {
+ /* ALC663 has a mono output pin on 0x17 */
+ sprintf(name, "%s Playback Switch", pfx);
+ err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
+ HDA_COMPOSE_AMP_VAL(pin, 2, 0, HDA_OUTPUT));
+ return err;
+ }
+
if (alc880_is_fixed_pin(pin)) {
nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
/* printk("DAC nid=%x\n",nid); */
@@ -14011,6 +16155,8 @@ static void alc662_auto_init_analog_input(struct hda_codec *codec)
}
}
+#define alc662_auto_init_input_src alc882_auto_init_input_src
+
static int alc662_parse_auto_config(struct hda_codec *codec)
{
struct alc_spec *spec = codec->spec;
@@ -14053,8 +16199,16 @@ static int alc662_parse_auto_config(struct hda_codec *codec)
spec->num_mux_defs = 1;
spec->input_mux = &spec->private_imux;
-
+
spec->init_verbs[spec->num_init_verbs++] = alc662_auto_init_verbs;
+ if (codec->vendor_id == 0x10ec0663)
+ spec->init_verbs[spec->num_init_verbs++] =
+ alc663_auto_init_verbs;
+
+ err = alc_auto_add_mic_boost(codec);
+ if (err < 0)
+ return err;
+
spec->mixers[spec->num_mixers] = alc662_capture_mixer;
spec->num_mixers++;
return 1;
@@ -14067,6 +16221,7 @@ static void alc662_auto_init(struct hda_codec *codec)
alc662_auto_init_multi_out(codec);
alc662_auto_init_hp_out(codec);
alc662_auto_init_analog_input(codec);
+ alc662_auto_init_input_src(codec);
if (spec->unsol_event)
alc_sku_automute(codec);
}
@@ -14082,6 +16237,8 @@ static int patch_alc662(struct hda_codec *codec)
codec->spec = spec;
+ alc_fix_pll_init(codec, 0x20, 0x04, 15);
+
board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
alc662_models,
alc662_cfg_tbl);
@@ -14108,11 +16265,17 @@ static int patch_alc662(struct hda_codec *codec)
if (board_config != ALC662_AUTO)
setup_preset(spec, &alc662_presets[board_config]);
- spec->stream_name_analog = "ALC662 Analog";
+ if (codec->vendor_id == 0x10ec0663) {
+ spec->stream_name_analog = "ALC663 Analog";
+ spec->stream_name_digital = "ALC663 Digital";
+ } else {
+ spec->stream_name_analog = "ALC662 Analog";
+ spec->stream_name_digital = "ALC662 Digital";
+ }
+
spec->stream_analog_playback = &alc662_pcm_analog_playback;
spec->stream_analog_capture = &alc662_pcm_analog_capture;
- spec->stream_name_digital = "ALC662 Digital";
spec->stream_digital_playback = &alc662_pcm_digital_playback;
spec->stream_digital_capture = &alc662_pcm_digital_capture;
@@ -14151,9 +16314,12 @@ struct hda_codec_preset snd_hda_preset_realtek[] = {
.patch = patch_alc883 },
{ .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
.patch = patch_alc662 },
+ { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
{ .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
{ .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
{ .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 },
+ { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
+ .patch = patch_alc882 }, /* should be patch_alc883() in future */
{ .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
.patch = patch_alc882 }, /* should be patch_alc883() in future */
{ .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index a4f44a00bae8..c59065513118 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -33,10 +33,12 @@
#include "hda_codec.h"
#include "hda_local.h"
#include "hda_patch.h"
+#include "hda_beep.h"
#define NUM_CONTROL_ALLOC 32
#define STAC_PWR_EVENT 0x20
#define STAC_HP_EVENT 0x30
+#define STAC_VREF_EVENT 0x40
enum {
STAC_REF,
@@ -71,9 +73,15 @@ enum {
};
enum {
+ STAC_92HD83XXX_REF,
+ STAC_92HD83XXX_MODELS
+};
+
+enum {
STAC_92HD71BXX_REF,
STAC_DELL_M4_1,
STAC_DELL_M4_2,
+ STAC_HP_M4,
STAC_92HD71BXX_MODELS
};
@@ -94,6 +102,9 @@ enum {
STAC_INTEL_MAC_V3,
STAC_INTEL_MAC_V4,
STAC_INTEL_MAC_V5,
+ STAC_INTEL_MAC_AUTO, /* This model is selected if no module parameter
+ * is given, one of the above models will be
+ * chosen according to the subsystem id. */
/* for backward compatibility */
STAC_MACMINI,
STAC_MACBOOK,
@@ -101,6 +112,7 @@ enum {
STAC_MACBOOK_PRO_V2,
STAC_IMAC_INTEL,
STAC_IMAC_INTEL_20,
+ STAC_ECS_202,
STAC_922X_DELL_D81,
STAC_922X_DELL_D82,
STAC_922X_DELL_M81,
@@ -127,6 +139,7 @@ struct sigmatel_spec {
unsigned int mic_switch: 1;
unsigned int alt_switch: 1;
unsigned int hp_detect: 1;
+ unsigned int spdif_mute: 1;
/* gpio lines */
unsigned int eapd_mask;
@@ -135,17 +148,22 @@ struct sigmatel_spec {
unsigned int gpio_data;
unsigned int gpio_mute;
+ /* stream */
+ unsigned int stream_delay;
+
/* analog loopback */
unsigned char aloopback_mask;
unsigned char aloopback_shift;
/* power management */
unsigned int num_pwrs;
+ unsigned int *pwr_mapping;
hda_nid_t *pwr_nids;
hda_nid_t *dac_list;
/* playback */
struct hda_input_mux *mono_mux;
+ struct hda_input_mux *amp_mux;
unsigned int cur_mmux;
struct hda_multi_out multiout;
hda_nid_t dac_nids[5];
@@ -159,8 +177,14 @@ struct sigmatel_spec {
unsigned int num_dmics;
hda_nid_t *dmux_nids;
unsigned int num_dmuxes;
+ hda_nid_t *smux_nids;
+ unsigned int num_smuxes;
+ const char **spdif_labels;
+
hda_nid_t dig_in_nid;
hda_nid_t mono_nid;
+ hda_nid_t anabeep_nid;
+ hda_nid_t digbeep_nid;
/* pin widgets */
hda_nid_t *pin_nids;
@@ -177,6 +201,12 @@ struct sigmatel_spec {
unsigned int cur_dmux[2];
struct hda_input_mux *input_mux;
unsigned int cur_mux[3];
+ struct hda_input_mux *sinput_mux;
+ unsigned int cur_smux[2];
+ unsigned int cur_amux;
+ hda_nid_t *amp_nids;
+ unsigned int num_amps;
+ unsigned int powerdown_adcs;
/* i/o switches */
unsigned int io_switch[2];
@@ -192,6 +222,8 @@ struct sigmatel_spec {
struct snd_kcontrol_new *kctl_alloc;
struct hda_input_mux private_dimux;
struct hda_input_mux private_imux;
+ struct hda_input_mux private_smux;
+ struct hda_input_mux private_amp_mux;
struct hda_input_mux private_mono_mux;
};
@@ -212,10 +244,19 @@ static hda_nid_t stac92hd73xx_pwr_nids[8] = {
0x0f, 0x10, 0x11
};
+static hda_nid_t stac92hd73xx_slave_dig_outs[2] = {
+ 0x26, 0,
+};
+
static hda_nid_t stac92hd73xx_adc_nids[2] = {
0x1a, 0x1b
};
+#define DELL_M6_AMP 2
+static hda_nid_t stac92hd73xx_amp_nids[3] = {
+ 0x0b, 0x0c, 0x0e
+};
+
#define STAC92HD73XX_NUM_DMICS 2
static hda_nid_t stac92hd73xx_dmic_nids[STAC92HD73XX_NUM_DMICS + 1] = {
0x13, 0x14, 0
@@ -234,6 +275,41 @@ static hda_nid_t stac92hd73xx_dmux_nids[2] = {
0x20, 0x21,
};
+static hda_nid_t stac92hd73xx_smux_nids[2] = {
+ 0x22, 0x23,
+};
+
+#define STAC92HD83XXX_NUM_DMICS 2
+static hda_nid_t stac92hd83xxx_dmic_nids[STAC92HD83XXX_NUM_DMICS + 1] = {
+ 0x11, 0x12, 0
+};
+
+#define STAC92HD81_DAC_COUNT 2
+#define STAC92HD83_DAC_COUNT 3
+static hda_nid_t stac92hd83xxx_dac_nids[STAC92HD73_DAC_COUNT] = {
+ 0x13, 0x14, 0x22,
+};
+
+static hda_nid_t stac92hd83xxx_dmux_nids[2] = {
+ 0x17, 0x18,
+};
+
+static hda_nid_t stac92hd83xxx_adc_nids[2] = {
+ 0x15, 0x16,
+};
+
+static hda_nid_t stac92hd83xxx_pwr_nids[4] = {
+ 0xa, 0xb, 0xd, 0xe,
+};
+
+static hda_nid_t stac92hd83xxx_slave_dig_outs[2] = {
+ 0x1e, 0,
+};
+
+static unsigned int stac92hd83xxx_pwr_mapping[4] = {
+ 0x03, 0x0c, 0x10, 0x40,
+};
+
static hda_nid_t stac92hd71bxx_pwr_nids[3] = {
0x0a, 0x0d, 0x0f
};
@@ -246,8 +322,12 @@ static hda_nid_t stac92hd71bxx_mux_nids[2] = {
0x1a, 0x1b
};
-static hda_nid_t stac92hd71bxx_dmux_nids[1] = {
- 0x1c,
+static hda_nid_t stac92hd71bxx_dmux_nids[2] = {
+ 0x1c, 0x1d,
+};
+
+static hda_nid_t stac92hd71bxx_smux_nids[2] = {
+ 0x24, 0x25,
};
static hda_nid_t stac92hd71bxx_dac_nids[1] = {
@@ -259,6 +339,10 @@ static hda_nid_t stac92hd71bxx_dmic_nids[STAC92HD71BXX_NUM_DMICS + 1] = {
0x18, 0x19, 0
};
+static hda_nid_t stac92hd71bxx_slave_dig_outs[2] = {
+ 0x22, 0
+};
+
static hda_nid_t stac925x_adc_nids[1] = {
0x03,
};
@@ -296,6 +380,10 @@ static hda_nid_t stac927x_mux_nids[3] = {
0x15, 0x16, 0x17
};
+static hda_nid_t stac927x_smux_nids[1] = {
+ 0x21,
+};
+
static hda_nid_t stac927x_dac_nids[6] = {
0x02, 0x03, 0x04, 0x05, 0x06, 0
};
@@ -309,6 +397,11 @@ static hda_nid_t stac927x_dmic_nids[STAC927X_NUM_DMICS + 1] = {
0x13, 0x14, 0
};
+static const char *stac927x_spdif_labels[5] = {
+ "Digital Playback", "ADAT", "Analog Mux 1",
+ "Analog Mux 2", "Analog Mux 3"
+};
+
static hda_nid_t stac9205_adc_nids[2] = {
0x12, 0x13
};
@@ -321,6 +414,10 @@ static hda_nid_t stac9205_dmux_nids[1] = {
0x1d,
};
+static hda_nid_t stac9205_smux_nids[1] = {
+ 0x21,
+};
+
#define STAC9205_NUM_DMICS 2
static hda_nid_t stac9205_dmic_nids[STAC9205_NUM_DMICS + 1] = {
0x17, 0x18, 0
@@ -344,12 +441,18 @@ static hda_nid_t stac922x_pin_nids[10] = {
static hda_nid_t stac92hd73xx_pin_nids[13] = {
0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
0x0f, 0x10, 0x11, 0x12, 0x13,
- 0x14, 0x1e, 0x22
+ 0x14, 0x22, 0x23
};
-static hda_nid_t stac92hd71bxx_pin_nids[10] = {
+static hda_nid_t stac92hd83xxx_pin_nids[14] = {
+ 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
+ 0x0f, 0x10, 0x11, 0x12, 0x13,
+ 0x1d, 0x1e, 0x1f, 0x20
+};
+static hda_nid_t stac92hd71bxx_pin_nids[11] = {
0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
0x0f, 0x14, 0x18, 0x19, 0x1e,
+ 0x1f,
};
static hda_nid_t stac927x_pin_nids[14] = {
@@ -364,6 +467,34 @@ static hda_nid_t stac9205_pin_nids[12] = {
0x21, 0x22,
};
+#define stac92xx_amp_volume_info snd_hda_mixer_amp_volume_info
+
+static int stac92xx_amp_volume_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;
+ hda_nid_t nid = spec->amp_nids[spec->cur_amux];
+
+ kcontrol->private_value ^= get_amp_nid(kcontrol);
+ kcontrol->private_value |= nid;
+
+ return snd_hda_mixer_amp_volume_get(kcontrol, ucontrol);
+}
+
+static int stac92xx_amp_volume_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 = spec->amp_nids[spec->cur_amux];
+
+ kcontrol->private_value ^= get_amp_nid(kcontrol);
+ kcontrol->private_value |= nid;
+
+ return snd_hda_mixer_amp_volume_put(kcontrol, ucontrol);
+}
+
static int stac92xx_dmux_enum_info(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *uinfo)
{
@@ -394,6 +525,58 @@ static int stac92xx_dmux_enum_put(struct snd_kcontrol *kcontrol,
spec->dmux_nids[dmux_idx], &spec->cur_dmux[dmux_idx]);
}
+static int stac92xx_smux_enum_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct sigmatel_spec *spec = codec->spec;
+ return snd_hda_input_mux_info(spec->sinput_mux, uinfo);
+}
+
+static int stac92xx_smux_enum_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;
+ unsigned int smux_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
+
+ ucontrol->value.enumerated.item[0] = spec->cur_smux[smux_idx];
+ return 0;
+}
+
+static int stac92xx_smux_enum_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;
+ struct hda_input_mux *smux = &spec->private_smux;
+ unsigned int smux_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
+ int err, val;
+ hda_nid_t nid;
+
+ err = snd_hda_input_mux_put(codec, spec->sinput_mux, ucontrol,
+ spec->smux_nids[smux_idx], &spec->cur_smux[smux_idx]);
+ if (err < 0)
+ return err;
+
+ if (spec->spdif_mute) {
+ if (smux_idx == 0)
+ nid = spec->multiout.dig_out_nid;
+ else
+ nid = codec->slave_dig_outs[smux_idx - 1];
+ if (spec->cur_smux[smux_idx] == smux->num_items - 1)
+ val = AMP_OUT_MUTE;
+ if (smux_idx == 0)
+ nid = spec->multiout.dig_out_nid;
+ else
+ nid = codec->slave_dig_outs[smux_idx - 1];
+ /* un/mute SPDIF out */
+ snd_hda_codec_write_cache(codec, nid, 0,
+ AC_VERB_SET_AMP_GAIN_MUTE, val);
+ }
+ return 0;
+}
+
static int stac92xx_mux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
{
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
@@ -449,6 +632,41 @@ static int stac92xx_mono_mux_enum_put(struct snd_kcontrol *kcontrol,
spec->mono_nid, &spec->cur_mmux);
}
+static int stac92xx_amp_mux_enum_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct sigmatel_spec *spec = codec->spec;
+ return snd_hda_input_mux_info(spec->amp_mux, uinfo);
+}
+
+static int stac92xx_amp_mux_enum_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.enumerated.item[0] = spec->cur_amux;
+ return 0;
+}
+
+static int stac92xx_amp_mux_enum_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;
+ struct snd_kcontrol *ctl =
+ snd_hda_find_mixer_ctl(codec, "Amp Capture Volume");
+ if (!ctl)
+ return -EINVAL;
+
+ snd_ctl_notify(codec->bus->card, SNDRV_CTL_EVENT_MASK_VALUE |
+ SNDRV_CTL_EVENT_MASK_INFO, &ctl->id);
+
+ return snd_hda_input_mux_put(codec, spec->amp_mux, ucontrol,
+ 0, &spec->cur_amux);
+}
+
#define stac92xx_aloopback_info snd_ctl_boolean_mono_info
static int stac92xx_aloopback_get(struct snd_kcontrol *kcontrol,
@@ -543,8 +761,8 @@ static struct hda_verb dell_eq_core_init[] = {
{ 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xec},
/* setup audio connections */
{ 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
- { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x01},
- { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x02},
+ { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x02},
+ { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x01},
/* setup adcs to point to mixer */
{ 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b},
{ 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b},
@@ -557,8 +775,9 @@ static struct hda_verb dell_eq_core_init[] = {
};
static struct hda_verb dell_m6_core_init[] = {
- /* set master volume and direct control */
- { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
+ /* set master volume to max value without distortion
+ * and direct control */
+ { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xec},
/* setup audio connections */
{ 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
{ 0x0a, AC_VERB_SET_CONNECT_SEL, 0x01},
@@ -624,33 +843,47 @@ static struct hda_verb stac92hd73xx_10ch_core_init[] = {
{}
};
+static struct hda_verb stac92hd83xxx_core_init[] = {
+ /* start of config #1 */
+ { 0xe, AC_VERB_SET_CONNECT_SEL, 0x3},
+
+ /* start of config #2 */
+ { 0xa, AC_VERB_SET_CONNECT_SEL, 0x0},
+ { 0xb, AC_VERB_SET_CONNECT_SEL, 0x0},
+ { 0xd, AC_VERB_SET_CONNECT_SEL, 0x1},
+
+ /* power state controls amps */
+ { 0x01, AC_VERB_SET_EAPD, 1 << 2},
+};
+
static struct hda_verb stac92hd71bxx_core_init[] = {
/* set master volume and direct control */
{ 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
/* connect headphone jack to dac1 */
{ 0x0a, AC_VERB_SET_CONNECT_SEL, 0x01},
- { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Speaker */
/* unmute right and left channels for nodes 0x0a, 0xd, 0x0f */
{ 0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
{ 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
{ 0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
};
+#define HD_DISABLE_PORTF 2
static struct hda_verb stac92hd71bxx_analog_core_init[] = {
+ /* start of config #1 */
+
+ /* connect port 0f to audio mixer */
+ { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x2},
+ /* unmute right and left channels for node 0x0f */
+ { 0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+ /* start of config #2 */
+
/* set master volume and direct control */
{ 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
/* connect headphone jack to dac1 */
{ 0x0a, AC_VERB_SET_CONNECT_SEL, 0x01},
- /* connect ports 0d and 0f to audio mixer */
- { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x2},
- { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x2},
- { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Speaker */
- /* unmute dac0 input in audio mixer */
- { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
- /* unmute right and left channels for nodes 0x0a, 0xd, 0x0f */
+ /* unmute right and left channels for nodes 0x0a, 0xd */
{ 0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
{ 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- { 0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
{}
};
@@ -679,12 +912,16 @@ static struct hda_verb d965_core_init[] = {
static struct hda_verb stac927x_core_init[] = {
/* set master volume and direct control */
{ 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
+ /* enable analog pc beep path */
+ { 0x01, AC_VERB_SET_DIGI_CONVERT_2, 1 << 5},
{}
};
static struct hda_verb stac9205_core_init[] = {
/* set master volume and direct control */
{ 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
+ /* enable analog pc beep path */
+ { 0x01, AC_VERB_SET_DIGI_CONVERT_2, 1 << 5},
{}
};
@@ -698,6 +935,31 @@ static struct hda_verb stac9205_core_init[] = {
.put = stac92xx_mono_mux_enum_put, \
}
+#define STAC_AMP_MUX \
+ { \
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
+ .name = "Amp Selector Capture Switch", \
+ .count = 1, \
+ .info = stac92xx_amp_mux_enum_info, \
+ .get = stac92xx_amp_mux_enum_get, \
+ .put = stac92xx_amp_mux_enum_put, \
+ }
+
+#define STAC_AMP_VOL(xname, nid, chs, idx, dir) \
+ { \
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
+ .name = xname, \
+ .index = 0, \
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \
+ SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
+ SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK, \
+ .info = stac92xx_amp_volume_info, \
+ .get = stac92xx_amp_volume_get, \
+ .put = stac92xx_amp_volume_put, \
+ .tlv = { .c = snd_hda_mixer_amp_tlv }, \
+ .private_value = HDA_COMPOSE_AMP_VAL(nid, chs, idx, dir) \
+ }
+
#define STAC_INPUT_SOURCE(cnt) \
{ \
.iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
@@ -725,33 +987,36 @@ static struct snd_kcontrol_new stac9200_mixer[] = {
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),
{ } /* end */
};
+#define DELL_M6_MIXER 6
static struct snd_kcontrol_new stac92hd73xx_6ch_mixer[] = {
- STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 3),
-
- HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x20, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x20, 0x0, HDA_OUTPUT),
-
- HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x21, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x21, 0x0, HDA_OUTPUT),
-
+ /* start of config #1 */
HDA_CODEC_VOLUME("Front Mic Mixer Capture Volume", 0x1d, 0, HDA_INPUT),
HDA_CODEC_MUTE("Front Mic Mixer Capture Switch", 0x1d, 0, HDA_INPUT),
- HDA_CODEC_VOLUME("Mic Mixer Capture Volume", 0x1d, 0x1, HDA_INPUT),
- HDA_CODEC_MUTE("Mic Mixer Capture Switch", 0x1d, 0x1, HDA_INPUT),
-
HDA_CODEC_VOLUME("Line In Mixer Capture Volume", 0x1d, 0x2, HDA_INPUT),
HDA_CODEC_MUTE("Line In Mixer Capture Switch", 0x1d, 0x2, HDA_INPUT),
+ HDA_CODEC_VOLUME("CD Mixer Capture Volume", 0x1d, 0x4, HDA_INPUT),
+ HDA_CODEC_MUTE("CD Mixer Capture Switch", 0x1d, 0x4, HDA_INPUT),
+
+ /* start of config #2 */
+ HDA_CODEC_VOLUME("Mic Mixer Capture Volume", 0x1d, 0x1, HDA_INPUT),
+ HDA_CODEC_MUTE("Mic Mixer Capture Switch", 0x1d, 0x1, HDA_INPUT),
+
HDA_CODEC_VOLUME("DAC Mixer Capture Volume", 0x1d, 0x3, HDA_INPUT),
HDA_CODEC_MUTE("DAC Mixer Capture Switch", 0x1d, 0x3, HDA_INPUT),
- HDA_CODEC_VOLUME("CD Mixer Capture Volume", 0x1d, 0x4, HDA_INPUT),
- HDA_CODEC_MUTE("CD Mixer Capture Switch", 0x1d, 0x4, HDA_INPUT),
+ STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 3),
+
+ HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x20, 0x0, HDA_OUTPUT),
+ HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x20, 0x0, HDA_OUTPUT),
+
+ HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x21, 0x0, HDA_OUTPUT),
+ HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x21, 0x0, HDA_OUTPUT),
+
{ } /* end */
};
@@ -807,19 +1072,59 @@ static struct snd_kcontrol_new stac92hd73xx_10ch_mixer[] = {
{ } /* end */
};
+
+static struct snd_kcontrol_new stac92hd83xxx_mixer[] = {
+ HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x17, 0x0, HDA_OUTPUT),
+ HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x17, 0x0, HDA_OUTPUT),
+
+ HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x18, 0x0, HDA_OUTPUT),
+ HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x18, 0x0, HDA_OUTPUT),
+
+ HDA_CODEC_VOLUME("DAC0 Capture Volume", 0x1b, 0, HDA_INPUT),
+ HDA_CODEC_MUTE("DAC0 Capture Switch", 0x1b, 0, HDA_INPUT),
+
+ HDA_CODEC_VOLUME("DAC1 Capture Volume", 0x1b, 0x1, HDA_INPUT),
+ HDA_CODEC_MUTE("DAC1 Capture Switch", 0x1b, 0x1, HDA_INPUT),
+
+ HDA_CODEC_VOLUME("Front Mic Capture Volume", 0x1b, 0x2, HDA_INPUT),
+ HDA_CODEC_MUTE("Front Mic Capture Switch", 0x1b, 0x2, HDA_INPUT),
+
+ HDA_CODEC_VOLUME("Line In Capture Volume", 0x1b, 0x3, HDA_INPUT),
+ HDA_CODEC_MUTE("Line In Capture Switch", 0x1b, 0x3, HDA_INPUT),
+
+ /*
+ HDA_CODEC_VOLUME("Mic Capture Volume", 0x1b, 0x4, HDA_INPUT),
+ HDA_CODEC_MUTE("Mic Capture Switch", 0x1b 0x4, HDA_INPUT),
+ */
+ { } /* end */
+};
+
static struct snd_kcontrol_new stac92hd71bxx_analog_mixer[] = {
STAC_INPUT_SOURCE(2),
+ STAC_ANALOG_LOOPBACK(0xFA0, 0x7A0, 2),
HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1c, 0x0, HDA_OUTPUT),
HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1c, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME_IDX("Capture Mux Volume", 0x0, 0x1a, 0x0, HDA_OUTPUT),
HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x1d, 0x0, HDA_OUTPUT),
HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1d, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME_IDX("Capture Mux Volume", 0x1, 0x1b, 0x0, HDA_OUTPUT),
+ /* analog pc-beep replaced with digital beep support */
+ /*
+ HDA_CODEC_VOLUME("PC Beep Volume", 0x17, 0x2, HDA_INPUT),
+ HDA_CODEC_MUTE("PC Beep Switch", 0x17, 0x2, HDA_INPUT),
+ */
+
+ HDA_CODEC_MUTE("Import0 Mux Capture Switch", 0x17, 0x0, HDA_INPUT),
+ HDA_CODEC_VOLUME("Import0 Mux Capture Volume", 0x17, 0x0, HDA_INPUT),
+
+ HDA_CODEC_MUTE("Import1 Mux Capture Switch", 0x17, 0x1, HDA_INPUT),
+ HDA_CODEC_VOLUME("Import1 Mux Capture Volume", 0x17, 0x1, HDA_INPUT),
- HDA_CODEC_MUTE("Analog Loopback 1", 0x17, 0x3, HDA_INPUT),
- HDA_CODEC_MUTE("Analog Loopback 2", 0x17, 0x4, HDA_INPUT),
+ HDA_CODEC_MUTE("DAC0 Capture Switch", 0x17, 0x3, HDA_INPUT),
+ HDA_CODEC_VOLUME("DAC0 Capture Volume", 0x17, 0x3, HDA_INPUT),
+
+ HDA_CODEC_MUTE("DAC1 Capture Switch", 0x17, 0x4, HDA_INPUT),
+ HDA_CODEC_VOLUME("DAC1 Capture Volume", 0x17, 0x4, HDA_INPUT),
{ } /* end */
};
@@ -829,11 +1134,9 @@ static struct snd_kcontrol_new stac92hd71bxx_mixer[] = {
HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1c, 0x0, HDA_OUTPUT),
HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1c, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME_IDX("Capture Mux Volume", 0x0, 0x1a, 0x0, HDA_OUTPUT),
HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x1d, 0x0, HDA_OUTPUT),
HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1d, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME_IDX("Capture Mux Volume", 0x1, 0x1b, 0x0, HDA_OUTPUT),
{ } /* end */
};
@@ -841,7 +1144,6 @@ static struct snd_kcontrol_new stac925x_mixer[] = {
STAC_INPUT_SOURCE(1),
HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_OUTPUT),
HDA_CODEC_MUTE("Capture Switch", 0x14, 0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("Capture Mux Volume", 0x0f, 0, HDA_OUTPUT),
{ } /* end */
};
@@ -851,12 +1153,9 @@ static struct snd_kcontrol_new stac9205_mixer[] = {
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 */
};
@@ -865,11 +1164,9 @@ static struct snd_kcontrol_new stac922x_mixer[] = {
STAC_INPUT_SOURCE(2),
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 */
};
@@ -880,15 +1177,12 @@ static struct snd_kcontrol_new stac927x_mixer[] = {
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 */
};
@@ -901,6 +1195,15 @@ static struct snd_kcontrol_new stac_dmux_mixer = {
.put = stac92xx_dmux_enum_put,
};
+static struct snd_kcontrol_new stac_smux_mixer = {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "IEC958 Playback Source",
+ /* count set later */
+ .info = stac92xx_smux_enum_info,
+ .get = stac92xx_smux_enum_get,
+ .put = stac92xx_smux_enum_put,
+};
+
static const char *slave_vols[] = {
"Front Playback Volume",
"Surround Playback Volume",
@@ -952,6 +1255,22 @@ static int stac92xx_build_controls(struct hda_codec *codec)
if (err < 0)
return err;
}
+ if (spec->num_smuxes > 0) {
+ int wcaps = get_wcaps(codec, spec->multiout.dig_out_nid);
+ struct hda_input_mux *smux = &spec->private_smux;
+ /* check for mute support on SPDIF out */
+ if (wcaps & AC_WCAP_OUT_AMP) {
+ smux->items[smux->num_items].label = "Off";
+ smux->items[smux->num_items].index = 0;
+ smux->num_items++;
+ spec->spdif_mute = 1;
+ }
+ stac_smux_mixer.count = spec->num_smuxes;
+ err = snd_ctl_add(codec->bus->card,
+ snd_ctl_new1(&stac_smux_mixer, codec));
+ if (err < 0)
+ return err;
+ }
if (spec->multiout.dig_out_nid) {
err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid);
@@ -963,7 +1282,7 @@ static int stac92xx_build_controls(struct hda_codec *codec)
return err;
spec->multiout.share_spdif = 1;
}
- if (spec->dig_in_nid) {
+ if (spec->dig_in_nid && (!spec->gpio_dir & 0x01)) {
err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
if (err < 0)
return err;
@@ -1311,40 +1630,65 @@ static struct snd_pci_quirk stac92hd73xx_cfg_tbl[] = {
{} /* terminator */
};
-static unsigned int ref92hd71bxx_pin_configs[10] = {
+static unsigned int ref92hd83xxx_pin_configs[14] = {
+ 0x02214030, 0x02211010, 0x02a19020, 0x02170130,
+ 0x01014050, 0x01819040, 0x01014020, 0x90a3014e,
+ 0x40f000f0, 0x40f000f0, 0x40f000f0, 0x40f000f0,
+ 0x01451160, 0x98560170,
+};
+
+static unsigned int *stac92hd83xxx_brd_tbl[STAC_92HD83XXX_MODELS] = {
+ [STAC_92HD83XXX_REF] = ref92hd83xxx_pin_configs,
+};
+
+static const char *stac92hd83xxx_models[STAC_92HD83XXX_MODELS] = {
+ [STAC_92HD83XXX_REF] = "ref",
+};
+
+static struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = {
+ /* SigmaTel reference board */
+ SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
+ "DFI LanParty", STAC_92HD71BXX_REF),
+};
+
+static unsigned int ref92hd71bxx_pin_configs[11] = {
0x02214030, 0x02a19040, 0x01a19020, 0x01014010,
- 0x0181302e, 0x01114010, 0x01019020, 0x90a000f0,
- 0x90a000f0, 0x01452050,
+ 0x0181302e, 0x01014010, 0x01019020, 0x90a000f0,
+ 0x90a000f0, 0x01452050, 0x01452050,
};
-static unsigned int dell_m4_1_pin_configs[13] = {
+static unsigned int dell_m4_1_pin_configs[11] = {
0x0421101f, 0x04a11221, 0x40f000f0, 0x90170110,
0x23a1902e, 0x23014250, 0x40f000f0, 0x90a000f0,
- 0x40f000f0, 0x4f0000f0,
+ 0x40f000f0, 0x4f0000f0, 0x4f0000f0,
};
-static unsigned int dell_m4_2_pin_configs[13] = {
+static unsigned int dell_m4_2_pin_configs[11] = {
0x0421101f, 0x04a11221, 0x90a70330, 0x90170110,
0x23a1902e, 0x23014250, 0x40f000f0, 0x40f000f0,
- 0x40f000f0, 0x044413b0,
+ 0x40f000f0, 0x044413b0, 0x044413b0,
};
static unsigned int *stac92hd71bxx_brd_tbl[STAC_92HD71BXX_MODELS] = {
[STAC_92HD71BXX_REF] = ref92hd71bxx_pin_configs,
[STAC_DELL_M4_1] = dell_m4_1_pin_configs,
[STAC_DELL_M4_2] = dell_m4_2_pin_configs,
+ [STAC_HP_M4] = NULL,
};
static const char *stac92hd71bxx_models[STAC_92HD71BXX_MODELS] = {
[STAC_92HD71BXX_REF] = "ref",
[STAC_DELL_M4_1] = "dell-m4-1",
[STAC_DELL_M4_2] = "dell-m4-2",
+ [STAC_HP_M4] = "hp-m4",
};
static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = {
/* SigmaTel reference board */
SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
"DFI LanParty", STAC_92HD71BXX_REF),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x361a,
+ "unknown HP", STAC_HP_M4),
SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0233,
"unknown Dell", STAC_DELL_M4_1),
SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0234,
@@ -1463,6 +1807,11 @@ static unsigned int intel_mac_v5_pin_configs[10] = {
0x400000fc, 0x400000fb,
};
+static unsigned int ecs202_pin_configs[10] = {
+ 0x0221401f, 0x02a19020, 0x01a19020, 0x01114010,
+ 0x408000f0, 0x01813022, 0x074510a0, 0x40c400f1,
+ 0x9037012e, 0x40e000f2,
+};
static unsigned int *stac922x_brd_tbl[STAC_922X_MODELS] = {
[STAC_D945_REF] = ref922x_pin_configs,
@@ -1473,6 +1822,7 @@ static unsigned int *stac922x_brd_tbl[STAC_922X_MODELS] = {
[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,
+ [STAC_INTEL_MAC_AUTO] = intel_mac_v3_pin_configs,
/* for backward compatibility */
[STAC_MACMINI] = intel_mac_v3_pin_configs,
[STAC_MACBOOK] = intel_mac_v5_pin_configs,
@@ -1480,6 +1830,7 @@ static unsigned int *stac922x_brd_tbl[STAC_922X_MODELS] = {
[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_ECS_202] = ecs202_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,
@@ -1495,6 +1846,7 @@ static const char *stac922x_models[STAC_922X_MODELS] = {
[STAC_INTEL_MAC_V3] = "intel-mac-v3",
[STAC_INTEL_MAC_V4] = "intel-mac-v4",
[STAC_INTEL_MAC_V5] = "intel-mac-v5",
+ [STAC_INTEL_MAC_AUTO] = "intel-mac-auto",
/* for backward compatibility */
[STAC_MACMINI] = "macmini",
[STAC_MACBOOK] = "macbook",
@@ -1502,6 +1854,7 @@ static const char *stac922x_models[STAC_922X_MODELS] = {
[STAC_MACBOOK_PRO_V2] = "macbook-pro",
[STAC_IMAC_INTEL] = "imac-intel",
[STAC_IMAC_INTEL_20] = "imac-intel-20",
+ [STAC_ECS_202] = "ecs202",
[STAC_922X_DELL_D81] = "dell-d81",
[STAC_922X_DELL_D82] = "dell-d82",
[STAC_922X_DELL_M81] = "dell-m81",
@@ -1566,9 +1919,9 @@ static struct snd_pci_quirk stac922x_cfg_tbl[] = {
SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0707,
"Intel D945P", STAC_D945GTP5),
/* other systems */
- /* Apple Mac Mini (early 2006) */
+ /* Apple Intel Mac (Mac Mini, MacBook, MacBook Pro...) */
SND_PCI_QUIRK(0x8384, 0x7680,
- "Mac Mini", STAC_INTEL_MAC_V3),
+ "Mac", STAC_INTEL_MAC_AUTO),
/* Dell systems */
SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a7,
"unknown Dell", STAC_922X_DELL_D81),
@@ -1588,6 +1941,33 @@ static struct snd_pci_quirk stac922x_cfg_tbl[] = {
"unknown Dell", STAC_922X_DELL_D81),
SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d7,
"Dell XPS M1210", STAC_922X_DELL_M82),
+ /* ECS/PC Chips boards */
+ SND_PCI_QUIRK(0x1019, 0x2144,
+ "ECS/PC chips", STAC_ECS_202),
+ SND_PCI_QUIRK(0x1019, 0x2608,
+ "ECS/PC chips", STAC_ECS_202),
+ SND_PCI_QUIRK(0x1019, 0x2633,
+ "ECS/PC chips P17G/1333", STAC_ECS_202),
+ SND_PCI_QUIRK(0x1019, 0x2811,
+ "ECS/PC chips", STAC_ECS_202),
+ SND_PCI_QUIRK(0x1019, 0x2812,
+ "ECS/PC chips", STAC_ECS_202),
+ SND_PCI_QUIRK(0x1019, 0x2813,
+ "ECS/PC chips", STAC_ECS_202),
+ SND_PCI_QUIRK(0x1019, 0x2814,
+ "ECS/PC chips", STAC_ECS_202),
+ SND_PCI_QUIRK(0x1019, 0x2815,
+ "ECS/PC chips", STAC_ECS_202),
+ SND_PCI_QUIRK(0x1019, 0x2816,
+ "ECS/PC chips", STAC_ECS_202),
+ SND_PCI_QUIRK(0x1019, 0x2817,
+ "ECS/PC chips", STAC_ECS_202),
+ SND_PCI_QUIRK(0x1019, 0x2818,
+ "ECS/PC chips", STAC_ECS_202),
+ SND_PCI_QUIRK(0x1019, 0x2819,
+ "ECS/PC chips", STAC_ECS_202),
+ SND_PCI_QUIRK(0x1019, 0x2820,
+ "ECS/PC chips", STAC_ECS_202),
{} /* terminator */
};
@@ -1667,8 +2047,8 @@ static struct snd_pci_quirk stac927x_cfg_tbl[] = {
/* Dell 3 stack systems with verb table in BIOS */
SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f3, "Dell Inspiron 1420", STAC_DELL_BIOS),
SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0227, "Dell Vostro 1400 ", STAC_DELL_BIOS),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x022f, "Dell ", STAC_DELL_BIOS),
SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x022e, "Dell ", STAC_DELL_BIOS),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x022f, "Dell Inspiron 1525", STAC_DELL_3ST),
SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0242, "Dell ", STAC_DELL_BIOS),
SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0243, "Dell ", STAC_DELL_BIOS),
SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02ff, "Dell ", STAC_DELL_BIOS),
@@ -1754,12 +2134,8 @@ static struct snd_pci_quirk stac9205_cfg_tbl[] = {
"unknown Dell", STAC_9205_DELL_M42),
SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f8,
"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,
- "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,
@@ -1770,18 +2146,14 @@ static struct snd_pci_quirk stac9205_cfg_tbl[] = {
"Dell Precision", STAC_9205_DELL_M43),
SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ff,
"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,
- "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, 0x0204,
"unknown Dell", STAC_9205_DELL_M42),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0206,
+ "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, 0x021c,
+ "Dell Precision", STAC_9205_DELL_M43),
SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021f,
"Dell Inspiron", STAC_9205_DELL_M44),
SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0228,
@@ -1859,6 +2231,8 @@ static int stac92xx_playback_pcm_open(struct hda_pcm_stream *hinfo,
struct snd_pcm_substream *substream)
{
struct sigmatel_spec *spec = codec->spec;
+ if (spec->stream_delay)
+ msleep(spec->stream_delay);
return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
hinfo);
}
@@ -1922,9 +2296,14 @@ static int stac92xx_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
struct snd_pcm_substream *substream)
{
struct sigmatel_spec *spec = codec->spec;
+ hda_nid_t nid = spec->adc_nids[substream->number];
- snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
- stream_tag, 0, format);
+ if (spec->powerdown_adcs) {
+ msleep(40);
+ snd_hda_codec_write_cache(codec, nid, 0,
+ AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
+ }
+ snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format);
return 0;
}
@@ -1933,8 +2312,12 @@ static int stac92xx_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
struct snd_pcm_substream *substream)
{
struct sigmatel_spec *spec = codec->spec;
+ hda_nid_t nid = spec->adc_nids[substream->number];
- snd_hda_codec_cleanup_stream(codec, spec->adc_nids[substream->number]);
+ snd_hda_codec_cleanup_stream(codec, nid);
+ if (spec->powerdown_adcs)
+ snd_hda_codec_write_cache(codec, nid, 0,
+ AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
return 0;
}
@@ -2185,6 +2568,8 @@ enum {
STAC_CTL_WIDGET_VOL,
STAC_CTL_WIDGET_MUTE,
STAC_CTL_WIDGET_MONO_MUX,
+ STAC_CTL_WIDGET_AMP_MUX,
+ STAC_CTL_WIDGET_AMP_VOL,
STAC_CTL_WIDGET_HP_SWITCH,
STAC_CTL_WIDGET_IO_SWITCH,
STAC_CTL_WIDGET_CLFE_SWITCH
@@ -2194,13 +2579,16 @@ static struct snd_kcontrol_new stac92xx_control_templates[] = {
HDA_CODEC_VOLUME(NULL, 0, 0, 0),
HDA_CODEC_MUTE(NULL, 0, 0, 0),
STAC_MONO_MUX,
+ STAC_AMP_MUX,
+ STAC_AMP_VOL(NULL, 0, 0, 0, 0),
STAC_CODEC_HP_SWITCH(NULL),
STAC_CODEC_IO_SWITCH(NULL, 0),
STAC_CODEC_CLFE_SWITCH(NULL, 0),
};
/* add dynamic controls */
-static int stac92xx_add_control(struct sigmatel_spec *spec, int type, const char *name, unsigned long val)
+static int stac92xx_add_control_idx(struct sigmatel_spec *spec, int type,
+ int idx, const char *name, unsigned long val)
{
struct snd_kcontrol_new *knew;
@@ -2220,6 +2608,7 @@ static int stac92xx_add_control(struct sigmatel_spec *spec, int type, const char
knew = &spec->kctl_alloc[spec->num_kctl_used];
*knew = stac92xx_control_templates[type];
+ knew->index = idx;
knew->name = kstrdup(name, GFP_KERNEL);
if (! knew->name)
return -ENOMEM;
@@ -2228,6 +2617,14 @@ static int stac92xx_add_control(struct sigmatel_spec *spec, int type, const char
return 0;
}
+
+/* add dynamic controls */
+static int stac92xx_add_control(struct sigmatel_spec *spec, int type,
+ const char *name, unsigned long val)
+{
+ return stac92xx_add_control_idx(spec, type, 0, name, val);
+}
+
/* flag inputs as additional dynamic lineouts */
static int stac92xx_add_dyn_out_pins(struct hda_codec *codec, struct auto_pin_cfg *cfg)
{
@@ -2459,6 +2856,10 @@ static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec,
}
}
+ if ((spec->multiout.num_dacs - cfg->line_outs) > 0 &&
+ cfg->hp_outs && !spec->multiout.hp_nid)
+ spec->multiout.hp_nid = nid;
+
if (cfg->hp_outs > 1) {
err = stac92xx_add_control(spec,
STAC_CTL_WIDGET_HP_SWITCH,
@@ -2571,8 +2972,8 @@ static int stac92xx_auto_create_hp_ctls(struct hda_codec *codec,
}
/* labels for mono mux outputs */
-static const char *stac92xx_mono_labels[3] = {
- "DAC0", "DAC1", "Mixer"
+static const char *stac92xx_mono_labels[4] = {
+ "DAC0", "DAC1", "Mixer", "DAC2"
};
/* create mono mux for mono out on capable codecs */
@@ -2601,6 +3002,116 @@ static int stac92xx_auto_create_mono_output_ctls(struct hda_codec *codec)
"Mono Mux", spec->mono_nid);
}
+/* labels for amp mux outputs */
+static const char *stac92xx_amp_labels[3] = {
+ "Front Microphone", "Microphone", "Line In",
+};
+
+/* create amp out controls mux on capable codecs */
+static int stac92xx_auto_create_amp_output_ctls(struct hda_codec *codec)
+{
+ struct sigmatel_spec *spec = codec->spec;
+ struct hda_input_mux *amp_mux = &spec->private_amp_mux;
+ int i, err;
+
+ for (i = 0; i < spec->num_amps; i++) {
+ amp_mux->items[amp_mux->num_items].label =
+ stac92xx_amp_labels[i];
+ amp_mux->items[amp_mux->num_items].index = i;
+ amp_mux->num_items++;
+ }
+
+ if (spec->num_amps > 1) {
+ err = stac92xx_add_control(spec, STAC_CTL_WIDGET_AMP_MUX,
+ "Amp Selector Capture Switch", 0);
+ if (err < 0)
+ return err;
+ }
+ return stac92xx_add_control(spec, STAC_CTL_WIDGET_AMP_VOL,
+ "Amp Capture Volume",
+ HDA_COMPOSE_AMP_VAL(spec->amp_nids[0], 3, 0, HDA_INPUT));
+}
+
+
+/* create PC beep volume controls */
+static int stac92xx_auto_create_beep_ctls(struct hda_codec *codec,
+ hda_nid_t nid)
+{
+ struct sigmatel_spec *spec = codec->spec;
+ u32 caps = query_amp_caps(codec, nid, HDA_OUTPUT);
+ int err;
+
+ /* check for mute support for the the amp */
+ if ((caps & AC_AMPCAP_MUTE) >> AC_AMPCAP_MUTE_SHIFT) {
+ err = stac92xx_add_control(spec, STAC_CTL_WIDGET_MUTE,
+ "PC Beep Playback Switch",
+ HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT));
+ if (err < 0)
+ return err;
+ }
+
+ /* check to see if there is volume support for the amp */
+ if ((caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT) {
+ err = stac92xx_add_control(spec, STAC_CTL_WIDGET_VOL,
+ "PC Beep Playback Volume",
+ HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT));
+ if (err < 0)
+ return err;
+ }
+ return 0;
+}
+
+static int stac92xx_auto_create_mux_input_ctls(struct hda_codec *codec)
+{
+ struct sigmatel_spec *spec = codec->spec;
+ int wcaps, nid, i, err = 0;
+
+ for (i = 0; i < spec->num_muxes; i++) {
+ nid = spec->mux_nids[i];
+ wcaps = get_wcaps(codec, nid);
+
+ if (wcaps & AC_WCAP_OUT_AMP) {
+ err = stac92xx_add_control_idx(spec,
+ STAC_CTL_WIDGET_VOL, i, "Mux Capture Volume",
+ HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
+ if (err < 0)
+ return err;
+ }
+ }
+ return 0;
+};
+
+static const char *stac92xx_spdif_labels[3] = {
+ "Digital Playback", "Analog Mux 1", "Analog Mux 2",
+};
+
+static int stac92xx_auto_create_spdif_mux_ctls(struct hda_codec *codec)
+{
+ struct sigmatel_spec *spec = codec->spec;
+ struct hda_input_mux *spdif_mux = &spec->private_smux;
+ const char **labels = spec->spdif_labels;
+ int i, num_cons;
+ hda_nid_t con_lst[HDA_MAX_NUM_INPUTS];
+
+ num_cons = snd_hda_get_connections(codec,
+ spec->smux_nids[0],
+ con_lst,
+ HDA_MAX_NUM_INPUTS);
+ if (!num_cons)
+ return -EINVAL;
+
+ if (!labels)
+ labels = stac92xx_spdif_labels;
+
+ for (i = 0; i < num_cons; i++) {
+ spdif_mux->items[spdif_mux->num_items].label = labels[i];
+ spdif_mux->items[spdif_mux->num_items].index = i;
+ spdif_mux->num_items++;
+ }
+
+ return 0;
+}
+
/* labels for dmic mux inputs */
static const char *stac92xx_dmic_labels[5] = {
"Analog Inputs", "Digital Mic 1", "Digital Mic 2",
@@ -2648,16 +3159,19 @@ static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec,
}
continue;
found:
- wcaps = get_wcaps(codec, nid);
+ wcaps = get_wcaps(codec, nid) &
+ (AC_WCAP_OUT_AMP | AC_WCAP_IN_AMP);
- if (wcaps & AC_WCAP_OUT_AMP) {
+ if (wcaps) {
sprintf(name, "%s Capture Volume",
stac92xx_dmic_labels[dimux->num_items]);
err = stac92xx_add_control(spec,
STAC_CTL_WIDGET_VOL,
name,
- HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
+ HDA_COMPOSE_AMP_VAL(nid, 3, 0,
+ (wcaps & AC_WCAP_OUT_AMP) ?
+ HDA_OUTPUT : HDA_INPUT));
if (err < 0)
return err;
}
@@ -2781,8 +3295,8 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out
hp_speaker_swap = 1;
}
if (spec->autocfg.mono_out_pin) {
- int dir = (get_wcaps(codec, spec->autocfg.mono_out_pin)
- & AC_WCAP_OUT_AMP) ? HDA_OUTPUT : HDA_INPUT;
+ int dir = get_wcaps(codec, spec->autocfg.mono_out_pin) &
+ (AC_WCAP_OUT_AMP | AC_WCAP_IN_AMP);
u32 caps = query_amp_caps(codec,
spec->autocfg.mono_out_pin, dir);
hda_nid_t conn_list[1];
@@ -2804,21 +3318,26 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out
!(wcaps & AC_WCAP_LR_SWAP))
spec->mono_nid = conn_list[0];
}
- /* all mono outs have a least a mute/unmute switch */
- err = stac92xx_add_control(spec, STAC_CTL_WIDGET_MUTE,
- "Mono Playback Switch",
- HDA_COMPOSE_AMP_VAL(spec->autocfg.mono_out_pin,
- 1, 0, dir));
- if (err < 0)
- return err;
- /* check to see if there is volume support for the amp */
- if ((caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT) {
- err = stac92xx_add_control(spec, STAC_CTL_WIDGET_VOL,
- "Mono Playback Volume",
- HDA_COMPOSE_AMP_VAL(spec->autocfg.mono_out_pin,
- 1, 0, dir));
+ if (dir) {
+ hda_nid_t nid = spec->autocfg.mono_out_pin;
+
+ /* most mono outs have a least a mute/unmute switch */
+ dir = (dir & AC_WCAP_OUT_AMP) ? HDA_OUTPUT : HDA_INPUT;
+ err = stac92xx_add_control(spec, STAC_CTL_WIDGET_MUTE,
+ "Mono Playback Switch",
+ HDA_COMPOSE_AMP_VAL(nid, 1, 0, dir));
if (err < 0)
return err;
+ /* check for volume support for the amp */
+ if ((caps & AC_AMPCAP_NUM_STEPS)
+ >> AC_AMPCAP_NUM_STEPS_SHIFT) {
+ err = stac92xx_add_control(spec,
+ STAC_CTL_WIDGET_VOL,
+ "Mono Playback Volume",
+ HDA_COMPOSE_AMP_VAL(nid, 1, 0, dir));
+ if (err < 0)
+ return err;
+ }
}
stac92xx_auto_set_pinctl(codec, spec->autocfg.mono_out_pin,
@@ -2836,6 +3355,28 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out
if (err < 0)
return err;
+ /* setup analog beep controls */
+ if (spec->anabeep_nid > 0) {
+ err = stac92xx_auto_create_beep_ctls(codec,
+ spec->anabeep_nid);
+ if (err < 0)
+ return err;
+ }
+
+ /* setup digital beep controls and input device */
+#ifdef CONFIG_SND_HDA_INPUT_BEEP
+ if (spec->digbeep_nid > 0) {
+ hda_nid_t nid = spec->digbeep_nid;
+
+ err = stac92xx_auto_create_beep_ctls(codec, nid);
+ if (err < 0)
+ return err;
+ err = snd_hda_attach_beep_device(codec, nid);
+ if (err < 0)
+ return err;
+ }
+#endif
+
if (hp_speaker_swap == 1) {
/* Restore the hp_outs and line_outs */
memcpy(spec->autocfg.hp_pins, spec->autocfg.line_out_pins,
@@ -2864,11 +3405,25 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out
if (err < 0)
return err;
}
-
- if (spec->num_dmics > 0)
+ if (spec->num_amps > 0) {
+ err = stac92xx_auto_create_amp_output_ctls(codec);
+ if (err < 0)
+ return err;
+ }
+ if (spec->num_dmics > 0 && !spec->dinput_mux)
if ((err = stac92xx_auto_create_dmic_input_ctls(codec,
&spec->autocfg)) < 0)
return err;
+ if (spec->num_muxes > 0) {
+ err = stac92xx_auto_create_mux_input_ctls(codec);
+ if (err < 0)
+ return err;
+ }
+ if (spec->num_smuxes > 0) {
+ err = stac92xx_auto_create_spdif_mux_ctls(codec);
+ if (err < 0)
+ return err;
+ }
spec->multiout.max_channels = spec->multiout.num_dacs * 2;
if (spec->multiout.max_channels > 2)
@@ -2876,17 +3431,17 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out
if (spec->autocfg.dig_out_pin)
spec->multiout.dig_out_nid = dig_out;
- if (spec->autocfg.dig_in_pin)
+ if (dig_in && spec->autocfg.dig_in_pin)
spec->dig_in_nid = dig_in;
if (spec->kctl_alloc)
spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
spec->input_mux = &spec->private_imux;
- if (!spec->dinput_mux)
- spec->dinput_mux = &spec->private_dimux;
+ spec->dinput_mux = &spec->private_dimux;
+ spec->sinput_mux = &spec->private_smux;
spec->mono_mux = &spec->private_mono_mux;
-
+ spec->amp_mux = &spec->private_amp_mux;
return 1;
}
@@ -3066,6 +3621,12 @@ static int stac92xx_init(struct hda_codec *codec)
snd_hda_sequence_write(codec, spec->init);
+ /* power down adcs initially */
+ if (spec->powerdown_adcs)
+ for (i = 0; i < spec->num_adcs; i++)
+ snd_hda_codec_write_cache(codec,
+ spec->adc_nids[i], 0,
+ AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
/* set up pins */
if (spec->hp_detect) {
/* Enable unsolicited responses on the HP widget */
@@ -3087,7 +3648,12 @@ static int stac92xx_init(struct hda_codec *codec)
for (i = 0; i < AUTO_PIN_LAST; i++) {
hda_nid_t nid = cfg->input_pins[i];
if (nid) {
- unsigned int pinctl = AC_PINCTL_IN_EN;
+ unsigned int pinctl = snd_hda_codec_read(codec, nid,
+ 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
+ /* if PINCTL already set then skip */
+ if (pinctl & AC_PINCAP_IN)
+ continue;
+ pinctl = AC_PINCTL_IN_EN;
if (i == AUTO_PIN_MIC || i == AUTO_PIN_FRONT_MIC)
pinctl |= stac92xx_get_vref(codec, nid);
stac92xx_auto_set_pinctl(codec, nid, pinctl);
@@ -3103,13 +3669,16 @@ static int stac92xx_init(struct hda_codec *codec)
0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
int def_conf = snd_hda_codec_read(codec, spec->pwr_nids[i],
0, AC_VERB_GET_CONFIG_DEFAULT, 0);
+ def_conf = get_defcfg_connect(def_conf);
/* outputs are only ports capable of power management
* any attempts on powering down a input port cause the
* referenced VREF to act quirky.
*/
if (pinctl & AC_PINCTL_IN_EN)
continue;
- if (get_defcfg_connect(def_conf) != AC_JACK_PORT_FIXED)
+ /* skip any ports that don't have jacks since presence
+ * detection is useless */
+ if (def_conf && def_conf != AC_JACK_PORT_FIXED)
continue;
enable_pin_detect(codec, spec->pwr_nids[i], event | i);
codec->patch_ops.unsol_event(codec, (event | i) << 26);
@@ -3147,6 +3716,7 @@ static void stac92xx_free(struct hda_codec *codec)
kfree(spec->bios_pin_configs);
kfree(spec);
+ snd_hda_detach_beep_device(codec);
}
static void stac92xx_set_pinctl(struct hda_codec *codec, hda_nid_t nid,
@@ -3268,7 +3838,12 @@ static void stac92xx_pin_sense(struct hda_codec *codec, int idx)
val = snd_hda_codec_read(codec, codec->afg, 0, 0x0fec, 0x0)
& 0x000000ff;
presence = get_hp_pin_presence(codec, nid);
- idx = 1 << idx;
+
+ /* several codecs have two power down bits */
+ if (spec->pwr_mapping)
+ idx = spec->pwr_mapping[idx];
+ else
+ idx = 1 << idx;
if (presence)
val &= ~idx;
@@ -3284,13 +3859,22 @@ static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res)
struct sigmatel_spec *spec = codec->spec;
int idx = res >> 26 & 0x0f;
- switch ((res >> 26) & 0x30) {
+ switch ((res >> 26) & 0x70) {
case STAC_HP_EVENT:
stac92xx_hp_detect(codec, res);
/* fallthru */
case STAC_PWR_EVENT:
if (spec->num_pwrs > 0)
stac92xx_pin_sense(codec, idx);
+ break;
+ case STAC_VREF_EVENT: {
+ int data = snd_hda_codec_read(codec, codec->afg, 0,
+ AC_VERB_GET_GPIO_DATA, 0);
+ /* toggle VREF state based on GPIOx status */
+ snd_hda_codec_write(codec, codec->afg, 0, 0x7e0,
+ !!(data & (1 << idx)));
+ break;
+ }
}
}
@@ -3467,9 +4051,9 @@ static struct hda_input_mux stac92hd73xx_dmux = {
.num_items = 4,
.items = {
{ "Analog Inputs", 0x0b },
- { "CD", 0x08 },
{ "Digital Mic 1", 0x09 },
{ "Digital Mic 2", 0x0a },
+ { "CD", 0x08 },
}
};
@@ -3484,6 +4068,7 @@ static int patch_stac92hd73xx(struct hda_codec *codec)
return -ENOMEM;
codec->spec = spec;
+ codec->slave_dig_outs = stac92hd73xx_slave_dig_outs;
spec->num_pins = ARRAY_SIZE(stac92hd73xx_pin_nids);
spec->pin_nids = stac92hd73xx_pin_nids;
spec->board_config = snd_hda_check_board_config(codec,
@@ -3516,17 +4101,14 @@ again:
switch (spec->multiout.num_dacs) {
case 0x3: /* 6 Channel */
- spec->multiout.hp_nid = 0x17;
spec->mixer = stac92hd73xx_6ch_mixer;
spec->init = stac92hd73xx_6ch_core_init;
break;
case 0x4: /* 8 Channel */
- spec->multiout.hp_nid = 0x18;
spec->mixer = stac92hd73xx_8ch_mixer;
spec->init = stac92hd73xx_8ch_core_init;
break;
case 0x5: /* 10 Channel */
- spec->multiout.hp_nid = 0x19;
spec->mixer = stac92hd73xx_10ch_mixer;
spec->init = stac92hd73xx_10ch_core_init;
};
@@ -3535,27 +4117,34 @@ again:
spec->aloopback_mask = 0x01;
spec->aloopback_shift = 8;
+ spec->digbeep_nid = 0x1c;
spec->mux_nids = stac92hd73xx_mux_nids;
spec->adc_nids = stac92hd73xx_adc_nids;
spec->dmic_nids = stac92hd73xx_dmic_nids;
spec->dmux_nids = stac92hd73xx_dmux_nids;
+ spec->smux_nids = stac92hd73xx_smux_nids;
+ spec->amp_nids = stac92hd73xx_amp_nids;
+ spec->num_amps = ARRAY_SIZE(stac92hd73xx_amp_nids);
spec->num_muxes = ARRAY_SIZE(stac92hd73xx_mux_nids);
spec->num_adcs = ARRAY_SIZE(stac92hd73xx_adc_nids);
spec->num_dmuxes = ARRAY_SIZE(stac92hd73xx_dmux_nids);
- spec->dinput_mux = &stac92hd73xx_dmux;
- /* GPIO0 High = Enable EAPD */
- spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0x1;
- spec->gpio_data = 0x01;
+ memcpy(&spec->private_dimux, &stac92hd73xx_dmux,
+ sizeof(stac92hd73xx_dmux));
switch (spec->board_config) {
case STAC_DELL_M6:
spec->init = dell_eq_core_init;
+ spec->num_smuxes = 0;
+ spec->mixer = &stac92hd73xx_6ch_mixer[DELL_M6_MIXER];
+ spec->amp_nids = &stac92hd73xx_amp_nids[DELL_M6_AMP];
+ spec->num_amps = 1;
switch (codec->subsystem_id) {
case 0x1028025e: /* Analog Mics */
case 0x1028025f:
stac92xx_set_config_reg(codec, 0x0b, 0x90A70170);
spec->num_dmics = 0;
+ spec->private_dimux.num_items = 1;
break;
case 0x10280271: /* Digital Mics */
case 0x10280272:
@@ -3565,23 +4154,32 @@ again:
case 0x10280255:
stac92xx_set_config_reg(codec, 0x13, 0x90A60160);
spec->num_dmics = 1;
+ spec->private_dimux.num_items = 2;
break;
case 0x10280256: /* Both */
case 0x10280057:
stac92xx_set_config_reg(codec, 0x0b, 0x90A70170);
stac92xx_set_config_reg(codec, 0x13, 0x90A60160);
spec->num_dmics = 1;
+ spec->private_dimux.num_items = 2;
break;
}
break;
default:
spec->num_dmics = STAC92HD73XX_NUM_DMICS;
+ spec->num_smuxes = ARRAY_SIZE(stac92hd73xx_smux_nids);
}
+ if (spec->board_config > STAC_92HD73XX_REF) {
+ /* GPIO0 High = Enable EAPD */
+ spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0x1;
+ spec->gpio_data = 0x01;
+ }
+ spec->dinput_mux = &spec->private_dimux;
spec->num_pwrs = ARRAY_SIZE(stac92hd73xx_pwr_nids);
spec->pwr_nids = stac92hd73xx_pwr_nids;
- err = stac92xx_parse_auto_config(codec, 0x22, 0x24);
+ err = stac92xx_parse_auto_config(codec, 0x25, 0x27);
if (!err) {
if (spec->board_config < 0) {
@@ -3603,6 +4201,146 @@ again:
return 0;
}
+static struct hda_input_mux stac92hd83xxx_dmux = {
+ .num_items = 3,
+ .items = {
+ { "Analog Inputs", 0x03 },
+ { "Digital Mic 1", 0x04 },
+ { "Digital Mic 2", 0x05 },
+ }
+};
+
+static int patch_stac92hd83xxx(struct hda_codec *codec)
+{
+ struct sigmatel_spec *spec;
+ int err;
+
+ spec = kzalloc(sizeof(*spec), GFP_KERNEL);
+ if (spec == NULL)
+ return -ENOMEM;
+
+ codec->spec = spec;
+ codec->slave_dig_outs = stac92hd83xxx_slave_dig_outs;
+ spec->mono_nid = 0x19;
+ spec->digbeep_nid = 0x21;
+ spec->dmic_nids = stac92hd83xxx_dmic_nids;
+ spec->dmux_nids = stac92hd83xxx_dmux_nids;
+ spec->adc_nids = stac92hd83xxx_adc_nids;
+ spec->pwr_nids = stac92hd83xxx_pwr_nids;
+ spec->pwr_mapping = stac92hd83xxx_pwr_mapping;
+ spec->num_pwrs = ARRAY_SIZE(stac92hd83xxx_pwr_nids);
+ spec->multiout.dac_nids = stac92hd83xxx_dac_nids;
+
+ spec->init = stac92hd83xxx_core_init;
+ switch (codec->vendor_id) {
+ case 0x111d7605:
+ spec->multiout.num_dacs = STAC92HD81_DAC_COUNT;
+ break;
+ default:
+ spec->num_pwrs--;
+ spec->init++; /* switch to config #2 */
+ spec->multiout.num_dacs = STAC92HD83_DAC_COUNT;
+ }
+
+ spec->mixer = stac92hd83xxx_mixer;
+ spec->num_pins = ARRAY_SIZE(stac92hd83xxx_pin_nids);
+ spec->num_dmuxes = ARRAY_SIZE(stac92hd83xxx_dmux_nids);
+ spec->num_adcs = ARRAY_SIZE(stac92hd83xxx_adc_nids);
+ spec->num_dmics = STAC92HD83XXX_NUM_DMICS;
+ spec->dinput_mux = &stac92hd83xxx_dmux;
+ spec->pin_nids = stac92hd83xxx_pin_nids;
+ spec->board_config = snd_hda_check_board_config(codec,
+ STAC_92HD83XXX_MODELS,
+ stac92hd83xxx_models,
+ stac92hd83xxx_cfg_tbl);
+again:
+ if (spec->board_config < 0) {
+ snd_printdd(KERN_INFO "hda_codec: Unknown model for"
+ " STAC92HD83XXX, using BIOS defaults\n");
+ err = stac92xx_save_bios_config_regs(codec);
+ if (err < 0) {
+ stac92xx_free(codec);
+ return err;
+ }
+ spec->pin_configs = spec->bios_pin_configs;
+ } else {
+ spec->pin_configs = stac92hd83xxx_brd_tbl[spec->board_config];
+ stac92xx_set_config_regs(codec);
+ }
+
+ err = stac92xx_parse_auto_config(codec, 0x1d, 0);
+ if (!err) {
+ if (spec->board_config < 0) {
+ printk(KERN_WARNING "hda_codec: No auto-config is "
+ "available, default to model=ref\n");
+ spec->board_config = STAC_92HD83XXX_REF;
+ goto again;
+ }
+ err = -EINVAL;
+ }
+
+ if (err < 0) {
+ stac92xx_free(codec);
+ return err;
+ }
+
+ codec->patch_ops = stac92xx_patch_ops;
+
+ return 0;
+}
+
+#ifdef SND_HDA_NEEDS_RESUME
+static void stac92hd71xx_set_power_state(struct hda_codec *codec, int pwr)
+{
+ struct sigmatel_spec *spec = codec->spec;
+ int i;
+ snd_hda_codec_write_cache(codec, codec->afg, 0,
+ AC_VERB_SET_POWER_STATE, pwr);
+
+ msleep(1);
+ for (i = 0; i < spec->num_adcs; i++) {
+ snd_hda_codec_write_cache(codec,
+ spec->adc_nids[i], 0,
+ AC_VERB_SET_POWER_STATE, pwr);
+ }
+};
+
+static int stac92hd71xx_resume(struct hda_codec *codec)
+{
+ stac92hd71xx_set_power_state(codec, AC_PWRST_D0);
+ return stac92xx_resume(codec);
+}
+
+static int stac92hd71xx_suspend(struct hda_codec *codec, pm_message_t state)
+{
+ stac92hd71xx_set_power_state(codec, AC_PWRST_D3);
+ return 0;
+};
+
+#endif
+
+static struct hda_codec_ops stac92hd71bxx_patch_ops = {
+ .build_controls = stac92xx_build_controls,
+ .build_pcms = stac92xx_build_pcms,
+ .init = stac92xx_init,
+ .free = stac92xx_free,
+ .unsol_event = stac92xx_unsol_event,
+#ifdef SND_HDA_NEEDS_RESUME
+ .resume = stac92hd71xx_resume,
+ .suspend = stac92hd71xx_suspend,
+#endif
+};
+
+static struct hda_input_mux stac92hd71bxx_dmux = {
+ .num_items = 4,
+ .items = {
+ { "Analog Inputs", 0x00 },
+ { "Mixer", 0x01 },
+ { "Digital Mic 1", 0x02 },
+ { "Digital Mic 2", 0x03 },
+ }
+};
+
static int patch_stac92hd71bxx(struct hda_codec *codec)
{
struct sigmatel_spec *spec;
@@ -3613,8 +4351,12 @@ static int patch_stac92hd71bxx(struct hda_codec *codec)
return -ENOMEM;
codec->spec = spec;
+ codec->patch_ops = stac92xx_patch_ops;
spec->num_pins = ARRAY_SIZE(stac92hd71bxx_pin_nids);
+ spec->num_pwrs = ARRAY_SIZE(stac92hd71bxx_pwr_nids);
spec->pin_nids = stac92hd71bxx_pin_nids;
+ memcpy(&spec->private_dimux, &stac92hd71bxx_dmux,
+ sizeof(stac92hd71bxx_dmux));
spec->board_config = snd_hda_check_board_config(codec,
STAC_92HD71BXX_MODELS,
stac92hd71bxx_models,
@@ -3641,37 +4383,101 @@ again:
case 0x111d76b5:
spec->mixer = stac92hd71bxx_mixer;
spec->init = stac92hd71bxx_core_init;
+ codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs;
+ break;
+ case 0x111d7608: /* 5 Port with Analog Mixer */
+ switch (codec->subsystem_id) {
+ case 0x103c361a:
+ /* Enable VREF power saving on GPIO1 detect */
+ snd_hda_codec_write(codec, codec->afg, 0,
+ AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x02);
+ snd_hda_codec_write_cache(codec, codec->afg, 0,
+ AC_VERB_SET_UNSOLICITED_ENABLE,
+ (AC_USRSP_EN | STAC_VREF_EVENT | 0x01));
+ spec->gpio_mask |= 0x02;
+ break;
+ }
+ if ((codec->revision_id & 0xf) == 0 ||
+ (codec->revision_id & 0xf) == 1) {
+#ifdef SND_HDA_NEEDS_RESUME
+ codec->patch_ops = stac92hd71bxx_patch_ops;
+#endif
+ spec->stream_delay = 40; /* 40 milliseconds */
+ }
+
+ /* no output amps */
+ spec->num_pwrs = 0;
+ spec->mixer = stac92hd71bxx_analog_mixer;
+ spec->dinput_mux = &spec->private_dimux;
+
+ /* disable VSW */
+ spec->init = &stac92hd71bxx_analog_core_init[HD_DISABLE_PORTF];
+ stac92xx_set_config_reg(codec, 0xf, 0x40f000f0);
break;
+ case 0x111d7603: /* 6 Port with Analog Mixer */
+ if ((codec->revision_id & 0xf) == 1) {
+#ifdef SND_HDA_NEEDS_RESUME
+ codec->patch_ops = stac92hd71bxx_patch_ops;
+#endif
+ spec->stream_delay = 40; /* 40 milliseconds */
+ }
+
+ /* no output amps */
+ spec->num_pwrs = 0;
+ /* fallthru */
default:
+ spec->dinput_mux = &spec->private_dimux;
spec->mixer = stac92hd71bxx_analog_mixer;
spec->init = stac92hd71bxx_analog_core_init;
+ codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs;
}
- spec->aloopback_mask = 0x20;
+ spec->aloopback_mask = 0x50;
spec->aloopback_shift = 0;
- /* GPIO0 High = EAPD */
- spec->gpio_mask = 0x01;
- spec->gpio_dir = 0x01;
- spec->gpio_mask = 0x01;
- spec->gpio_data = 0x01;
+ if (spec->board_config > STAC_92HD71BXX_REF) {
+ /* GPIO0 = EAPD */
+ spec->gpio_mask = 0x01;
+ spec->gpio_dir = 0x01;
+ spec->gpio_data = 0x01;
+ }
+ spec->powerdown_adcs = 1;
+ spec->digbeep_nid = 0x26;
spec->mux_nids = stac92hd71bxx_mux_nids;
spec->adc_nids = stac92hd71bxx_adc_nids;
spec->dmic_nids = stac92hd71bxx_dmic_nids;
spec->dmux_nids = stac92hd71bxx_dmux_nids;
+ spec->smux_nids = stac92hd71bxx_smux_nids;
+ spec->pwr_nids = stac92hd71bxx_pwr_nids;
spec->num_muxes = ARRAY_SIZE(stac92hd71bxx_mux_nids);
spec->num_adcs = ARRAY_SIZE(stac92hd71bxx_adc_nids);
- spec->num_dmics = STAC92HD71BXX_NUM_DMICS;
- spec->num_dmuxes = ARRAY_SIZE(stac92hd71bxx_dmux_nids);
- spec->num_pwrs = ARRAY_SIZE(stac92hd71bxx_pwr_nids);
- spec->pwr_nids = stac92hd71bxx_pwr_nids;
+ switch (spec->board_config) {
+ case STAC_HP_M4:
+ spec->num_dmics = 0;
+ spec->num_smuxes = 0;
+ spec->num_dmuxes = 0;
+
+ /* enable internal microphone */
+ stac92xx_set_config_reg(codec, 0x0e, 0x01813040);
+ stac92xx_auto_set_pinctl(codec, 0x0e,
+ AC_PINCTL_IN_EN | AC_PINCTL_VREF_80);
+ break;
+ default:
+ spec->num_dmics = STAC92HD71BXX_NUM_DMICS;
+ spec->num_smuxes = ARRAY_SIZE(stac92hd71bxx_smux_nids);
+ spec->num_dmuxes = ARRAY_SIZE(stac92hd71bxx_dmux_nids);
+ };
spec->multiout.num_dacs = 1;
spec->multiout.hp_nid = 0x11;
spec->multiout.dac_nids = stac92hd71bxx_dac_nids;
+ if (spec->dinput_mux)
+ spec->private_dimux.num_items +=
+ spec->num_dmics -
+ (ARRAY_SIZE(stac92hd71bxx_dmic_nids) - 1);
err = stac92xx_parse_auto_config(codec, 0x21, 0x23);
if (!err) {
@@ -3689,8 +4495,6 @@ again:
return err;
}
- codec->patch_ops = stac92xx_patch_ops;
-
return 0;
};
@@ -3709,7 +4513,7 @@ static int patch_stac922x(struct hda_codec *codec)
spec->board_config = snd_hda_check_board_config(codec, STAC_922X_MODELS,
stac922x_models,
stac922x_cfg_tbl);
- if (spec->board_config == STAC_INTEL_MAC_V3) {
+ if (spec->board_config == STAC_INTEL_MAC_AUTO) {
spec->gpio_mask = spec->gpio_dir = 0x03;
spec->gpio_data = 0x03;
/* Intel Macs have all same PCI SSID, so we need to check
@@ -3741,6 +4545,9 @@ static int patch_stac922x(struct hda_codec *codec)
case 0x106b2200:
spec->board_config = STAC_INTEL_MAC_V5;
break;
+ default:
+ spec->board_config = STAC_INTEL_MAC_V3;
+ break;
}
}
@@ -3829,10 +4636,14 @@ static int patch_stac927x(struct hda_codec *codec)
stac92xx_set_config_regs(codec);
}
+ spec->digbeep_nid = 0x23;
spec->adc_nids = stac927x_adc_nids;
spec->num_adcs = ARRAY_SIZE(stac927x_adc_nids);
spec->mux_nids = stac927x_mux_nids;
spec->num_muxes = ARRAY_SIZE(stac927x_mux_nids);
+ spec->smux_nids = stac927x_smux_nids;
+ spec->num_smuxes = ARRAY_SIZE(stac927x_smux_nids);
+ spec->spdif_labels = stac927x_spdif_labels;
spec->dac_list = stac927x_dac_nids;
spec->multiout.dac_nids = spec->dac_nids;
@@ -3875,9 +4686,11 @@ static int patch_stac927x(struct hda_codec *codec)
spec->num_dmuxes = ARRAY_SIZE(stac927x_dmux_nids);
break;
default:
- /* GPIO0 High = Enable EAPD */
- spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0x1;
- spec->gpio_data = 0x01;
+ if (spec->board_config > STAC_D965_REF) {
+ /* GPIO0 High = Enable EAPD */
+ spec->eapd_mask = spec->gpio_mask = 0x01;
+ spec->gpio_dir = spec->gpio_data = 0x01;
+ }
spec->num_dmics = 0;
spec->init = stac927x_core_init;
@@ -3949,10 +4762,13 @@ static int patch_stac9205(struct hda_codec *codec)
stac92xx_set_config_regs(codec);
}
+ spec->digbeep_nid = 0x23;
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->smux_nids = stac9205_smux_nids;
+ spec->num_smuxes = ARRAY_SIZE(stac9205_smux_nids);
spec->dmic_nids = stac9205_dmic_nids;
spec->num_dmics = STAC9205_NUM_DMICS;
spec->dmux_nids = stac9205_dmux_nids;
@@ -3988,6 +4804,9 @@ static int patch_stac9205(struct hda_codec *codec)
*/
spec->gpio_data = 0x01;
break;
+ case STAC_9205_REF:
+ /* SPDIF-In enabled */
+ break;
default:
/* GPIO0 High = EAPD */
spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0x1;
@@ -4306,10 +5125,13 @@ struct hda_codec_preset snd_hda_preset_sigmatel[] = {
{ .id = 0x838476a5, .name = "STAC9255D", .patch = patch_stac9205 },
{ .id = 0x838476a6, .name = "STAC9254", .patch = patch_stac9205 },
{ .id = 0x838476a7, .name = "STAC9254D", .patch = patch_stac9205 },
+ { .id = 0x111d7603, .name = "92HD75B3X5", .patch = patch_stac92hd71bxx},
+ { .id = 0x111d7604, .name = "92HD83C1X5", .patch = patch_stac92hd83xxx},
+ { .id = 0x111d7605, .name = "92HD81B1X5", .patch = patch_stac92hd83xxx},
+ { .id = 0x111d7608, .name = "92HD75B2X5", .patch = patch_stac92hd71bxx},
{ .id = 0x111d7674, .name = "92HD73D1X5", .patch = patch_stac92hd73xx },
{ .id = 0x111d7675, .name = "92HD73C1X5", .patch = patch_stac92hd73xx },
{ .id = 0x111d7676, .name = "92HD73E1X5", .patch = patch_stac92hd73xx },
- { .id = 0x111d7608, .name = "92HD71BXX", .patch = patch_stac92hd71bxx },
{ .id = 0x111d76b0, .name = "92HD71B8X", .patch = patch_stac92hd71bxx },
{ .id = 0x111d76b1, .name = "92HD71B8X", .patch = patch_stac92hd71bxx },
{ .id = 0x111d76b2, .name = "92HD71B7X", .patch = patch_stac92hd71bxx },
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
index e7e43524f8c7..63e4871e5d8f 100644
--- a/sound/pci/hda/patch_via.c
+++ b/sound/pci/hda/patch_via.c
@@ -1,10 +1,10 @@
/*
* Universal Interface for Intel High Definition Audio Codec
*
- * HD audio interface patch for VIA VT1708 codec
+ * HD audio interface patch for VIA VT1702/VT1708/VT1709 codec
*
- * Copyright (c) 2006 Lydia Wang <lydiawang@viatech.com>
- * Takashi Iwai <tiwai@suse.de>
+ * Copyright (c) 2006-2008 Lydia Wang <lydiawang@viatech.com>
+ * Takashi Iwai <tiwai@suse.de>
*
* 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
@@ -29,6 +29,13 @@
/* 2006-09-08 Lydia Wang Fix internal loopback recording source select bug */
/* 2007-09-12 Lydia Wang Add EAPD enable during driver initialization */
/* 2007-09-17 Lydia Wang Add VT1708B codec support */
+/* 2007-11-14 Lydia Wang Add VT1708A codec HP and CD pin connect config */
+/* 2008-02-03 Lydia Wang Fix Rear channels and Back channels inverse issue */
+/* 2008-03-06 Lydia Wang Add VT1702 codec and VT1708S codec support */
+/* 2008-04-09 Lydia Wang Add mute front speaker when HP plugin */
+/* 2008-04-09 Lydia Wang Add Independent HP feature */
+/* 2008-05-28 Lydia Wang Add second S/PDIF Out support for VT1702 */
+/* 2008-09-15 Logan Li Add VT1708S Mic Boost workaround/backdoor */
/* */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
@@ -37,6 +44,7 @@
#include <linux/delay.h>
#include <linux/slab.h>
#include <sound/core.h>
+#include <sound/asoundef.h>
#include "hda_codec.h"
#include "hda_local.h"
#include "hda_patch.h"
@@ -53,6 +61,8 @@
#define VT1708_DIGOUT_NID 0x14
#define VT1708_DIGIN_NID 0x16
#define VT1708_DIGIN_PIN 0x26
+#define VT1708_HP_PIN_NID 0x20
+#define VT1708_CD_PIN_NID 0x24
#define VT1709_HP_DAC_NID 0x28
#define VT1709_DIGOUT_NID 0x13
@@ -64,12 +74,64 @@
#define VT1708B_DIGIN_NID 0x15
#define VT1708B_DIGIN_PIN 0x21
+#define VT1708S_HP_NID 0x25
+#define VT1708S_DIGOUT_NID 0x12
+
+#define VT1702_HP_NID 0x17
+#define VT1702_DIGOUT_NID 0x11
+
#define IS_VT1708_VENDORID(x) ((x) >= 0x11061708 && (x) <= 0x1106170b)
#define IS_VT1709_10CH_VENDORID(x) ((x) >= 0x1106e710 && (x) <= 0x1106e713)
#define IS_VT1709_6CH_VENDORID(x) ((x) >= 0x1106e714 && (x) <= 0x1106e717)
#define IS_VT1708B_8CH_VENDORID(x) ((x) >= 0x1106e720 && (x) <= 0x1106e723)
#define IS_VT1708B_4CH_VENDORID(x) ((x) >= 0x1106e724 && (x) <= 0x1106e727)
+#define IS_VT1708S_VENDORID(x) ((x) >= 0x11060397 && (x) <= 0x11067397)
+#define IS_VT1702_VENDORID(x) ((x) >= 0x11060398 && (x) <= 0x11067398)
+
+enum VIA_HDA_CODEC {
+ UNKNOWN = -1,
+ VT1708,
+ VT1709_10CH,
+ VT1709_6CH,
+ VT1708B_8CH,
+ VT1708B_4CH,
+ VT1708S,
+ VT1702,
+ CODEC_TYPES,
+};
+
+static enum VIA_HDA_CODEC get_codec_type(u32 vendor_id)
+{
+ u16 ven_id = vendor_id >> 16;
+ u16 dev_id = vendor_id & 0xffff;
+ enum VIA_HDA_CODEC codec_type;
+
+ /* get codec type */
+ if (ven_id != 0x1106)
+ codec_type = UNKNOWN;
+ else if (dev_id >= 0x1708 && dev_id <= 0x170b)
+ codec_type = VT1708;
+ else if (dev_id >= 0xe710 && dev_id <= 0xe713)
+ codec_type = VT1709_10CH;
+ else if (dev_id >= 0xe714 && dev_id <= 0xe717)
+ codec_type = VT1709_6CH;
+ else if (dev_id >= 0xe720 && dev_id <= 0xe723)
+ codec_type = VT1708B_8CH;
+ else if (dev_id >= 0xe724 && dev_id <= 0xe727)
+ codec_type = VT1708B_4CH;
+ else if ((dev_id & 0xfff) == 0x397
+ && (dev_id >> 12) < 8)
+ codec_type = VT1708S;
+ else if ((dev_id & 0xfff) == 0x398
+ && (dev_id >> 12) < 8)
+ codec_type = VT1702;
+ else
+ codec_type = UNKNOWN;
+ return codec_type;
+};
+#define VIA_HP_EVENT 0x01
+#define VIA_GPIO_EVENT 0x02
enum {
VIA_CTL_WIDGET_VOL,
@@ -77,12 +139,54 @@ enum {
};
enum {
- AUTO_SEQ_FRONT,
+ AUTO_SEQ_FRONT = 0,
AUTO_SEQ_SURROUND,
AUTO_SEQ_CENLFE,
AUTO_SEQ_SIDE
};
+#define get_amp_nid(kc) ((kc)->private_value & 0xffff)
+
+/* Some VT1708S based boards gets the micboost setting wrong, so we have
+ * to apply some brute-force and re-write the TLV's by software. */
+static int mic_boost_tlv(struct snd_kcontrol *kcontrol, int op_flag,
+ unsigned int size, unsigned int __user *_tlv)
+{
+ struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+ hda_nid_t nid = get_amp_nid(kcontrol);
+
+ if (get_codec_type(codec->vendor_id) == VT1708S
+ && (nid == 0x1a || nid == 0x1e)) {
+ if (size < 4 * sizeof(unsigned int))
+ return -ENOMEM;
+ if (put_user(1, _tlv)) /* SNDRV_CTL_TLVT_DB_SCALE */
+ return -EFAULT;
+ if (put_user(2 * sizeof(unsigned int), _tlv + 1))
+ return -EFAULT;
+ if (put_user(0, _tlv + 2)) /* offset = 0 */
+ return -EFAULT;
+ if (put_user(1000, _tlv + 3)) /* step size = 10 dB */
+ return -EFAULT;
+ }
+ return 0;
+}
+
+static int mic_boost_volume_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+ hda_nid_t nid = get_amp_nid(kcontrol);
+
+ if (get_codec_type(codec->vendor_id) == VT1708S
+ && (nid == 0x1a || nid == 0x1e)) {
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+ uinfo->count = 2;
+ uinfo->value.integer.min = 0;
+ uinfo->value.integer.max = 3;
+ }
+ return 0;
+}
+
static struct snd_kcontrol_new vt1708_control_templates[] = {
HDA_CODEC_VOLUME(NULL, 0, 0, 0),
HDA_CODEC_MUTE(NULL, 0, 0, 0),
@@ -94,7 +198,8 @@ struct via_spec {
struct snd_kcontrol_new *mixers[3];
unsigned int num_mixers;
- struct hda_verb *init_verbs;
+ struct hda_verb *init_verbs[5];
+ unsigned int num_iverbs;
char *stream_name_analog;
struct hda_pcm_stream *stream_analog_playback;
@@ -106,6 +211,7 @@ struct via_spec {
/* playback */
struct hda_multi_out multiout;
+ hda_nid_t extra_dig_out_nid;
/* capture */
unsigned int num_adc_nids;
@@ -117,15 +223,19 @@ struct via_spec {
unsigned int cur_mux[3];
/* PCM information */
- struct hda_pcm pcm_rec[2];
+ struct hda_pcm pcm_rec[3];
/* dynamic controls, init_verbs and input_mux */
struct auto_pin_cfg autocfg;
unsigned int num_kctl_alloc, num_kctl_used;
struct snd_kcontrol_new *kctl_alloc;
- struct hda_input_mux private_imux;
+ struct hda_input_mux private_imux[2];
hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
+ /* HP mode source */
+ const struct hda_input_mux *hp_mux;
+ unsigned int hp_independent_mode;
+
#ifdef CONFIG_SND_HDA_POWER_SAVE
struct hda_loopback_check loopback;
#endif
@@ -146,6 +256,16 @@ static hda_nid_t vt1708B_adc_nids[2] = {
0x13, 0x14
};
+static hda_nid_t vt1708S_adc_nids[2] = {
+ /* ADC1-2 */
+ 0x13, 0x14
+};
+
+static hda_nid_t vt1702_adc_nids[3] = {
+ /* ADC1-2 */
+ 0x12, 0x20, 0x1F
+};
+
/* add dynamic controls */
static int via_add_control(struct via_spec *spec, int type, const char *name,
unsigned long val)
@@ -283,19 +403,108 @@ static int via_mux_enum_put(struct snd_kcontrol *kcontrol,
return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
0x18, &spec->cur_mux[adc_idx]);
else if ((IS_VT1709_10CH_VENDORID(vendor_id) ||
- IS_VT1709_6CH_VENDORID(vendor_id)) && adc_idx == 0)
+ IS_VT1709_6CH_VENDORID(vendor_id)) && (adc_idx == 0))
return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
0x19, &spec->cur_mux[adc_idx]);
else if ((IS_VT1708B_8CH_VENDORID(vendor_id) ||
- IS_VT1708B_4CH_VENDORID(vendor_id)) && adc_idx == 0)
+ IS_VT1708B_4CH_VENDORID(vendor_id)) && (adc_idx == 0))
return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
0x17, &spec->cur_mux[adc_idx]);
+ else if (IS_VT1702_VENDORID(vendor_id) && (adc_idx == 0))
+ return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
+ 0x13, &spec->cur_mux[adc_idx]);
else
return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
spec->adc_nids[adc_idx],
&spec->cur_mux[adc_idx]);
}
+static int via_independent_hp_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct via_spec *spec = codec->spec;
+ return snd_hda_input_mux_info(spec->hp_mux, uinfo);
+}
+
+static int via_independent_hp_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct via_spec *spec = codec->spec;
+ hda_nid_t nid = spec->autocfg.hp_pins[0];
+ unsigned int pinsel = snd_hda_codec_read(codec, nid, 0,
+ AC_VERB_GET_CONNECT_SEL,
+ 0x00);
+
+ ucontrol->value.enumerated.item[0] = pinsel;
+
+ return 0;
+}
+
+static int via_independent_hp_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct via_spec *spec = codec->spec;
+ hda_nid_t nid = spec->autocfg.hp_pins[0];
+ unsigned int pinsel = ucontrol->value.enumerated.item[0];
+ unsigned int con_nid = snd_hda_codec_read(codec, nid, 0,
+ AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
+
+ if (con_nid == spec->multiout.hp_nid) {
+ if (pinsel == 0) {
+ if (!spec->hp_independent_mode) {
+ if (spec->multiout.num_dacs > 1)
+ spec->multiout.num_dacs -= 1;
+ spec->hp_independent_mode = 1;
+ }
+ } else if (pinsel == 1) {
+ if (spec->hp_independent_mode) {
+ if (spec->multiout.num_dacs > 1)
+ spec->multiout.num_dacs += 1;
+ spec->hp_independent_mode = 0;
+ }
+ }
+ } else {
+ if (pinsel == 0) {
+ if (spec->hp_independent_mode) {
+ if (spec->multiout.num_dacs > 1)
+ spec->multiout.num_dacs += 1;
+ spec->hp_independent_mode = 0;
+ }
+ } else if (pinsel == 1) {
+ if (!spec->hp_independent_mode) {
+ if (spec->multiout.num_dacs > 1)
+ spec->multiout.num_dacs -= 1;
+ spec->hp_independent_mode = 1;
+ }
+ }
+ }
+ snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL,
+ pinsel);
+
+ if (spec->multiout.hp_nid &&
+ spec->multiout.hp_nid != spec->multiout.dac_nids[HDA_FRONT])
+ snd_hda_codec_setup_stream(codec,
+ spec->multiout.hp_nid,
+ 0, 0, 0);
+
+ return 0;
+}
+
+static struct snd_kcontrol_new via_hp_mixer[] = {
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "Independent HP",
+ .count = 1,
+ .info = via_independent_hp_info,
+ .get = via_independent_hp_get,
+ .put = via_independent_hp_put,
+ },
+ { } /* end */
+};
+
/* capture mixer elements */
static struct snd_kcontrol_new vt1708_capture_mixer[] = {
HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_INPUT),
@@ -380,6 +589,138 @@ static int via_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
}
+
+static void playback_multi_pcm_prep_0(struct hda_codec *codec,
+ unsigned int stream_tag,
+ unsigned int format,
+ struct snd_pcm_substream *substream)
+{
+ struct via_spec *spec = codec->spec;
+ struct hda_multi_out *mout = &spec->multiout;
+ hda_nid_t *nids = mout->dac_nids;
+ int chs = substream->runtime->channels;
+ int i;
+
+ mutex_lock(&codec->spdif_mutex);
+ if (mout->dig_out_nid && mout->dig_out_used != HDA_DIG_EXCLUSIVE) {
+ if (chs == 2 &&
+ snd_hda_is_supported_format(codec, mout->dig_out_nid,
+ format) &&
+ !(codec->spdif_status & IEC958_AES0_NONAUDIO)) {
+ mout->dig_out_used = HDA_DIG_ANALOG_DUP;
+ /* turn off SPDIF once; otherwise the IEC958 bits won't
+ * be updated */
+ if (codec->spdif_ctls & AC_DIG1_ENABLE)
+ snd_hda_codec_write(codec, mout->dig_out_nid, 0,
+ AC_VERB_SET_DIGI_CONVERT_1,
+ codec->spdif_ctls &
+ ~AC_DIG1_ENABLE & 0xff);
+ snd_hda_codec_setup_stream(codec, mout->dig_out_nid,
+ stream_tag, 0, format);
+ /* turn on again (if needed) */
+ if (codec->spdif_ctls & AC_DIG1_ENABLE)
+ snd_hda_codec_write(codec, mout->dig_out_nid, 0,
+ AC_VERB_SET_DIGI_CONVERT_1,
+ codec->spdif_ctls & 0xff);
+ } else {
+ mout->dig_out_used = 0;
+ snd_hda_codec_setup_stream(codec, mout->dig_out_nid,
+ 0, 0, 0);
+ }
+ }
+ mutex_unlock(&codec->spdif_mutex);
+
+ /* front */
+ snd_hda_codec_setup_stream(codec, nids[HDA_FRONT], stream_tag,
+ 0, format);
+
+ if (mout->hp_nid && mout->hp_nid != nids[HDA_FRONT] &&
+ !spec->hp_independent_mode)
+ /* headphone out will just decode front left/right (stereo) */
+ snd_hda_codec_setup_stream(codec, mout->hp_nid, stream_tag,
+ 0, format);
+
+ /* extra outputs copied from front */
+ for (i = 0; i < ARRAY_SIZE(mout->extra_out_nid); i++)
+ if (mout->extra_out_nid[i])
+ snd_hda_codec_setup_stream(codec,
+ mout->extra_out_nid[i],
+ stream_tag, 0, format);
+
+ /* surrounds */
+ for (i = 1; i < mout->num_dacs; i++) {
+ if (chs >= (i + 1) * 2) /* independent out */
+ snd_hda_codec_setup_stream(codec, nids[i], stream_tag,
+ i * 2, format);
+ else /* copy front */
+ snd_hda_codec_setup_stream(codec, nids[i], stream_tag,
+ 0, format);
+ }
+}
+
+static int via_playback_multi_pcm_prepare(struct hda_pcm_stream *hinfo,
+ struct hda_codec *codec,
+ unsigned int stream_tag,
+ unsigned int format,
+ struct snd_pcm_substream *substream)
+{
+ struct via_spec *spec = codec->spec;
+ struct hda_multi_out *mout = &spec->multiout;
+ hda_nid_t *nids = mout->dac_nids;
+
+ if (substream->number == 0)
+ playback_multi_pcm_prep_0(codec, stream_tag, format,
+ substream);
+ else {
+ if (mout->hp_nid && mout->hp_nid != nids[HDA_FRONT] &&
+ spec->hp_independent_mode)
+ snd_hda_codec_setup_stream(codec, mout->hp_nid,
+ stream_tag, 0, format);
+ }
+
+ return 0;
+}
+
+static int via_playback_multi_pcm_cleanup(struct hda_pcm_stream *hinfo,
+ struct hda_codec *codec,
+ struct snd_pcm_substream *substream)
+{
+ struct via_spec *spec = codec->spec;
+ struct hda_multi_out *mout = &spec->multiout;
+ hda_nid_t *nids = mout->dac_nids;
+ int i;
+
+ if (substream->number == 0) {
+ for (i = 0; i < mout->num_dacs; i++)
+ snd_hda_codec_setup_stream(codec, nids[i], 0, 0, 0);
+
+ if (mout->hp_nid && !spec->hp_independent_mode)
+ snd_hda_codec_setup_stream(codec, mout->hp_nid,
+ 0, 0, 0);
+
+ for (i = 0; i < ARRAY_SIZE(mout->extra_out_nid); i++)
+ if (mout->extra_out_nid[i])
+ snd_hda_codec_setup_stream(codec,
+ mout->extra_out_nid[i],
+ 0, 0, 0);
+ mutex_lock(&codec->spdif_mutex);
+ if (mout->dig_out_nid &&
+ mout->dig_out_used == HDA_DIG_ANALOG_DUP) {
+ snd_hda_codec_setup_stream(codec, mout->dig_out_nid,
+ 0, 0, 0);
+ mout->dig_out_used = 0;
+ }
+ mutex_unlock(&codec->spdif_mutex);
+ } else {
+ if (mout->hp_nid && mout->hp_nid != nids[HDA_FRONT] &&
+ spec->hp_independent_mode)
+ snd_hda_codec_setup_stream(codec, mout->hp_nid,
+ 0, 0, 0);
+ }
+
+ return 0;
+}
+
/*
* Digital out
*/
@@ -399,6 +740,21 @@ static int via_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
return snd_hda_multi_out_dig_close(codec, &spec->multiout);
}
+/* setup SPDIF output stream */
+static void setup_dig_playback_stream(struct hda_codec *codec, hda_nid_t nid,
+ unsigned int stream_tag, unsigned int format)
+{
+ /* turn off SPDIF once; otherwise the IEC958 bits won't be updated */
+ if (codec->spdif_ctls & AC_DIG1_ENABLE)
+ snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
+ codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff);
+ snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format);
+ /* turn on again (if needed) */
+ if (codec->spdif_ctls & AC_DIG1_ENABLE)
+ snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
+ codec->spdif_ctls & 0xff);
+}
+
static int via_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
struct hda_codec *codec,
unsigned int stream_tag,
@@ -406,8 +762,20 @@ static int via_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
struct snd_pcm_substream *substream)
{
struct via_spec *spec = codec->spec;
- return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
- stream_tag, format, substream);
+ hda_nid_t nid;
+
+ /* 1st or 2nd S/PDIF */
+ if (substream->number == 0)
+ nid = spec->multiout.dig_out_nid;
+ else if (substream->number == 1)
+ nid = spec->extra_dig_out_nid;
+ else
+ return -1;
+
+ mutex_lock(&codec->spdif_mutex);
+ setup_dig_playback_stream(codec, nid, stream_tag, format);
+ mutex_unlock(&codec->spdif_mutex);
+ return 0;
}
/*
@@ -436,14 +804,14 @@ static int via_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
}
static struct hda_pcm_stream vt1708_pcm_analog_playback = {
- .substreams = 1,
+ .substreams = 2,
.channels_min = 2,
.channels_max = 8,
.nid = 0x10, /* NID to query formats and rates */
.ops = {
.open = via_playback_pcm_open,
- .prepare = via_playback_pcm_prepare,
- .cleanup = via_playback_pcm_cleanup
+ .prepare = via_playback_multi_pcm_prepare,
+ .cleanup = via_playback_multi_pcm_cleanup
},
};
@@ -515,6 +883,13 @@ static int via_build_controls(struct hda_codec *codec)
if (err < 0)
return err;
spec->multiout.share_spdif = 1;
+
+ if (spec->extra_dig_out_nid) {
+ err = snd_hda_create_spdif_out_ctls(codec,
+ spec->extra_dig_out_nid);
+ if (err < 0)
+ return err;
+ }
}
if (spec->dig_in_nid) {
err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
@@ -580,10 +955,89 @@ static void via_free(struct hda_codec *codec)
kfree(codec->spec);
}
+/* mute internal speaker if HP is plugged */
+static void via_hp_automute(struct hda_codec *codec)
+{
+ unsigned int present;
+ struct via_spec *spec = codec->spec;
+
+ present = snd_hda_codec_read(codec, spec->autocfg.hp_pins[0], 0,
+ AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
+ snd_hda_codec_amp_stereo(codec, spec->autocfg.line_out_pins[0],
+ HDA_OUTPUT, 0, HDA_AMP_MUTE,
+ present ? HDA_AMP_MUTE : 0);
+}
+
+static void via_gpio_control(struct hda_codec *codec)
+{
+ unsigned int gpio_data;
+ unsigned int vol_counter;
+ unsigned int vol;
+ unsigned int master_vol;
+
+ struct via_spec *spec = codec->spec;
+
+ gpio_data = snd_hda_codec_read(codec, codec->afg, 0,
+ AC_VERB_GET_GPIO_DATA, 0) & 0x03;
+
+ vol_counter = (snd_hda_codec_read(codec, codec->afg, 0,
+ 0xF84, 0) & 0x3F0000) >> 16;
+
+ vol = vol_counter & 0x1F;
+ master_vol = snd_hda_codec_read(codec, 0x1A, 0,
+ AC_VERB_GET_AMP_GAIN_MUTE,
+ AC_AMP_GET_INPUT);
+
+ if (gpio_data == 0x02) {
+ /* unmute line out */
+ snd_hda_codec_amp_stereo(codec, spec->autocfg.line_out_pins[0],
+ HDA_OUTPUT, 0, HDA_AMP_MUTE, 0);
+
+ if (vol_counter & 0x20) {
+ /* decrease volume */
+ if (vol > master_vol)
+ vol = master_vol;
+ snd_hda_codec_amp_stereo(codec, 0x1A, HDA_INPUT,
+ 0, HDA_AMP_VOLMASK,
+ master_vol-vol);
+ } else {
+ /* increase volume */
+ snd_hda_codec_amp_stereo(codec, 0x1A, HDA_INPUT, 0,
+ HDA_AMP_VOLMASK,
+ ((master_vol+vol) > 0x2A) ? 0x2A :
+ (master_vol+vol));
+ }
+ } else if (!(gpio_data & 0x02)) {
+ /* mute line out */
+ snd_hda_codec_amp_stereo(codec,
+ spec->autocfg.line_out_pins[0],
+ HDA_OUTPUT, 0, HDA_AMP_MUTE,
+ HDA_AMP_MUTE);
+ }
+}
+
+/* unsolicited event for jack sensing */
+static void via_unsol_event(struct hda_codec *codec,
+ unsigned int res)
+{
+ res >>= 26;
+ if (res == VIA_HP_EVENT)
+ via_hp_automute(codec);
+ else if (res == VIA_GPIO_EVENT)
+ via_gpio_control(codec);
+}
+
+static hda_nid_t slave_dig_outs[] = {
+ 0,
+};
+
static int via_init(struct hda_codec *codec)
{
struct via_spec *spec = codec->spec;
- snd_hda_sequence_write(codec, spec->init_verbs);
+ int i;
+ for (i = 0; i < spec->num_iverbs; i++)
+ snd_hda_sequence_write(codec, spec->init_verbs[i]);
+
/* Lydia Add for EAPD enable */
if (!spec->dig_in_nid) { /* No Digital In connection */
if (IS_VT1708_VENDORID(codec->vendor_id)) {
@@ -611,6 +1065,9 @@ static int via_init(struct hda_codec *codec)
snd_hda_codec_write(codec, spec->autocfg.dig_in_pin, 0,
AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN);
+ /* no slave outs */
+ codec->slave_dig_outs = slave_dig_outs;
+
return 0;
}
@@ -657,10 +1114,10 @@ static int vt1708_auto_fill_dac_nids(struct via_spec *spec,
spec->multiout.dac_nids[i] = 0x12;
break;
case AUTO_SEQ_SURROUND:
- spec->multiout.dac_nids[i] = 0x13;
+ spec->multiout.dac_nids[i] = 0x11;
break;
case AUTO_SEQ_SIDE:
- spec->multiout.dac_nids[i] = 0x11;
+ spec->multiout.dac_nids[i] = 0x13;
break;
}
}
@@ -685,7 +1142,7 @@ static int vt1708_auto_create_multi_out_ctls(struct via_spec *spec,
continue;
if (i != AUTO_SEQ_FRONT)
- nid_vol = 0x1b - i + 1;
+ nid_vol = 0x18 + i;
if (i == AUTO_SEQ_CENLFE) {
/* Center/LFE */
@@ -760,6 +1217,24 @@ static int vt1708_auto_create_multi_out_ctls(struct via_spec *spec,
return 0;
}
+static void create_hp_imux(struct via_spec *spec)
+{
+ int i;
+ struct hda_input_mux *imux = &spec->private_imux[1];
+ static const char *texts[] = { "OFF", "ON", NULL};
+
+ /* for hp mode select */
+ i = 0;
+ while (texts[i] != NULL) {
+ imux->items[imux->num_items].label = texts[i];
+ imux->items[imux->num_items].index = i;
+ imux->num_items++;
+ i++;
+ }
+
+ spec->hp_mux = &spec->private_imux[1];
+}
+
static int vt1708_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
{
int err;
@@ -780,6 +1255,8 @@ static int vt1708_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
if (err < 0)
return err;
+ create_hp_imux(spec);
+
return 0;
}
@@ -790,7 +1267,7 @@ static int vt1708_auto_create_analog_input_ctls(struct via_spec *spec,
static char *labels[] = {
"Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL
};
- struct hda_input_mux *imux = &spec->private_imux;
+ struct hda_input_mux *imux = &spec->private_imux[0];
int i, err, idx = 0;
/* for internal loopback recording select */
@@ -840,11 +1317,36 @@ static struct hda_amp_list vt1708_loopbacks[] = {
};
#endif
+static void vt1708_set_pinconfig_connect(struct hda_codec *codec, hda_nid_t nid)
+{
+ unsigned int def_conf;
+ unsigned char seqassoc;
+
+ def_conf = snd_hda_codec_read(codec, nid, 0,
+ AC_VERB_GET_CONFIG_DEFAULT, 0);
+ seqassoc = (unsigned char) get_defcfg_association(def_conf);
+ seqassoc = (seqassoc << 4) | get_defcfg_sequence(def_conf);
+ if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE) {
+ if (seqassoc == 0xff) {
+ def_conf = def_conf & (~(AC_JACK_PORT_BOTH << 30));
+ snd_hda_codec_write(codec, nid, 0,
+ AC_VERB_SET_CONFIG_DEFAULT_BYTES_3,
+ def_conf >> 24);
+ }
+ }
+
+ return;
+}
+
static int vt1708_parse_auto_config(struct hda_codec *codec)
{
struct via_spec *spec = codec->spec;
int err;
+ /* Add HP and CD pin config connect bit re-config action */
+ vt1708_set_pinconfig_connect(codec, VT1708_HP_PIN_NID);
+ vt1708_set_pinconfig_connect(codec, VT1708_CD_PIN_NID);
+
err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
if (err < 0)
return err;
@@ -874,9 +1376,12 @@ static int vt1708_parse_auto_config(struct hda_codec *codec)
if (spec->kctl_alloc)
spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
- spec->init_verbs = vt1708_volume_init_verbs;
+ spec->init_verbs[spec->num_iverbs++] = vt1708_volume_init_verbs;
+
+ spec->input_mux = &spec->private_imux[0];
- spec->input_mux = &spec->private_imux;
+ if (spec->hp_mux)
+ spec->mixers[spec->num_mixers++] = via_hp_mixer;
return 1;
}
@@ -897,7 +1402,7 @@ static int patch_vt1708(struct hda_codec *codec)
int err;
/* create a codec specific record */
- spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
+ spec = kzalloc(sizeof(*spec), GFP_KERNEL);
if (spec == NULL)
return -ENOMEM;
@@ -966,6 +1471,11 @@ static struct snd_kcontrol_new vt1709_capture_mixer[] = {
{ } /* end */
};
+static struct hda_verb vt1709_uniwill_init_verbs[] = {
+ {0x20, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_HP_EVENT},
+ { }
+};
+
/*
* generic initialization of ADC, input mixers and output mixers
*/
@@ -1090,11 +1600,11 @@ static int vt1709_auto_fill_dac_nids(struct via_spec *spec,
break;
case AUTO_SEQ_SURROUND:
/* AOW3 */
- spec->multiout.dac_nids[i] = 0x27;
+ spec->multiout.dac_nids[i] = 0x11;
break;
case AUTO_SEQ_SIDE:
/* AOW1 */
- spec->multiout.dac_nids[i] = 0x11;
+ spec->multiout.dac_nids[i] = 0x27;
break;
default:
break;
@@ -1203,26 +1713,26 @@ static int vt1709_auto_create_multi_out_ctls(struct via_spec *spec,
} else if (i == AUTO_SEQ_SURROUND) {
sprintf(name, "%s Playback Volume", chname[i]);
err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
- HDA_COMPOSE_AMP_VAL(0x29, 3, 0,
+ HDA_COMPOSE_AMP_VAL(0x1a, 3, 0,
HDA_OUTPUT));
if (err < 0)
return err;
sprintf(name, "%s Playback Switch", chname[i]);
err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
- HDA_COMPOSE_AMP_VAL(0x29, 3, 0,
+ HDA_COMPOSE_AMP_VAL(0x1a, 3, 0,
HDA_OUTPUT));
if (err < 0)
return err;
} else if (i == AUTO_SEQ_SIDE) {
sprintf(name, "%s Playback Volume", chname[i]);
err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
- HDA_COMPOSE_AMP_VAL(0x1a, 3, 0,
+ HDA_COMPOSE_AMP_VAL(0x29, 3, 0,
HDA_OUTPUT));
if (err < 0)
return err;
sprintf(name, "%s Playback Switch", chname[i]);
err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
- HDA_COMPOSE_AMP_VAL(0x1a, 3, 0,
+ HDA_COMPOSE_AMP_VAL(0x29, 3, 0,
HDA_OUTPUT));
if (err < 0)
return err;
@@ -1265,7 +1775,7 @@ static int vt1709_auto_create_analog_input_ctls(struct via_spec *spec,
static char *labels[] = {
"Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL
};
- struct hda_input_mux *imux = &spec->private_imux;
+ struct hda_input_mux *imux = &spec->private_imux[0];
int i, err, idx = 0;
/* for internal loopback recording select */
@@ -1339,7 +1849,10 @@ static int vt1709_parse_auto_config(struct hda_codec *codec)
if (spec->kctl_alloc)
spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
- spec->input_mux = &spec->private_imux;
+ spec->input_mux = &spec->private_imux[0];
+
+ if (spec->hp_mux)
+ spec->mixers[spec->num_mixers++] = via_hp_mixer;
return 1;
}
@@ -1360,7 +1873,7 @@ static int patch_vt1709_10ch(struct hda_codec *codec)
int err;
/* create a codec specific record */
- spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
+ spec = kzalloc(sizeof(*spec), GFP_KERNEL);
if (spec == NULL)
return -ENOMEM;
@@ -1375,7 +1888,8 @@ static int patch_vt1709_10ch(struct hda_codec *codec)
"Using genenic mode...\n");
}
- spec->init_verbs = vt1709_10ch_volume_init_verbs;
+ spec->init_verbs[spec->num_iverbs++] = vt1709_10ch_volume_init_verbs;
+ spec->init_verbs[spec->num_iverbs++] = vt1709_uniwill_init_verbs;
spec->stream_name_analog = "VT1709 Analog";
spec->stream_analog_playback = &vt1709_10ch_pcm_analog_playback;
@@ -1396,6 +1910,7 @@ static int patch_vt1709_10ch(struct hda_codec *codec)
codec->patch_ops = via_patch_ops;
codec->patch_ops.init = via_auto_init;
+ codec->patch_ops.unsol_event = via_unsol_event;
#ifdef CONFIG_SND_HDA_POWER_SAVE
spec->loopback.amplist = vt1709_loopbacks;
#endif
@@ -1451,7 +1966,7 @@ static int patch_vt1709_6ch(struct hda_codec *codec)
int err;
/* create a codec specific record */
- spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
+ spec = kzalloc(sizeof(*spec), GFP_KERNEL);
if (spec == NULL)
return -ENOMEM;
@@ -1466,7 +1981,8 @@ static int patch_vt1709_6ch(struct hda_codec *codec)
"Using genenic mode...\n");
}
- spec->init_verbs = vt1709_6ch_volume_init_verbs;
+ spec->init_verbs[spec->num_iverbs++] = vt1709_6ch_volume_init_verbs;
+ spec->init_verbs[spec->num_iverbs++] = vt1709_uniwill_init_verbs;
spec->stream_name_analog = "VT1709 Analog";
spec->stream_analog_playback = &vt1709_6ch_pcm_analog_playback;
@@ -1487,6 +2003,7 @@ static int patch_vt1709_6ch(struct hda_codec *codec)
codec->patch_ops = via_patch_ops;
codec->patch_ops.init = via_auto_init;
+ codec->patch_ops.unsol_event = via_unsol_event;
#ifdef CONFIG_SND_HDA_POWER_SAVE
spec->loopback.amplist = vt1709_loopbacks;
#endif
@@ -1586,27 +2103,32 @@ static struct hda_verb vt1708B_4ch_volume_init_verbs[] = {
{ }
};
+static struct hda_verb vt1708B_uniwill_init_verbs[] = {
+ {0x1D, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_HP_EVENT},
+ { }
+};
+
static struct hda_pcm_stream vt1708B_8ch_pcm_analog_playback = {
- .substreams = 1,
+ .substreams = 2,
.channels_min = 2,
.channels_max = 8,
.nid = 0x10, /* NID to query formats and rates */
.ops = {
.open = via_playback_pcm_open,
- .prepare = via_playback_pcm_prepare,
- .cleanup = via_playback_pcm_cleanup
+ .prepare = via_playback_multi_pcm_prepare,
+ .cleanup = via_playback_multi_pcm_cleanup
},
};
static struct hda_pcm_stream vt1708B_4ch_pcm_analog_playback = {
- .substreams = 1,
+ .substreams = 2,
.channels_min = 2,
.channels_max = 4,
.nid = 0x10, /* NID to query formats and rates */
.ops = {
.open = via_playback_pcm_open,
- .prepare = via_playback_pcm_prepare,
- .cleanup = via_playback_pcm_cleanup
+ .prepare = via_playback_multi_pcm_prepare,
+ .cleanup = via_playback_multi_pcm_cleanup
},
};
@@ -1662,10 +2184,10 @@ static int vt1708B_auto_fill_dac_nids(struct via_spec *spec,
spec->multiout.dac_nids[i] = 0x24;
break;
case AUTO_SEQ_SURROUND:
- spec->multiout.dac_nids[i] = 0x25;
+ spec->multiout.dac_nids[i] = 0x11;
break;
case AUTO_SEQ_SIDE:
- spec->multiout.dac_nids[i] = 0x11;
+ spec->multiout.dac_nids[i] = 0x25;
break;
}
}
@@ -1680,7 +2202,7 @@ static int vt1708B_auto_create_multi_out_ctls(struct via_spec *spec,
{
char name[32];
static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" };
- hda_nid_t nid_vols[] = {0x16, 0x27, 0x26, 0x18};
+ hda_nid_t nid_vols[] = {0x16, 0x18, 0x26, 0x27};
hda_nid_t nid, nid_vol = 0;
int i, err;
@@ -1785,6 +2307,8 @@ static int vt1708B_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
if (err < 0)
return err;
+ create_hp_imux(spec);
+
return 0;
}
@@ -1795,7 +2319,7 @@ static int vt1708B_auto_create_analog_input_ctls(struct via_spec *spec,
static char *labels[] = {
"Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL
};
- struct hda_input_mux *imux = &spec->private_imux;
+ struct hda_input_mux *imux = &spec->private_imux[0];
int i, err, idx = 0;
/* for internal loopback recording select */
@@ -1869,7 +2393,10 @@ static int vt1708B_parse_auto_config(struct hda_codec *codec)
if (spec->kctl_alloc)
spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
- spec->input_mux = &spec->private_imux;
+ spec->input_mux = &spec->private_imux[0];
+
+ if (spec->hp_mux)
+ spec->mixers[spec->num_mixers++] = via_hp_mixer;
return 1;
}
@@ -1890,7 +2417,7 @@ static int patch_vt1708B_8ch(struct hda_codec *codec)
int err;
/* create a codec specific record */
- spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
+ spec = kzalloc(sizeof(*spec), GFP_KERNEL);
if (spec == NULL)
return -ENOMEM;
@@ -1906,7 +2433,8 @@ static int patch_vt1708B_8ch(struct hda_codec *codec)
"from BIOS. Using genenic mode...\n");
}
- spec->init_verbs = vt1708B_8ch_volume_init_verbs;
+ spec->init_verbs[spec->num_iverbs++] = vt1708B_8ch_volume_init_verbs;
+ spec->init_verbs[spec->num_iverbs++] = vt1708B_uniwill_init_verbs;
spec->stream_name_analog = "VT1708B Analog";
spec->stream_analog_playback = &vt1708B_8ch_pcm_analog_playback;
@@ -1926,6 +2454,7 @@ static int patch_vt1708B_8ch(struct hda_codec *codec)
codec->patch_ops = via_patch_ops;
codec->patch_ops.init = via_auto_init;
+ codec->patch_ops.unsol_event = via_unsol_event;
#ifdef CONFIG_SND_HDA_POWER_SAVE
spec->loopback.amplist = vt1708B_loopbacks;
#endif
@@ -1939,7 +2468,7 @@ static int patch_vt1708B_4ch(struct hda_codec *codec)
int err;
/* create a codec specific record */
- spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
+ spec = kzalloc(sizeof(*spec), GFP_KERNEL);
if (spec == NULL)
return -ENOMEM;
@@ -1955,7 +2484,8 @@ static int patch_vt1708B_4ch(struct hda_codec *codec)
"from BIOS. Using genenic mode...\n");
}
- spec->init_verbs = vt1708B_4ch_volume_init_verbs;
+ spec->init_verbs[spec->num_iverbs++] = vt1708B_4ch_volume_init_verbs;
+ spec->init_verbs[spec->num_iverbs++] = vt1708B_uniwill_init_verbs;
spec->stream_name_analog = "VT1708B Analog";
spec->stream_analog_playback = &vt1708B_4ch_pcm_analog_playback;
@@ -1975,6 +2505,7 @@ static int patch_vt1708B_4ch(struct hda_codec *codec)
codec->patch_ops = via_patch_ops;
codec->patch_ops.init = via_auto_init;
+ codec->patch_ops.unsol_event = via_unsol_event;
#ifdef CONFIG_SND_HDA_POWER_SAVE
spec->loopback.amplist = vt1708B_loopbacks;
#endif
@@ -1982,6 +2513,752 @@ static int patch_vt1708B_4ch(struct hda_codec *codec)
return 0;
}
+/* Patch for VT1708S */
+
+/* VT1708S software backdoor based override for buggy hardware micboost
+ * setting */
+#define MIC_BOOST_VOLUME(xname, nid) { \
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
+ .name = xname, \
+ .index = 0, \
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \
+ SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
+ SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK, \
+ .info = mic_boost_volume_info, \
+ .get = snd_hda_mixer_amp_volume_get, \
+ .put = snd_hda_mixer_amp_volume_put, \
+ .tlv = { .c = mic_boost_tlv }, \
+ .private_value = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT) }
+
+/* capture mixer elements */
+static struct snd_kcontrol_new vt1708S_capture_mixer[] = {
+ HDA_CODEC_VOLUME("Capture Volume", 0x13, 0x0, HDA_INPUT),
+ HDA_CODEC_MUTE("Capture Switch", 0x13, 0x0, HDA_INPUT),
+ HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x14, 0x0, HDA_INPUT),
+ HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x14, 0x0, HDA_INPUT),
+ MIC_BOOST_VOLUME("Mic Boost Capture Volume", 0x1A),
+ MIC_BOOST_VOLUME("Front Mic Boost Capture Volume", 0x1E),
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ /* The multiple "Capture Source" controls confuse alsamixer
+ * So call somewhat different..
+ */
+ /* .name = "Capture Source", */
+ .name = "Input Source",
+ .count = 1,
+ .info = via_mux_enum_info,
+ .get = via_mux_enum_get,
+ .put = via_mux_enum_put,
+ },
+ { } /* end */
+};
+
+static struct hda_verb vt1708S_volume_init_verbs[] = {
+ /* Unmute ADC0-1 and set the default input to mic-in */
+ {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+ {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+
+ /* Unmute 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 */
+ {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+ {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+ {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
+ {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
+ {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
+
+ /* Setup default input of PW4 to MW0 */
+ {0x1d, AC_VERB_SET_CONNECT_SEL, 0x0},
+ /* PW9, PW10 Output enable */
+ {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
+ {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
+ /* Enable Mic Boost Volume backdoor */
+ {0x1, 0xf98, 0x1},
+ { }
+};
+
+static struct hda_verb vt1708S_uniwill_init_verbs[] = {
+ {0x1D, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_HP_EVENT},
+ { }
+};
+
+static struct hda_pcm_stream vt1708S_pcm_analog_playback = {
+ .substreams = 2,
+ .channels_min = 2,
+ .channels_max = 8,
+ .nid = 0x10, /* NID to query formats and rates */
+ .ops = {
+ .open = via_playback_pcm_open,
+ .prepare = via_playback_pcm_prepare,
+ .cleanup = via_playback_pcm_cleanup
+ },
+};
+
+static struct hda_pcm_stream vt1708S_pcm_analog_capture = {
+ .substreams = 2,
+ .channels_min = 2,
+ .channels_max = 2,
+ .nid = 0x13, /* NID to query formats and rates */
+ .ops = {
+ .prepare = via_capture_pcm_prepare,
+ .cleanup = via_capture_pcm_cleanup
+ },
+};
+
+static struct hda_pcm_stream vt1708S_pcm_digital_playback = {
+ .substreams = 2,
+ .channels_min = 2,
+ .channels_max = 2,
+ /* NID is set in via_build_pcms */
+ .ops = {
+ .open = via_dig_playback_pcm_open,
+ .close = via_dig_playback_pcm_close,
+ .prepare = via_dig_playback_pcm_prepare
+ },
+};
+
+/* fill in the dac_nids table from the parsed pin configuration */
+static int vt1708S_auto_fill_dac_nids(struct via_spec *spec,
+ const struct auto_pin_cfg *cfg)
+{
+ int i;
+ hda_nid_t nid;
+
+ spec->multiout.num_dacs = cfg->line_outs;
+
+ spec->multiout.dac_nids = spec->private_dac_nids;
+
+ for (i = 0; i < 4; i++) {
+ nid = cfg->line_out_pins[i];
+ if (nid) {
+ /* config dac list */
+ switch (i) {
+ case AUTO_SEQ_FRONT:
+ spec->multiout.dac_nids[i] = 0x10;
+ break;
+ case AUTO_SEQ_CENLFE:
+ spec->multiout.dac_nids[i] = 0x24;
+ break;
+ case AUTO_SEQ_SURROUND:
+ spec->multiout.dac_nids[i] = 0x11;
+ break;
+ case AUTO_SEQ_SIDE:
+ spec->multiout.dac_nids[i] = 0x25;
+ break;
+ }
+ }
+ }
+
+ return 0;
+}
+
+/* add playback controls from the parsed DAC table */
+static int vt1708S_auto_create_multi_out_ctls(struct via_spec *spec,
+ const struct auto_pin_cfg *cfg)
+{
+ char name[32];
+ static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" };
+ hda_nid_t nid_vols[] = {0x10, 0x11, 0x24, 0x25};
+ hda_nid_t nid_mutes[] = {0x1C, 0x18, 0x26, 0x27};
+ hda_nid_t nid, nid_vol, nid_mute;
+ int i, err;
+
+ for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
+ nid = cfg->line_out_pins[i];
+
+ if (!nid)
+ continue;
+
+ nid_vol = nid_vols[i];
+ nid_mute = nid_mutes[i];
+
+ if (i == AUTO_SEQ_CENLFE) {
+ /* Center/LFE */
+ err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
+ "Center Playback Volume",
+ HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
+ HDA_OUTPUT));
+ if (err < 0)
+ return err;
+ err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
+ "LFE Playback Volume",
+ HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
+ HDA_OUTPUT));
+ if (err < 0)
+ return err;
+ err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
+ "Center Playback Switch",
+ HDA_COMPOSE_AMP_VAL(nid_mute,
+ 1, 0,
+ HDA_OUTPUT));
+ if (err < 0)
+ return err;
+ err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
+ "LFE Playback Switch",
+ HDA_COMPOSE_AMP_VAL(nid_mute,
+ 2, 0,
+ HDA_OUTPUT));
+ if (err < 0)
+ return err;
+ } else if (i == AUTO_SEQ_FRONT) {
+ /* add control to mixer index 0 */
+ err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
+ "Master Front Playback Volume",
+ HDA_COMPOSE_AMP_VAL(0x16, 3, 0,
+ HDA_INPUT));
+ if (err < 0)
+ return err;
+ err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
+ "Master Front Playback Switch",
+ HDA_COMPOSE_AMP_VAL(0x16, 3, 0,
+ HDA_INPUT));
+ if (err < 0)
+ return err;
+
+ /* Front */
+ sprintf(name, "%s Playback Volume", chname[i]);
+ err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
+ HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
+ HDA_OUTPUT));
+ if (err < 0)
+ return err;
+ sprintf(name, "%s Playback Switch", chname[i]);
+ err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
+ HDA_COMPOSE_AMP_VAL(nid_mute,
+ 3, 0,
+ HDA_OUTPUT));
+ if (err < 0)
+ return err;
+ } else {
+ sprintf(name, "%s Playback Volume", chname[i]);
+ err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
+ HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
+ HDA_OUTPUT));
+ if (err < 0)
+ return err;
+ sprintf(name, "%s Playback Switch", chname[i]);
+ err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
+ HDA_COMPOSE_AMP_VAL(nid_mute,
+ 3, 0,
+ HDA_OUTPUT));
+ if (err < 0)
+ return err;
+ }
+ }
+
+ return 0;
+}
+
+static int vt1708S_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
+{
+ int err;
+
+ if (!pin)
+ return 0;
+
+ spec->multiout.hp_nid = VT1708S_HP_NID; /* AOW3 */
+
+ err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
+ "Headphone Playback Volume",
+ HDA_COMPOSE_AMP_VAL(0x25, 3, 0, HDA_OUTPUT));
+ if (err < 0)
+ return err;
+
+ err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
+ "Headphone Playback Switch",
+ HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
+ if (err < 0)
+ return err;
+
+ create_hp_imux(spec);
+
+ return 0;
+}
+
+/* create playback/capture controls for input pins */
+static int vt1708S_auto_create_analog_input_ctls(struct via_spec *spec,
+ const struct auto_pin_cfg *cfg)
+{
+ static char *labels[] = {
+ "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL
+ };
+ struct hda_input_mux *imux = &spec->private_imux[0];
+ int i, err, idx = 0;
+
+ /* for internal loopback recording select */
+ imux->items[imux->num_items].label = "Stereo Mixer";
+ imux->items[imux->num_items].index = 5;
+ imux->num_items++;
+
+ for (i = 0; i < AUTO_PIN_LAST; i++) {
+ if (!cfg->input_pins[i])
+ continue;
+
+ switch (cfg->input_pins[i]) {
+ case 0x1a: /* Mic */
+ idx = 2;
+ break;
+
+ case 0x1b: /* Line In */
+ idx = 3;
+ break;
+
+ case 0x1e: /* Front Mic */
+ idx = 4;
+ break;
+
+ case 0x1f: /* CD */
+ idx = 1;
+ break;
+ }
+ err = via_new_analog_input(spec, cfg->input_pins[i], labels[i],
+ idx, 0x16);
+ if (err < 0)
+ return err;
+ imux->items[imux->num_items].label = labels[i];
+ imux->items[imux->num_items].index = idx-1;
+ imux->num_items++;
+ }
+ return 0;
+}
+
+static int vt1708S_parse_auto_config(struct hda_codec *codec)
+{
+ struct via_spec *spec = codec->spec;
+ int err;
+ static hda_nid_t vt1708s_ignore[] = {0x21, 0};
+
+ err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
+ vt1708s_ignore);
+ if (err < 0)
+ return err;
+ err = vt1708S_auto_fill_dac_nids(spec, &spec->autocfg);
+ if (err < 0)
+ return err;
+ if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
+ return 0; /* can't find valid BIOS pin config */
+
+ err = vt1708S_auto_create_multi_out_ctls(spec, &spec->autocfg);
+ if (err < 0)
+ return err;
+ err = vt1708S_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
+ if (err < 0)
+ return err;
+ err = vt1708S_auto_create_analog_input_ctls(spec, &spec->autocfg);
+ if (err < 0)
+ return err;
+
+ spec->multiout.max_channels = spec->multiout.num_dacs * 2;
+
+ if (spec->autocfg.dig_out_pin)
+ spec->multiout.dig_out_nid = VT1708S_DIGOUT_NID;
+
+ spec->extra_dig_out_nid = 0x15;
+
+ if (spec->kctl_alloc)
+ spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
+
+ spec->input_mux = &spec->private_imux[0];
+
+ if (spec->hp_mux)
+ spec->mixers[spec->num_mixers++] = via_hp_mixer;
+
+ return 1;
+}
+
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+static struct hda_amp_list vt1708S_loopbacks[] = {
+ { 0x16, HDA_INPUT, 1 },
+ { 0x16, HDA_INPUT, 2 },
+ { 0x16, HDA_INPUT, 3 },
+ { 0x16, HDA_INPUT, 4 },
+ { } /* end */
+};
+#endif
+
+static int patch_vt1708S(struct hda_codec *codec)
+{
+ struct via_spec *spec;
+ int err;
+
+ /* create a codec specific record */
+ spec = kzalloc(sizeof(*spec), GFP_KERNEL);
+ if (spec == NULL)
+ return -ENOMEM;
+
+ codec->spec = spec;
+
+ /* automatic parse from the BIOS config */
+ err = vt1708S_parse_auto_config(codec);
+ if (err < 0) {
+ via_free(codec);
+ return err;
+ } else if (!err) {
+ printk(KERN_INFO "hda_codec: Cannot set up configuration "
+ "from BIOS. Using genenic mode...\n");
+ }
+
+ spec->init_verbs[spec->num_iverbs++] = vt1708S_volume_init_verbs;
+ spec->init_verbs[spec->num_iverbs++] = vt1708S_uniwill_init_verbs;
+
+ spec->stream_name_analog = "VT1708S Analog";
+ spec->stream_analog_playback = &vt1708S_pcm_analog_playback;
+ spec->stream_analog_capture = &vt1708S_pcm_analog_capture;
+
+ spec->stream_name_digital = "VT1708S Digital";
+ spec->stream_digital_playback = &vt1708S_pcm_digital_playback;
+
+ if (!spec->adc_nids && spec->input_mux) {
+ spec->adc_nids = vt1708S_adc_nids;
+ spec->num_adc_nids = ARRAY_SIZE(vt1708S_adc_nids);
+ spec->mixers[spec->num_mixers] = vt1708S_capture_mixer;
+ spec->num_mixers++;
+ }
+
+ codec->patch_ops = via_patch_ops;
+
+ codec->patch_ops.init = via_auto_init;
+ codec->patch_ops.unsol_event = via_unsol_event;
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+ spec->loopback.amplist = vt1708S_loopbacks;
+#endif
+
+ return 0;
+}
+
+/* Patch for VT1702 */
+
+/* capture mixer elements */
+static struct snd_kcontrol_new vt1702_capture_mixer[] = {
+ HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_INPUT),
+ HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_INPUT),
+ HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x20, 0x0, HDA_INPUT),
+ HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x20, 0x0, HDA_INPUT),
+ HDA_CODEC_VOLUME("Digital Mic Capture Volume", 0x1F, 0x0, HDA_INPUT),
+ HDA_CODEC_MUTE("Digital Mic Capture Switch", 0x1F, 0x0, HDA_INPUT),
+ HDA_CODEC_VOLUME("Digital Mic Boost Capture Volume", 0x1E, 0x0,
+ HDA_INPUT),
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ /* The multiple "Capture Source" controls confuse alsamixer
+ * So call somewhat different..
+ */
+ /* .name = "Capture Source", */
+ .name = "Input Source",
+ .count = 1,
+ .info = via_mux_enum_info,
+ .get = via_mux_enum_get,
+ .put = via_mux_enum_put,
+ },
+ { } /* end */
+};
+
+static struct hda_verb vt1702_volume_init_verbs[] = {
+ /*
+ * Unmute ADC0-1 and set the default input to mic-in
+ */
+ {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+ {0x1F, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+ {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+
+
+ /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
+ * mixer widget
+ */
+ /* Amp Indices: Mic1 = 1, Line = 1, Mic2 = 3 */
+ {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+ {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+ {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
+ {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
+ {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
+
+ /* Setup default input of PW4 to MW0 */
+ {0x17, AC_VERB_SET_CONNECT_SEL, 0x1},
+ /* PW6 PW7 Output enable */
+ {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
+ {0x1C, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
+ { }
+};
+
+static struct hda_verb vt1702_uniwill_init_verbs[] = {
+ {0x01, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_GPIO_EVENT},
+ {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_HP_EVENT},
+ { }
+};
+
+static struct hda_pcm_stream vt1702_pcm_analog_playback = {
+ .substreams = 2,
+ .channels_min = 2,
+ .channels_max = 2,
+ .nid = 0x10, /* NID to query formats and rates */
+ .ops = {
+ .open = via_playback_pcm_open,
+ .prepare = via_playback_multi_pcm_prepare,
+ .cleanup = via_playback_multi_pcm_cleanup
+ },
+};
+
+static struct hda_pcm_stream vt1702_pcm_analog_capture = {
+ .substreams = 3,
+ .channels_min = 2,
+ .channels_max = 2,
+ .nid = 0x12, /* NID to query formats and rates */
+ .ops = {
+ .prepare = via_capture_pcm_prepare,
+ .cleanup = via_capture_pcm_cleanup
+ },
+};
+
+static struct hda_pcm_stream vt1702_pcm_digital_playback = {
+ .substreams = 2,
+ .channels_min = 2,
+ .channels_max = 2,
+ /* NID is set in via_build_pcms */
+ .ops = {
+ .open = via_dig_playback_pcm_open,
+ .close = via_dig_playback_pcm_close,
+ .prepare = via_dig_playback_pcm_prepare
+ },
+};
+
+/* fill in the dac_nids table from the parsed pin configuration */
+static int vt1702_auto_fill_dac_nids(struct via_spec *spec,
+ const struct auto_pin_cfg *cfg)
+{
+ spec->multiout.num_dacs = 1;
+ spec->multiout.dac_nids = spec->private_dac_nids;
+
+ if (cfg->line_out_pins[0]) {
+ /* config dac list */
+ spec->multiout.dac_nids[0] = 0x10;
+ }
+
+ return 0;
+}
+
+/* add playback controls from the parsed DAC table */
+static int vt1702_auto_create_line_out_ctls(struct via_spec *spec,
+ const struct auto_pin_cfg *cfg)
+{
+ int err;
+
+ if (!cfg->line_out_pins[0])
+ return -1;
+
+ /* add control to mixer index 0 */
+ err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
+ "Master Front Playback Volume",
+ HDA_COMPOSE_AMP_VAL(0x1A, 3, 0, HDA_INPUT));
+ if (err < 0)
+ return err;
+ err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
+ "Master Front Playback Switch",
+ HDA_COMPOSE_AMP_VAL(0x1A, 3, 0, HDA_INPUT));
+ if (err < 0)
+ return err;
+
+ /* Front */
+ err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
+ "Front Playback Volume",
+ HDA_COMPOSE_AMP_VAL(0x10, 3, 0, HDA_OUTPUT));
+ if (err < 0)
+ return err;
+ err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
+ "Front Playback Switch",
+ HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT));
+ if (err < 0)
+ return err;
+
+ return 0;
+}
+
+static int vt1702_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
+{
+ int err;
+
+ if (!pin)
+ return 0;
+
+ spec->multiout.hp_nid = 0x1D;
+
+ err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
+ "Headphone Playback Volume",
+ HDA_COMPOSE_AMP_VAL(0x1D, 3, 0, HDA_OUTPUT));
+ if (err < 0)
+ return err;
+
+ err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
+ "Headphone Playback Switch",
+ HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
+ if (err < 0)
+ return err;
+
+ create_hp_imux(spec);
+
+ return 0;
+}
+
+/* create playback/capture controls for input pins */
+static int vt1702_auto_create_analog_input_ctls(struct via_spec *spec,
+ const struct auto_pin_cfg *cfg)
+{
+ static char *labels[] = {
+ "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL
+ };
+ struct hda_input_mux *imux = &spec->private_imux[0];
+ int i, err, idx = 0;
+
+ /* for internal loopback recording select */
+ imux->items[imux->num_items].label = "Stereo Mixer";
+ imux->items[imux->num_items].index = 3;
+ imux->num_items++;
+
+ for (i = 0; i < AUTO_PIN_LAST; i++) {
+ if (!cfg->input_pins[i])
+ continue;
+
+ switch (cfg->input_pins[i]) {
+ case 0x14: /* Mic */
+ idx = 1;
+ break;
+
+ case 0x15: /* Line In */
+ idx = 2;
+ break;
+
+ case 0x18: /* Front Mic */
+ idx = 3;
+ break;
+ }
+ err = via_new_analog_input(spec, cfg->input_pins[i],
+ labels[i], idx, 0x1A);
+ if (err < 0)
+ return err;
+ imux->items[imux->num_items].label = labels[i];
+ imux->items[imux->num_items].index = idx-1;
+ imux->num_items++;
+ }
+ return 0;
+}
+
+static int vt1702_parse_auto_config(struct hda_codec *codec)
+{
+ struct via_spec *spec = codec->spec;
+ int err;
+ static hda_nid_t vt1702_ignore[] = {0x1C, 0};
+
+ err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
+ vt1702_ignore);
+ if (err < 0)
+ return err;
+ err = vt1702_auto_fill_dac_nids(spec, &spec->autocfg);
+ if (err < 0)
+ return err;
+ if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
+ return 0; /* can't find valid BIOS pin config */
+
+ err = vt1702_auto_create_line_out_ctls(spec, &spec->autocfg);
+ if (err < 0)
+ return err;
+ err = vt1702_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
+ if (err < 0)
+ return err;
+ err = vt1702_auto_create_analog_input_ctls(spec, &spec->autocfg);
+ if (err < 0)
+ return err;
+
+ spec->multiout.max_channels = spec->multiout.num_dacs * 2;
+
+ if (spec->autocfg.dig_out_pin)
+ spec->multiout.dig_out_nid = VT1702_DIGOUT_NID;
+
+ spec->extra_dig_out_nid = 0x1B;
+
+ if (spec->kctl_alloc)
+ spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
+
+ spec->input_mux = &spec->private_imux[0];
+
+ if (spec->hp_mux)
+ spec->mixers[spec->num_mixers++] = via_hp_mixer;
+
+ return 1;
+}
+
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+static struct hda_amp_list vt1702_loopbacks[] = {
+ { 0x1A, HDA_INPUT, 1 },
+ { 0x1A, HDA_INPUT, 2 },
+ { 0x1A, HDA_INPUT, 3 },
+ { 0x1A, HDA_INPUT, 4 },
+ { } /* end */
+};
+#endif
+
+static int patch_vt1702(struct hda_codec *codec)
+{
+ struct via_spec *spec;
+ int err;
+ unsigned int response;
+ unsigned char control;
+
+ /* create a codec specific record */
+ spec = kzalloc(sizeof(*spec), GFP_KERNEL);
+ if (spec == NULL)
+ return -ENOMEM;
+
+ codec->spec = spec;
+
+ /* automatic parse from the BIOS config */
+ err = vt1702_parse_auto_config(codec);
+ if (err < 0) {
+ via_free(codec);
+ return err;
+ } else if (!err) {
+ printk(KERN_INFO "hda_codec: Cannot set up configuration "
+ "from BIOS. Using genenic mode...\n");
+ }
+
+ spec->init_verbs[spec->num_iverbs++] = vt1702_volume_init_verbs;
+ spec->init_verbs[spec->num_iverbs++] = vt1702_uniwill_init_verbs;
+
+ spec->stream_name_analog = "VT1702 Analog";
+ spec->stream_analog_playback = &vt1702_pcm_analog_playback;
+ spec->stream_analog_capture = &vt1702_pcm_analog_capture;
+
+ spec->stream_name_digital = "VT1702 Digital";
+ spec->stream_digital_playback = &vt1702_pcm_digital_playback;
+
+ if (!spec->adc_nids && spec->input_mux) {
+ spec->adc_nids = vt1702_adc_nids;
+ spec->num_adc_nids = ARRAY_SIZE(vt1702_adc_nids);
+ spec->mixers[spec->num_mixers] = vt1702_capture_mixer;
+ spec->num_mixers++;
+ }
+
+ codec->patch_ops = via_patch_ops;
+
+ codec->patch_ops.init = via_auto_init;
+ codec->patch_ops.unsol_event = via_unsol_event;
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+ spec->loopback.amplist = vt1702_loopbacks;
+#endif
+
+ /* Open backdoor */
+ response = snd_hda_codec_read(codec, codec->afg, 0, 0xF8C, 0);
+ control = (unsigned char)(response & 0xff);
+ control |= 0x3;
+ snd_hda_codec_write(codec, codec->afg, 0, 0xF88, control);
+
+ /* Enable GPIO 0&1 for volume&mute control */
+ /* Enable GPIO 2 for DMIC-DATA */
+ response = snd_hda_codec_read(codec, codec->afg, 0, 0xF84, 0);
+ control = (unsigned char)((response >> 16) & 0x3f);
+ snd_hda_codec_write(codec, codec->afg, 0, 0xF82, control);
+
+ return 0;
+}
+
/*
* patch entries
*/
@@ -2022,5 +3299,37 @@ struct hda_codec_preset snd_hda_preset_via[] = {
.patch = patch_vt1708B_4ch},
{ .id = 0x1106E727, .name = "VIA VT1708B 4-Ch",
.patch = patch_vt1708B_4ch},
+ { .id = 0x11060397, .name = "VIA VT1708S",
+ .patch = patch_vt1708S},
+ { .id = 0x11061397, .name = "VIA VT1708S",
+ .patch = patch_vt1708S},
+ { .id = 0x11062397, .name = "VIA VT1708S",
+ .patch = patch_vt1708S},
+ { .id = 0x11063397, .name = "VIA VT1708S",
+ .patch = patch_vt1708S},
+ { .id = 0x11064397, .name = "VIA VT1708S",
+ .patch = patch_vt1708S},
+ { .id = 0x11065397, .name = "VIA VT1708S",
+ .patch = patch_vt1708S},
+ { .id = 0x11066397, .name = "VIA VT1708S",
+ .patch = patch_vt1708S},
+ { .id = 0x11067397, .name = "VIA VT1708S",
+ .patch = patch_vt1708S},
+ { .id = 0x11060398, .name = "VIA VT1702",
+ .patch = patch_vt1702},
+ { .id = 0x11061398, .name = "VIA VT1702",
+ .patch = patch_vt1702},
+ { .id = 0x11062398, .name = "VIA VT1702",
+ .patch = patch_vt1702},
+ { .id = 0x11063398, .name = "VIA VT1702",
+ .patch = patch_vt1702},
+ { .id = 0x11064398, .name = "VIA VT1702",
+ .patch = patch_vt1702},
+ { .id = 0x11065398, .name = "VIA VT1702",
+ .patch = patch_vt1702},
+ { .id = 0x11066398, .name = "VIA VT1702",
+ .patch = patch_vt1702},
+ { .id = 0x11067398, .name = "VIA VT1702",
+ .patch = patch_vt1702},
{} /* terminator */
};
diff --git a/sound/pci/ice1712/ak4xxx.c b/sound/pci/ice1712/ak4xxx.c
index dab31b2756a6..03391da8c8c7 100644
--- a/sound/pci/ice1712/ak4xxx.c
+++ b/sound/pci/ice1712/ak4xxx.c
@@ -59,7 +59,8 @@ static void snd_ice1712_akm4xxx_write(struct snd_akm4xxx *ak, int chip,
struct snd_ak4xxx_private *priv = (void *)ak->private_value[0];
struct snd_ice1712 *ice = ak->private_data[0];
- snd_assert(chip >= 0 && chip < 4, return);
+ if (snd_BUG_ON(chip < 0 || chip >= 4))
+ return;
tmp = snd_ice1712_gpio_read(ice);
tmp |= priv->add_flags;
diff --git a/sound/pci/ice1712/aureon.c b/sound/pci/ice1712/aureon.c
index 868ae291b960..110d16e52733 100644
--- a/sound/pci/ice1712/aureon.c
+++ b/sound/pci/ice1712/aureon.c
@@ -44,10 +44,9 @@
* not working: prety much everything else, at least i could verify that
* we have no digital output, no capture, pretty bad clicks and poops
* on mixer switch and other coll stuff.
- *
- */
+ */
-#include <asm/io.h>
+#include <linux/io.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/init.h>
@@ -131,7 +130,7 @@ static void aureon_pca9554_write(struct snd_ice1712 *ice, unsigned char reg,
snd_ice1712_gpio_write(ice, tmp);
udelay(50);
- /*
+ /*
* send i2c stop condition and start condition
* to obtain sane state
*/
@@ -152,10 +151,16 @@ static void aureon_pca9554_write(struct snd_ice1712 *ice, unsigned char reg,
* skipping ack cycles inbetween
*/
for (j = 0; j < 3; j++) {
- switch(j) {
- case 0: val = dev; break;
- case 1: val = reg; break;
- case 2: val = data; break;
+ switch (j) {
+ case 0:
+ val = dev;
+ break;
+ case 1:
+ val = reg;
+ break;
+ case 2:
+ val = data;
+ break;
}
for (i = 7; i >= 0; i--) {
tmp &= ~AUREON_SPI_CLK;
@@ -171,7 +176,7 @@ static void aureon_pca9554_write(struct snd_ice1712 *ice, unsigned char reg,
snd_ice1712_gpio_write(ice, tmp);
udelay(40);
}
- tmp &= ~AUREON_SPI_CLK;
+ tmp &= ~AUREON_SPI_CLK;
snd_ice1712_gpio_write(ice, tmp);
udelay(40);
tmp |= AUREON_SPI_CLK;
@@ -203,7 +208,7 @@ static int aureon_universe_inmux_info(struct snd_kcontrol *kcontrol,
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, texts[uinfo->value.enumerated.item]);
return 0;
@@ -231,12 +236,12 @@ static int aureon_universe_inmux_put(struct snd_kcontrol *kcontrol,
return -EINVAL;
snd_ice1712_save_gpio_status(ice);
oval = spec->pca9554_out;
- if ((change = (oval != nval))) {
+ change = (oval != nval);
+ if (change) {
aureon_pca9554_write(ice, PCA9554_OUT, nval);
spec->pca9554_out = nval;
}
snd_ice1712_restore_gpio_status(ice);
-
return change;
}
@@ -256,7 +261,7 @@ static void aureon_ac97_write(struct snd_ice1712 *ice, unsigned short reg,
udelay(10);
tmp &= ~AUREON_AC97_ADDR;
snd_ice1712_gpio_write(ice, tmp);
- udelay(10);
+ udelay(10);
/* Send low-order byte to XILINX chip */
tmp &= ~AUREON_AC97_DATA_MASK;
@@ -269,7 +274,7 @@ static void aureon_ac97_write(struct snd_ice1712 *ice, unsigned short reg,
tmp &= ~AUREON_AC97_DATA_LOW;
snd_ice1712_gpio_write(ice, tmp);
udelay(10);
-
+
/* Send high-order byte to XILINX chip */
tmp &= ~AUREON_AC97_DATA_MASK;
tmp |= (val >> 8) & AUREON_AC97_DATA_MASK;
@@ -282,7 +287,7 @@ static void aureon_ac97_write(struct snd_ice1712 *ice, unsigned short reg,
tmp &= ~AUREON_AC97_DATA_HIGH;
snd_ice1712_gpio_write(ice, tmp);
udelay(10);
-
+
/* Instruct XILINX chip to parse the data to the STAC9744 chip */
tmp |= AUREON_AC97_COMMIT;
snd_ice1712_gpio_write(ice, tmp);
@@ -290,7 +295,7 @@ static void aureon_ac97_write(struct snd_ice1712 *ice, unsigned short reg,
tmp &= ~AUREON_AC97_COMMIT;
snd_ice1712_gpio_write(ice, tmp);
udelay(10);
-
+
/* Store the data in out private buffer */
spec->stac9744[(reg & 0x7F) >> 1] = val;
}
@@ -304,7 +309,7 @@ static unsigned short aureon_ac97_read(struct snd_ice1712 *ice, unsigned short r
/*
* Initialize STAC9744 chip
*/
-static int aureon_ac97_init (struct snd_ice1712 *ice)
+static int aureon_ac97_init(struct snd_ice1712 *ice)
{
struct aureon_spec *spec = ice->spec;
int i;
@@ -335,20 +340,21 @@ static int aureon_ac97_init (struct snd_ice1712 *ice)
tmp = (snd_ice1712_gpio_read(ice) | AUREON_AC97_RESET) & ~AUREON_AC97_DATA_MASK;
snd_ice1712_gpio_write(ice, tmp);
udelay(3);
-
+
tmp &= ~AUREON_AC97_RESET;
snd_ice1712_gpio_write(ice, tmp);
udelay(3);
-
+
tmp |= AUREON_AC97_RESET;
snd_ice1712_gpio_write(ice, tmp);
udelay(3);
-
+
memset(&spec->stac9744, 0, sizeof(spec->stac9744));
- for (i=0; ac97_defaults[i] != (unsigned short)-1; i+=2)
+ for (i = 0; ac97_defaults[i] != (unsigned short)-1; i += 2)
spec->stac9744[(ac97_defaults[i]) >> 1] = ac97_defaults[i+1];
-
- aureon_ac97_write(ice, AC97_MASTER, 0x0000); // Unmute AC'97 master volume permanently - muting is done by WM8770
+
+ /* Unmute AC'97 master volume permanently - muting is done by WM8770 */
+ aureon_ac97_write(ice, AC97_MASTER, 0x0000);
return 0;
}
@@ -388,7 +394,7 @@ static int aureon_ac97_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_ele
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
unsigned short ovol, nvol;
int change;
-
+
snd_ice1712_save_gpio_status(ice);
ovol = aureon_ac97_read(ice, kcontrol->private_value & 0x7F);
@@ -396,13 +402,14 @@ static int aureon_ac97_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_ele
if (kcontrol->private_value & AUREON_AC97_STEREO)
nvol |= ((0x1F - ucontrol->value.integer.value[1]) << 8) & 0x1F00;
nvol |= ovol & ~0x1F1F;
-
- if ((change = (ovol != nvol)))
+
+ change = (ovol != nvol);
+ if (change)
aureon_ac97_write(ice, kcontrol->private_value & 0x7F, nvol);
snd_ice1712_restore_gpio_status(ice);
- return change;
+ return change;
}
/*
@@ -416,7 +423,8 @@ static int aureon_ac97_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_el
mutex_lock(&ice->gpio_mutex);
- ucontrol->value.integer.value[0] = aureon_ac97_read(ice, kcontrol->private_value & 0x7F) & 0x8000 ? 0 : 1;
+ ucontrol->value.integer.value[0] = aureon_ac97_read(ice,
+ kcontrol->private_value & 0x7F) & 0x8000 ? 0 : 1;
mutex_unlock(&ice->gpio_mutex);
return 0;
@@ -429,13 +437,14 @@ static int aureon_ac97_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_el
int change;
snd_ice1712_save_gpio_status(ice);
-
+
ovol = aureon_ac97_read(ice, kcontrol->private_value & 0x7F);
- nvol = (ucontrol->value.integer.value[0] ? 0x0000 : 0x8000) | (ovol & ~ 0x8000);
-
- if ((change = (ovol != nvol)))
+ nvol = (ucontrol->value.integer.value[0] ? 0x0000 : 0x8000) | (ovol & ~0x8000);
+
+ change = (ovol != nvol);
+ if (change)
aureon_ac97_write(ice, kcontrol->private_value & 0x7F, nvol);
-
+
snd_ice1712_restore_gpio_status(ice);
return change;
@@ -465,13 +474,14 @@ static int aureon_ac97_micboost_put(struct snd_kcontrol *kcontrol, struct snd_ct
int change;
snd_ice1712_save_gpio_status(ice);
-
+
ovol = aureon_ac97_read(ice, AC97_MIC);
nvol = (ucontrol->value.integer.value[0] ? 0x0000 : 0x0020) | (ovol & ~0x0020);
-
- if ((change = (ovol != nvol)))
+
+ change = (ovol != nvol);
+ if (change)
aureon_ac97_write(ice, AC97_MIC, nvol);
-
+
snd_ice1712_restore_gpio_status(ice);
return change;
@@ -493,16 +503,15 @@ static void aureon_spi_write(struct snd_ice1712 *ice, unsigned int cs, unsigned
snd_ice1712_gpio_set_mask(ice, ~(PRODIGY_SPI_MOSI|PRODIGY_SPI_CLK|PRODIGY_WM_CS));
mosi = PRODIGY_SPI_MOSI;
clk = PRODIGY_SPI_CLK;
- }
- else {
+ } else {
snd_ice1712_gpio_set_mask(ice, ~(AUREON_WM_RW|AUREON_SPI_MOSI|AUREON_SPI_CLK|
AUREON_WM_CS|AUREON_CS8415_CS));
mosi = AUREON_SPI_MOSI;
clk = AUREON_SPI_CLK;
-
+
tmp |= AUREON_WM_RW;
}
-
+
tmp &= ~cs;
snd_ice1712_gpio_write(ice, tmp);
udelay(1);
@@ -534,7 +543,9 @@ static void aureon_spi_write(struct snd_ice1712 *ice, unsigned int cs, unsigned
/*
* Read data in SPI mode
*/
-static void aureon_spi_read(struct snd_ice1712 *ice, unsigned int cs, unsigned int data, int bits, unsigned char *buffer, int size) {
+static void aureon_spi_read(struct snd_ice1712 *ice, unsigned int cs,
+ unsigned int data, int bits, unsigned char *buffer, int size)
+{
int i, j;
unsigned int tmp;
@@ -544,7 +555,7 @@ static void aureon_spi_read(struct snd_ice1712 *ice, unsigned int cs, unsigned i
snd_ice1712_gpio_write(ice, tmp);
udelay(1);
- for (i=bits-1; i>=0; i--) {
+ for (i = bits-1; i >= 0; i--) {
if (data & (1 << i))
tmp |= AUREON_SPI_MOSI;
else
@@ -561,9 +572,9 @@ static void aureon_spi_read(struct snd_ice1712 *ice, unsigned int cs, unsigned i
udelay(1);
}
- for (j=0; j<size; j++) {
+ for (j = 0; j < size; j++) {
unsigned char outdata = 0;
- for (i=7; i>=0; i--) {
+ for (i = 7; i >= 0; i--) {
tmp = snd_ice1712_gpio_read(ice);
outdata <<= 1;
outdata |= (tmp & AUREON_SPI_MISO) ? 1 : 0;
@@ -584,19 +595,24 @@ static void aureon_spi_read(struct snd_ice1712 *ice, unsigned int cs, unsigned i
snd_ice1712_gpio_write(ice, tmp);
}
-static unsigned char aureon_cs8415_get(struct snd_ice1712 *ice, int reg) {
+static unsigned char aureon_cs8415_get(struct snd_ice1712 *ice, int reg)
+{
unsigned char val;
aureon_spi_write(ice, AUREON_CS8415_CS, 0x2000 | reg, 16);
aureon_spi_read(ice, AUREON_CS8415_CS, 0x21, 8, &val, 1);
return val;
}
-static void aureon_cs8415_read(struct snd_ice1712 *ice, int reg, unsigned char *buffer, int size) {
+static void aureon_cs8415_read(struct snd_ice1712 *ice, int reg,
+ unsigned char *buffer, int size)
+{
aureon_spi_write(ice, AUREON_CS8415_CS, 0x2000 | reg, 16);
aureon_spi_read(ice, AUREON_CS8415_CS, 0x21, 8, buffer, size);
}
-static void aureon_cs8415_put(struct snd_ice1712 *ice, int reg, unsigned char val) {
+static void aureon_cs8415_put(struct snd_ice1712 *ice, int reg,
+ unsigned char val)
+{
aureon_spi_write(ice, AUREON_CS8415_CS, 0x200000 | (reg << 8) | val, 24);
}
@@ -654,18 +670,20 @@ static int aureon_ac97_mmute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_e
return 0;
}
-static int aureon_ac97_mmute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) {
+static int aureon_ac97_mmute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+{
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
unsigned short ovol, nvol;
int change;
-
+
snd_ice1712_save_gpio_status(ice);
-
+
ovol = wm_get(ice, WM_OUT_MUX1);
nvol = (ovol & ~0x02) | (ucontrol->value.integer.value[0] ? 0x02 : 0x00);
- if ((change = (ovol != nvol)))
+ change = (ovol != nvol);
+ if (change)
wm_put(ice, WM_OUT_MUX1, nvol);
-
+
snd_ice1712_restore_gpio_status(ice);
return change;
@@ -702,12 +720,12 @@ static const unsigned char wm_vol[256] = {
static void wm_set_vol(struct snd_ice1712 *ice, unsigned int index, unsigned short vol, unsigned short master)
{
unsigned char nvol;
-
+
if ((master & WM_VOL_MUTE) || (vol & WM_VOL_MUTE))
nvol = 0;
else
nvol = 127 - wm_vol[(((vol & ~WM_VOL_MUTE) * (master & ~WM_VOL_MUTE)) / 127) & WM_VOL_MAX];
-
+
wm_put(ice, index, nvol);
wm_put_nocache(ice, index, 0x180 | nvol);
}
@@ -736,7 +754,8 @@ static int wm_pcm_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_va
snd_ice1712_save_gpio_status(ice);
oval = wm_get(ice, WM_MUTE);
nval = (oval & ~0x10) | (ucontrol->value.integer.value[0] ? 0 : 0x10);
- if ((change = (nval != oval)))
+ change = (oval != nval);
+ if (change)
wm_put(ice, WM_MUTE, nval);
snd_ice1712_restore_gpio_status(ice);
@@ -760,7 +779,7 @@ static int wm_master_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
struct aureon_spec *spec = ice->spec;
int i;
- for (i=0; i<2; i++)
+ for (i = 0; i < 2; i++)
ucontrol->value.integer.value[i] =
spec->master[i] & ~WM_VOL_MUTE;
return 0;
@@ -849,7 +868,8 @@ static int wm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *
/*
* WM8770 mute control
*/
-static int wm_mute_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) {
+static int wm_mute_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
+{
uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
uinfo->count = kcontrol->private_value >> 8;
uinfo->value.integer.min = 0;
@@ -862,7 +882,7 @@ static int wm_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
struct aureon_spec *spec = ice->spec;
int voices, ofs, i;
-
+
voices = kcontrol->private_value >> 8;
ofs = kcontrol->private_value & 0xFF;
@@ -907,7 +927,7 @@ static int wm_master_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem
{
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
struct aureon_spec *spec = ice->spec;
-
+
ucontrol->value.integer.value[0] =
(spec->master[0] & WM_VOL_MUTE) ? 0 : 1;
ucontrol->value.integer.value[1] =
@@ -1083,21 +1103,21 @@ static int wm_adc_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val
static int wm_adc_mux_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
{
static const char * const texts[] = {
- "CD", //AIN1
- "Aux", //AIN2
- "Line", //AIN3
- "Mic", //AIN4
- "AC97" //AIN5
+ "CD", /* AIN1 */
+ "Aux", /* AIN2 */
+ "Line", /* AIN3 */
+ "Mic", /* AIN4 */
+ "AC97" /* AIN5 */
};
static const char * const universe_texts[] = {
- "Aux1", //AIN1
- "CD", //AIN2
- "Phono", //AIN3
- "Line", //AIN4
- "Aux2", //AIN5
- "Mic", //AIN6
- "Aux3", //AIN7
- "AC97" //AIN8
+ "Aux1", /* AIN1 */
+ "CD", /* AIN2 */
+ "Phono", /* AIN3 */
+ "Line", /* AIN4 */
+ "Aux2", /* AIN5 */
+ "Mic", /* AIN6 */
+ "Aux3", /* AIN7 */
+ "AC97" /* AIN8 */
};
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
@@ -1108,8 +1128,7 @@ static int wm_adc_mux_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_in
if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
strcpy(uinfo->value.enumerated.name, universe_texts[uinfo->value.enumerated.item]);
- }
- else {
+ } else {
uinfo->value.enumerated.items = 5;
if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
@@ -1156,8 +1175,8 @@ static int aureon_cs8415_mux_info(struct snd_kcontrol *kcontrol, struct snd_ctl_
{
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
static const char * const aureon_texts[] = {
- "CD", //RXP0
- "Optical" //RXP1
+ "CD", /* RXP0 */
+ "Optical" /* RXP1 */
};
static const char * const prodigy_texts[] = {
"CD",
@@ -1180,10 +1199,10 @@ static int aureon_cs8415_mux_get(struct snd_kcontrol *kcontrol, struct snd_ctl_e
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
struct aureon_spec *spec = ice->spec;
- //snd_ice1712_save_gpio_status(ice);
- //val = aureon_cs8415_get(ice, CS8415_CTRL2);
+ /* snd_ice1712_save_gpio_status(ice); */
+ /* val = aureon_cs8415_get(ice, CS8415_CTRL2); */
ucontrol->value.enumerated.item[0] = spec->cs8415_mux;
- //snd_ice1712_restore_gpio_status(ice);
+ /* snd_ice1712_restore_gpio_status(ice); */
return 0;
}
@@ -1206,7 +1225,7 @@ static int aureon_cs8415_mux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e
return change;
}
-static int aureon_cs8415_rate_info (struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
+static int aureon_cs8415_rate_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
{
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
uinfo->count = 1;
@@ -1215,7 +1234,7 @@ static int aureon_cs8415_rate_info (struct snd_kcontrol *kcontrol, struct snd_ct
return 0;
}
-static int aureon_cs8415_rate_get (struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int aureon_cs8415_rate_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
unsigned char ratio;
@@ -1229,7 +1248,7 @@ static int aureon_cs8415_rate_get (struct snd_kcontrol *kcontrol, struct snd_ctl
*/
#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)
+static int aureon_cs8415_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
snd_ice1712_save_gpio_status(ice);
@@ -1238,7 +1257,7 @@ static int aureon_cs8415_mute_get (struct snd_kcontrol *kcontrol, struct snd_ctl
return 0;
}
-static int aureon_cs8415_mute_put (struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int aureon_cs8415_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
unsigned char oval, nval;
@@ -1249,7 +1268,8 @@ static int aureon_cs8415_mute_put (struct snd_kcontrol *kcontrol, struct snd_ctl
nval = oval & ~0x20;
else
nval = oval | 0x20;
- if ((change = (oval != nval)))
+ change = (oval != nval);
+ if (change)
aureon_cs8415_put(ice, CS8415_CTRL1, nval);
snd_ice1712_restore_gpio_status(ice);
return change;
@@ -1258,15 +1278,17 @@ static int aureon_cs8415_mute_put (struct snd_kcontrol *kcontrol, struct snd_ctl
/*
* CS8415A Q-Sub info
*/
-static int aureon_cs8415_qsub_info (struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) {
+static int aureon_cs8415_qsub_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
+{
uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
uinfo->count = 10;
return 0;
}
-static int aureon_cs8415_qsub_get (struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) {
+static int aureon_cs8415_qsub_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+{
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
-
+
snd_ice1712_save_gpio_status(ice);
aureon_cs8415_read(ice, CS8415_QSUB, ucontrol->value.bytes.data, 10);
snd_ice1712_restore_gpio_status(ice);
@@ -1274,18 +1296,21 @@ static int aureon_cs8415_qsub_get (struct snd_kcontrol *kcontrol, struct snd_ctl
return 0;
}
-static int aureon_cs8415_spdif_info (struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) {
+static int aureon_cs8415_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
+{
uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
uinfo->count = 1;
return 0;
}
-static int aureon_cs8415_mask_get (struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) {
+static int aureon_cs8415_mask_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+{
memset(ucontrol->value.iec958.status, 0xFF, 24);
return 0;
}
-static int aureon_cs8415_spdif_get (struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) {
+static int aureon_cs8415_spdif_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+{
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
snd_ice1712_save_gpio_status(ice);
@@ -1311,9 +1336,9 @@ static int aureon_set_headphone_amp(struct snd_ice1712 *ice, int enable)
else
if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT &&
ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71XT)
- tmp &= ~ AUREON_HP_SEL;
+ tmp &= ~AUREON_HP_SEL;
else
- tmp &= ~ PRODIGY_HP_SEL;
+ tmp &= ~PRODIGY_HP_SEL;
if (tmp != tmp2) {
snd_ice1712_gpio_write(ice, tmp);
return 1;
@@ -1325,7 +1350,7 @@ static int aureon_get_headphone_amp(struct snd_ice1712 *ice)
{
unsigned int tmp = snd_ice1712_gpio_read(ice);
- return ( tmp & AUREON_HP_SEL )!= 0;
+ return (tmp & AUREON_HP_SEL) != 0;
}
#define aureon_hpamp_info snd_ctl_boolean_mono_info
@@ -1343,7 +1368,7 @@ static int aureon_hpamp_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_v
{
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- return aureon_set_headphone_amp(ice,ucontrol->value.integer.value[0]);
+ return aureon_set_headphone_amp(ice, ucontrol->value.integer.value[0]);
}
/*
@@ -1390,7 +1415,7 @@ static int aureon_oversampling_info(struct snd_kcontrol *k, struct snd_ctl_elem_
uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
- return 0;
+ return 0;
}
static int aureon_oversampling_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
@@ -1434,7 +1459,7 @@ static struct snd_kcontrol_new aureon_dac_controls[] __devinitdata = {
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ),
+ SNDRV_CTL_ELEM_ACCESS_TLV_READ),
.name = "Master Playback Volume",
.info = wm_master_vol_info,
.get = wm_master_vol_get,
@@ -1452,7 +1477,7 @@ static struct snd_kcontrol_new aureon_dac_controls[] __devinitdata = {
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ),
+ SNDRV_CTL_ELEM_ACCESS_TLV_READ),
.name = "Front Playback Volume",
.info = wm_vol_info,
.get = wm_vol_get,
@@ -1471,7 +1496,7 @@ static struct snd_kcontrol_new aureon_dac_controls[] __devinitdata = {
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ),
+ SNDRV_CTL_ELEM_ACCESS_TLV_READ),
.name = "Rear Playback Volume",
.info = wm_vol_info,
.get = wm_vol_get,
@@ -1490,7 +1515,7 @@ static struct snd_kcontrol_new aureon_dac_controls[] __devinitdata = {
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ),
+ SNDRV_CTL_ELEM_ACCESS_TLV_READ),
.name = "Center Playback Volume",
.info = wm_vol_info,
.get = wm_vol_get,
@@ -1509,7 +1534,7 @@ static struct snd_kcontrol_new aureon_dac_controls[] __devinitdata = {
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ),
+ SNDRV_CTL_ELEM_ACCESS_TLV_READ),
.name = "LFE Playback Volume",
.info = wm_vol_info,
.get = wm_vol_get,
@@ -1528,7 +1553,7 @@ static struct snd_kcontrol_new aureon_dac_controls[] __devinitdata = {
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ),
+ SNDRV_CTL_ELEM_ACCESS_TLV_READ),
.name = "Side Playback Volume",
.info = wm_vol_info,
.get = wm_vol_get,
@@ -1539,23 +1564,23 @@ static struct snd_kcontrol_new aureon_dac_controls[] __devinitdata = {
};
static struct snd_kcontrol_new wm_controls[] __devinitdata = {
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "PCM Playback Switch",
.info = wm_pcm_mute_info,
.get = wm_pcm_mute_get,
.put = wm_pcm_mute_put
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ },
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ),
+ SNDRV_CTL_ELEM_ACCESS_TLV_READ),
.name = "PCM Playback Volume",
.info = wm_pcm_vol_info,
.get = wm_pcm_vol_get,
.put = wm_pcm_vol_put,
.tlv = { .p = db_scale_wm_pcm }
- },
+ },
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "Capture Switch",
@@ -1566,7 +1591,7 @@ static struct snd_kcontrol_new wm_controls[] __devinitdata = {
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ),
+ SNDRV_CTL_ELEM_ACCESS_TLV_READ),
.name = "Capture Volume",
.info = wm_adc_vol_info,
.get = wm_adc_vol_get,
@@ -1605,232 +1630,232 @@ static struct snd_kcontrol_new wm_controls[] __devinitdata = {
};
static struct snd_kcontrol_new ac97_controls[] __devinitdata = {
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "AC97 Playback Switch",
.info = aureon_ac97_mmute_info,
.get = aureon_ac97_mmute_get,
.put = aureon_ac97_mmute_put,
.private_value = AC97_MASTER
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ },
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ),
- .name = "AC97 Playback Volume",
- .info = aureon_ac97_vol_info,
- .get = aureon_ac97_vol_get,
- .put = aureon_ac97_vol_put,
- .private_value = AC97_MASTER|AUREON_AC97_STEREO,
+ SNDRV_CTL_ELEM_ACCESS_TLV_READ),
+ .name = "AC97 Playback Volume",
+ .info = aureon_ac97_vol_info,
+ .get = aureon_ac97_vol_get,
+ .put = aureon_ac97_vol_put,
+ .private_value = AC97_MASTER|AUREON_AC97_STEREO,
.tlv = { .p = db_scale_ac97_master }
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "CD Playback Switch",
- .info = aureon_ac97_mute_info,
- .get = aureon_ac97_mute_get,
- .put = aureon_ac97_mute_put,
- .private_value = AC97_CD
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ },
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "CD Playback Switch",
+ .info = aureon_ac97_mute_info,
+ .get = aureon_ac97_mute_get,
+ .put = aureon_ac97_mute_put,
+ .private_value = AC97_CD
+ },
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ),
- .name = "CD Playback Volume",
- .info = aureon_ac97_vol_info,
- .get = aureon_ac97_vol_get,
- .put = aureon_ac97_vol_put,
- .private_value = AC97_CD|AUREON_AC97_STEREO,
+ SNDRV_CTL_ELEM_ACCESS_TLV_READ),
+ .name = "CD Playback Volume",
+ .info = aureon_ac97_vol_info,
+ .get = aureon_ac97_vol_get,
+ .put = aureon_ac97_vol_put,
+ .private_value = AC97_CD|AUREON_AC97_STEREO,
.tlv = { .p = db_scale_ac97_gain }
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Aux Playback Switch",
- .info = aureon_ac97_mute_info,
- .get = aureon_ac97_mute_get,
- .put = aureon_ac97_mute_put,
- .private_value = AC97_AUX,
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ },
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "Aux Playback Switch",
+ .info = aureon_ac97_mute_info,
+ .get = aureon_ac97_mute_get,
+ .put = aureon_ac97_mute_put,
+ .private_value = AC97_AUX,
+ },
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ),
- .name = "Aux Playback Volume",
- .info = aureon_ac97_vol_info,
- .get = aureon_ac97_vol_get,
- .put = aureon_ac97_vol_put,
- .private_value = AC97_AUX|AUREON_AC97_STEREO,
+ SNDRV_CTL_ELEM_ACCESS_TLV_READ),
+ .name = "Aux Playback Volume",
+ .info = aureon_ac97_vol_info,
+ .get = aureon_ac97_vol_get,
+ .put = aureon_ac97_vol_put,
+ .private_value = AC97_AUX|AUREON_AC97_STEREO,
.tlv = { .p = db_scale_ac97_gain }
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Line Playback Switch",
- .info = aureon_ac97_mute_info,
- .get = aureon_ac97_mute_get,
- .put = aureon_ac97_mute_put,
- .private_value = AC97_LINE
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ },
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "Line Playback Switch",
+ .info = aureon_ac97_mute_info,
+ .get = aureon_ac97_mute_get,
+ .put = aureon_ac97_mute_put,
+ .private_value = AC97_LINE
+ },
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ),
- .name = "Line Playback Volume",
- .info = aureon_ac97_vol_info,
- .get = aureon_ac97_vol_get,
- .put = aureon_ac97_vol_put,
- .private_value = AC97_LINE|AUREON_AC97_STEREO,
+ SNDRV_CTL_ELEM_ACCESS_TLV_READ),
+ .name = "Line Playback Volume",
+ .info = aureon_ac97_vol_info,
+ .get = aureon_ac97_vol_get,
+ .put = aureon_ac97_vol_put,
+ .private_value = AC97_LINE|AUREON_AC97_STEREO,
.tlv = { .p = db_scale_ac97_gain }
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Mic Playback Switch",
- .info = aureon_ac97_mute_info,
- .get = aureon_ac97_mute_get,
- .put = aureon_ac97_mute_put,
- .private_value = AC97_MIC
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ },
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "Mic Playback Switch",
+ .info = aureon_ac97_mute_info,
+ .get = aureon_ac97_mute_get,
+ .put = aureon_ac97_mute_put,
+ .private_value = AC97_MIC
+ },
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ),
- .name = "Mic Playback Volume",
- .info = aureon_ac97_vol_info,
- .get = aureon_ac97_vol_get,
- .put = aureon_ac97_vol_put,
- .private_value = AC97_MIC,
+ SNDRV_CTL_ELEM_ACCESS_TLV_READ),
+ .name = "Mic Playback Volume",
+ .info = aureon_ac97_vol_info,
+ .get = aureon_ac97_vol_get,
+ .put = aureon_ac97_vol_put,
+ .private_value = AC97_MIC,
.tlv = { .p = db_scale_ac97_gain }
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Mic Boost (+20dB)",
- .info = aureon_ac97_micboost_info,
- .get = aureon_ac97_micboost_get,
- .put = aureon_ac97_micboost_put
- }
+ },
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "Mic Boost (+20dB)",
+ .info = aureon_ac97_micboost_info,
+ .get = aureon_ac97_micboost_get,
+ .put = aureon_ac97_micboost_put
+ }
};
static struct snd_kcontrol_new universe_ac97_controls[] __devinitdata = {
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "AC97 Playback Switch",
.info = aureon_ac97_mmute_info,
.get = aureon_ac97_mmute_get,
.put = aureon_ac97_mmute_put,
.private_value = AC97_MASTER
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ },
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ),
- .name = "AC97 Playback Volume",
- .info = aureon_ac97_vol_info,
- .get = aureon_ac97_vol_get,
- .put = aureon_ac97_vol_put,
- .private_value = AC97_MASTER|AUREON_AC97_STEREO,
+ SNDRV_CTL_ELEM_ACCESS_TLV_READ),
+ .name = "AC97 Playback Volume",
+ .info = aureon_ac97_vol_info,
+ .get = aureon_ac97_vol_get,
+ .put = aureon_ac97_vol_put,
+ .private_value = AC97_MASTER|AUREON_AC97_STEREO,
.tlv = { .p = db_scale_ac97_master }
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "CD Playback Switch",
- .info = aureon_ac97_mute_info,
- .get = aureon_ac97_mute_get,
- .put = aureon_ac97_mute_put,
- .private_value = AC97_AUX
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ },
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "CD Playback Switch",
+ .info = aureon_ac97_mute_info,
+ .get = aureon_ac97_mute_get,
+ .put = aureon_ac97_mute_put,
+ .private_value = AC97_AUX
+ },
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ),
- .name = "CD Playback Volume",
- .info = aureon_ac97_vol_info,
- .get = aureon_ac97_vol_get,
- .put = aureon_ac97_vol_put,
- .private_value = AC97_AUX|AUREON_AC97_STEREO,
+ SNDRV_CTL_ELEM_ACCESS_TLV_READ),
+ .name = "CD Playback Volume",
+ .info = aureon_ac97_vol_info,
+ .get = aureon_ac97_vol_get,
+ .put = aureon_ac97_vol_put,
+ .private_value = AC97_AUX|AUREON_AC97_STEREO,
.tlv = { .p = db_scale_ac97_gain }
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Phono Playback Switch",
- .info = aureon_ac97_mute_info,
- .get = aureon_ac97_mute_get,
- .put = aureon_ac97_mute_put,
- .private_value = AC97_CD
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ },
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "Phono Playback Switch",
+ .info = aureon_ac97_mute_info,
+ .get = aureon_ac97_mute_get,
+ .put = aureon_ac97_mute_put,
+ .private_value = AC97_CD
+ },
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ),
- .name = "Phono Playback Volume",
- .info = aureon_ac97_vol_info,
- .get = aureon_ac97_vol_get,
- .put = aureon_ac97_vol_put,
- .private_value = AC97_CD|AUREON_AC97_STEREO,
+ SNDRV_CTL_ELEM_ACCESS_TLV_READ),
+ .name = "Phono Playback Volume",
+ .info = aureon_ac97_vol_info,
+ .get = aureon_ac97_vol_get,
+ .put = aureon_ac97_vol_put,
+ .private_value = AC97_CD|AUREON_AC97_STEREO,
.tlv = { .p = db_scale_ac97_gain }
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Line Playback Switch",
- .info = aureon_ac97_mute_info,
- .get = aureon_ac97_mute_get,
- .put = aureon_ac97_mute_put,
- .private_value = AC97_LINE
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ },
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "Line Playback Switch",
+ .info = aureon_ac97_mute_info,
+ .get = aureon_ac97_mute_get,
+ .put = aureon_ac97_mute_put,
+ .private_value = AC97_LINE
+ },
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ),
- .name = "Line Playback Volume",
- .info = aureon_ac97_vol_info,
- .get = aureon_ac97_vol_get,
- .put = aureon_ac97_vol_put,
- .private_value = AC97_LINE|AUREON_AC97_STEREO,
+ SNDRV_CTL_ELEM_ACCESS_TLV_READ),
+ .name = "Line Playback Volume",
+ .info = aureon_ac97_vol_info,
+ .get = aureon_ac97_vol_get,
+ .put = aureon_ac97_vol_put,
+ .private_value = AC97_LINE|AUREON_AC97_STEREO,
.tlv = { .p = db_scale_ac97_gain }
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Mic Playback Switch",
- .info = aureon_ac97_mute_info,
- .get = aureon_ac97_mute_get,
- .put = aureon_ac97_mute_put,
- .private_value = AC97_MIC
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ },
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "Mic Playback Switch",
+ .info = aureon_ac97_mute_info,
+ .get = aureon_ac97_mute_get,
+ .put = aureon_ac97_mute_put,
+ .private_value = AC97_MIC
+ },
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ),
- .name = "Mic Playback Volume",
- .info = aureon_ac97_vol_info,
- .get = aureon_ac97_vol_get,
- .put = aureon_ac97_vol_put,
- .private_value = AC97_MIC,
+ SNDRV_CTL_ELEM_ACCESS_TLV_READ),
+ .name = "Mic Playback Volume",
+ .info = aureon_ac97_vol_info,
+ .get = aureon_ac97_vol_get,
+ .put = aureon_ac97_vol_put,
+ .private_value = AC97_MIC,
.tlv = { .p = db_scale_ac97_gain }
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Mic Boost (+20dB)",
- .info = aureon_ac97_micboost_info,
- .get = aureon_ac97_micboost_get,
- .put = aureon_ac97_micboost_put
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Aux Playback Switch",
- .info = aureon_ac97_mute_info,
- .get = aureon_ac97_mute_get,
- .put = aureon_ac97_mute_put,
- .private_value = AC97_VIDEO,
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ },
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "Mic Boost (+20dB)",
+ .info = aureon_ac97_micboost_info,
+ .get = aureon_ac97_micboost_get,
+ .put = aureon_ac97_micboost_put
+ },
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "Aux Playback Switch",
+ .info = aureon_ac97_mute_info,
+ .get = aureon_ac97_mute_get,
+ .put = aureon_ac97_mute_put,
+ .private_value = AC97_VIDEO,
+ },
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ),
- .name = "Aux Playback Volume",
- .info = aureon_ac97_vol_info,
- .get = aureon_ac97_vol_get,
- .put = aureon_ac97_vol_put,
- .private_value = AC97_VIDEO|AUREON_AC97_STEREO,
+ SNDRV_CTL_ELEM_ACCESS_TLV_READ),
+ .name = "Aux Playback Volume",
+ .info = aureon_ac97_vol_info,
+ .get = aureon_ac97_vol_get,
+ .put = aureon_ac97_vol_put,
+ .private_value = AC97_VIDEO|AUREON_AC97_STEREO,
.tlv = { .p = db_scale_ac97_gain }
- },
+ },
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "Aux Source",
@@ -1844,43 +1869,43 @@ static struct snd_kcontrol_new universe_ac97_controls[] __devinitdata = {
static struct snd_kcontrol_new cs8415_controls[] __devinitdata = {
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH),
+ .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, SWITCH),
.info = aureon_cs8415_mute_info,
.get = aureon_cs8415_mute_get,
.put = aureon_cs8415_mute_put
},
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,NONE) "Source",
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, NONE) "Source",
.info = aureon_cs8415_mux_info,
.get = aureon_cs8415_mux_get,
.put = aureon_cs8415_mux_put,
},
{
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("Q-subcode ",CAPTURE,DEFAULT),
+ .name = SNDRV_CTL_NAME_IEC958("Q-subcode ", CAPTURE, DEFAULT),
.access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
.info = aureon_cs8415_qsub_info,
.get = aureon_cs8415_qsub_get,
},
{
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,MASK),
+ .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, MASK),
.access = SNDRV_CTL_ELEM_ACCESS_READ,
.info = aureon_cs8415_spdif_info,
.get = aureon_cs8415_mask_get
},
{
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,DEFAULT),
+ .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, DEFAULT),
.access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
.info = aureon_cs8415_spdif_info,
.get = aureon_cs8415_spdif_get
},
{
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,NONE) "Rate",
- .access =SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
+ .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, NONE) "Rate",
+ .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
.info = aureon_cs8415_rate_info,
.get = aureon_cs8415_rate_get
}
@@ -1905,15 +1930,14 @@ static int __devinit aureon_add_controls(struct snd_ice1712 *ice)
if (err < 0)
return err;
}
-
+
if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON71_UNIVERSE) {
for (i = 0; i < ARRAY_SIZE(universe_ac97_controls); i++) {
err = snd_ctl_add(ice->card, snd_ctl_new1(&universe_ac97_controls[i], ice));
if (err < 0)
return err;
}
- }
- else if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT &&
+ } else if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT &&
ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71XT) {
for (i = 0; i < ARRAY_SIZE(ac97_controls); i++) {
err = snd_ctl_add(ice->card, snd_ctl_new1(&ac97_controls[i], ice));
@@ -1932,7 +1956,7 @@ static int __devinit aureon_add_controls(struct snd_ice1712 *ice)
else if ((id & 0x0F) != 0x01)
snd_printk(KERN_INFO "Detected unsupported CS8415 rev. (%c)\n", (char)((id & 0x0F) + 'A' - 1));
else {
- for (i = 0; i< ARRAY_SIZE(cs8415_controls); i++) {
+ for (i = 0; i < ARRAY_SIZE(cs8415_controls); i++) {
struct snd_kcontrol *kctl;
err = snd_ctl_add(ice->card, (kctl = snd_ctl_new1(&cs8415_controls[i], ice)));
if (err < 0)
@@ -1943,7 +1967,7 @@ static int __devinit aureon_add_controls(struct snd_ice1712 *ice)
}
snd_ice1712_restore_gpio_status(ice);
}
-
+
return 0;
}
@@ -2059,11 +2083,12 @@ static int __devinit aureon_init(struct snd_ice1712 *ice)
/* to remeber the register values of CS8415 */
ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
- if (! ice->akm)
+ if (!ice->akm)
return -ENOMEM;
ice->akm_codecs = 1;
-
- if ((err = aureon_ac97_init(ice)) != 0)
+
+ err = aureon_ac97_init(ice);
+ if (err != 0)
return err;
snd_ice1712_gpio_set_dir(ice, 0x5fffff); /* fix this for the time being */
@@ -2086,7 +2111,7 @@ static int __devinit aureon_init(struct snd_ice1712 *ice)
/* initialize WM8770 codec */
if (ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71 ||
ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71LT ||
- ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71XT)
+ ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71XT)
p = wm_inits_prodigy;
else
p = wm_inits_aureon;
@@ -2105,10 +2130,10 @@ static int __devinit aureon_init(struct snd_ice1712 *ice)
snd_ice1712_restore_gpio_status(ice);
- /* initialize PCA9554 pin directions & set default input*/
+ /* initialize PCA9554 pin directions & set default input */
aureon_pca9554_write(ice, PCA9554_DIR, 0x00);
aureon_pca9554_write(ice, PCA9554_OUT, 0x00); /* internal AUX */
-
+
spec->master[0] = WM_VOL_MUTE;
spec->master[1] = WM_VOL_MUTE;
for (i = 0; i < ice->num_total_dacs; i++) {
@@ -2158,6 +2183,24 @@ static unsigned char aureon71_eeprom[] __devinitdata = {
};
#define prodigy71_eeprom aureon71_eeprom
+static unsigned char aureon71_universe_eeprom[] __devinitdata = {
+ [ICE_EEP2_SYSCONF] = 0x2b, /* clock 512, mpu401, spdif-in/ADC,
+ * 4DACs
+ */
+ [ICE_EEP2_ACLINK] = 0x80, /* I2S */
+ [ICE_EEP2_I2S] = 0xfc, /* vol, 96k, 24bit, 192k */
+ [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */
+ [ICE_EEP2_GPIO_DIR] = 0xff,
+ [ICE_EEP2_GPIO_DIR1] = 0xff,
+ [ICE_EEP2_GPIO_DIR2] = 0x5f,
+ [ICE_EEP2_GPIO_MASK] = 0x00,
+ [ICE_EEP2_GPIO_MASK1] = 0x00,
+ [ICE_EEP2_GPIO_MASK2] = 0x00,
+ [ICE_EEP2_GPIO_STATE] = 0x00,
+ [ICE_EEP2_GPIO_STATE1] = 0x00,
+ [ICE_EEP2_GPIO_STATE2] = 0x00,
+};
+
static unsigned char prodigy71lt_eeprom[] __devinitdata = {
[ICE_EEP2_SYSCONF] = 0x4b, /* clock 384, spdif-in/ADC, 4DACs */
[ICE_EEP2_ACLINK] = 0x80, /* I2S */
@@ -2197,14 +2240,14 @@ struct snd_ice1712_card_info snd_vt1724_aureon_cards[] __devinitdata = {
.eeprom_data = aureon71_eeprom,
.driver = "Aureon71",
},
- {
- .subvendor = VT1724_SUBDEVICE_AUREON71_UNIVERSE,
- .name = "Terratec Aureon 7.1-Universe",
+ {
+ .subvendor = VT1724_SUBDEVICE_AUREON71_UNIVERSE,
+ .name = "Terratec Aureon 7.1-Universe",
.model = "universe",
- .chip_init = aureon_init,
- .build_controls = aureon_add_controls,
- .eeprom_size = sizeof(aureon71_eeprom),
- .eeprom_data = aureon71_eeprom,
+ .chip_init = aureon_init,
+ .build_controls = aureon_add_controls,
+ .eeprom_size = sizeof(aureon71_universe_eeprom),
+ .eeprom_data = aureon71_universe_eeprom,
.driver = "Aureon71Univ", /* keep in 15 letters */
},
{
diff --git a/sound/pci/ice1712/delta.c b/sound/pci/ice1712/delta.c
index 0ed96c178059..d216362626d0 100644
--- a/sound/pci/ice1712/delta.c
+++ b/sound/pci/ice1712/delta.c
@@ -400,7 +400,7 @@ static void delta_setup_spdif(struct snd_ice1712 *ice, int rate)
static int snd_ice1712_delta1010lt_wordclock_status_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
- char reg = 0x10; // cs8427 receiver error register
+ char reg = 0x10; /* CS8427 receiver error register */
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
if (snd_i2c_sendbytes(ice->cs8427, &reg, 1) != 1)
diff --git a/sound/pci/ice1712/delta.h b/sound/pci/ice1712/delta.h
index ea7116c304c0..f7f14df81f26 100644
--- a/sound/pci/ice1712/delta.h
+++ b/sound/pci/ice1712/delta.h
@@ -31,6 +31,7 @@
"{MidiMan M Audio,Delta DiO 2496},"\
"{MidiMan M Audio,Delta 66},"\
"{MidiMan M Audio,Delta 44},"\
+ "{MidiMan M Audio,Delta 410},"\
"{MidiMan M Audio,Audiophile 24/96},"\
"{Digigram,VX442},"\
"{Lionstracs,Mediastation},"
diff --git a/sound/pci/ice1712/envy24ht.h b/sound/pci/ice1712/envy24ht.h
index 43b9e3e858be..a0c5e009bb4a 100644
--- a/sound/pci/ice1712/envy24ht.h
+++ b/sound/pci/ice1712/envy24ht.h
@@ -93,9 +93,13 @@ enum {
#define VT1724_REG_MPU_TXFIFO 0x0a /*byte ro. number of bytes in TX fifo*/
#define VT1724_REG_MPU_RXFIFO 0x0b /*byte ro. number of bytes in RX fifo*/
-//are these 2 the wrong way around? they don't seem to be used yet anyway
-#define VT1724_REG_MPU_CTRL 0x0c /* byte */
-#define VT1724_REG_MPU_DATA 0x0d /* byte */
+#define VT1724_REG_MPU_DATA 0x0c /* byte */
+#define VT1724_REG_MPU_CTRL 0x0d /* byte */
+#define VT1724_MPU_UART 0x01
+#define VT1724_MPU_TX_EMPTY 0x02
+#define VT1724_MPU_TX_FULL 0x04
+#define VT1724_MPU_RX_EMPTY 0x08
+#define VT1724_MPU_RX_FULL 0x10
#define VT1724_REG_MPU_FIFO_WM 0x0e /*byte set the high/low watermarks for RX/TX fifos*/
#define VT1724_MPU_RX_FIFO 0x20 //1=rx fifo watermark 0=tx fifo watermark
diff --git a/sound/pci/ice1712/ews.c b/sound/pci/ice1712/ews.c
index 013fc4f04822..6fe35b812040 100644
--- a/sound/pci/ice1712/ews.c
+++ b/sound/pci/ice1712/ews.c
@@ -149,7 +149,8 @@ static int snd_ice1712_ews88mt_chip_select(struct snd_ice1712 *ice, int chip_mas
struct ews_spec *spec = ice->spec;
unsigned char data, ndata;
- snd_assert(chip_mask >= 0 && chip_mask <= 0x0f, return -EINVAL);
+ if (snd_BUG_ON(chip_mask < 0 || chip_mask > 0x0f))
+ return -EINVAL;
snd_i2c_lock(ice->i2c);
if (snd_i2c_readbytes(spec->i2cdevs[EWS_I2C_PCF2], &data, 1) != 1)
goto __error;
@@ -685,7 +686,8 @@ static int snd_ice1712_ews88mt_input_sense_get(struct snd_kcontrol *kcontrol, st
int channel = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
unsigned char data;
- snd_assert(channel >= 0 && channel <= 7, return 0);
+ if (snd_BUG_ON(channel < 0 || channel > 7))
+ return 0;
snd_i2c_lock(ice->i2c);
if (snd_i2c_readbytes(spec->i2cdevs[EWS_I2C_PCF1], &data, 1) != 1) {
snd_i2c_unlock(ice->i2c);
@@ -705,7 +707,8 @@ static int snd_ice1712_ews88mt_input_sense_put(struct snd_kcontrol *kcontrol, st
int channel = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
unsigned char data, ndata;
- snd_assert(channel >= 0 && channel <= 7, return 0);
+ if (snd_BUG_ON(channel < 0 || channel > 7))
+ return 0;
snd_i2c_lock(ice->i2c);
if (snd_i2c_readbytes(spec->i2cdevs[EWS_I2C_PCF1], &data, 1) != 1) {
snd_i2c_unlock(ice->i2c);
diff --git a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c
index 29d449d73c98..5b442383fcda 100644
--- a/sound/pci/ice1712/ice1712.c
+++ b/sound/pci/ice1712/ice1712.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
- */
+ */
/*
NOTES:
@@ -35,7 +35,7 @@
*
* 2002.11.26 James Stafford <jstafford@ampltd.com>
* Added support for VT1724 (Envy24HT)
- * I have left out support for 176.4 and 192 KHz for the moment.
+ * I have left out support for 176.4 and 192 KHz for the moment.
* I also haven't done anything with the internal S/PDIF transmitter or the MPU-401
*
* 2003.02.20 Taksahi Iwai <tiwai@suse.de>
@@ -47,7 +47,7 @@
*/
-#include <asm/io.h>
+#include <linux/io.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/init.h>
@@ -123,7 +123,7 @@ static unsigned int PRO_RATE_DEFAULT = 44100;
/*
* Basic I/O
*/
-
+
/* check whether the clock mode is spdif-in */
static inline int is_spdif_master(struct snd_ice1712 *ice)
{
@@ -135,13 +135,13 @@ static inline int is_pro_rate_locked(struct snd_ice1712 *ice)
return is_spdif_master(ice) || PRO_RATE_LOCKED;
}
-static inline void snd_ice1712_ds_write(struct snd_ice1712 * ice, u8 channel, u8 addr, u32 data)
+static inline void snd_ice1712_ds_write(struct snd_ice1712 *ice, u8 channel, u8 addr, u32 data)
{
outb((channel << 4) | addr, ICEDS(ice, INDEX));
outl(data, ICEDS(ice, DATA));
}
-static inline u32 snd_ice1712_ds_read(struct snd_ice1712 * ice, u8 channel, u8 addr)
+static inline u32 snd_ice1712_ds_read(struct snd_ice1712 *ice, u8 channel, u8 addr)
{
outb((channel << 4) | addr, ICEDS(ice, INDEX));
return inl(ICEDS(ice, DATA));
@@ -260,7 +260,7 @@ static unsigned short snd_ice1712_pro_ac97_read(struct snd_ac97 *ac97,
static int snd_ice1712_digmix_route_ac97_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
-
+
ucontrol->value.integer.value[0] = inb(ICEMT(ice, MONITOR_ROUTECTRL)) & ICE1712_ROUTE_AC97 ? 1 : 0;
return 0;
}
@@ -269,11 +269,12 @@ static int snd_ice1712_digmix_route_ac97_put(struct snd_kcontrol *kcontrol, stru
{
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
unsigned char val, nval;
-
+
spin_lock_irq(&ice->reg_lock);
val = inb(ICEMT(ice, MONITOR_ROUTECTRL));
nval = val & ~ICE1712_ROUTE_AC97;
- if (ucontrol->value.integer.value[0]) nval |= ICE1712_ROUTE_AC97;
+ if (ucontrol->value.integer.value[0])
+ nval |= ICE1712_ROUTE_AC97;
outb(nval, ICEMT(ice, MONITOR_ROUTECTRL));
spin_unlock_irq(&ice->reg_lock);
return val != nval;
@@ -329,7 +330,7 @@ static int snd_ice1712_cs8427_set_input_clock(struct snd_ice1712 *ice, int spdif
unsigned char reg[2] = { 0x80 | 4, 0 }; /* CS8427 auto increment | register number 4 + data */
unsigned char val, nval;
int res = 0;
-
+
snd_i2c_lock(ice->i2c);
if (snd_i2c_sendbytes(ice->cs8427, reg, 1) != 1) {
snd_i2c_unlock(ice->i2c);
@@ -381,9 +382,9 @@ int __devinit snd_ice1712_init_cs8427(struct snd_ice1712 *ice, int addr)
{
int err;
- if ((err = snd_cs8427_create(ice->i2c, addr,
- (ice->cs8427_timeout * HZ) / 1000,
- &ice->cs8427)) < 0) {
+ err = snd_cs8427_create(ice->i2c, addr,
+ (ice->cs8427_timeout * HZ) / 1000, &ice->cs8427);
+ if (err < 0) {
snd_printk(KERN_ERR "CS8427 initialization failed\n");
return err;
}
@@ -395,9 +396,9 @@ int __devinit snd_ice1712_init_cs8427(struct snd_ice1712 *ice, int addr)
static void snd_ice1712_set_input_clock_source(struct snd_ice1712 *ice, int spdif_is_master)
{
- /* change CS8427 clock source too */
- if (ice->cs8427)
- snd_ice1712_cs8427_set_input_clock(ice, spdif_is_master);
+ /* change CS8427 clock source too */
+ if (ice->cs8427)
+ snd_ice1712_cs8427_set_input_clock(ice, spdif_is_master);
/* notify ak4524 chip as well */
if (spdif_is_master) {
unsigned int i;
@@ -457,11 +458,12 @@ static irqreturn_t snd_ice1712_interrupt(int irq, void *dev_id)
u16 pbkstatus;
struct snd_pcm_substream *substream;
pbkstatus = inw(ICEDS(ice, INTSTAT));
- //printk("pbkstatus = 0x%x\n", pbkstatus);
+ /* printk("pbkstatus = 0x%x\n", pbkstatus); */
for (idx = 0; idx < 6; idx++) {
if ((pbkstatus & (3 << (idx * 2))) == 0)
continue;
- if ((substream = ice->playback_con_substream_ds[idx]) != NULL)
+ substream = ice->playback_con_substream_ds[idx];
+ if (substream != NULL)
snd_pcm_period_elapsed(substream);
outw(3 << (idx * 2), ICEDS(ice, INTSTAT));
}
@@ -507,7 +509,7 @@ static int snd_ice1712_playback_trigger(struct snd_pcm_substream *substream,
struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
int result = 0;
u32 tmp;
-
+
spin_lock(&ice->reg_lock);
tmp = snd_ice1712_read(ice, ICE1712_IREG_PBK_CTRL);
if (cmd == SNDRV_PCM_TRIGGER_START) {
@@ -532,7 +534,7 @@ static int snd_ice1712_playback_ds_trigger(struct snd_pcm_substream *substream,
struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
int result = 0;
u32 tmp;
-
+
spin_lock(&ice->reg_lock);
tmp = snd_ice1712_ds_read(ice, substream->number * 2, ICE1712_DSC_CONTROL);
if (cmd == SNDRV_PCM_TRIGGER_START) {
@@ -557,7 +559,7 @@ static int snd_ice1712_capture_trigger(struct snd_pcm_substream *substream,
struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
int result = 0;
u8 tmp;
-
+
spin_lock(&ice->reg_lock);
tmp = snd_ice1712_read(ice, ICE1712_IREG_CAP_CTRL);
if (cmd == SNDRV_PCM_TRIGGER_START) {
@@ -711,8 +713,7 @@ static snd_pcm_uframes_t snd_ice1712_capture_pointer(struct snd_pcm_substream *s
return bytes_to_frames(substream->runtime, ptr);
}
-static const struct snd_pcm_hardware snd_ice1712_playback =
-{
+static const struct snd_pcm_hardware snd_ice1712_playback = {
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
SNDRV_PCM_INFO_MMAP_VALID |
@@ -731,8 +732,7 @@ static const struct snd_pcm_hardware snd_ice1712_playback =
.fifo_size = 0,
};
-static const struct snd_pcm_hardware snd_ice1712_playback_ds =
-{
+static const struct snd_pcm_hardware snd_ice1712_playback_ds = {
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
SNDRV_PCM_INFO_MMAP_VALID |
@@ -751,8 +751,7 @@ static const struct snd_pcm_hardware snd_ice1712_playback_ds =
.fifo_size = 0,
};
-static const struct snd_pcm_hardware snd_ice1712_capture =
-{
+static const struct snd_pcm_hardware snd_ice1712_capture = {
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
SNDRV_PCM_INFO_MMAP_VALID),
@@ -788,7 +787,7 @@ static int snd_ice1712_playback_ds_open(struct snd_pcm_substream *substream)
ice->playback_con_substream_ds[substream->number] = substream;
runtime->hw = snd_ice1712_playback_ds;
- spin_lock_irq(&ice->reg_lock);
+ spin_lock_irq(&ice->reg_lock);
tmp = inw(ICEDS(ice, INTMASK)) & ~(1 << (substream->number * 2));
outw(tmp, ICEDS(ice, INTMASK));
spin_unlock_irq(&ice->reg_lock);
@@ -821,7 +820,7 @@ static int snd_ice1712_playback_ds_close(struct snd_pcm_substream *substream)
struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
u32 tmp;
- spin_lock_irq(&ice->reg_lock);
+ spin_lock_irq(&ice->reg_lock);
tmp = inw(ICEDS(ice, INTMASK)) | (3 << (substream->number * 2));
outw(tmp, ICEDS(ice, INTMASK));
spin_unlock_irq(&ice->reg_lock);
@@ -870,7 +869,7 @@ static struct snd_pcm_ops snd_ice1712_capture_ops = {
.pointer = snd_ice1712_capture_pointer,
};
-static int __devinit snd_ice1712_pcm(struct snd_ice1712 * ice, int device, struct snd_pcm ** rpcm)
+static int __devinit snd_ice1712_pcm(struct snd_ice1712 *ice, int device, struct snd_pcm **rpcm)
{
struct snd_pcm *pcm;
int err;
@@ -900,7 +899,7 @@ static int __devinit snd_ice1712_pcm(struct snd_ice1712 * ice, int device, struc
return 0;
}
-static int __devinit snd_ice1712_pcm_ds(struct snd_ice1712 * ice, int device, struct snd_pcm ** rpcm)
+static int __devinit snd_ice1712_pcm_ds(struct snd_ice1712 *ice, int device, struct snd_pcm **rpcm)
{
struct snd_pcm *pcm;
int err;
@@ -1029,14 +1028,14 @@ static void snd_ice1712_set_pro_rate(struct snd_ice1712 *ice, unsigned int rate,
if (inb(ICEMT(ice, PLAYBACK_CONTROL)) & (ICE1712_CAPTURE_START_SHADOW|
ICE1712_PLAYBACK_PAUSE|
ICE1712_PLAYBACK_START)) {
- __out:
+__out:
spin_unlock_irqrestore(&ice->reg_lock, flags);
return;
}
if (!force && is_pro_rate_locked(ice))
goto __out;
- old = inb(ICEMT(ice, RATE));
+ old = inb(ICEMT(ice, RATE));
if (!force && old == val)
goto __out;
outb(val, ICEMT(ice, RATE));
@@ -1123,8 +1122,7 @@ static snd_pcm_uframes_t snd_ice1712_capture_pro_pointer(struct snd_pcm_substrea
return bytes_to_frames(substream->runtime, ptr);
}
-static const struct snd_pcm_hardware snd_ice1712_playback_pro =
-{
+static const struct snd_pcm_hardware snd_ice1712_playback_pro = {
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
SNDRV_PCM_INFO_MMAP_VALID |
@@ -1143,8 +1141,7 @@ static const struct snd_pcm_hardware snd_ice1712_playback_pro =
.fifo_size = 0,
};
-static const struct snd_pcm_hardware snd_ice1712_capture_pro =
-{
+static const struct snd_pcm_hardware snd_ice1712_capture_pro = {
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
SNDRV_PCM_INFO_MMAP_VALID |
@@ -1238,7 +1235,7 @@ static struct snd_pcm_ops snd_ice1712_capture_pro_ops = {
.pointer = snd_ice1712_capture_pro_pointer,
};
-static int __devinit snd_ice1712_pcm_profi(struct snd_ice1712 * ice, int device, struct snd_pcm ** rpcm)
+static int __devinit snd_ice1712_pcm_profi(struct snd_ice1712 *ice, int device, struct snd_pcm **rpcm)
{
struct snd_pcm *pcm;
int err;
@@ -1262,7 +1259,7 @@ static int __devinit snd_ice1712_pcm_profi(struct snd_ice1712 * ice, int device,
ice->pcm_pro = pcm;
if (rpcm)
*rpcm = pcm;
-
+
if (ice->cs8427) {
/* assign channels to iec958 */
err = snd_cs8427_iec958_build(ice->cs8427,
@@ -1272,7 +1269,8 @@ static int __devinit snd_ice1712_pcm_profi(struct snd_ice1712 * ice, int device,
return err;
}
- if ((err = snd_ice1712_build_pro_mixer(ice)) < 0)
+ err = snd_ice1712_build_pro_mixer(ice);
+ if (err < 0)
return err;
return 0;
}
@@ -1299,7 +1297,7 @@ static int snd_ice1712_pro_mixer_switch_get(struct snd_kcontrol *kcontrol, struc
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
int priv_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) +
kcontrol->private_value;
-
+
spin_lock_irq(&ice->reg_lock);
ucontrol->value.integer.value[0] =
!((ice->pro_volumes[priv_idx] >> 15) & 1);
@@ -1341,7 +1339,7 @@ static int snd_ice1712_pro_mixer_volume_get(struct snd_kcontrol *kcontrol, struc
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
int priv_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) +
kcontrol->private_value;
-
+
spin_lock_irq(&ice->reg_lock);
ucontrol->value.integer.value[0] =
(ice->pro_volumes[priv_idx] >> 0) & 127;
@@ -1406,7 +1404,7 @@ static struct snd_kcontrol_new snd_ice1712_multi_capture_analog_switch __devinit
static struct snd_kcontrol_new snd_ice1712_multi_capture_spdif_switch __devinitdata = {
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = SNDRV_CTL_NAME_IEC958("Multi ",CAPTURE,SWITCH),
+ .name = SNDRV_CTL_NAME_IEC958("Multi ", CAPTURE, SWITCH),
.info = snd_ice1712_pro_mixer_switch_info,
.get = snd_ice1712_pro_mixer_switch_get,
.put = snd_ice1712_pro_mixer_switch_put,
@@ -1428,7 +1426,7 @@ static struct snd_kcontrol_new snd_ice1712_multi_capture_analog_volume __devinit
static struct snd_kcontrol_new snd_ice1712_multi_capture_spdif_volume __devinitdata = {
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = SNDRV_CTL_NAME_IEC958("Multi ",CAPTURE,VOLUME),
+ .name = SNDRV_CTL_NAME_IEC958("Multi ", CAPTURE, VOLUME),
.info = snd_ice1712_pro_mixer_volume_info,
.get = snd_ice1712_pro_mixer_volume_get,
.put = snd_ice1712_pro_mixer_volume_put,
@@ -1448,7 +1446,7 @@ static int __devinit snd_ice1712_build_pro_mixer(struct snd_ice1712 *ice)
if (err < 0)
return err;
}
-
+
if (ice->num_total_adcs > 0) {
struct snd_kcontrol_new tmp = snd_ice1712_multi_capture_analog_switch;
tmp.count = ice->num_total_adcs;
@@ -1495,7 +1493,7 @@ static void snd_ice1712_mixer_free_ac97(struct snd_ac97 *ac97)
ice->ac97 = NULL;
}
-static int __devinit snd_ice1712_ac97_mixer(struct snd_ice1712 * ice)
+static int __devinit snd_ice1712_ac97_mixer(struct snd_ice1712 *ice)
{
int err, bus_num = 0;
struct snd_ac97_template ac97;
@@ -1510,27 +1508,32 @@ static int __devinit snd_ice1712_ac97_mixer(struct snd_ice1712 * ice)
};
if (ice_has_con_ac97(ice)) {
- if ((err = snd_ac97_bus(ice->card, bus_num++, &con_ops, NULL, &pbus)) < 0)
+ err = snd_ac97_bus(ice->card, bus_num++, &con_ops, NULL, &pbus);
+ if (err < 0)
return err;
memset(&ac97, 0, sizeof(ac97));
ac97.private_data = ice;
ac97.private_free = snd_ice1712_mixer_free_ac97;
- if ((err = snd_ac97_mixer(pbus, &ac97, &ice->ac97)) < 0)
+ err = snd_ac97_mixer(pbus, &ac97, &ice->ac97);
+ if (err < 0)
printk(KERN_WARNING "ice1712: cannot initialize ac97 for consumer, skipped\n");
else {
- if ((err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_mixer_digmix_route_ac97, ice))) < 0)
+ err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_mixer_digmix_route_ac97, ice));
+ if (err < 0)
return err;
return 0;
}
}
- if (! (ice->eeprom.data[ICE_EEP1_ACLINK] & ICE1712_CFG_PRO_I2S)) {
- if ((err = snd_ac97_bus(ice->card, bus_num, &pro_ops, NULL, &pbus)) < 0)
+ if (!(ice->eeprom.data[ICE_EEP1_ACLINK] & ICE1712_CFG_PRO_I2S)) {
+ err = snd_ac97_bus(ice->card, bus_num, &pro_ops, NULL, &pbus);
+ if (err < 0)
return err;
memset(&ac97, 0, sizeof(ac97));
ac97.private_data = ice;
ac97.private_free = snd_ice1712_mixer_free_ac97;
- if ((err = snd_ac97_mixer(pbus, &ac97, &ice->ac97)) < 0)
+ err = snd_ac97_mixer(pbus, &ac97, &ice->ac97);
+ if (err < 0)
printk(KERN_WARNING "ice1712: cannot initialize pro ac97, skipped\n");
else
return 0;
@@ -1549,7 +1552,7 @@ static inline unsigned int eeprom_double(struct snd_ice1712 *ice, int idx)
return (unsigned int)ice->eeprom.data[idx] | ((unsigned int)ice->eeprom.data[idx + 1] << 8);
}
-static void snd_ice1712_proc_read(struct snd_info_entry *entry,
+static void snd_ice1712_proc_read(struct snd_info_entry *entry,
struct snd_info_buffer *buffer)
{
struct snd_ice1712 *ice = entry->private_data;
@@ -1585,15 +1588,15 @@ static void snd_ice1712_proc_read(struct snd_info_entry *entry,
snd_iprintf(buffer, " SPDOUT : 0x%04x\n", (unsigned)inw(ICEMT(ice, ROUTE_SPDOUT)));
snd_iprintf(buffer, " RATE : 0x%02x\n", (unsigned)inb(ICEMT(ice, RATE)));
snd_iprintf(buffer, " GPIO_DATA : 0x%02x\n", (unsigned)snd_ice1712_get_gpio_data(ice));
- snd_iprintf(buffer, " GPIO_WRITE_MASK : 0x%02x\n", (unsigned)snd_ice1712_read(ice, ICE1712_IREG_GPIO_WRITE_MASK));
+ snd_iprintf(buffer, " GPIO_WRITE_MASK : 0x%02x\n", (unsigned)snd_ice1712_read(ice, ICE1712_IREG_GPIO_WRITE_MASK));
snd_iprintf(buffer, " GPIO_DIRECTION : 0x%02x\n", (unsigned)snd_ice1712_read(ice, ICE1712_IREG_GPIO_DIRECTION));
}
-static void __devinit snd_ice1712_proc_init(struct snd_ice1712 * ice)
+static void __devinit snd_ice1712_proc_init(struct snd_ice1712 *ice)
{
struct snd_info_entry *entry;
- if (! snd_card_proc_new(ice->card, "ice1712", &entry))
+ if (!snd_card_proc_new(ice->card, "ice1712", &entry))
snd_info_set_text_ops(entry, ice, snd_ice1712_proc_read);
}
@@ -1613,7 +1616,7 @@ static int snd_ice1712_eeprom_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
-
+
memcpy(ucontrol->value.bytes.data, &ice->eeprom, sizeof(ice->eeprom));
return 0;
}
@@ -1641,7 +1644,7 @@ static int snd_ice1712_spdif_default_get(struct snd_kcontrol *kcontrol,
{
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
if (ice->spdif.ops.default_get)
- ice->spdif.ops.default_get(ice, ucontrol);
+ ice->spdif.ops.default_get(ice, ucontrol);
return 0;
}
@@ -1657,7 +1660,7 @@ static int snd_ice1712_spdif_default_put(struct snd_kcontrol *kcontrol,
static struct snd_kcontrol_new snd_ice1712_spdif_default __devinitdata =
{
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
+ .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT),
.info = snd_ice1712_spdif_info,
.get = snd_ice1712_spdif_default_get,
.put = snd_ice1712_spdif_default_put
@@ -1709,7 +1712,7 @@ static struct snd_kcontrol_new snd_ice1712_spdif_maskc __devinitdata =
{
.access = SNDRV_CTL_ELEM_ACCESS_READ,
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK),
+ .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, CON_MASK),
.info = snd_ice1712_spdif_info,
.get = snd_ice1712_spdif_maskc_get,
};
@@ -1718,7 +1721,7 @@ static struct snd_kcontrol_new snd_ice1712_spdif_maskp __devinitdata =
{
.access = SNDRV_CTL_ELEM_ACCESS_READ,
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PRO_MASK),
+ .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, PRO_MASK),
.info = snd_ice1712_spdif_info,
.get = snd_ice1712_spdif_maskp_get,
};
@@ -1746,7 +1749,7 @@ static struct snd_kcontrol_new snd_ice1712_spdif_stream __devinitdata =
.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
SNDRV_CTL_ELEM_ACCESS_INACTIVE),
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PCM_STREAM),
+ .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, PCM_STREAM),
.info = snd_ice1712_spdif_info,
.get = snd_ice1712_spdif_stream_get,
.put = snd_ice1712_spdif_stream_put
@@ -1758,7 +1761,7 @@ int snd_ice1712_gpio_get(struct snd_kcontrol *kcontrol,
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
unsigned char mask = kcontrol->private_value & 0xff;
int invert = (kcontrol->private_value & (1<<24)) ? 1 : 0;
-
+
snd_ice1712_save_gpio_status(ice);
ucontrol->value.integer.value[0] =
(snd_ice1712_gpio_read(ice) & mask ? 1 : 0) ^ invert;
@@ -1825,7 +1828,7 @@ static int snd_ice1712_pro_internal_clock_get(struct snd_kcontrol *kcontrol,
9, 6, 3, 1, 7, 4, 0, 12, 8, 5, 2, 11, 255, 255, 255, 10
};
unsigned char val;
-
+
spin_lock_irq(&ice->reg_lock);
if (is_spdif_master(ice)) {
ucontrol->value.enumerated.item[0] = 13;
@@ -1867,7 +1870,7 @@ static int snd_ice1712_pro_internal_clock_put(struct snd_kcontrol *kcontrol,
if ((oval & ICE1712_SPDIF_MASTER) !=
(inb(ICEMT(ice, RATE)) & ICE1712_SPDIF_MASTER))
- snd_ice1712_set_input_clock_source(ice, is_spdif_master(ice));
+ snd_ice1712_set_input_clock_source(ice, is_spdif_master(ice));
return change;
}
@@ -1897,7 +1900,7 @@ static int snd_ice1712_pro_internal_clock_default_info(struct snd_kcontrol *kcon
"64000", /* 10: 15 */
"88200", /* 11: 11 */
"96000", /* 12: 7 */
- // "IEC958 Input", /* 13: -- */
+ /* "IEC958 Input", 13: -- */
};
uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
uinfo->count = 1;
@@ -2026,7 +2029,7 @@ static int snd_ice1712_pro_route_info(struct snd_kcontrol *kcontrol,
"IEC958 In L", "IEC958 In R", /* 9-10 */
"Digital Mixer", /* 11 - optional */
};
-
+
uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
uinfo->count = 1;
uinfo->value.enumerated.items =
@@ -2070,7 +2073,7 @@ static int snd_ice1712_pro_route_analog_put(struct snd_kcontrol *kcontrol,
int change, shift;
int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
unsigned int val, old_val, nval;
-
+
/* update PSDOUT */
if (ucontrol->value.enumerated.item[0] >= 11)
nval = idx < 2 ? 1 : 0; /* dig mixer (or pcm) */
@@ -2140,7 +2143,7 @@ static int snd_ice1712_pro_route_spdif_put(struct snd_kcontrol *kcontrol,
int change, shift;
int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
unsigned int val, old_val, nval;
-
+
/* update SPDOUT */
spin_lock_irq(&ice->reg_lock);
val = old_val = inw(ICEMT(ice, ROUTE_SPDOUT));
@@ -2182,7 +2185,7 @@ static struct snd_kcontrol_new snd_ice1712_mixer_pro_analog_route __devinitdata
static struct snd_kcontrol_new snd_ice1712_mixer_pro_spdif_route __devinitdata = {
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Route",
+ .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, NONE) "Route",
.info = snd_ice1712_pro_route_info,
.get = snd_ice1712_pro_route_spdif_get,
.put = snd_ice1712_pro_route_spdif_put,
@@ -2204,7 +2207,7 @@ static int snd_ice1712_pro_volume_rate_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
-
+
ucontrol->value.integer.value[0] = inb(ICEMT(ice, MONITOR_RATE));
return 0;
}
@@ -2245,7 +2248,7 @@ static int snd_ice1712_pro_peak_get(struct snd_kcontrol *kcontrol,
{
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
int idx;
-
+
spin_lock_irq(&ice->reg_lock);
for (idx = 0; idx < 22; idx++) {
outb(idx, ICEMT(ice, MONITOR_PEAKINDEX));
@@ -2296,12 +2299,12 @@ static int __devinit snd_ice1712_read_eeprom(struct snd_ice1712 *ice,
unsigned int i, size;
struct snd_ice1712_card_info * const *tbl, *c;
- if (! modelname || ! *modelname) {
+ if (!modelname || !*modelname) {
ice->eeprom.subvendor = 0;
if ((inb(ICEREG(ice, I2C_CTRL)) & ICE1712_I2C_EEPROM) != 0)
ice->eeprom.subvendor = (snd_ice1712_read_i2c(ice, dev, 0x00) << 0) |
- (snd_ice1712_read_i2c(ice, dev, 0x01) << 8) |
- (snd_ice1712_read_i2c(ice, dev, 0x02) << 16) |
+ (snd_ice1712_read_i2c(ice, dev, 0x01) << 8) |
+ (snd_ice1712_read_i2c(ice, dev, 0x02) << 16) |
(snd_ice1712_read_i2c(ice, dev, 0x03) << 24);
if (ice->eeprom.subvendor == 0 ||
ice->eeprom.subvendor == (unsigned int)-1) {
@@ -2318,12 +2321,12 @@ static int __devinit snd_ice1712_read_eeprom(struct snd_ice1712 *ice,
}
for (tbl = card_tables; *tbl; tbl++) {
for (c = *tbl; c->subvendor; c++) {
- if (modelname && c->model && ! strcmp(modelname, c->model)) {
+ if (modelname && c->model && !strcmp(modelname, c->model)) {
printk(KERN_INFO "ice1712: Using board model %s\n", c->name);
ice->eeprom.subvendor = c->subvendor;
} else if (c->subvendor != ice->eeprom.subvendor)
continue;
- if (! c->eeprom_size || ! c->eeprom_data)
+ if (!c->eeprom_size || !c->eeprom_data)
goto found;
/* if the EEPROM is given by the driver, use it */
snd_printdd("using the defined eeprom..\n");
@@ -2416,7 +2419,8 @@ int __devinit snd_ice1712_spdif_build_controls(struct snd_ice1712 *ice)
int err;
struct snd_kcontrol *kctl;
- snd_assert(ice->pcm_pro != NULL, return -EIO);
+ if (snd_BUG_ON(!ice->pcm_pro))
+ return -EIO;
err = snd_ctl_add(ice->card, kctl = snd_ctl_new1(&snd_ice1712_spdif_default, ice));
if (err < 0)
return err;
@@ -2483,13 +2487,13 @@ static int __devinit snd_ice1712_build_controls(struct snd_ice1712 *ice)
static int snd_ice1712_free(struct snd_ice1712 *ice)
{
- if (! ice->port)
+ if (!ice->port)
goto __hw_end;
/* mask all interrupts */
outb(0xc0, ICEMT(ice, IRQ));
outb(0xff, ICEREG(ice, IRQMASK));
/* --- */
- __hw_end:
+__hw_end:
if (ice->irq >= 0)
free_irq(ice->irq, ice);
@@ -2514,7 +2518,7 @@ static int __devinit snd_ice1712_create(struct snd_card *card,
int omni,
int cs8427_timeout,
int dxr_enable,
- struct snd_ice1712 ** r_ice1712)
+ struct snd_ice1712 **r_ice1712)
{
struct snd_ice1712 *ice;
int err;
@@ -2524,8 +2528,9 @@ static int __devinit snd_ice1712_create(struct snd_card *card,
*r_ice1712 = NULL;
- /* enable PCI device */
- if ((err = pci_enable_device(pci)) < 0)
+ /* enable PCI device */
+ err = pci_enable_device(pci);
+ if (err < 0)
return err;
/* check, if we can restrict PCI DMA transfers to 28 bits */
if (pci_set_dma_mask(pci, DMA_28BIT_MASK) < 0 ||
@@ -2569,7 +2574,8 @@ static int __devinit snd_ice1712_create(struct snd_card *card,
snd_ice1712_proc_init(ice);
synchronize_irq(pci->irq);
- if ((err = pci_request_regions(pci, "ICE1712")) < 0) {
+ err = pci_request_regions(pci, "ICE1712");
+ if (err < 0) {
kfree(ice);
pci_disable_device(pci);
return err;
@@ -2585,7 +2591,7 @@ static int __devinit snd_ice1712_create(struct snd_card *card,
snd_ice1712_free(ice);
return -EIO;
}
-
+
ice->irq = pci->irq;
if (snd_ice1712_read_eeprom(ice, modelname) < 0) {
@@ -2605,9 +2611,10 @@ static int __devinit snd_ice1712_create(struct snd_card *card,
ICEREG(ice, IRQMASK));
outb(0x00, ICEMT(ice, IRQ));
- if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, ice, &ops)) < 0) {
+ err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, ice, &ops);
+ if (err < 0) {
snd_ice1712_free(ice);
- return err;
+ return err;
}
snd_card_set_dev(card, &pci->dev);
@@ -2647,10 +2654,10 @@ static int __devinit snd_ice1712_probe(struct pci_dev *pci,
strcpy(card->driver, "ICE1712");
strcpy(card->shortname, "ICEnsemble ICE1712");
-
- if ((err = snd_ice1712_create(card, pci, model[dev], omni[dev],
- cs8427_timeout[dev], dxr_enable[dev],
- &ice)) < 0) {
+
+ err = snd_ice1712_create(card, pci, model[dev], omni[dev],
+ cs8427_timeout[dev], dxr_enable[dev], &ice);
+ if (err < 0) {
snd_card_free(card);
return err;
}
@@ -2662,7 +2669,8 @@ static int __devinit snd_ice1712_probe(struct pci_dev *pci,
if (c->driver) /* specific driver? */
strcpy(card->driver, c->driver);
if (c->chip_init) {
- if ((err = c->chip_init(ice)) < 0) {
+ err = c->chip_init(ice);
+ if (err < 0) {
snd_card_free(card);
return err;
}
@@ -2674,47 +2682,52 @@ static int __devinit snd_ice1712_probe(struct pci_dev *pci,
c = &no_matched;
__found:
- if ((err = snd_ice1712_pcm_profi(ice, pcm_dev++, NULL)) < 0) {
+ err = snd_ice1712_pcm_profi(ice, pcm_dev++, NULL);
+ if (err < 0) {
snd_card_free(card);
return err;
}
-
+
if (ice_has_con_ac97(ice))
- if ((err = snd_ice1712_pcm(ice, pcm_dev++, NULL)) < 0) {
+ err = snd_ice1712_pcm(ice, pcm_dev++, NULL);
+ if (err < 0) {
snd_card_free(card);
return err;
}
- if ((err = snd_ice1712_ac97_mixer(ice)) < 0) {
+ err = snd_ice1712_ac97_mixer(ice);
+ if (err < 0) {
snd_card_free(card);
return err;
}
- if ((err = snd_ice1712_build_controls(ice)) < 0) {
+ err = snd_ice1712_build_controls(ice);
+ if (err < 0) {
snd_card_free(card);
return err;
}
if (c->build_controls) {
- if ((err = c->build_controls(ice)) < 0) {
+ err = c->build_controls(ice);
+ if (err < 0) {
snd_card_free(card);
return err;
}
}
if (ice_has_con_ac97(ice))
- if ((err = snd_ice1712_pcm_ds(ice, pcm_dev++, NULL)) < 0) {
+ err = snd_ice1712_pcm_ds(ice, pcm_dev++, NULL);
+ if (err < 0) {
snd_card_free(card);
return err;
}
- if (! c->no_mpu401) {
- if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_ICE1712,
- ICEREG(ice, MPU1_CTRL),
- (c->mpu401_1_info_flags |
- MPU401_INFO_INTEGRATED),
- ice->irq, 0,
- &ice->rmidi[0])) < 0) {
+ if (!c->no_mpu401) {
+ err = snd_mpu401_uart_new(card, 0, MPU401_HW_ICE1712,
+ ICEREG(ice, MPU1_CTRL),
+ (c->mpu401_1_info_flags | MPU401_INFO_INTEGRATED),
+ ice->irq, 0, &ice->rmidi[0]);
+ if (err < 0) {
snd_card_free(card);
return err;
}
@@ -2726,12 +2739,12 @@ static int __devinit snd_ice1712_probe(struct pci_dev *pci,
if (ice->eeprom.data[ICE_EEP1_CODEC] & ICE1712_CFG_2xMPU401) {
/* 2nd port used */
- if ((err = snd_mpu401_uart_new(card, 1, MPU401_HW_ICE1712,
- ICEREG(ice, MPU2_CTRL),
- (c->mpu401_2_info_flags |
- MPU401_INFO_INTEGRATED),
- ice->irq, 0,
- &ice->rmidi[1])) < 0) {
+ err = snd_mpu401_uart_new(card, 1, MPU401_HW_ICE1712,
+ ICEREG(ice, MPU2_CTRL),
+ (c->mpu401_2_info_flags | MPU401_INFO_INTEGRATED),
+ ice->irq, 0, &ice->rmidi[1]);
+
+ if (err < 0) {
snd_card_free(card);
return err;
}
@@ -2749,7 +2762,8 @@ static int __devinit snd_ice1712_probe(struct pci_dev *pci,
sprintf(card->longname, "%s at 0x%lx, irq %i",
card->shortname, ice->port, ice->irq);
- 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/ice1712/ice1712.h b/sound/pci/ice1712/ice1712.h
index 3208901c740e..fdae6deba16b 100644
--- a/sound/pci/ice1712/ice1712.h
+++ b/sound/pci/ice1712/ice1712.h
@@ -20,7 +20,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
- */
+ */
#include <sound/control.h>
#include <sound/ac97_codec.h>
@@ -112,7 +112,7 @@
*/
#define ICEDS(ice, x) ((ice)->dmapath_port + ICE1712_DS_##x)
-
+
#define ICE1712_DS_INTMASK 0x00 /* word - interrupt mask */
#define ICE1712_DS_INTSTAT 0x02 /* word - interrupt status */
#define ICE1712_DS_DATA 0x04 /* dword - channel data */
@@ -121,7 +121,7 @@
/*
* Consumer section channel registers
*/
-
+
#define ICE1712_DSC_ADDR0 0x00 /* dword - base address 0 */
#define ICE1712_DSC_COUNT0 0x01 /* word - count 0 */
#define ICE1712_DSC_ADDR1 0x02 /* dword - base address 1 */
@@ -138,7 +138,7 @@
#define ICE1712_DSC_RATE 0x05 /* dword - rate */
#define ICE1712_DSC_VOLUME 0x06 /* word - volume control */
-/*
+/*
* Professional multi-track direct control registers
*/
@@ -214,7 +214,7 @@
/*
- *
+ *
*/
struct snd_ice1712;
@@ -253,12 +253,12 @@ enum {
ICE_EEP1_ADC_ID2,
ICE_EEP1_ADC_ID3
};
-
+
#define ice_has_con_ac97(ice) (!((ice)->eeprom.data[ICE_EEP1_CODEC] & ICE1712_CFG_NO_CON_AC97))
struct snd_ak4xxx_private {
- unsigned int cif: 1; /* CIF mode */
+ unsigned int cif:1; /* CIF mode */
unsigned char caddr; /* C0 and C1 bits */
unsigned int data_mask; /* DATA gpio bit */
unsigned int clk_mask; /* CLK gpio bit */
@@ -306,11 +306,11 @@ struct snd_ice1712 {
struct snd_pcm *pcm;
struct snd_pcm *pcm_ds;
struct snd_pcm *pcm_pro;
- struct snd_pcm_substream *playback_con_substream;
- struct snd_pcm_substream *playback_con_substream_ds[6];
- struct snd_pcm_substream *capture_con_substream;
- struct snd_pcm_substream *playback_pro_substream;
- struct snd_pcm_substream *capture_pro_substream;
+ struct snd_pcm_substream *playback_con_substream;
+ struct snd_pcm_substream *playback_con_substream_ds[6];
+ struct snd_pcm_substream *capture_con_substream;
+ struct snd_pcm_substream *playback_pro_substream;
+ struct snd_pcm_substream *capture_pro_substream;
unsigned int playback_pro_size;
unsigned int capture_pro_size;
unsigned int playback_con_virt_addr[6];
@@ -326,13 +326,15 @@ struct snd_ice1712 {
struct snd_ice1712_eeprom eeprom;
unsigned int pro_volumes[20];
- unsigned int omni: 1; /* Delta Omni I/O */
- unsigned int dxr_enable: 1; /* Terratec DXR enable for DMX6FIRE */
- unsigned int vt1724: 1;
- unsigned int vt1720: 1;
- unsigned int has_spdif: 1; /* VT1720/4 - has SPDIF I/O */
- unsigned int force_pdma4: 1; /* VT1720/4 - PDMA4 as non-spdif */
- unsigned int force_rdma1: 1; /* VT1720/4 - RDMA1 as non-spdif */
+ unsigned int omni:1; /* Delta Omni I/O */
+ unsigned int dxr_enable:1; /* Terratec DXR enable for DMX6FIRE */
+ unsigned int vt1724:1;
+ unsigned int vt1720:1;
+ unsigned int has_spdif:1; /* VT1720/4 - has SPDIF I/O */
+ unsigned int force_pdma4:1; /* VT1720/4 - PDMA4 as non-spdif */
+ unsigned int force_rdma1:1; /* VT1720/4 - RDMA1 as non-spdif */
+ unsigned int midi_output:1; /* VT1720/4: MIDI output triggered */
+ unsigned int midi_input:1; /* VT1720/4: MIDI input triggered */
unsigned int num_total_dacs; /* total DACs */
unsigned int num_total_adcs; /* total ADCs */
unsigned int cur_rate; /* current rate */
@@ -349,7 +351,7 @@ struct snd_ice1712 {
struct snd_i2c_bus *i2c; /* I2C bus */
struct snd_i2c_device *cs8427; /* CS8427 I2C device */
unsigned int cs8427_timeout; /* CS8427 reset timeout in HZ/100 */
-
+
struct ice1712_gpio {
unsigned int direction; /* current direction bits */
unsigned int write_mask; /* current mask bits */
@@ -453,7 +455,7 @@ static inline int snd_ice1712_gpio_read_bits(struct snd_ice1712 *ice,
{
ice->gpio.direction &= ~mask;
snd_ice1712_gpio_set_dir(ice, ice->gpio.direction);
- return (snd_ice1712_gpio_read(ice) & mask);
+ return snd_ice1712_gpio_read(ice) & mask;
}
int snd_ice1712_spdif_build_controls(struct snd_ice1712 *ice);
@@ -465,13 +467,13 @@ int snd_ice1712_akm4xxx_build_controls(struct snd_ice1712 *ice);
int snd_ice1712_init_cs8427(struct snd_ice1712 *ice, int addr);
-static inline void snd_ice1712_write(struct snd_ice1712 * ice, u8 addr, u8 data)
+static inline void snd_ice1712_write(struct snd_ice1712 *ice, u8 addr, u8 data)
{
outb(addr, ICEREG(ice, INDEX));
outb(data, ICEREG(ice, DATA));
}
-static inline u8 snd_ice1712_read(struct snd_ice1712 * ice, u8 addr)
+static inline u8 snd_ice1712_read(struct snd_ice1712 *ice, u8 addr)
{
outb(addr, ICEREG(ice, INDEX));
return inb(ICEREG(ice, DATA));
@@ -489,7 +491,7 @@ struct snd_ice1712_card_info {
char *driver;
int (*chip_init)(struct snd_ice1712 *);
int (*build_controls)(struct snd_ice1712 *);
- unsigned int no_mpu401: 1;
+ unsigned int no_mpu401:1;
unsigned int mpu401_1_info_flags;
unsigned int mpu401_2_info_flags;
const char *mpu401_1_name;
diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c
index 67350901772c..1b3f11702713 100644
--- a/sound/pci/ice1712/ice1724.c
+++ b/sound/pci/ice1712/ice1724.c
@@ -20,9 +20,9 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
- */
+ */
-#include <asm/io.h>
+#include <linux/io.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/init.h>
@@ -32,7 +32,7 @@
#include <linux/mutex.h>
#include <sound/core.h>
#include <sound/info.h>
-#include <sound/mpu401.h>
+#include <sound/rawmidi.h>
#include <sound/initval.h>
#include <sound/asoundef.h>
@@ -105,7 +105,7 @@ static unsigned int PRO_RATE_DEFAULT = 44100;
/*
* Basic I/O
*/
-
+
/*
* default rates, default clock routines
*/
@@ -198,7 +198,7 @@ static void snd_vt1724_set_gpio_dir(struct snd_ice1712 *ice, unsigned int data)
static void snd_vt1724_set_gpio_mask(struct snd_ice1712 *ice, unsigned int data)
{
outw(data, ICEREG1724(ice, GPIO_WRITE_MASK));
- if (! ice->vt1720) /* VT1720 supports only 16 GPIO bits */
+ if (!ice->vt1720) /* VT1720 supports only 16 GPIO bits */
outb((data >> 16) & 0xff, ICEREG1724(ice, GPIO_WRITE_MASK_22));
inw(ICEREG1724(ice, GPIO_WRITE_MASK)); /* dummy read for pci-posting */
}
@@ -206,7 +206,7 @@ static void snd_vt1724_set_gpio_mask(struct snd_ice1712 *ice, unsigned int data)
static void snd_vt1724_set_gpio_data(struct snd_ice1712 *ice, unsigned int data)
{
outw(data, ICEREG1724(ice, GPIO_DATA));
- if (! ice->vt1720)
+ if (!ice->vt1720)
outb(data >> 16, ICEREG1724(ice, GPIO_DATA_22));
inw(ICEREG1724(ice, GPIO_DATA)); /* dummy read for pci-posting */
}
@@ -214,7 +214,7 @@ static void snd_vt1724_set_gpio_data(struct snd_ice1712 *ice, unsigned int data)
static unsigned int snd_vt1724_get_gpio_data(struct snd_ice1712 *ice)
{
unsigned int data;
- if (! ice->vt1720)
+ if (!ice->vt1720)
data = (unsigned int)inb(ICEREG1724(ice, GPIO_DATA_22));
else
data = 0;
@@ -223,30 +223,153 @@ static unsigned int snd_vt1724_get_gpio_data(struct snd_ice1712 *ice)
}
/*
- * MPU401 accessor
+ * MIDI
*/
-static unsigned char snd_vt1724_mpu401_read(struct snd_mpu401 *mpu,
- unsigned long addr)
+
+static void vt1724_midi_clear_rx(struct snd_ice1712 *ice)
{
- /* fix status bits to the standard position */
- /* only RX_EMPTY and TX_FULL are checked */
- if (addr == MPU401C(mpu))
- return (inb(addr) & 0x0c) << 4;
+ unsigned int count;
+
+ for (count = inb(ICEREG1724(ice, MPU_RXFIFO)); count > 0; --count)
+ inb(ICEREG1724(ice, MPU_DATA));
+}
+
+static inline struct snd_rawmidi_substream *
+get_rawmidi_substream(struct snd_ice1712 *ice, unsigned int stream)
+{
+ return list_first_entry(&ice->rmidi[0]->streams[stream].substreams,
+ struct snd_rawmidi_substream, list);
+}
+
+static void vt1724_midi_write(struct snd_ice1712 *ice)
+{
+ struct snd_rawmidi_substream *s;
+ int count, i;
+ u8 buffer[32];
+
+ s = get_rawmidi_substream(ice, SNDRV_RAWMIDI_STREAM_OUTPUT);
+ count = 31 - inb(ICEREG1724(ice, MPU_TXFIFO));
+ if (count > 0) {
+ count = snd_rawmidi_transmit(s, buffer, count);
+ for (i = 0; i < count; ++i)
+ outb(buffer[i], ICEREG1724(ice, MPU_DATA));
+ }
+}
+
+static void vt1724_midi_read(struct snd_ice1712 *ice)
+{
+ struct snd_rawmidi_substream *s;
+ int count, i;
+ u8 buffer[32];
+
+ s = get_rawmidi_substream(ice, SNDRV_RAWMIDI_STREAM_INPUT);
+ count = inb(ICEREG1724(ice, MPU_RXFIFO));
+ if (count > 0) {
+ count = min(count, 32);
+ for (i = 0; i < count; ++i)
+ buffer[i] = inb(ICEREG1724(ice, MPU_DATA));
+ snd_rawmidi_receive(s, buffer, count);
+ }
+}
+
+static void vt1724_enable_midi_irq(struct snd_rawmidi_substream *substream,
+ u8 flag, int enable)
+{
+ struct snd_ice1712 *ice = substream->rmidi->private_data;
+ u8 mask;
+
+ spin_lock_irq(&ice->reg_lock);
+ mask = inb(ICEREG1724(ice, IRQMASK));
+ if (enable)
+ mask &= ~flag;
else
- return inb(addr);
+ mask |= flag;
+ outb(mask, ICEREG1724(ice, IRQMASK));
+ spin_unlock_irq(&ice->reg_lock);
}
-static void snd_vt1724_mpu401_write(struct snd_mpu401 *mpu,
- unsigned char data, unsigned long addr)
+static int vt1724_midi_output_open(struct snd_rawmidi_substream *s)
{
- if (addr == MPU401C(mpu)) {
- if (data == MPU401_ENTER_UART)
- outb(0x01, addr);
- /* what else? */
- } else
- outb(data, addr);
+ vt1724_enable_midi_irq(s, VT1724_IRQ_MPU_TX, 1);
+ return 0;
}
+static int vt1724_midi_output_close(struct snd_rawmidi_substream *s)
+{
+ vt1724_enable_midi_irq(s, VT1724_IRQ_MPU_TX, 0);
+ return 0;
+}
+
+static void vt1724_midi_output_trigger(struct snd_rawmidi_substream *s, int up)
+{
+ struct snd_ice1712 *ice = s->rmidi->private_data;
+ unsigned long flags;
+
+ spin_lock_irqsave(&ice->reg_lock, flags);
+ if (up) {
+ ice->midi_output = 1;
+ vt1724_midi_write(ice);
+ } else {
+ ice->midi_output = 0;
+ }
+ spin_unlock_irqrestore(&ice->reg_lock, flags);
+}
+
+static void vt1724_midi_output_drain(struct snd_rawmidi_substream *s)
+{
+ struct snd_ice1712 *ice = s->rmidi->private_data;
+ unsigned long timeout;
+
+ /* 32 bytes should be transmitted in less than about 12 ms */
+ timeout = jiffies + msecs_to_jiffies(15);
+ do {
+ if (inb(ICEREG1724(ice, MPU_CTRL)) & VT1724_MPU_TX_EMPTY)
+ break;
+ schedule_timeout_uninterruptible(1);
+ } while (time_after(timeout, jiffies));
+}
+
+static struct snd_rawmidi_ops vt1724_midi_output_ops = {
+ .open = vt1724_midi_output_open,
+ .close = vt1724_midi_output_close,
+ .trigger = vt1724_midi_output_trigger,
+ .drain = vt1724_midi_output_drain,
+};
+
+static int vt1724_midi_input_open(struct snd_rawmidi_substream *s)
+{
+ vt1724_midi_clear_rx(s->rmidi->private_data);
+ vt1724_enable_midi_irq(s, VT1724_IRQ_MPU_RX, 1);
+ return 0;
+}
+
+static int vt1724_midi_input_close(struct snd_rawmidi_substream *s)
+{
+ vt1724_enable_midi_irq(s, VT1724_IRQ_MPU_RX, 0);
+ return 0;
+}
+
+static void vt1724_midi_input_trigger(struct snd_rawmidi_substream *s, int up)
+{
+ struct snd_ice1712 *ice = s->rmidi->private_data;
+ unsigned long flags;
+
+ spin_lock_irqsave(&ice->reg_lock, flags);
+ if (up) {
+ ice->midi_input = 1;
+ vt1724_midi_read(ice);
+ } else {
+ ice->midi_input = 0;
+ }
+ spin_unlock_irqrestore(&ice->reg_lock, flags);
+}
+
+static struct snd_rawmidi_ops vt1724_midi_input_ops = {
+ .open = vt1724_midi_input_open,
+ .close = vt1724_midi_input_close,
+ .trigger = vt1724_midi_input_trigger,
+};
+
/*
* Interrupt handler
@@ -276,15 +399,12 @@ static irqreturn_t snd_vt1724_interrupt(int irq, void *dev_id)
break;
}
#endif
- handled = 1;
+ handled = 1;
if (status & VT1724_IRQ_MPU_TX) {
- if (ice->rmidi[0])
- snd_mpu401_uart_interrupt_tx(irq,
- ice->rmidi[0]->private_data);
- else /* disable TX to be sure */
- outb(inb(ICEREG1724(ice, IRQMASK)) |
- VT1724_IRQ_MPU_TX,
- ICEREG1724(ice, IRQMASK));
+ spin_lock(&ice->reg_lock);
+ if (ice->midi_output)
+ vt1724_midi_write(ice);
+ spin_unlock(&ice->reg_lock);
/* Due to mysterical reasons, MPU_TX is always
* generated (and can't be cleared) when a PCM
* playback is going. So let's ignore at the
@@ -293,13 +413,12 @@ static irqreturn_t snd_vt1724_interrupt(int irq, void *dev_id)
status_mask &= ~VT1724_IRQ_MPU_TX;
}
if (status & VT1724_IRQ_MPU_RX) {
- if (ice->rmidi[0])
- snd_mpu401_uart_interrupt(irq,
- ice->rmidi[0]->private_data);
- else /* disable RX to be sure */
- outb(inb(ICEREG1724(ice, IRQMASK)) |
- VT1724_IRQ_MPU_RX,
- ICEREG1724(ice, IRQMASK));
+ spin_lock(&ice->reg_lock);
+ if (ice->midi_input)
+ vt1724_midi_read(ice);
+ else
+ vt1724_midi_clear_rx(ice);
+ spin_unlock(&ice->reg_lock);
}
/* ack MPU irq */
outb(status, ICEREG1724(ice, IRQSTAT));
@@ -349,8 +468,8 @@ static irqreturn_t snd_vt1724_interrupt(int irq, void *dev_id)
/* ought to really handle this properly */
if (mtstat & VT1724_MULTI_FIFO_ERR) {
unsigned char fstat = inb(ICEMT1724(ice, DMA_FIFO_ERR));
- outb(fstat, ICEMT1724(ice, DMA_FIFO_ERR));
- outb(VT1724_MULTI_FIFO_ERR | inb(ICEMT1724(ice, DMA_INT_MASK)), ICEMT1724(ice, DMA_INT_MASK));
+ outb(fstat, ICEMT1724(ice, DMA_FIFO_ERR));
+ outb(VT1724_MULTI_FIFO_ERR | inb(ICEMT1724(ice, DMA_INT_MASK)), ICEMT1724(ice, DMA_INT_MASK));
/* If I don't do this, I get machine lockup due to continual interrupts */
}
@@ -614,17 +733,17 @@ static int snd_vt1724_playback_pro_prepare(struct snd_pcm_substream *substream)
outl(substream->runtime->dma_addr, ICEMT1724(ice, PLAYBACK_ADDR));
size = (snd_pcm_lib_buffer_bytes(substream) >> 2) - 1;
- // outl(size, ICEMT1724(ice, PLAYBACK_SIZE));
+ /* outl(size, ICEMT1724(ice, PLAYBACK_SIZE)); */
outw(size, ICEMT1724(ice, PLAYBACK_SIZE));
outb(size >> 16, ICEMT1724(ice, PLAYBACK_SIZE) + 2);
size = (snd_pcm_lib_period_bytes(substream) >> 2) - 1;
- // outl(size, ICEMT1724(ice, PLAYBACK_COUNT));
+ /* outl(size, ICEMT1724(ice, PLAYBACK_COUNT)); */
outw(size, ICEMT1724(ice, PLAYBACK_COUNT));
outb(size >> 16, ICEMT1724(ice, PLAYBACK_COUNT) + 2);
spin_unlock_irq(&ice->reg_lock);
- // printk("pro prepare: ch = %d, addr = 0x%x, buffer = 0x%x, period = 0x%x\n", substream->runtime->channels, (unsigned int)substream->runtime->dma_addr, snd_pcm_lib_buffer_bytes(substream), snd_pcm_lib_period_bytes(substream));
+ /* printk("pro prepare: ch = %d, addr = 0x%x, buffer = 0x%x, period = 0x%x\n", substream->runtime->channels, (unsigned int)substream->runtime->dma_addr, snd_pcm_lib_buffer_bytes(substream), snd_pcm_lib_period_bytes(substream)); */
return 0;
}
@@ -652,7 +771,7 @@ static snd_pcm_uframes_t snd_vt1724_playback_pro_pointer(struct snd_pcm_substrea
ptr = inl(ICEMT1724(ice, PLAYBACK_SIZE)) & 0xffffff;
ptr = (ptr + 1) << 2;
ptr = bytes_to_frames(substream->runtime, ptr);
- if (! ptr)
+ if (!ptr)
;
else if (ptr <= substream->runtime->buffer_size)
ptr = substream->runtime->buffer_size - ptr;
@@ -696,7 +815,7 @@ static snd_pcm_uframes_t snd_vt1724_pcm_pointer(struct snd_pcm_substream *substr
ptr = inw(ice->profi_port + reg->size);
ptr = (ptr + 1) << 2;
ptr = bytes_to_frames(substream->runtime, ptr);
- if (! ptr)
+ if (!ptr)
;
else if (ptr <= substream->runtime->buffer_size)
ptr = substream->runtime->buffer_size - ptr;
@@ -723,8 +842,7 @@ static const struct vt1724_pcm_reg vt1724_capture_pro_reg = {
.start = VT1724_RDMA0_START,
};
-static const struct snd_pcm_hardware snd_vt1724_playback_pro =
-{
+static const struct snd_pcm_hardware snd_vt1724_playback_pro = {
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
SNDRV_PCM_INFO_MMAP_VALID |
@@ -742,8 +860,7 @@ static const struct snd_pcm_hardware snd_vt1724_playback_pro =
.periods_max = 1024,
};
-static const struct snd_pcm_hardware snd_vt1724_spdif =
-{
+static const struct snd_pcm_hardware snd_vt1724_spdif = {
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
SNDRV_PCM_INFO_MMAP_VALID |
@@ -764,8 +881,7 @@ static const struct snd_pcm_hardware snd_vt1724_spdif =
.periods_max = 1024,
};
-static const struct snd_pcm_hardware snd_vt1724_2ch_stereo =
-{
+static const struct snd_pcm_hardware snd_vt1724_2ch_stereo = {
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
SNDRV_PCM_INFO_MMAP_VALID |
@@ -823,7 +939,7 @@ static int snd_vt1724_playback_pro_open(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
- int chs;
+ int chs, num_indeps;
runtime->private_data = (void *)&vt1724_playback_pro_reg;
ice->playback_pro_substream = substream;
@@ -833,7 +949,8 @@ static int snd_vt1724_playback_pro_open(struct snd_pcm_substream *substream)
set_rate_constraints(ice, substream);
mutex_lock(&ice->open_mutex);
/* calculate the currently available channels */
- for (chs = 0; chs < 3; chs++) {
+ num_indeps = ice->num_total_dacs / 2 - 1;
+ for (chs = 0; chs < num_indeps; chs++) {
if (ice->pcm_reserved[chs])
break;
}
@@ -910,7 +1027,7 @@ static struct snd_pcm_ops snd_vt1724_capture_pro_ops = {
.pointer = snd_vt1724_pcm_pointer,
};
-static int __devinit snd_vt1724_pcm_profi(struct snd_ice1712 * ice, int device)
+static int __devinit snd_vt1724_pcm_profi(struct snd_ice1712 *ice, int device)
{
struct snd_pcm *pcm;
int err;
@@ -995,7 +1112,7 @@ static void update_spdif_rate(struct snd_ice1712 *ice, unsigned int rate)
static int snd_vt1724_playback_spdif_prepare(struct snd_pcm_substream *substream)
{
struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
- if (! ice->force_pdma4)
+ if (!ice->force_pdma4)
update_spdif_rate(ice, substream->runtime->rate);
return snd_vt1724_pcm_prepare(substream);
}
@@ -1095,7 +1212,7 @@ static struct snd_pcm_ops snd_vt1724_capture_spdif_ops = {
};
-static int __devinit snd_vt1724_pcm_spdif(struct snd_ice1712 * ice, int device)
+static int __devinit snd_vt1724_pcm_spdif(struct snd_ice1712 *ice, int device)
{
char *name;
struct snd_pcm *pcm;
@@ -1114,7 +1231,7 @@ static int __devinit snd_vt1724_pcm_spdif(struct snd_ice1712 * ice, int device)
ice->has_spdif = 1;
} else
capt = 0;
- if (! play && ! capt)
+ if (!play && !capt)
return 0; /* no spdif device */
if (ice->force_pdma4 || ice->force_rdma1)
@@ -1229,7 +1346,7 @@ static struct snd_pcm_ops snd_vt1724_playback_indep_ops = {
};
-static int __devinit snd_vt1724_pcm_indep(struct snd_ice1712 * ice, int device)
+static int __devinit snd_vt1724_pcm_indep(struct snd_ice1712 *ice, int device)
{
struct snd_pcm *pcm;
int play;
@@ -1264,11 +1381,11 @@ static int __devinit snd_vt1724_pcm_indep(struct snd_ice1712 * ice, int device)
* Mixer section
*/
-static int __devinit snd_vt1724_ac97_mixer(struct snd_ice1712 * ice)
+static int __devinit snd_vt1724_ac97_mixer(struct snd_ice1712 *ice)
{
int err;
- if (! (ice->eeprom.data[ICE_EEP2_ACLINK] & VT1724_CFG_PRO_I2S)) {
+ if (!(ice->eeprom.data[ICE_EEP2_ACLINK] & VT1724_CFG_PRO_I2S)) {
struct snd_ac97_bus *pbus;
struct snd_ac97_template ac97;
static struct snd_ac97_bus_ops ops = {
@@ -1281,11 +1398,13 @@ static int __devinit snd_vt1724_ac97_mixer(struct snd_ice1712 * ice)
mdelay(5); /* FIXME */
outb(inb(ICEMT1724(ice, AC97_CMD)) & ~0x80, ICEMT1724(ice, AC97_CMD));
- if ((err = snd_ac97_bus(ice->card, 0, &ops, NULL, &pbus)) < 0)
+ err = snd_ac97_bus(ice->card, 0, &ops, NULL, &pbus);
+ if (err < 0)
return err;
memset(&ac97, 0, sizeof(ac97));
ac97.private_data = ice;
- if ((err = snd_ac97_mixer(pbus, &ac97, &ice->ac97)) < 0)
+ err = snd_ac97_mixer(pbus, &ac97, &ice->ac97);
+ if (err < 0)
printk(KERN_WARNING "ice1712: cannot initialize pro ac97, skipped\n");
else
return 0;
@@ -1306,7 +1425,7 @@ static inline unsigned int eeprom_triple(struct snd_ice1712 *ice, int idx)
((unsigned int)ice->eeprom.data[idx + 2] << 16);
}
-static void snd_vt1724_proc_read(struct snd_info_entry *entry,
+static void snd_vt1724_proc_read(struct snd_info_entry *entry,
struct snd_info_buffer *buffer)
{
struct snd_ice1712 *ice = entry->private_data;
@@ -1348,11 +1467,11 @@ static void snd_vt1724_proc_read(struct snd_info_entry *entry,
idx, inb(ice->profi_port+idx));
}
-static void __devinit snd_vt1724_proc_init(struct snd_ice1712 * ice)
+static void __devinit snd_vt1724_proc_init(struct snd_ice1712 *ice)
{
struct snd_info_entry *entry;
- if (! snd_card_proc_new(ice->card, "ice1724", &entry))
+ if (!snd_card_proc_new(ice->card, "ice1724", &entry))
snd_info_set_text_ops(entry, ice, snd_vt1724_proc_read);
}
@@ -1372,7 +1491,7 @@ static int snd_vt1724_eeprom_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
-
+
memcpy(ucontrol->value.bytes.data, &ice->eeprom, sizeof(ice->eeprom));
return 0;
}
@@ -1487,13 +1606,13 @@ static int snd_vt1724_spdif_default_put(struct snd_kcontrol *kcontrol,
if (val != old)
update_spdif_bits(ice, val);
spin_unlock_irq(&ice->reg_lock);
- return (val != old);
+ return val != old;
}
static struct snd_kcontrol_new snd_vt1724_spdif_default __devinitdata =
{
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
+ .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT),
.info = snd_vt1724_spdif_info,
.get = snd_vt1724_spdif_default_get,
.put = snd_vt1724_spdif_default_put
@@ -1526,7 +1645,7 @@ static struct snd_kcontrol_new snd_vt1724_spdif_maskc __devinitdata =
{
.access = SNDRV_CTL_ELEM_ACCESS_READ,
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK),
+ .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, CON_MASK),
.info = snd_vt1724_spdif_info,
.get = snd_vt1724_spdif_maskc_get,
};
@@ -1535,7 +1654,7 @@ static struct snd_kcontrol_new snd_vt1724_spdif_maskp __devinitdata =
{
.access = SNDRV_CTL_ELEM_ACCESS_READ,
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PRO_MASK),
+ .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, PRO_MASK),
.info = snd_vt1724_spdif_info,
.get = snd_vt1724_spdif_maskp_get,
};
@@ -1572,8 +1691,8 @@ static struct snd_kcontrol_new snd_vt1724_spdif_switch __devinitdata =
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
/* FIXME: the following conflict with IEC958 Playback Route */
- // .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH),
- .name = SNDRV_CTL_NAME_IEC958("Output ",NONE,SWITCH),
+ /* .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, SWITCH), */
+ .name = SNDRV_CTL_NAME_IEC958("Output ", NONE, SWITCH),
.info = snd_vt1724_spdif_sw_info,
.get = snd_vt1724_spdif_sw_get,
.put = snd_vt1724_spdif_sw_put
@@ -1593,7 +1712,7 @@ int snd_vt1724_gpio_get(struct snd_kcontrol *kcontrol,
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
int shift = kcontrol->private_value & 0xff;
int invert = (kcontrol->private_value & (1<<24)) ? 1 : 0;
-
+
snd_ice1712_save_gpio_status(ice);
ucontrol->value.integer.value[0] =
(snd_ice1712_gpio_read(ice) & (1 << shift) ? 1 : 0) ^ invert;
@@ -1648,7 +1767,7 @@ static int snd_vt1724_pro_internal_clock_get(struct snd_kcontrol *kcontrol,
{
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
unsigned int i, rate;
-
+
spin_lock_irq(&ice->reg_lock);
if (ice->is_spdif_master(ice)) {
ucontrol->value.enumerated.item[0] = ice->hw_rates->count;
@@ -1804,7 +1923,7 @@ static int snd_vt1724_pro_route_info(struct snd_kcontrol *kcontrol,
"H/W In 0", "H/W In 1", /* 1-2 */
"IEC958 In L", "IEC958 In R", /* 3-4 */
};
-
+
uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
uinfo->count = 1;
uinfo->value.enumerated.items = 5;
@@ -1834,7 +1953,7 @@ static int get_route_val(struct snd_ice1712 *ice, int shift)
val = inl(ICEMT1724(ice, ROUTE_PLAYBACK));
val >>= shift;
- val &= 7; //we now have 3 bits per output
+ val &= 7; /* we now have 3 bits per output */
eitem = xlate[val];
if (eitem == 255) {
snd_BUG();
@@ -1913,7 +2032,7 @@ static struct snd_kcontrol_new snd_vt1724_mixer_pro_analog_route __devinitdata =
static struct snd_kcontrol_new snd_vt1724_mixer_pro_spdif_route __devinitdata = {
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Route",
+ .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, NONE) "Route",
.info = snd_vt1724_pro_route_info,
.get = snd_vt1724_pro_route_spdif_get,
.put = snd_vt1724_pro_route_spdif_put,
@@ -1936,7 +2055,7 @@ static int snd_vt1724_pro_peak_get(struct snd_kcontrol *kcontrol,
{
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
int idx;
-
+
spin_lock_irq(&ice->reg_lock);
for (idx = 0; idx < 22; idx++) {
outb(idx, ICEMT1724(ice, MONITOR_PEAKINDEX));
@@ -1963,7 +2082,7 @@ static struct snd_ice1712_card_info no_matched __devinitdata;
static struct snd_ice1712_card_info *card_tables[] __devinitdata = {
snd_vt1724_revo_cards,
- snd_vt1724_amp_cards,
+ snd_vt1724_amp_cards,
snd_vt1724_aureon_cards,
snd_vt1720_mobo_cards,
snd_vt1720_pontis_cards,
@@ -2001,7 +2120,7 @@ unsigned char snd_vt1724_read_i2c(struct snd_ice1712 *ice,
wait_i2c_busy(ice);
val = inb(ICEREG1724(ice, I2C_DATA));
mutex_unlock(&ice->i2c_mutex);
- //printk("i2c_read: [0x%x,0x%x] = 0x%x\n", dev, addr, val);
+ /* printk("i2c_read: [0x%x,0x%x] = 0x%x\n", dev, addr, val); */
return val;
}
@@ -2010,7 +2129,7 @@ void snd_vt1724_write_i2c(struct snd_ice1712 *ice,
{
mutex_lock(&ice->i2c_mutex);
wait_i2c_busy(ice);
- //printk("i2c_write: [0x%x,0x%x] = 0x%x\n", dev, addr, data);
+ /* printk("i2c_write: [0x%x,0x%x] = 0x%x\n", dev, addr, data); */
outb(addr, ICEREG1724(ice, I2C_BYTE_ADDR));
outb(data, ICEREG1724(ice, I2C_DATA));
outb(dev | VT1724_I2C_WRITE, ICEREG1724(ice, I2C_DEV_ADDR));
@@ -2025,13 +2144,13 @@ static int __devinit snd_vt1724_read_eeprom(struct snd_ice1712 *ice,
unsigned int i, size;
struct snd_ice1712_card_info * const *tbl, *c;
- if (! modelname || ! *modelname) {
+ if (!modelname || !*modelname) {
ice->eeprom.subvendor = 0;
if ((inb(ICEREG1724(ice, I2C_CTRL)) & VT1724_I2C_EEPROM) != 0)
ice->eeprom.subvendor =
(snd_vt1724_read_i2c(ice, dev, 0x00) << 0) |
- (snd_vt1724_read_i2c(ice, dev, 0x01) << 8) |
- (snd_vt1724_read_i2c(ice, dev, 0x02) << 16) |
+ (snd_vt1724_read_i2c(ice, dev, 0x01) << 8) |
+ (snd_vt1724_read_i2c(ice, dev, 0x02) << 16) |
(snd_vt1724_read_i2c(ice, dev, 0x03) << 24);
if (ice->eeprom.subvendor == 0 ||
ice->eeprom.subvendor == (unsigned int)-1) {
@@ -2054,13 +2173,13 @@ static int __devinit snd_vt1724_read_eeprom(struct snd_ice1712 *ice,
for (tbl = card_tables; *tbl; tbl++) {
for (c = *tbl; c->subvendor; c++) {
if (modelname && c->model &&
- ! strcmp(modelname, c->model)) {
+ !strcmp(modelname, c->model)) {
printk(KERN_INFO "ice1724: Using board model %s\n",
c->name);
ice->eeprom.subvendor = c->subvendor;
} else if (c->subvendor != ice->eeprom.subvendor)
continue;
- if (! c->eeprom_size || ! c->eeprom_data)
+ if (!c->eeprom_size || !c->eeprom_data)
goto found;
/* if the EEPROM is given by the driver, use it */
snd_printdd("using the defined eeprom..\n");
@@ -2131,7 +2250,8 @@ static int __devinit snd_vt1724_spdif_build_controls(struct snd_ice1712 *ice)
int err;
struct snd_kcontrol *kctl;
- snd_assert(ice->pcm != NULL, return -EIO);
+ if (snd_BUG_ON(!ice->pcm))
+ return -EIO;
err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_vt1724_mixer_pro_spdif_route, ice));
if (err < 0)
@@ -2201,13 +2321,13 @@ static int __devinit snd_vt1724_build_controls(struct snd_ice1712 *ice)
static int snd_vt1724_free(struct snd_ice1712 *ice)
{
- if (! ice->port)
+ if (!ice->port)
goto __hw_end;
/* mask all interrupts */
outb(0xff, ICEMT1724(ice, DMA_INT_MASK));
outb(0xff, ICEREG1724(ice, IRQMASK));
/* --- */
- __hw_end:
+__hw_end:
if (ice->irq >= 0)
free_irq(ice->irq, ice);
pci_release_regions(ice->pci);
@@ -2227,7 +2347,7 @@ static int snd_vt1724_dev_free(struct snd_device *device)
static int __devinit snd_vt1724_create(struct snd_card *card,
struct pci_dev *pci,
const char *modelname,
- struct snd_ice1712 ** r_ice1712)
+ struct snd_ice1712 **r_ice1712)
{
struct snd_ice1712 *ice;
int err;
@@ -2238,8 +2358,9 @@ static int __devinit snd_vt1724_create(struct snd_card *card,
*r_ice1712 = NULL;
- /* enable PCI device */
- if ((err = pci_enable_device(pci)) < 0)
+ /* enable PCI device */
+ err = pci_enable_device(pci);
+ if (err < 0)
return err;
ice = kzalloc(sizeof(*ice), GFP_KERNEL);
@@ -2263,7 +2384,8 @@ static int __devinit snd_vt1724_create(struct snd_card *card,
snd_vt1724_proc_init(ice);
synchronize_irq(pci->irq);
- if ((err = pci_request_regions(pci, "ICE1724")) < 0) {
+ err = pci_request_regions(pci, "ICE1724");
+ if (err < 0) {
kfree(ice);
pci_disable_device(pci);
return err;
@@ -2298,9 +2420,10 @@ static int __devinit snd_vt1724_create(struct snd_card *card,
*/
outb(VT1724_MULTI_FIFO_ERR, ICEMT1724(ice, DMA_INT_MASK));
- if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, ice, &ops)) < 0) {
+ err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, ice, &ops);
+ if (err < 0) {
snd_vt1724_free(ice);
- return err;
+ return err;
}
snd_card_set_dev(card, &pci->dev);
@@ -2338,8 +2461,9 @@ static int __devinit snd_vt1724_probe(struct pci_dev *pci,
strcpy(card->driver, "ICE1724");
strcpy(card->shortname, "ICEnsemble ICE1724");
-
- if ((err = snd_vt1724_create(card, pci, model[dev], &ice)) < 0) {
+
+ err = snd_vt1724_create(card, pci, model[dev], &ice);
+ if (err < 0) {
snd_card_free(card);
return err;
}
@@ -2351,7 +2475,8 @@ static int __devinit snd_vt1724_probe(struct pci_dev *pci,
if (c->driver) /* specific driver? */
strcpy(card->driver, c->driver);
if (c->chip_init) {
- if ((err = c->chip_init(ice)) < 0) {
+ err = c->chip_init(ice);
+ if (err < 0) {
snd_card_free(card);
return err;
}
@@ -2361,15 +2486,15 @@ static int __devinit snd_vt1724_probe(struct pci_dev *pci,
}
}
c = &no_matched;
- __found:
- /*
- * VT1724 has separate DMAs for the analog and the SPDIF streams while
- * ICE1712 has only one for both (mixed up).
- *
- * Confusingly the analog PCM is named "professional" here because it
- * was called so in ice1712 driver, and vt1724 driver is derived from
- * ice1712 driver.
- */
+__found:
+ /*
+ * VT1724 has separate DMAs for the analog and the SPDIF streams while
+ * ICE1712 has only one for both (mixed up).
+ *
+ * Confusingly the analog PCM is named "professional" here because it
+ * was called so in ice1712 driver, and vt1724 driver is derived from
+ * ice1712 driver.
+ */
ice->pro_rate_default = PRO_RATE_DEFAULT;
if (!ice->is_spdif_master)
ice->is_spdif_master = stdclock_is_spdif_master;
@@ -2384,76 +2509,86 @@ static int __devinit snd_vt1724_probe(struct pci_dev *pci,
if (!ice->hw_rates)
set_std_hw_rates(ice);
- if ((err = snd_vt1724_pcm_profi(ice, pcm_dev++)) < 0) {
+ err = snd_vt1724_pcm_profi(ice, pcm_dev++);
+ if (err < 0) {
snd_card_free(card);
return err;
}
-
- if ((err = snd_vt1724_pcm_spdif(ice, pcm_dev++)) < 0) {
+
+ err = snd_vt1724_pcm_spdif(ice, pcm_dev++);
+ if (err < 0) {
snd_card_free(card);
return err;
}
-
- if ((err = snd_vt1724_pcm_indep(ice, pcm_dev++)) < 0) {
+
+ err = snd_vt1724_pcm_indep(ice, pcm_dev++);
+ if (err < 0) {
snd_card_free(card);
return err;
}
- if ((err = snd_vt1724_ac97_mixer(ice)) < 0) {
+ err = snd_vt1724_ac97_mixer(ice);
+ if (err < 0) {
snd_card_free(card);
return err;
}
- if ((err = snd_vt1724_build_controls(ice)) < 0) {
+ err = snd_vt1724_build_controls(ice);
+ if (err < 0) {
snd_card_free(card);
return err;
}
if (ice->pcm && ice->has_spdif) { /* has SPDIF I/O */
- if ((err = snd_vt1724_spdif_build_controls(ice)) < 0) {
+ err = snd_vt1724_spdif_build_controls(ice);
+ if (err < 0) {
snd_card_free(card);
return err;
}
}
if (c->build_controls) {
- if ((err = c->build_controls(ice)) < 0) {
+ err = c->build_controls(ice);
+ if (err < 0) {
snd_card_free(card);
return err;
}
}
- if (! c->no_mpu401) {
+ if (!c->no_mpu401) {
if (ice->eeprom.data[ICE_EEP2_SYSCONF] & VT1724_CFG_MPU401) {
- struct snd_mpu401 *mpu;
- if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_ICE1712,
- ICEREG1724(ice, MPU_CTRL),
- (MPU401_INFO_INTEGRATED |
- MPU401_INFO_NO_ACK |
- MPU401_INFO_TX_IRQ),
- ice->irq, 0,
- &ice->rmidi[0])) < 0) {
+ struct snd_rawmidi *rmidi;
+
+ err = snd_rawmidi_new(card, "MIDI", 0, 1, 1, &rmidi);
+ if (err < 0) {
snd_card_free(card);
return err;
}
- mpu = ice->rmidi[0]->private_data;
- mpu->read = snd_vt1724_mpu401_read;
- mpu->write = snd_vt1724_mpu401_write;
- /* unmask MPU RX/TX irqs */
- outb(inb(ICEREG1724(ice, IRQMASK)) &
- ~(VT1724_IRQ_MPU_RX | VT1724_IRQ_MPU_TX),
- ICEREG1724(ice, IRQMASK));
+ ice->rmidi[0] = rmidi;
+ rmidi->private_data = ice;
+ strcpy(rmidi->name, "ICE1724 MIDI");
+ rmidi->info_flags = SNDRV_RAWMIDI_INFO_OUTPUT |
+ SNDRV_RAWMIDI_INFO_INPUT |
+ SNDRV_RAWMIDI_INFO_DUPLEX;
+ snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT,
+ &vt1724_midi_output_ops);
+ snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT,
+ &vt1724_midi_input_ops);
+
/* set watermarks */
outb(VT1724_MPU_RX_FIFO | 0x1,
ICEREG1724(ice, MPU_FIFO_WM));
outb(0x1, ICEREG1724(ice, MPU_FIFO_WM));
+ /* set UART mode */
+ outb(VT1724_MPU_UART, ICEREG1724(ice, MPU_CTRL));
}
}
sprintf(card->longname, "%s at 0x%lx, irq %i",
card->shortname, ice->port, ice->irq);
- 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/ice1712/juli.c b/sound/pci/ice1712/juli.c
index b4e0c16852a6..c51659b9caf6 100644
--- a/sound/pci/ice1712/juli.c
+++ b/sound/pci/ice1712/juli.c
@@ -21,7 +21,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
- */
+ */
#include <asm/io.h>
#include <linux/delay.h>
@@ -34,9 +34,10 @@
#include "ice1712.h"
#include "envy24ht.h"
#include "juli.h"
+
struct juli_spec {
struct ak4114 *ak4114;
- unsigned int analog: 1;
+ unsigned int analog:1;
};
/*
@@ -160,14 +161,17 @@ static int get_gpio_val(int rate)
return 0;
}
-static void juli_ak4114_write(void *private_data, unsigned char reg, unsigned char val)
+static void juli_ak4114_write(void *private_data, unsigned char reg,
+ unsigned char val)
{
- snd_vt1724_write_i2c((struct snd_ice1712 *)private_data, AK4114_ADDR, reg, val);
+ snd_vt1724_write_i2c((struct snd_ice1712 *)private_data, AK4114_ADDR,
+ reg, val);
}
-
+
static unsigned char juli_ak4114_read(void *private_data, unsigned char reg)
{
- return snd_vt1724_read_i2c((struct snd_ice1712 *)private_data, AK4114_ADDR, reg);
+ return snd_vt1724_read_i2c((struct snd_ice1712 *)private_data,
+ AK4114_ADDR, reg);
}
/*
@@ -175,7 +179,7 @@ static unsigned char juli_ak4114_read(void *private_data, unsigned char reg)
* to the external rate
*/
static void juli_spdif_in_open(struct snd_ice1712 *ice,
- struct snd_pcm_substream *substream)
+ struct snd_pcm_substream *substream)
{
struct juli_spec *spec = ice->spec;
struct snd_pcm_runtime *runtime = substream->runtime;
@@ -208,7 +212,8 @@ static void juli_akm_write(struct snd_akm4xxx *ak, int chip,
{
struct snd_ice1712 *ice = ak->private_data[0];
- snd_assert(chip == 0, return);
+ if (snd_BUG_ON(chip))
+ return;
snd_vt1724_write_i2c(ice, AK4358_ADDR, addr, data);
}
@@ -571,10 +576,12 @@ static void juli_ak4114_change(struct ak4114 *ak4114, unsigned char c0,
static int __devinit juli_init(struct snd_ice1712 *ice)
{
static const unsigned char ak4114_init_vals[] = {
- /* AK4117_REG_PWRDN */ AK4114_RST | AK4114_PWN | AK4114_OCKS0 | AK4114_OCKS1,
+ /* AK4117_REG_PWRDN */ AK4114_RST | AK4114_PWN |
+ AK4114_OCKS0 | AK4114_OCKS1,
/* AK4114_REQ_FORMAT */ AK4114_DIF_I24I2S,
/* AK4114_REG_IO0 */ AK4114_TX1E,
- /* AK4114_REG_IO1 */ AK4114_EFH_1024 | AK4114_DIT | AK4114_IPS(1),
+ /* AK4114_REG_IO1 */ AK4114_EFH_1024 | AK4114_DIT |
+ AK4114_IPS(1),
/* AK4114_REG_INT0_MASK */ 0,
/* AK4114_REG_INT1_MASK */ 0
};
@@ -604,12 +611,14 @@ static int __devinit juli_init(struct snd_ice1712 *ice)
spec->ak4114->check_flags = 0;
#if 0
- /* it seems that the analog doughter board detection does not work
- reliably, so force the analog flag; it should be very rare
- to use Juli@ without the analog doughter board */
+/*
+ * it seems that the analog doughter board detection does not work reliably, so
+ * force the analog flag; it should be very rare (if ever) to come at Juli@
+ * used without the analog daughter board
+ */
spec->analog = (ice->gpio.get_data(ice) & GPIO_ANALOG_PRESENT) ? 0 : 1;
#else
- spec->analog = 1;
+ spec->analog = 1;
#endif
if (spec->analog) {
@@ -617,14 +626,16 @@ static int __devinit juli_init(struct snd_ice1712 *ice)
ice->num_total_dacs = 2;
ice->num_total_adcs = 2;
- ak = ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
- if (! ak)
+ ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
+ ak = ice->akm;
+ if (!ak)
return -ENOMEM;
ice->akm_codecs = 1;
- if ((err = snd_ice1712_akm4xxx_init(ak, &akm_juli_dac, NULL, ice)) < 0)
+ err = snd_ice1712_akm4xxx_init(ak, &akm_juli_dac, NULL, ice);
+ if (err < 0)
return err;
}
-
+
/* juli is clocked by Xilinx array */
ice->hw_rates = &juli_rates_info;
ice->is_spdif_master = juli_is_spdif_master;
diff --git a/sound/pci/ice1712/phase.c b/sound/pci/ice1712/phase.c
index 5a158b73dcaa..de29be8c9657 100644
--- a/sound/pci/ice1712/phase.c
+++ b/sound/pci/ice1712/phase.c
@@ -22,15 +22,24 @@
*/
/* PHASE 22 overview:
- * Audio controller: VIA Envy24HT-S (slightly trimmed down version of Envy24HT)
+ * Audio controller: VIA Envy24HT-S (slightly trimmed down Envy24HT, 4in/4out)
* Analog chip: AK4524 (partially via Philip's 74HCT125)
- * Digital receiver: CS8414-CS (not supported in this release)
+ * Digital receiver: CS8414-CS (supported in this release)
+ * PHASE 22 revision 2.0 and Terrasoniq/Musonik TS22PCI have CS8416
+ * (support status unknown, please test and report)
*
* Envy connects to AK4524
* - CS directly from GPIO 10
* - CCLK via 74HCT125's gate #4 from GPIO 4
* - CDTI via 74HCT125's gate #2 from GPIO 5
- * CDTI may be completely blocked by 74HCT125's gate #1 controlled by GPIO 3
+ * CDTI may be completely blocked by 74HCT125's gate #1
+ * controlled by GPIO 3
+ */
+
+/* PHASE 28 overview:
+ * Audio controller: VIA Envy24HT (full untrimmed version, 4in/8out)
+ * Analog chip: WM8770 (8 channel 192k DAC, 2 channel 96k ADC)
+ * Digital receiver: CS8414-CS (supported in this release)
*/
#include <asm/io.h>
@@ -77,18 +86,18 @@ struct phase28_spec {
* Computed as 20 * Log10(255 / x)
*/
static const unsigned char wm_vol[256] = {
- 127, 48, 42, 39, 36, 34, 33, 31, 30, 29, 28, 27, 27, 26, 25, 25, 24, 24, 23,
- 23, 22, 22, 21, 21, 21, 20, 20, 20, 19, 19, 19, 18, 18, 18, 18, 17, 17, 17,
- 17, 16, 16, 16, 16, 15, 15, 15, 15, 15, 15, 14, 14, 14, 14, 14, 13, 13, 13,
- 13, 13, 13, 13, 12, 12, 12, 12, 12, 12, 12, 11, 11, 11, 11, 11, 11, 11, 11,
- 11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0
+ 127, 48, 42, 39, 36, 34, 33, 31, 30, 29, 28, 27, 27, 26, 25, 25, 24,
+ 24, 23, 23, 22, 22, 21, 21, 21, 20, 20, 20, 19, 19, 19, 18, 18, 18, 18,
+ 17, 17, 17, 17, 16, 16, 16, 16, 15, 15, 15, 15, 15, 15, 14, 14, 14, 14,
+ 14, 13, 13, 13, 13, 13, 13, 13, 12, 12, 12, 12, 12, 12, 12, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
#define WM_VOL_MAX (sizeof(wm_vol) - 1)
@@ -117,26 +126,31 @@ static int __devinit phase22_init(struct snd_ice1712 *ice)
struct snd_akm4xxx *ak;
int err;
- // Configure DAC/ADC description for generic part of ice1724
+ /* Configure DAC/ADC description for generic part of ice1724 */
switch (ice->eeprom.subvendor) {
case VT1724_SUBDEVICE_PHASE22:
+ case VT1724_SUBDEVICE_TS22:
ice->num_total_dacs = 2;
ice->num_total_adcs = 2;
- ice->vt1720 = 1; // Envy24HT-S have 16 bit wide GPIO
+ ice->vt1720 = 1; /* Envy24HT-S have 16 bit wide GPIO */
break;
default:
snd_BUG();
return -EINVAL;
}
- // Initialize analog chips
- ak = ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
- if (! ak)
+ /* Initialize analog chips */
+ ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
+ ak = ice->akm;
+ if (!ak)
return -ENOMEM;
ice->akm_codecs = 1;
switch (ice->eeprom.subvendor) {
case VT1724_SUBDEVICE_PHASE22:
- if ((err = snd_ice1712_akm4xxx_init(ak, &akm_phase22, &akm_phase22_priv, ice)) < 0)
+ case VT1724_SUBDEVICE_TS22:
+ err = snd_ice1712_akm4xxx_init(ak, &akm_phase22,
+ &akm_phase22_priv, ice);
+ if (err < 0)
return err;
break;
}
@@ -150,6 +164,7 @@ static int __devinit phase22_add_controls(struct snd_ice1712 *ice)
switch (ice->eeprom.subvendor) {
case VT1724_SUBDEVICE_PHASE22:
+ case VT1724_SUBDEVICE_TS22:
err = snd_ice1712_akm4xxx_build_controls(ice);
if (err < 0)
return err;
@@ -158,9 +173,10 @@ static int __devinit phase22_add_controls(struct snd_ice1712 *ice)
}
static unsigned char phase22_eeprom[] __devinitdata = {
- [ICE_EEP2_SYSCONF] = 0x00, /* 1xADC, 1xDACs */
+ [ICE_EEP2_SYSCONF] = 0x28, /* clock 512, mpu 401,
+ spdif-in/1xADC, 1xDACs */
[ICE_EEP2_ACLINK] = 0x80, /* I2S */
- [ICE_EEP2_I2S] = 0xf8, /* vol, 96k, 24bit */
+ [ICE_EEP2_I2S] = 0xf0, /* vol, 96k, 24bit */
[ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */
[ICE_EEP2_GPIO_DIR] = 0xff,
[ICE_EEP2_GPIO_DIR1] = 0xff,
@@ -174,7 +190,8 @@ static unsigned char phase22_eeprom[] __devinitdata = {
};
static unsigned char phase28_eeprom[] __devinitdata = {
- [ICE_EEP2_SYSCONF] = 0x0b, /* clock 512, spdif-in/ADC, 4DACs */
+ [ICE_EEP2_SYSCONF] = 0x2b, /* clock 512, mpu401,
+ spdif-in/1xADC, 4xDACs */
[ICE_EEP2_ACLINK] = 0x80, /* I2S */
[ICE_EEP2_I2S] = 0xfc, /* vol, 96k, 24bit, 192k */
[ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */
@@ -192,15 +209,16 @@ static unsigned char phase28_eeprom[] __devinitdata = {
/*
* write data in the SPI mode
*/
-static void phase28_spi_write(struct snd_ice1712 *ice, unsigned int cs, unsigned int data, int bits)
+static void phase28_spi_write(struct snd_ice1712 *ice, unsigned int cs,
+ unsigned int data, int bits)
{
unsigned int tmp;
int i;
tmp = snd_ice1712_gpio_read(ice);
- snd_ice1712_gpio_set_mask(ice, ~(PHASE28_WM_RW|PHASE28_SPI_MOSI|PHASE28_SPI_CLK|
- PHASE28_WM_CS));
+ snd_ice1712_gpio_set_mask(ice, ~(PHASE28_WM_RW|PHASE28_SPI_MOSI|
+ PHASE28_SPI_CLK|PHASE28_WM_CS));
tmp |= PHASE28_WM_RW;
tmp &= ~cs;
snd_ice1712_gpio_write(ice, tmp);
@@ -259,14 +277,16 @@ static void wm_put(struct snd_ice1712 *ice, int reg, unsigned short val)
ice->akm[0].images[reg + 1] = val;
}
-static void wm_set_vol(struct snd_ice1712 *ice, unsigned int index, unsigned short vol, unsigned short master)
+static void wm_set_vol(struct snd_ice1712 *ice, unsigned int index,
+ unsigned short vol, unsigned short master)
{
unsigned char nvol;
if ((master & WM_VOL_MUTE) || (vol & WM_VOL_MUTE))
nvol = 0;
else
- nvol = 127 - wm_vol[(((vol & ~WM_VOL_MUTE) * (master & ~WM_VOL_MUTE)) / 127) & WM_VOL_MAX];
+ nvol = 127 - wm_vol[(((vol & ~WM_VOL_MUTE) *
+ (master & ~WM_VOL_MUTE)) / 127) & WM_VOL_MAX];
wm_put(ice, index, nvol);
wm_put_nocache(ice, index, 0x180 | nvol);
@@ -277,17 +297,20 @@ static void wm_set_vol(struct snd_ice1712 *ice, unsigned int index, unsigned sho
*/
#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)
+static int wm_pcm_mute_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
mutex_lock(&ice->gpio_mutex);
- ucontrol->value.integer.value[0] = (wm_get(ice, WM_MUTE) & 0x10) ? 0 : 1;
+ ucontrol->value.integer.value[0] = (wm_get(ice, WM_MUTE) & 0x10) ?
+ 0 : 1;
mutex_unlock(&ice->gpio_mutex);
return 0;
}
-static int wm_pcm_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int wm_pcm_mute_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
unsigned short nval, oval;
@@ -296,7 +319,8 @@ static int wm_pcm_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_va
snd_ice1712_save_gpio_status(ice);
oval = wm_get(ice, WM_MUTE);
nval = (oval & ~0x10) | (ucontrol->value.integer.value[0] ? 0 : 0x10);
- if ((change = (nval != oval)))
+ change = (nval != oval);
+ if (change)
wm_put(ice, WM_MUTE, nval);
snd_ice1712_restore_gpio_status(ice);
@@ -306,7 +330,8 @@ static int wm_pcm_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_va
/*
* Master volume attenuation mixer control
*/
-static int wm_master_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
+static int wm_master_vol_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
{
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
uinfo->count = 2;
@@ -315,17 +340,20 @@ static int wm_master_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem
return 0;
}
-static int wm_master_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int wm_master_vol_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
struct phase28_spec *spec = ice->spec;
int i;
- for (i=0; i<2; i++)
- ucontrol->value.integer.value[i] = spec->master[i] & ~WM_VOL_MUTE;
+ for (i = 0; i < 2; i++)
+ ucontrol->value.integer.value[i] = spec->master[i] &
+ ~WM_VOL_MUTE;
return 0;
}
-static int wm_master_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int wm_master_vol_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
struct phase28_spec *spec = ice->spec;
@@ -355,38 +383,38 @@ static int __devinit phase28_init(struct snd_ice1712 *ice)
{
static const unsigned short wm_inits_phase28[] = {
/* These come first to reduce init pop noise */
- 0x1b, 0x044, /* ADC Mux (AC'97 source) */
- 0x1c, 0x00B, /* Out Mux1 (VOUT1 = DAC+AUX, VOUT2 = DAC) */
- 0x1d, 0x009, /* Out Mux2 (VOUT2 = DAC, VOUT3 = DAC) */
-
- 0x18, 0x000, /* All power-up */
-
- 0x16, 0x122, /* I2S, normal polarity, 24bit */
- 0x17, 0x022, /* 256fs, slave mode */
- 0x00, 0, /* DAC1 analog mute */
- 0x01, 0, /* DAC2 analog mute */
- 0x02, 0, /* DAC3 analog mute */
- 0x03, 0, /* DAC4 analog mute */
- 0x04, 0, /* DAC5 analog mute */
- 0x05, 0, /* DAC6 analog mute */
- 0x06, 0, /* DAC7 analog mute */
- 0x07, 0, /* DAC8 analog mute */
- 0x08, 0x100, /* master analog mute */
- 0x09, 0xff, /* DAC1 digital full */
- 0x0a, 0xff, /* DAC2 digital full */
- 0x0b, 0xff, /* DAC3 digital full */
- 0x0c, 0xff, /* DAC4 digital full */
- 0x0d, 0xff, /* DAC5 digital full */
- 0x0e, 0xff, /* DAC6 digital full */
- 0x0f, 0xff, /* DAC7 digital full */
- 0x10, 0xff, /* DAC8 digital full */
- 0x11, 0x1ff, /* master digital full */
- 0x12, 0x000, /* phase normal */
- 0x13, 0x090, /* unmute DAC L/R */
- 0x14, 0x000, /* all unmute */
- 0x15, 0x000, /* no deemphasis, no ZFLG */
- 0x19, 0x000, /* -12dB ADC/L */
- 0x1a, 0x000, /* -12dB ADC/R */
+ 0x1b, 0x044, /* ADC Mux (AC'97 source) */
+ 0x1c, 0x00B, /* Out Mux1 (VOUT1 = DAC+AUX, VOUT2 = DAC) */
+ 0x1d, 0x009, /* Out Mux2 (VOUT2 = DAC, VOUT3 = DAC) */
+
+ 0x18, 0x000, /* All power-up */
+
+ 0x16, 0x122, /* I2S, normal polarity, 24bit */
+ 0x17, 0x022, /* 256fs, slave mode */
+ 0x00, 0, /* DAC1 analog mute */
+ 0x01, 0, /* DAC2 analog mute */
+ 0x02, 0, /* DAC3 analog mute */
+ 0x03, 0, /* DAC4 analog mute */
+ 0x04, 0, /* DAC5 analog mute */
+ 0x05, 0, /* DAC6 analog mute */
+ 0x06, 0, /* DAC7 analog mute */
+ 0x07, 0, /* DAC8 analog mute */
+ 0x08, 0x100, /* master analog mute */
+ 0x09, 0xff, /* DAC1 digital full */
+ 0x0a, 0xff, /* DAC2 digital full */
+ 0x0b, 0xff, /* DAC3 digital full */
+ 0x0c, 0xff, /* DAC4 digital full */
+ 0x0d, 0xff, /* DAC5 digital full */
+ 0x0e, 0xff, /* DAC6 digital full */
+ 0x0f, 0xff, /* DAC7 digital full */
+ 0x10, 0xff, /* DAC8 digital full */
+ 0x11, 0x1ff, /* master digital full */
+ 0x12, 0x000, /* phase normal */
+ 0x13, 0x090, /* unmute DAC L/R */
+ 0x14, 0x000, /* all unmute */
+ 0x15, 0x000, /* no deemphasis, no ZFLG */
+ 0x19, 0x000, /* -12dB ADC/L */
+ 0x1a, 0x000, /* -12dB ADC/R */
(unsigned short)-1
};
@@ -404,17 +432,19 @@ static int __devinit phase28_init(struct snd_ice1712 *ice)
return -ENOMEM;
ice->spec = spec;
- // Initialize analog chips
- ak = ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
+ /* Initialize analog chips */
+ ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
+ ak = ice->akm;
if (!ak)
return -ENOMEM;
ice->akm_codecs = 1;
- snd_ice1712_gpio_set_dir(ice, 0x5fffff); /* fix this for the time being */
+ snd_ice1712_gpio_set_dir(ice, 0x5fffff); /* fix this for time being */
/* reset the wm codec as the SPI mode */
snd_ice1712_save_gpio_status(ice);
- snd_ice1712_gpio_set_mask(ice, ~(PHASE28_WM_RESET|PHASE28_WM_CS|PHASE28_HP_SEL));
+ snd_ice1712_gpio_set_mask(ice, ~(PHASE28_WM_RESET|PHASE28_WM_CS|
+ PHASE28_HP_SEL));
tmp = snd_ice1712_gpio_read(ice);
tmp &= ~PHASE28_WM_RESET;
@@ -446,7 +476,8 @@ static int __devinit phase28_init(struct snd_ice1712 *ice)
/*
* DAC volume attenuation mixer control
*/
-static int wm_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
+static int wm_vol_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
{
int voices = kcontrol->private_value >> 8;
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
@@ -456,7 +487,8 @@ static int wm_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *
return 0;
}
-static int wm_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int wm_vol_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
struct phase28_spec *spec = ice->spec;
@@ -470,7 +502,8 @@ static int wm_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *
return 0;
}
-static int wm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int wm_vol_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
struct phase28_spec *spec = ice->spec;
@@ -501,7 +534,8 @@ static int wm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *
/*
* WM8770 mute control
*/
-static int wm_mute_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) {
+static int wm_mute_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo) {
uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
uinfo->count = kcontrol->private_value >> 8;
uinfo->value.integer.min = 0;
@@ -509,7 +543,8 @@ static int wm_mute_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info
return 0;
}
-static int wm_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int wm_mute_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
struct phase28_spec *spec = ice->spec;
@@ -524,7 +559,8 @@ static int wm_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value
return 0;
}
-static int wm_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int wm_mute_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
struct phase28_spec *spec = ice->spec;
@@ -539,9 +575,10 @@ static int wm_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value
if (ucontrol->value.integer.value[i] != val) {
spec->vol[ofs + i] &= ~WM_VOL_MUTE;
spec->vol[ofs + i] |=
- ucontrol->value.integer.value[i] ? 0 : WM_VOL_MUTE;
+ ucontrol->value.integer.value[i] ? 0 :
+ WM_VOL_MUTE;
wm_set_vol(ice, ofs + i, spec->vol[ofs + i],
- spec->master[i]);
+ spec->master[i]);
change = 1;
}
}
@@ -555,7 +592,8 @@ static int wm_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value
*/
#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)
+static int wm_master_mute_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
struct phase28_spec *spec = ice->spec;
@@ -567,7 +605,8 @@ static int wm_master_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem
return 0;
}
-static int wm_master_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int wm_master_mute_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
struct phase28_spec *spec = ice->spec;
@@ -580,11 +619,12 @@ static int wm_master_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem
int dac;
spec->master[i] &= ~WM_VOL_MUTE;
spec->master[i] |=
- ucontrol->value.integer.value[i] ? 0 : WM_VOL_MUTE;
+ ucontrol->value.integer.value[i] ? 0 :
+ WM_VOL_MUTE;
for (dac = 0; dac < ice->num_total_dacs; dac += 2)
wm_set_vol(ice, WM_DAC_ATTEN + dac + i,
- spec->vol[dac + i],
- spec->master[i]);
+ spec->vol[dac + i],
+ spec->master[i]);
change = 1;
}
}
@@ -597,7 +637,8 @@ static int wm_master_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem
#define PCM_0dB 0xff
#define PCM_RES 128 /* -64dB */
#define PCM_MIN (PCM_0dB - PCM_RES)
-static int wm_pcm_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
+static int wm_pcm_vol_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
{
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
uinfo->count = 1;
@@ -606,7 +647,8 @@ static int wm_pcm_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_in
return 0;
}
-static int wm_pcm_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int wm_pcm_vol_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
unsigned short val;
@@ -619,7 +661,8 @@ static int wm_pcm_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val
return 0;
}
-static int wm_pcm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int wm_pcm_vol_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
unsigned short ovol, nvol;
@@ -633,7 +676,8 @@ static int wm_pcm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val
ovol = wm_get(ice, WM_DAC_DIG_MASTER_ATTEN) & 0xff;
if (ovol != nvol) {
wm_put(ice, WM_DAC_DIG_MASTER_ATTEN, nvol); /* prelatch */
- wm_put_nocache(ice, WM_DAC_DIG_MASTER_ATTEN, nvol | 0x100); /* update */
+ /* update */
+ wm_put_nocache(ice, WM_DAC_DIG_MASTER_ATTEN, nvol | 0x100);
change = 1;
}
snd_ice1712_restore_gpio_status(ice);
@@ -645,18 +689,22 @@ static int wm_pcm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val
*/
#define phase28_deemp_info snd_ctl_boolean_mono_info
-static int phase28_deemp_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int phase28_deemp_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- ucontrol->value.integer.value[0] = (wm_get(ice, WM_DAC_CTRL2) & 0xf) == 0xf;
+ ucontrol->value.integer.value[0] = (wm_get(ice, WM_DAC_CTRL2) & 0xf) ==
+ 0xf;
return 0;
}
-static int phase28_deemp_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int phase28_deemp_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
int temp, temp2;
- temp2 = temp = wm_get(ice, WM_DAC_CTRL2);
+ temp = wm_get(ice, WM_DAC_CTRL2);
+ temp2 = temp;
if (ucontrol->value.integer.value[0])
temp |= 0xf;
else
@@ -671,7 +719,8 @@ static int phase28_deemp_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_
/*
* ADC Oversampling
*/
-static int phase28_oversampling_info(struct snd_kcontrol *k, struct snd_ctl_elem_info *uinfo)
+static int phase28_oversampling_info(struct snd_kcontrol *k,
+ struct snd_ctl_elem_info *uinfo)
{
static char *texts[2] = { "128x", "64x" };
@@ -680,25 +729,31 @@ static int phase28_oversampling_info(struct snd_kcontrol *k, struct snd_ctl_elem
uinfo->value.enumerated.items = 2;
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]);
+ uinfo->value.enumerated.item = uinfo->value.enumerated.items -
+ 1;
+ strcpy(uinfo->value.enumerated.name,
+ texts[uinfo->value.enumerated.item]);
- return 0;
+ return 0;
}
-static int phase28_oversampling_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int phase28_oversampling_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- ucontrol->value.enumerated.item[0] = (wm_get(ice, WM_MASTER) & 0x8) == 0x8;
+ ucontrol->value.enumerated.item[0] = (wm_get(ice, WM_MASTER) & 0x8) ==
+ 0x8;
return 0;
}
-static int phase28_oversampling_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int phase28_oversampling_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
int temp, temp2;
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
- temp2 = temp = wm_get(ice, WM_MASTER);
+ temp = wm_get(ice, WM_MASTER);
+ temp2 = temp;
if (ucontrol->value.enumerated.item[0])
temp |= 0x8;
@@ -871,13 +926,16 @@ static int __devinit phase28_add_controls(struct snd_ice1712 *ice)
counts = ARRAY_SIZE(phase28_dac_controls);
for (i = 0; i < counts; i++) {
- err = snd_ctl_add(ice->card, snd_ctl_new1(&phase28_dac_controls[i], ice));
+ err = snd_ctl_add(ice->card,
+ snd_ctl_new1(&phase28_dac_controls[i],
+ ice));
if (err < 0)
return err;
}
for (i = 0; i < ARRAY_SIZE(wm_controls); i++) {
- err = snd_ctl_add(ice->card, snd_ctl_new1(&wm_controls[i], ice));
+ err = snd_ctl_add(ice->card,
+ snd_ctl_new1(&wm_controls[i], ice));
if (err < 0)
return err;
}
@@ -904,5 +962,14 @@ struct snd_ice1712_card_info snd_vt1724_phase_cards[] __devinitdata = {
.eeprom_size = sizeof(phase28_eeprom),
.eeprom_data = phase28_eeprom,
},
+ {
+ .subvendor = VT1724_SUBDEVICE_TS22,
+ .name = "Terrasoniq TS22 PCI",
+ .model = "TS22",
+ .chip_init = phase22_init,
+ .build_controls = phase22_add_controls,
+ .eeprom_size = sizeof(phase22_eeprom),
+ .eeprom_data = phase22_eeprom,
+ },
{ } /* terminator */
};
diff --git a/sound/pci/ice1712/phase.h b/sound/pci/ice1712/phase.h
index 13e841b55488..7fc22d9d442f 100644
--- a/sound/pci/ice1712/phase.h
+++ b/sound/pci/ice1712/phase.h
@@ -22,13 +22,15 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
- */
+ */
-#define PHASE_DEVICE_DESC "{Terratec,Phase 22},"\
- "{Terratec,Phase 28},"
+#define PHASE_DEVICE_DESC "{Terratec,Phase 22},"\
+ "{Terratec,Phase 28},"\
+ "{Terrasoniq,TS22},"
#define VT1724_SUBDEVICE_PHASE22 0x3b155011
#define VT1724_SUBDEVICE_PHASE28 0x3b154911
+#define VT1724_SUBDEVICE_TS22 0x3b157b11
/* entry point */
extern struct snd_ice1712_card_info snd_vt1724_phase_cards[];
diff --git a/sound/pci/ice1712/pontis.c b/sound/pci/ice1712/pontis.c
index 203cdc1bf8da..6bc3f91b7281 100644
--- a/sound/pci/ice1712/pontis.c
+++ b/sound/pci/ice1712/pontis.c
@@ -43,7 +43,8 @@
/* WM8776 registers */
#define WM_HP_ATTEN_L 0x00 /* headphone left attenuation */
#define WM_HP_ATTEN_R 0x01 /* headphone left attenuation */
-#define WM_HP_MASTER 0x02 /* headphone master (both channels), override LLR */
+#define WM_HP_MASTER 0x02 /* headphone master (both channels) */
+ /* override LLR */
#define WM_DAC_ATTEN_L 0x03 /* digital left attenuation */
#define WM_DAC_ATTEN_R 0x04
#define WM_DAC_MASTER 0x05
@@ -740,7 +741,7 @@ static int __devinit pontis_init(struct snd_ice1712 *ice)
WM_DAC_ATTEN_L, 0x0100, /* DAC 0dB */
WM_DAC_ATTEN_R, 0x0000, /* DAC 0dB */
WM_DAC_ATTEN_R, 0x0100, /* DAC 0dB */
- // WM_DAC_MASTER, 0x0100, /* DAC master muted */
+ /* WM_DAC_MASTER, 0x0100, */ /* DAC master muted */
WM_PHASE_SWAP, 0x0000, /* phase normal */
WM_DAC_CTRL2, 0x0000, /* no deemphasis, no ZFLG */
WM_ADC_ATTEN_L, 0x0000, /* ADC muted */
diff --git a/sound/pci/ice1712/revo.c b/sound/pci/ice1712/revo.c
index 4d2631434dc8..b508bb360b97 100644
--- a/sound/pci/ice1712/revo.c
+++ b/sound/pci/ice1712/revo.c
@@ -1,7 +1,7 @@
/*
* ALSA driver for ICEnsemble ICE1712 (Envy24)
*
- * Lowlevel functions for M-Audio Revolution 7.1
+ * Lowlevel functions for M-Audio Audiophile 192, Revolution 7.1 and 5.1
*
* Copyright (c) 2003 Takashi Iwai <tiwai@suse.de>
*
@@ -48,7 +48,7 @@ static void revo_i2s_mclk_changed(struct snd_ice1712 *ice)
}
/*
- * change the rate of envy24HT, AK4355 and AK4381
+ * change the rate of Envy24HT, AK4355 and AK4381
*/
static void revo_set_rate_val(struct snd_akm4xxx *ak, unsigned int rate)
{
@@ -83,8 +83,8 @@ static void revo_set_rate_val(struct snd_akm4xxx *ak, unsigned int rate)
tmp = snd_akm4xxx_get(ak, 0, reg);
tmp &= ~(0x03 << shift);
tmp |= dfs << shift;
- // snd_akm4xxx_write(ak, 0, reg, tmp);
- snd_akm4xxx_set(ak, 0, reg, tmp); /* the value is written in reset(0) */
+ /* snd_akm4xxx_write(ak, 0, reg, tmp); */
+ snd_akm4xxx_set(ak, 0, reg, tmp); /* value is written in reset(0) */
snd_akm4xxx_reset(ak, 0);
}
@@ -216,6 +216,7 @@ static const struct snd_akm4xxx_dac_channel revo51_dac[] = {
AK_DAC("PCM Center Playback Volume", 1),
AK_DAC("PCM LFE Playback Volume", 1),
AK_DAC("PCM Rear Playback Volume", 2),
+ AK_DAC("PCM Headphone Volume", 2),
};
static const char *revo51_adc_input_names[] = {
@@ -279,7 +280,7 @@ static struct snd_ak4xxx_private akm_revo_surround_priv __devinitdata = {
static struct snd_akm4xxx akm_revo51 __devinitdata = {
.type = SND_AK4358,
- .num_dacs = 6,
+ .num_dacs = 8,
.ops = {
.set_rate_val = revo_set_rate_val
},
@@ -508,7 +509,7 @@ static int __devinit revo_init(struct snd_ice1712 *ice)
ice->gpio.i2s_mclk_changed = revo_i2s_mclk_changed;
break;
case VT1724_SUBDEVICE_REVOLUTION51:
- ice->num_total_dacs = 6;
+ ice->num_total_dacs = 8;
ice->num_total_adcs = 2;
break;
case VT1724_SUBDEVICE_AUDIOPHILE192:
@@ -524,16 +525,20 @@ static int __devinit revo_init(struct snd_ice1712 *ice)
ak = ice->akm = kcalloc(2, sizeof(struct snd_akm4xxx), GFP_KERNEL);
if (! ak)
return -ENOMEM;
- ice->akm_codecs = 2;
switch (ice->eeprom.subvendor) {
case VT1724_SUBDEVICE_REVOLUTION71:
ice->akm_codecs = 2;
- if ((err = snd_ice1712_akm4xxx_init(ak, &akm_revo_front, &akm_revo_front_priv, ice)) < 0)
+ err = snd_ice1712_akm4xxx_init(ak, &akm_revo_front,
+ &akm_revo_front_priv, ice);
+ if (err < 0)
return err;
- if ((err = snd_ice1712_akm4xxx_init(ak + 1, &akm_revo_surround, &akm_revo_surround_priv, ice)) < 0)
+ err = snd_ice1712_akm4xxx_init(ak+1, &akm_revo_surround,
+ &akm_revo_surround_priv, ice);
+ if (err < 0)
return err;
/* unmute all codecs */
- snd_ice1712_gpio_write_bits(ice, VT1724_REVO_MUTE, VT1724_REVO_MUTE);
+ snd_ice1712_gpio_write_bits(ice, VT1724_REVO_MUTE,
+ VT1724_REVO_MUTE);
break;
case VT1724_SUBDEVICE_REVOLUTION51:
ice->akm_codecs = 2;
diff --git a/sound/pci/ice1712/wtm.c b/sound/pci/ice1712/wtm.c
index a08d17c7e651..5af9e84456d1 100644
--- a/sound/pci/ice1712/wtm.c
+++ b/sound/pci/ice1712/wtm.c
@@ -1,12 +1,12 @@
/*
* ALSA driver for ICEnsemble VT1724 (Envy24HT)
- *
+ *
* Lowlevel functions for Ego Sys Waveterminal 192M
*
* Copyright (c) 2006 Guedez Clement <klem.dev@gmail.com>
* Some functions are taken from the Prodigy192 driver
* source
- *
+ *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
@@ -20,12 +20,12 @@
* 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 <asm/io.h>
+#include <linux/io.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/init.h>
@@ -39,9 +39,9 @@
/*
- * 2*ADC 6*DAC no1 ringbuffer r/w on i2c bus
+ * 2*ADC 6*DAC no1 ringbuffer r/w on i2c bus
*/
-static inline void stac9460_put(struct snd_ice1712 *ice, int reg,
+static inline void stac9460_put(struct snd_ice1712 *ice, int reg,
unsigned char val)
{
snd_vt1724_write_i2c(ice, STAC9460_I2C_ADDR, reg, val);
@@ -73,7 +73,7 @@ static inline unsigned char stac9460_2_get(struct snd_ice1712 *ice, int reg)
#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)
+ struct snd_ctl_elem_value *ucontrol)
{
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
unsigned char val;
@@ -88,14 +88,14 @@ static int stac9460_dac_mute_get(struct snd_kcontrol *kcontrol,
}
if (id < 6)
val = stac9460_get(ice, idx);
- else
- val = stac9460_2_get(ice,idx - 6);
+ else
+ val = stac9460_2_get(ice, idx - 6);
ucontrol->value.integer.value[0] = (~val >> 7) & 0x1;
return 0;
}
static int stac9460_dac_mute_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
+ struct snd_ctl_elem_value *ucontrol)
{
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
unsigned char new, old;
@@ -105,8 +105,8 @@ static int stac9460_dac_mute_put(struct snd_kcontrol *kcontrol,
if (kcontrol->private_value) {
idx = STAC946X_MASTER_VOLUME;
old = stac9460_get(ice, idx);
- new = (~ucontrol->value.integer.value[0]<< 7 & 0x80) |
- (old & ~0x80);
+ new = (~ucontrol->value.integer.value[0] << 7 & 0x80) |
+ (old & ~0x80);
change = (new != old);
if (change) {
stac9460_put(ice, idx, new);
@@ -117,16 +117,16 @@ static int stac9460_dac_mute_put(struct snd_kcontrol *kcontrol,
idx = id + STAC946X_LF_VOLUME;
if (id < 6)
old = stac9460_get(ice, idx);
- else
+ else
old = stac9460_2_get(ice, idx - 6);
- new = (~ucontrol->value.integer.value[0]<< 7 & 0x80) |
+ new = (~ucontrol->value.integer.value[0] << 7 & 0x80) |
(old & ~0x80);
change = (new != old);
if (change) {
if (id < 6)
- stac9460_put(ice, idx, new);
+ stac9460_put(ice, idx, new);
else
- stac9460_2_put(ice, idx - 6, new);
+ stac9460_2_put(ice, idx - 6, new);
}
}
return change;
@@ -136,7 +136,7 @@ static int stac9460_dac_mute_put(struct snd_kcontrol *kcontrol,
* DAC volume attenuation mixer control
*/
static int stac9460_dac_vol_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
+ struct snd_ctl_elem_info *uinfo)
{
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
uinfo->count = 1;
@@ -146,7 +146,7 @@ static int stac9460_dac_vol_info(struct snd_kcontrol *kcontrol,
}
static int stac9460_dac_vol_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
+ struct snd_ctl_elem_value *ucontrol)
{
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
int idx, id;
@@ -161,14 +161,14 @@ static int stac9460_dac_vol_get(struct snd_kcontrol *kcontrol,
}
if (id < 6)
vol = stac9460_get(ice, idx) & 0x7f;
- else
+ else
vol = stac9460_2_get(ice, idx - 6) & 0x7f;
ucontrol->value.integer.value[0] = 0x7f - vol;
return 0;
}
static int stac9460_dac_vol_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
+ struct snd_ctl_elem_value *ucontrol)
{
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
int idx, id;
@@ -182,8 +182,8 @@ static int stac9460_dac_vol_put(struct snd_kcontrol *kcontrol,
ovol = 0x7f - (tmp & 0x7f);
change = (ovol != nvol);
if (change) {
- stac9460_put(ice, idx, (0x7f - nvol) | (tmp & 0x80));
- stac9460_2_put(ice, idx, (0x7f - nvol) | (tmp & 0x80));
+ stac9460_put(ice, idx, (0x7f - nvol) | (tmp & 0x80));
+ stac9460_2_put(ice, idx, (0x7f - nvol) | (tmp & 0x80));
}
} else {
id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
@@ -191,17 +191,17 @@ static int stac9460_dac_vol_put(struct snd_kcontrol *kcontrol,
nvol = ucontrol->value.integer.value[0] & 0x7f;
if (id < 6)
tmp = stac9460_get(ice, idx);
- else
+ else
tmp = stac9460_2_get(ice, idx - 6);
ovol = 0x7f - (tmp & 0x7f);
change = (ovol != nvol);
if (change) {
if (id < 6)
stac9460_put(ice, idx, (0x7f - nvol) |
- (tmp & 0x80));
- else
+ (tmp & 0x80));
+ else
stac9460_2_put(ice, idx-6, (0x7f - nvol) |
- (tmp & 0x80));
+ (tmp & 0x80));
}
}
return change;
@@ -213,12 +213,12 @@ static int stac9460_dac_vol_put(struct snd_kcontrol *kcontrol,
#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)
+ struct snd_ctl_elem_value *ucontrol)
{
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
unsigned char val;
int i, id;
-
+
id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
if (id == 0) {
for (i = 0; i < 2; ++i) {
@@ -235,20 +235,20 @@ static int stac9460_adc_mute_get(struct snd_kcontrol *kcontrol,
}
static int stac9460_adc_mute_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
+ struct snd_ctl_elem_value *ucontrol)
{
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
unsigned char new, old;
int i, reg, id;
int change;
-
+
id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
if (id == 0) {
for (i = 0; i < 2; ++i) {
reg = STAC946X_MIC_L_VOLUME + i;
old = stac9460_get(ice, reg);
new = (~ucontrol->value.integer.value[i]<<7&0x80) |
- (old&~0x80);
+ (old&~0x80);
change = (new != old);
if (change)
stac9460_put(ice, reg, new);
@@ -258,7 +258,7 @@ static int stac9460_adc_mute_put(struct snd_kcontrol *kcontrol,
reg = STAC946X_MIC_L_VOLUME + i;
old = stac9460_2_get(ice, reg);
new = (~ucontrol->value.integer.value[i]<<7&0x80) |
- (old&~0x80);
+ (old&~0x80);
change = (new != old);
if (change)
stac9460_2_put(ice, reg, new);
@@ -271,7 +271,7 @@ static int stac9460_adc_mute_put(struct snd_kcontrol *kcontrol,
*ADC gain mixer control
*/
static int stac9460_adc_vol_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
+ struct snd_ctl_elem_info *uinfo)
{
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
uinfo->count = 2;
@@ -281,12 +281,12 @@ static int stac9460_adc_vol_info(struct snd_kcontrol *kcontrol,
}
static int stac9460_adc_vol_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
+ struct snd_ctl_elem_value *ucontrol)
{
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
int i, reg, id;
unsigned char vol;
-
+
id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
if (id == 0) {
for (i = 0; i < 2; ++i) {
@@ -305,13 +305,13 @@ static int stac9460_adc_vol_get(struct snd_kcontrol *kcontrol,
}
static int stac9460_adc_vol_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
+ struct snd_ctl_elem_value *ucontrol)
{
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
int i, reg, id;
unsigned char ovol, nvol;
int change;
-
+
id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
if (id == 0) {
for (i = 0; i < 2; ++i) {
@@ -321,7 +321,7 @@ static int stac9460_adc_vol_put(struct snd_kcontrol *kcontrol,
change = ((ovol & 0x0f) != nvol);
if (change)
stac9460_put(ice, reg, (0x0f - nvol) |
- (ovol & ~0x0f));
+ (ovol & ~0x0f));
}
} else {
for (i = 0; i < 2; ++i) {
@@ -331,7 +331,7 @@ static int stac9460_adc_vol_put(struct snd_kcontrol *kcontrol,
change = ((ovol & 0x0f) != nvol);
if (change)
stac9460_2_put(ice, reg, (0x0f - nvol) |
- (ovol & ~0x0f));
+ (ovol & ~0x0f));
}
}
return change;
@@ -344,23 +344,23 @@ static int stac9460_adc_vol_put(struct snd_kcontrol *kcontrol,
#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)
+ struct snd_ctl_elem_value *ucontrol)
{
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
unsigned char val;
int id;
-
+
id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
if (id == 0)
- val = stac9460_get(ice, STAC946X_GENERAL_PURPOSE);
+ val = stac9460_get(ice, STAC946X_GENERAL_PURPOSE);
else
- val = stac9460_2_get(ice, STAC946X_GENERAL_PURPOSE);
+ val = stac9460_2_get(ice, STAC946X_GENERAL_PURPOSE);
ucontrol->value.integer.value[0] = ~val>>7 & 0x1;
return 0;
}
static int stac9460_mic_sw_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
+ struct snd_ctl_elem_value *ucontrol)
{
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
unsigned char new, old;
@@ -368,16 +368,16 @@ static int stac9460_mic_sw_put(struct snd_kcontrol *kcontrol,
id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
if (id == 0)
- old = stac9460_get(ice, STAC946X_GENERAL_PURPOSE);
+ old = stac9460_get(ice, STAC946X_GENERAL_PURPOSE);
else
- old = stac9460_2_get(ice, STAC946X_GENERAL_PURPOSE);
- new = (~ucontrol->value.integer.value[0]<< 7 & 0x80) | (old & ~0x80);
+ old = stac9460_2_get(ice, STAC946X_GENERAL_PURPOSE);
+ new = (~ucontrol->value.integer.value[0] << 7 & 0x80) | (old & ~0x80);
change = (new != old);
if (change) {
if (id == 0)
- stac9460_put(ice, STAC946X_GENERAL_PURPOSE, new);
+ stac9460_put(ice, STAC946X_GENERAL_PURPOSE, new);
else
- stac9460_2_put(ice, STAC946X_GENERAL_PURPOSE, new);
+ stac9460_2_put(ice, STAC946X_GENERAL_PURPOSE, new);
}
return change;
}
@@ -443,7 +443,7 @@ static struct snd_kcontrol_new stac9640_controls[] __devinitdata = {
.get = stac9460_adc_vol_get,
.put = stac9460_adc_vol_put,
- }
+ }
};
@@ -470,7 +470,7 @@ static int __devinit wtm_init(struct snd_ice1712 *ice)
(unsigned short)-1
};
unsigned short *p;
-
+
/*WTM 192M*/
ice->num_total_dacs = 8;
ice->num_total_adcs = 4;
diff --git a/sound/pci/ice1712/wtm.h b/sound/pci/ice1712/wtm.h
index 03a394e442f1..423c1a204c0b 100644
--- a/sound/pci/ice1712/wtm.h
+++ b/sound/pci/ice1712/wtm.h
@@ -10,8 +10,8 @@
*/
#define AK4114_ADDR 0x20 /*S/PDIF receiver*/
-#define STAC9460_I2C_ADDR 0x54 /* ADC*2 | DAC*6 */
-#define STAC9460_2_I2C_ADDR 0x56 /* ADC|DAC *2 */
+#define STAC9460_I2C_ADDR 0x54 /* ADC*2 | DAC*6 */
+#define STAC9460_2_I2C_ADDR 0x56 /* ADC|DAC *2 */
extern struct snd_ice1712_card_info snd_vt1724_wtm_cards[];
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c
index 048d99e25ab0..c88d1eace1c4 100644
--- a/sound/pci/intel8x0.c
+++ b/sound/pci/intel8x0.c
@@ -59,6 +59,12 @@ MODULE_SUPPORTED_DEVICE("{{Intel,82801AA-ICH},"
"{SiS,SI7012},"
"{NVidia,nForce Audio},"
"{NVidia,nForce2 Audio},"
+ "{NVidia,nForce3 Audio},"
+ "{NVidia,MCP04},"
+ "{NVidia,MCP501},"
+ "{NVidia,CK804},"
+ "{NVidia,CK8},"
+ "{NVidia,CK8S},"
"{AMD,AMD768},"
"{AMD,AMD8111},"
"{ALI,M5455}}");
@@ -77,7 +83,7 @@ MODULE_PARM_DESC(index, "Index value for Intel i8x0 soundcard.");
module_param(id, charp, 0444);
MODULE_PARM_DESC(id, "ID string for Intel i8x0 soundcard.");
module_param(ac97_clock, int, 0444);
-MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (0 = auto-detect).");
+MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (0 = whitelist + auto-detect, 1 = force autodetect).");
module_param(ac97_quirk, charp, 0444);
MODULE_PARM_DESC(ac97_quirk, "AC'97 workaround for strange hardware.");
module_param(buggy_semaphore, bool, 0444);
@@ -1957,6 +1963,12 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = {
},
{
.subvendor = 0x10cf,
+ .subdevice = 0x127d,
+ .name = "Fujitsu Lifebook P7010",
+ .type = AC97_TUNE_HP_ONLY
+ },
+ {
+ .subvendor = 0x10cf,
.subdevice = 0x127e,
.name = "Fujitsu Lifebook C1211D",
.type = AC97_TUNE_HP_ONLY
@@ -2132,8 +2144,8 @@ static int __devinit snd_intel8x0_mixer(struct intel8x0 *chip, int ac97_clock,
snd_intel8x0_codec_read_test(chip, codecs);
chip->ac97_sdin[codecs] =
igetbyte(chip, ICHREG(SDM)) & ICH_LDI_MASK;
- snd_assert(chip->ac97_sdin[codecs] < 3,
- chip->ac97_sdin[codecs] = 0);
+ if (snd_BUG_ON(chip->ac97_sdin[codecs] >= 3))
+ chip->ac97_sdin[codecs] = 0;
} else
chip->ac97_sdin[codecs] = i;
codecs++;
@@ -2686,6 +2698,28 @@ static void __devinit intel8x0_measure_ac97_clock(struct intel8x0 *chip)
snd_ac97_update_power(chip->ac97[0], AC97_PCM_FRONT_DAC_RATE, 0);
}
+static struct snd_pci_quirk intel8x0_clock_list[] __devinitdata = {
+ SND_PCI_QUIRK(0x0e11, 0x008a, "AD1885", 41000),
+ SND_PCI_QUIRK(0x1028, 0x00be, "AD1885", 44100),
+ SND_PCI_QUIRK(0x1028, 0x0177, "AD1980", 48000),
+ SND_PCI_QUIRK(0x1043, 0x80f3, "AD1985", 48000),
+ { } /* terminator */
+};
+
+static int __devinit intel8x0_in_clock_list(struct intel8x0 *chip)
+{
+ struct pci_dev *pci = chip->pci;
+ const struct snd_pci_quirk *wl;
+
+ wl = snd_pci_quirk_lookup(pci, intel8x0_clock_list);
+ if (!wl)
+ return 0;
+ printk(KERN_INFO "intel8x0: white list rate for %04x:%04x is %i\n",
+ pci->subsystem_vendor, pci->subsystem_device, wl->value);
+ chip->ac97_bus->clock = wl->value;
+ return 1;
+}
+
#ifdef CONFIG_PROC_FS
static void snd_intel8x0_proc_read(struct snd_info_entry * entry,
struct snd_info_buffer *buffer)
@@ -3081,8 +3115,14 @@ static int __devinit snd_intel8x0_probe(struct pci_dev *pci,
"%s with %s at irq %i", card->shortname,
snd_ac97_get_short_name(chip->ac97[0]), chip->irq);
- if (! ac97_clock)
- intel8x0_measure_ac97_clock(chip);
+ if (ac97_clock == 0 || ac97_clock == 1) {
+ if (ac97_clock == 0) {
+ if (intel8x0_in_clock_list(chip) == 0)
+ intel8x0_measure_ac97_clock(chip);
+ } else {
+ intel8x0_measure_ac97_clock(chip);
+ }
+ }
if ((err = snd_card_register(card)) < 0) {
snd_card_free(card);
diff --git a/sound/pci/intel8x0m.c b/sound/pci/intel8x0m.c
index faf674e671ac..93449e464566 100644
--- a/sound/pci/intel8x0m.c
+++ b/sound/pci/intel8x0m.c
@@ -306,7 +306,8 @@ static unsigned int get_ich_codec_bit(struct intel8x0m *chip, unsigned int codec
static unsigned int codec_bit[3] = {
ICH_PCR, ICH_SCR, ICH_TCR
};
- snd_assert(codec < 3, return ICH_PCR);
+ if (snd_BUG_ON(codec >= 3))
+ return ICH_PCR;
return codec_bit[codec];
}
diff --git a/sound/pci/korg1212/korg1212-firmware.h b/sound/pci/korg1212/korg1212-firmware.h
deleted file mode 100644
index f6f5b91806a8..000000000000
--- a/sound/pci/korg1212/korg1212-firmware.h
+++ /dev/null
@@ -1,987 +0,0 @@
-static char dspCode [] = {
-0x01,0xff,0x18,0xff,0xf5,0xff,0xcf,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
-0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
-0x26,0xff,0x18,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
-0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
-0x00,0xff,0x0a,0xff,0xff,0xff,0x1f,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
-0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
-0x00,0xff,0x0a,0xff,0xff,0xff,0x1f,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
-0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
-0x00,0xff,0x0a,0xff,0xff,0xff,0x1f,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
-0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
-0x38,0xff,0x18,0xff,0xff,0xff,0xdf,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
-0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
-0x00,0xff,0x0a,0xff,0xff,0xff,0x1f,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
-0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
-0x03,0xff,0x3c,0xff,0xff,0xff,0xfc,0xff,0x67,0xff,0x40,0xff,0xff,0xff,0xc0,0xff,
-0xff,0xff,0x93,0xff,0xff,0xff,0xe0,0xff,0x00,0xff,0x0c,0xff,0xff,0xff,0x0c,0xff,
-0x0c,0xff,0x0c,0xff,0xff,0xff,0x00,0xff,0x30,0xff,0x0c,0xff,0xff,0xff,0x00,0xff,
-0x0f,0xff,0x40,0xff,0xff,0xff,0xf4,0xff,0x47,0xff,0x80,0xff,0xff,0xff,0x0a,0xff,
-0x82,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x8d,0xff,0x93,0xff,0xff,0xff,0x7a,0xff,
-0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,0x47,0xff,0x90,0xff,0xff,0xff,0x00,0xff,
-0x00,0xff,0x48,0xff,0xff,0xff,0x04,0xff,0xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,
-0x46,0xff,0x90,0xff,0xff,0xff,0x6a,0xff,0x00,0xff,0x0c,0xff,0xff,0xff,0x20,0xff,
-0x00,0xff,0x04,0xff,0xff,0xff,0x1c,0xff,0x00,0xff,0x04,0xff,0xff,0xff,0x1c,0xff,
-0x00,0xff,0x04,0xff,0xff,0xff,0x1c,0xff,0x00,0xff,0x04,0xff,0xff,0xff,0x1c,0xff,
-0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,
-0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,
-0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,
-0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,
-0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,
-0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,
-0x72,0xff,0x1c,0xff,0xff,0xff,0x5f,0xff,0x02,0xff,0x40,0xff,0xff,0xff,0x40,0xff,
-0x11,0xff,0x90,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x48,0xff,0xff,0xff,0x00,0xff,
-0x8b,0xff,0x93,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x00,0xff,
-0x86,0xff,0x93,0xff,0xff,0xff,0x70,0xff,0x8b,0xff,0x93,0xff,0xff,0xff,0x30,0xff,
-0x8d,0xff,0x93,0xff,0xff,0xff,0x40,0xff,0x02,0xff,0x91,0xff,0xff,0xff,0x80,0xff,
-0x02,0xff,0x91,0xff,0xff,0xff,0x90,0xff,0x8d,0xff,0x93,0xff,0xff,0xff,0xc0,0xff,
-0x46,0xff,0x90,0xff,0xff,0xff,0x20,0xff,0x8d,0xff,0x93,0xff,0xff,0xff,0xd0,0xff,
-0x00,0xff,0x48,0xff,0xff,0xff,0x00,0xff,0x8b,0xff,0x93,0xff,0xff,0xff,0x40,0xff,
-0xff,0xff,0x47,0xff,0xff,0xff,0xf0,0xff,0x8d,0xff,0x93,0xff,0xff,0xff,0xe0,0xff,
-0x00,0xff,0x34,0xff,0xff,0xff,0x17,0xff,0x00,0xff,0x38,0xff,0xff,0xff,0x17,0xff,
-0x80,0xff,0x37,0xff,0xff,0xff,0x02,0xff,0x84,0xff,0x3b,0xff,0xff,0xff,0x02,0xff,
-0x02,0xff,0x34,0xff,0xff,0xff,0x4a,0xff,0x02,0xff,0x38,0xff,0xff,0xff,0x4a,0xff,
-0x01,0xff,0x34,0xff,0xff,0xff,0x2b,0xff,0x01,0xff,0x38,0xff,0xff,0xff,0x2b,0xff,
-0x80,0xff,0x43,0xff,0xff,0xff,0x00,0xff,0x82,0xff,0x93,0xff,0xff,0xff,0x50,0xff,
-0x81,0xff,0x43,0xff,0xff,0xff,0x20,0xff,0x82,0xff,0x93,0xff,0xff,0xff,0x60,0xff,
-0x84,0xff,0x43,0xff,0xff,0xff,0x00,0xff,0x82,0xff,0x93,0xff,0xff,0xff,0x70,0xff,
-0x85,0xff,0x43,0xff,0xff,0xff,0x20,0xff,0x83,0xff,0x93,0xff,0xff,0xff,0xc0,0xff,
-0x82,0xff,0x37,0xff,0xff,0xff,0x81,0xff,0x00,0xff,0x34,0xff,0xff,0xff,0x89,0xff,
-0x88,0xff,0x43,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x68,0xff,0xff,0xff,0x07,0xff,
-0x82,0xff,0x83,0xff,0xff,0xff,0x60,0xff,0x00,0xff,0x68,0xff,0xff,0xff,0x07,0xff,
-0x8c,0xff,0x43,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x68,0xff,0xff,0xff,0x07,0xff,
-0x83,0xff,0x83,0xff,0xff,0xff,0xc0,0xff,0x00,0xff,0x68,0xff,0xff,0xff,0x07,0xff,
-0x8a,0xff,0x43,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x68,0xff,0xff,0xff,0x07,0xff,
-0x82,0xff,0x83,0xff,0xff,0xff,0x50,0xff,0x00,0xff,0x68,0xff,0xff,0xff,0x07,0xff,
-0x8e,0xff,0x43,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x68,0xff,0xff,0xff,0x07,0xff,
-0x82,0xff,0x83,0xff,0xff,0xff,0x70,0xff,0x00,0xff,0x68,0xff,0xff,0xff,0x07,0xff,
-0x83,0xff,0x37,0xff,0xff,0xff,0x01,0xff,0x00,0xff,0x34,0xff,0xff,0xff,0x89,0xff,
-0x00,0xff,0x34,0xff,0xff,0xff,0x26,0xff,0x30,0xff,0x0c,0xff,0xff,0xff,0x00,0xff,
-0x00,0xff,0x40,0xff,0xff,0xff,0x26,0xff,0x20,0xff,0x40,0xff,0xff,0xff,0x04,0xff,
-0x80,0xff,0x41,0xff,0xff,0xff,0x02,0xff,0xe0,0xff,0x20,0xff,0xff,0xff,0x0f,0xff,
-0x00,0xff,0x68,0xff,0xff,0xff,0xb6,0xff,0x63,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,
-0x62,0xff,0x6a,0xff,0xff,0xff,0xa6,0xff,0x62,0xff,0x6a,0xff,0xff,0xff,0xa6,0xff,
-0x00,0xff,0x68,0xff,0xff,0xff,0xa6,0xff,0x00,0xff,0x09,0xff,0xff,0xff,0x07,0xff,
-0x40,0xff,0x41,0xff,0xff,0xff,0x02,0xff,0xe0,0xff,0x20,0xff,0xff,0xff,0x0f,0xff,
-0x00,0xff,0x68,0xff,0xff,0xff,0xb6,0xff,0x63,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,
-0x62,0xff,0x6a,0xff,0xff,0xff,0xa6,0xff,0x62,0xff,0x6a,0xff,0xff,0xff,0xa6,0xff,
-0x00,0xff,0x68,0xff,0xff,0xff,0xa6,0xff,0x05,0xff,0x41,0xff,0xff,0xff,0x02,0xff,
-0xe0,0xff,0x20,0xff,0xff,0xff,0x0f,0xff,0x8b,0xff,0x93,0xff,0xff,0xff,0xbb,0xff,
-0x02,0xff,0x41,0xff,0xff,0xff,0x82,0xff,0xe0,0xff,0x20,0xff,0xff,0xff,0x0f,0xff,
-0x8b,0xff,0x93,0xff,0xff,0xff,0xcb,0xff,0x05,0xff,0x41,0xff,0xff,0xff,0xe2,0xff,
-0xe0,0xff,0x20,0xff,0xff,0xff,0x0f,0xff,0x8b,0xff,0x93,0xff,0xff,0xff,0xdb,0xff,
-0x20,0xff,0x0c,0xff,0xff,0xff,0x00,0xff,0x30,0xff,0x0c,0xff,0xff,0xff,0x00,0xff,
-0x00,0xff,0x40,0xff,0xff,0xff,0x26,0xff,0x00,0xff,0x41,0xff,0xff,0xff,0x02,0xff,
-0xe0,0xff,0x20,0xff,0xff,0xff,0x0f,0xff,0x83,0xff,0x93,0xff,0xff,0xff,0x82,0xff,
-0x83,0xff,0x93,0xff,0xff,0xff,0x9b,0xff,0x03,0xff,0x41,0xff,0xff,0xff,0x02,0xff,
-0xe0,0xff,0x20,0xff,0xff,0xff,0x0f,0xff,0x83,0xff,0x93,0xff,0xff,0xff,0xa2,0xff,
-0x83,0xff,0x93,0xff,0xff,0xff,0xbb,0xff,0x20,0xff,0x0c,0xff,0xff,0xff,0x00,0xff,
-0x00,0xff,0x40,0xff,0xff,0xff,0x00,0xff,0x44,0xff,0x90,0xff,0xff,0xff,0x60,0xff,
-0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
-0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
-0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
-0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
-0x21,0xff,0x40,0xff,0xff,0xff,0x60,0xff,0x40,0xff,0x90,0xff,0xff,0xff,0x20,0xff,
-0x02,0xff,0x35,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x34,0xff,0xff,0xff,0x08,0xff,
-0x00,0xff,0x3c,0xff,0xff,0xff,0x85,0xff,0x0a,0xff,0x14,0xff,0xff,0xff,0xae,0xff,
-0x00,0xff,0xa0,0xff,0xff,0xff,0x03,0xff,0x00,0xff,0x35,0xff,0xff,0xff,0x00,0xff,
-0x00,0xff,0x34,0xff,0xff,0xff,0x08,0xff,0x02,0xff,0x3c,0xff,0xff,0xff,0x05,0xff,
-0x0a,0xff,0x14,0xff,0xff,0xff,0xfe,0xff,0x00,0xff,0xa0,0xff,0xff,0xff,0x03,0xff,
-0x03,0xff,0x35,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x34,0xff,0xff,0xff,0x08,0xff,
-0x02,0xff,0x3c,0xff,0xff,0xff,0x05,0xff,0x0b,0xff,0x14,0xff,0xff,0xff,0x4e,0xff,
-0x00,0xff,0xa0,0xff,0xff,0xff,0x03,0xff,0x00,0xff,0x35,0xff,0xff,0xff,0x01,0xff,
-0x78,0xff,0x1c,0xff,0xff,0xff,0x5f,0xff,0x03,0xff,0x35,0xff,0xff,0xff,0x01,0xff,
-0x78,0xff,0x1c,0xff,0xff,0xff,0x5f,0xff,0x5b,0xff,0x40,0xff,0xff,0xff,0xf0,0xff,
-0xff,0xff,0x93,0xff,0xff,0xff,0x30,0xff,0x80,0xff,0x42,0xff,0xff,0xff,0x70,0xff,
-0xff,0xff,0x93,0xff,0xff,0xff,0x60,0xff,0xdf,0xff,0x40,0xff,0xff,0xff,0xf0,0xff,
-0xfe,0xff,0x93,0xff,0xff,0xff,0xf0,0xff,0x80,0xff,0x42,0xff,0xff,0xff,0x70,0xff,
-0xff,0xff,0x93,0xff,0xff,0xff,0x20,0xff,0xc1,0xff,0x41,0xff,0xff,0xff,0x80,0xff,
-0xff,0xff,0x93,0xff,0xff,0xff,0xf0,0xff,0x03,0xff,0x3c,0xff,0xff,0xff,0xfc,0xff,
-0x00,0xff,0x3c,0xff,0xff,0xff,0x04,0xff,0x02,0xff,0x3c,0xff,0xff,0xff,0x23,0xff,
-0x00,0xff,0x48,0xff,0xff,0xff,0x00,0xff,0x8b,0xff,0x93,0xff,0xff,0xff,0x20,0xff,
-0x59,0xff,0x18,0xff,0xff,0xff,0xdf,0xff,0x00,0xff,0x48,0xff,0xff,0xff,0x00,0xff,
-0x8b,0xff,0x93,0xff,0xff,0xff,0x20,0xff,0x18,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,
-0x0c,0xff,0x14,0xff,0xff,0xff,0xe4,0xff,0x8b,0xff,0x83,0xff,0xff,0xff,0x24,0xff,
-0x00,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x0d,0xff,0x18,0xff,0xff,0xff,0x0f,0xff,
-0x8b,0xff,0x83,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x14,0xff,
-0xe0,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x10,0xff,0x18,0xff,0xff,0xff,0xd0,0xff,
-0x8b,0xff,0x83,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x24,0xff,
-0xe0,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x10,0xff,0x18,0xff,0xff,0xff,0x30,0xff,
-0x8b,0xff,0x83,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x44,0xff,
-0xe0,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x22,0xff,0x18,0xff,0xff,0xff,0x90,0xff,
-0x8b,0xff,0x83,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x84,0xff,
-0xe0,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x22,0xff,0x18,0xff,0xff,0xff,0x90,0xff,
-0x0c,0xff,0x18,0xff,0xff,0xff,0x6f,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x00,0xff,
-0x86,0xff,0x93,0xff,0xff,0xff,0x70,0xff,0x76,0xff,0x1c,0xff,0xff,0xff,0x9f,0xff,
-0x86,0xff,0x83,0xff,0xff,0xff,0x50,0xff,0x86,0xff,0x83,0xff,0xff,0xff,0x64,0xff,
-0x60,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x74,0xff,0x18,0xff,0xff,0xff,0x81,0xff,
-0x00,0xff,0x35,0xff,0xff,0xff,0x00,0xff,0x60,0xff,0x1c,0xff,0xff,0xff,0x7f,0xff,
-0x61,0xff,0x1c,0xff,0xff,0xff,0xaf,0xff,0x77,0xff,0x1c,0xff,0xff,0xff,0xaf,0xff,
-0x63,0xff,0x1c,0xff,0xff,0xff,0x4f,0xff,0x05,0xff,0x35,0xff,0xff,0xff,0x00,0xff,
-0x92,0xff,0x3b,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x34,0xff,0xff,0xff,0x08,0xff,
-0x00,0xff,0x38,0xff,0xff,0xff,0x08,0xff,0x00,0xff,0x3c,0xff,0xff,0xff,0x65,0xff,
-0x0f,0xff,0x14,0xff,0xff,0xff,0x6e,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x03,0xff,
-0x00,0xff,0x60,0xff,0xff,0xff,0x13,0xff,0x00,0xff,0x78,0xff,0xff,0xff,0x13,0xff,
-0x00,0xff,0x78,0xff,0xff,0xff,0x03,0xff,0x05,0xff,0x35,0xff,0xff,0xff,0xe0,0xff,
-0x7f,0xff,0x38,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x34,0xff,0xff,0xff,0x08,0xff,
-0x00,0xff,0x38,0xff,0xff,0xff,0x08,0xff,0x00,0xff,0x3c,0xff,0xff,0xff,0x65,0xff,
-0x10,0xff,0x14,0xff,0xff,0xff,0x0e,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x03,0xff,
-0x00,0xff,0x60,0xff,0xff,0xff,0x13,0xff,0x00,0xff,0x58,0xff,0xff,0xff,0x13,0xff,
-0x00,0xff,0x58,0xff,0xff,0xff,0x03,0xff,0x79,0xff,0x1c,0xff,0xff,0xff,0xff,0xff,
-0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,0x0e,0xff,0x1c,0xff,0xff,0xff,0x1f,0xff,
-0x8d,0xff,0x83,0xff,0xff,0xff,0xe0,0xff,0x78,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,
-0x15,0xff,0x1c,0xff,0xff,0xff,0x85,0xff,0x75,0xff,0x1c,0xff,0xff,0xff,0x8f,0xff,
-0x00,0xff,0x40,0xff,0xff,0xff,0x40,0xff,0x8b,0xff,0x93,0xff,0xff,0xff,0x80,0xff,
-0x02,0xff,0x40,0xff,0xff,0xff,0x60,0xff,0x11,0xff,0x90,0xff,0xff,0xff,0x20,0xff,
-0x16,0xff,0x18,0xff,0xff,0xff,0x1f,0xff,0x0e,0xff,0x1c,0xff,0xff,0xff,0x1f,0xff,
-0x75,0xff,0x1c,0xff,0xff,0xff,0x8f,0xff,0x80,0xff,0x35,0xff,0xff,0xff,0x00,0xff,
-0x00,0xff,0x34,0xff,0xff,0xff,0x08,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x00,0xff,
-0x40,0xff,0x3c,0xff,0xff,0xff,0x05,0xff,0x11,0xff,0x14,0xff,0xff,0xff,0x4e,0xff,
-0x00,0xff,0x68,0xff,0xff,0xff,0x03,0xff,0x87,0xff,0x83,0xff,0xff,0xff,0xf0,0xff,
-0x86,0xff,0x93,0xff,0xff,0xff,0x80,0xff,0x90,0xff,0x37,0xff,0xff,0xff,0x00,0xff,
-0x02,0xff,0x34,0xff,0xff,0xff,0x08,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x03,0xff,
-0x89,0xff,0x93,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x03,0xff,
-0x89,0xff,0x93,0xff,0xff,0xff,0x30,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x03,0xff,
-0x89,0xff,0x93,0xff,0xff,0xff,0x40,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x03,0xff,
-0x89,0xff,0x93,0xff,0xff,0xff,0x50,0xff,0x86,0xff,0x97,0xff,0xff,0xff,0x90,0xff,
-0x03,0xff,0x35,0xff,0xff,0xff,0x00,0xff,0x60,0xff,0x1c,0xff,0xff,0xff,0x7f,0xff,
-0x63,0xff,0x1c,0xff,0xff,0xff,0x7f,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x00,0xff,
-0x8d,0xff,0x93,0xff,0xff,0xff,0x60,0xff,0x82,0xff,0x93,0xff,0xff,0xff,0x40,0xff,
-0x86,0xff,0x93,0xff,0xff,0xff,0xa0,0xff,0x83,0xff,0x37,0xff,0xff,0xff,0x80,0xff,
-0x75,0xff,0x1c,0xff,0xff,0xff,0x1f,0xff,0x83,0xff,0x43,0xff,0xff,0xff,0x00,0xff,
-0x87,0xff,0x93,0xff,0xff,0xff,0xe0,0xff,0x6a,0xff,0x1c,0xff,0xff,0xff,0x0f,0xff,
-0x40,0xff,0x41,0xff,0xff,0xff,0x00,0xff,0x8b,0xff,0x93,0xff,0xff,0xff,0x90,0xff,
-0x80,0xff,0x41,0xff,0xff,0xff,0x00,0xff,0x8b,0xff,0x93,0xff,0xff,0xff,0xa0,0xff,
-0x8b,0xff,0x87,0xff,0xff,0xff,0x90,0xff,0x7e,0xff,0x38,0xff,0xff,0xff,0x00,0xff,
-0x40,0xff,0x34,0xff,0xff,0xff,0x08,0xff,0x00,0xff,0x38,0xff,0xff,0xff,0x08,0xff,
-0x00,0xff,0x3c,0xff,0xff,0xff,0x55,0xff,0x13,0xff,0x14,0xff,0xff,0xff,0xbe,0xff,
-0x00,0xff,0x60,0xff,0xff,0xff,0x03,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x13,0xff,
-0x00,0xff,0x58,0xff,0xff,0xff,0x13,0xff,0x00,0xff,0x58,0xff,0xff,0xff,0x03,0xff,
-0x00,0xff,0x60,0xff,0xff,0xff,0x03,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x13,0xff,
-0x00,0xff,0x58,0xff,0xff,0xff,0x13,0xff,0x00,0xff,0x58,0xff,0xff,0xff,0x03,0xff,
-0x00,0xff,0x60,0xff,0xff,0xff,0x03,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x13,0xff,
-0x00,0xff,0x58,0xff,0xff,0xff,0x13,0xff,0x00,0xff,0x58,0xff,0xff,0xff,0x03,0xff,
-0x00,0xff,0x60,0xff,0xff,0xff,0x03,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x03,0xff,
-0x8b,0xff,0x97,0xff,0xff,0xff,0x90,0xff,0x05,0xff,0x41,0xff,0xff,0xff,0x00,0xff,
-0x92,0xff,0x43,0xff,0xff,0xff,0x01,0xff,0x86,0xff,0x93,0xff,0xff,0xff,0xf0,0xff,
-0x86,0xff,0x93,0xff,0xff,0xff,0xe1,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0xe0,0xff,
-0x78,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x15,0xff,0x1c,0xff,0xff,0xff,0x85,0xff,
-0x75,0xff,0x1c,0xff,0xff,0xff,0x8f,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0x40,0xff,
-0x78,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x53,0xff,0x18,0xff,0xff,0xff,0xb4,0xff,
-0x72,0xff,0x1c,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x00,0xff,
-0x8b,0xff,0x93,0xff,0xff,0xff,0x30,0xff,0x02,0xff,0x40,0xff,0xff,0xff,0x60,0xff,
-0x11,0xff,0x90,0xff,0xff,0xff,0x20,0xff,0x16,0xff,0x18,0xff,0xff,0xff,0x4f,0xff,
-0x38,0xff,0x42,0xff,0xff,0xff,0x50,0xff,0x48,0xff,0x90,0xff,0xff,0xff,0xa0,0xff,
-0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
-0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
-0x30,0xff,0x40,0xff,0xff,0xff,0x00,0xff,0x47,0xff,0x90,0xff,0xff,0xff,0x50,0xff,
-0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,0x1e,0xff,0x1c,0xff,0xff,0xff,0x0f,0xff,
-0x20,0xff,0x1c,0xff,0xff,0xff,0xcf,0xff,0x16,0xff,0x18,0xff,0xff,0xff,0x1f,0xff,
-0x00,0xff,0x40,0xff,0xff,0xff,0x00,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x70,0xff,
-0x18,0xff,0x1c,0xff,0xff,0xff,0xef,0xff,0x6a,0xff,0x1c,0xff,0xff,0xff,0xbf,0xff,
-0x5c,0xff,0x1c,0xff,0xff,0xff,0x7f,0xff,0x18,0xff,0x1c,0xff,0xff,0xff,0xef,0xff,
-0x67,0xff,0x1c,0xff,0xff,0xff,0x3f,0xff,0x5c,0xff,0x1c,0xff,0xff,0xff,0x7f,0xff,
-0x08,0xff,0x40,0xff,0xff,0xff,0x00,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x70,0xff,
-0x18,0xff,0x1c,0xff,0xff,0xff,0xef,0xff,0x69,0xff,0x1c,0xff,0xff,0xff,0x0f,0xff,
-0x5d,0xff,0x1c,0xff,0xff,0xff,0x2f,0xff,0x18,0xff,0x1c,0xff,0xff,0xff,0xef,0xff,
-0x79,0xff,0x1c,0xff,0xff,0xff,0x1f,0xff,0x5c,0xff,0x1c,0xff,0xff,0xff,0x7f,0xff,
-0x18,0xff,0x1c,0xff,0xff,0xff,0xef,0xff,0x5c,0xff,0x1c,0xff,0xff,0xff,0x7f,0xff,
-0x18,0xff,0x1c,0xff,0xff,0xff,0xef,0xff,0x5c,0xff,0x1c,0xff,0xff,0xff,0x7f,0xff,
-0x18,0xff,0x1c,0xff,0xff,0xff,0xef,0xff,0x5d,0xff,0x1c,0xff,0xff,0xff,0x2f,0xff,
-0x18,0xff,0x1c,0xff,0xff,0xff,0xef,0xff,0x5c,0xff,0x1c,0xff,0xff,0xff,0x7f,0xff,
-0x18,0xff,0x1c,0xff,0xff,0xff,0xef,0xff,0x5c,0xff,0x1c,0xff,0xff,0xff,0x7f,0xff,
-0x18,0xff,0x1c,0xff,0xff,0xff,0xef,0xff,0x5c,0xff,0x1c,0xff,0xff,0xff,0x7f,0xff,
-0x18,0xff,0x1c,0xff,0xff,0xff,0xef,0xff,0x5d,0xff,0x1c,0xff,0xff,0xff,0x2f,0xff,
-0x18,0xff,0x1c,0xff,0xff,0xff,0xef,0xff,0x5c,0xff,0x1c,0xff,0xff,0xff,0x7f,0xff,
-0x18,0xff,0x1c,0xff,0xff,0xff,0xef,0xff,0x5c,0xff,0x1c,0xff,0xff,0xff,0x7f,0xff,
-0x18,0xff,0x1c,0xff,0xff,0xff,0xef,0xff,0x5c,0xff,0x1c,0xff,0xff,0xff,0x7f,0xff,
-0x18,0xff,0x1c,0xff,0xff,0xff,0xef,0xff,0x5d,0xff,0x1c,0xff,0xff,0xff,0x2f,0xff,
-0x18,0xff,0x1c,0xff,0xff,0xff,0xef,0xff,0x66,0xff,0x1c,0xff,0xff,0xff,0x1f,0xff,
-0x5c,0xff,0x1c,0xff,0xff,0xff,0x7f,0xff,0x16,0xff,0x18,0xff,0xff,0xff,0x4f,0xff,
-0x8b,0xff,0x87,0xff,0xff,0xff,0x61,0xff,0x00,0xff,0x34,0xff,0xff,0xff,0x89,0xff,
-0x00,0xff,0x34,0xff,0xff,0xff,0x26,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x06,0xff,
-0x83,0xff,0x93,0xff,0xff,0xff,0xd0,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x06,0xff,
-0x83,0xff,0x93,0xff,0xff,0xff,0xe0,0xff,0x38,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,
-0x19,0xff,0x14,0xff,0xff,0xff,0x85,0xff,0x8b,0xff,0x83,0xff,0xff,0xff,0x50,0xff,
-0x78,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x07,0xff,
-0x04,0xff,0x0d,0xff,0xff,0xff,0x30,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x07,0xff,
-0x83,0xff,0x93,0xff,0xff,0xff,0xf0,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x07,0xff,
-0x08,0xff,0x0d,0xff,0xff,0xff,0x30,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x07,0xff,
-0x86,0xff,0x93,0xff,0xff,0xff,0x40,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x01,0xff,
-0x8b,0xff,0x93,0xff,0xff,0xff,0x51,0xff,0x00,0xff,0x34,0xff,0xff,0xff,0x46,0xff,
-0x00,0xff,0x09,0xff,0xff,0xff,0x06,0xff,0x8b,0xff,0x97,0xff,0xff,0xff,0x61,0xff,
-0x83,0xff,0x8b,0xff,0xff,0xff,0xd0,0xff,0x83,0xff,0x8b,0xff,0xff,0xff,0xe1,0xff,
-0x87,0xff,0x37,0xff,0xff,0xff,0x01,0xff,0x6e,0xff,0x1c,0xff,0xff,0xff,0xbf,0xff,
-0x87,0xff,0x37,0xff,0xff,0xff,0x00,0xff,0x92,0xff,0x37,0xff,0xff,0xff,0x01,0xff,
-0x7f,0xff,0x38,0xff,0xff,0xff,0x00,0xff,0x7e,0xff,0x38,0xff,0xff,0xff,0x01,0xff,
-0x23,0xff,0x1c,0xff,0xff,0xff,0xff,0xff,0x7e,0xff,0x38,0xff,0xff,0xff,0x00,0xff,
-0x83,0xff,0x87,0xff,0xff,0xff,0xf1,0xff,0x86,0xff,0x8b,0xff,0xff,0xff,0x41,0xff,
-0x6c,0xff,0x1c,0xff,0xff,0xff,0x2f,0xff,0x87,0xff,0x37,0xff,0xff,0xff,0x00,0xff,
-0x8b,0xff,0x8b,0xff,0xff,0xff,0xa0,0xff,0x00,0xff,0x34,0xff,0xff,0xff,0x08,0xff,
-0x40,0xff,0x38,0xff,0xff,0xff,0x08,0xff,0x00,0xff,0x3c,0xff,0xff,0xff,0x55,0xff,
-0x1b,0xff,0x14,0xff,0xff,0xff,0xce,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x03,0xff,
-0x00,0xff,0x60,0xff,0xff,0xff,0x13,0xff,0x00,0xff,0x78,0xff,0xff,0xff,0x13,0xff,
-0x00,0xff,0x78,0xff,0xff,0xff,0x03,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x03,0xff,
-0x00,0xff,0x60,0xff,0xff,0xff,0x13,0xff,0x00,0xff,0x78,0xff,0xff,0xff,0x13,0xff,
-0x00,0xff,0x78,0xff,0xff,0xff,0x03,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x03,0xff,
-0x00,0xff,0x60,0xff,0xff,0xff,0x13,0xff,0x00,0xff,0x78,0xff,0xff,0xff,0x13,0xff,
-0x00,0xff,0x78,0xff,0xff,0xff,0x03,0xff,0x8b,0xff,0x83,0xff,0xff,0xff,0xe1,0xff,
-0x8b,0xff,0x83,0xff,0xff,0xff,0xf0,0xff,0x00,0xff,0x78,0xff,0xff,0xff,0x13,0xff,
-0x00,0xff,0x78,0xff,0xff,0xff,0x03,0xff,0x8b,0xff,0x9b,0xff,0xff,0xff,0xa0,0xff,
-0x8b,0xff,0x87,0xff,0xff,0xff,0x90,0xff,0x7e,0xff,0x38,0xff,0xff,0xff,0x00,0xff,
-0x40,0xff,0x34,0xff,0xff,0xff,0x08,0xff,0x00,0xff,0x38,0xff,0xff,0xff,0x08,0xff,
-0x00,0xff,0x3c,0xff,0xff,0xff,0x55,0xff,0x1d,0xff,0x14,0xff,0xff,0xff,0x3e,0xff,
-0x00,0xff,0x60,0xff,0xff,0xff,0x03,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x13,0xff,
-0x00,0xff,0x58,0xff,0xff,0xff,0x13,0xff,0x00,0xff,0x58,0xff,0xff,0xff,0x03,0xff,
-0x00,0xff,0x60,0xff,0xff,0xff,0x03,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x13,0xff,
-0x00,0xff,0x58,0xff,0xff,0xff,0x13,0xff,0x00,0xff,0x58,0xff,0xff,0xff,0x03,0xff,
-0x00,0xff,0x60,0xff,0xff,0xff,0x03,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x13,0xff,
-0x00,0xff,0x58,0xff,0xff,0xff,0x13,0xff,0x00,0xff,0x58,0xff,0xff,0xff,0x03,0xff,
-0x00,0xff,0x60,0xff,0xff,0xff,0x03,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x03,0xff,
-0x8b,0xff,0x97,0xff,0xff,0xff,0x90,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,
-0x8b,0xff,0x87,0xff,0xff,0xff,0x61,0xff,0x00,0xff,0x34,0xff,0xff,0xff,0x89,0xff,
-0x00,0xff,0x34,0xff,0xff,0xff,0x26,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x06,0xff,
-0x83,0xff,0x93,0xff,0xff,0xff,0xd0,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x06,0xff,
-0x83,0xff,0x93,0xff,0xff,0xff,0xe0,0xff,0x8b,0xff,0x83,0xff,0xff,0xff,0x51,0xff,
-0x79,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x74,0xff,0x18,0xff,0xff,0xff,0xb4,0xff,
-0x38,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x1e,0xff,0x14,0xff,0xff,0xff,0xd5,0xff,
-0x8b,0xff,0x83,0xff,0xff,0xff,0x50,0xff,0x78,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,
-0x00,0xff,0x60,0xff,0xff,0xff,0x07,0xff,0x04,0xff,0x0d,0xff,0xff,0xff,0x30,0xff,
-0x00,0xff,0x60,0xff,0xff,0xff,0x07,0xff,0x83,0xff,0x93,0xff,0xff,0xff,0xf0,0xff,
-0x00,0xff,0x60,0xff,0xff,0xff,0x07,0xff,0x08,0xff,0x0d,0xff,0xff,0xff,0x30,0xff,
-0x00,0xff,0x60,0xff,0xff,0xff,0x07,0xff,0x86,0xff,0x93,0xff,0xff,0xff,0x40,0xff,
-0x00,0xff,0x40,0xff,0xff,0xff,0x01,0xff,0x8b,0xff,0x93,0xff,0xff,0xff,0x51,0xff,
-0x00,0xff,0x34,0xff,0xff,0xff,0x46,0xff,0x00,0xff,0x09,0xff,0xff,0xff,0x06,0xff,
-0x8b,0xff,0x97,0xff,0xff,0xff,0x61,0xff,0x83,0xff,0x8b,0xff,0xff,0xff,0xd0,0xff,
-0x83,0xff,0x8b,0xff,0xff,0xff,0xe1,0xff,0x87,0xff,0x37,0xff,0xff,0xff,0x01,0xff,
-0x6e,0xff,0x1c,0xff,0xff,0xff,0xbf,0xff,0x87,0xff,0x37,0xff,0xff,0xff,0x00,0xff,
-0x92,0xff,0x37,0xff,0xff,0xff,0x01,0xff,0x7f,0xff,0x38,0xff,0xff,0xff,0x00,0xff,
-0x23,0xff,0x1c,0xff,0xff,0xff,0xff,0xff,0x7e,0xff,0x38,0xff,0xff,0xff,0x00,0xff,
-0x83,0xff,0x87,0xff,0xff,0xff,0xf1,0xff,0x86,0xff,0x8b,0xff,0xff,0xff,0x41,0xff,
-0x6c,0xff,0x1c,0xff,0xff,0xff,0x2f,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,
-0x8d,0xff,0x8f,0xff,0xff,0xff,0xc5,0xff,0x20,0xff,0x14,0xff,0xff,0xff,0xae,0xff,
-0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,
-0x8b,0xff,0x83,0xff,0xff,0xff,0x84,0xff,0x00,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,
-0x8b,0xff,0x93,0xff,0xff,0xff,0x8a,0xff,0x64,0xff,0x1c,0xff,0xff,0xff,0xe0,0xff,
-0x7e,0xff,0x38,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x38,0xff,0xff,0xff,0x08,0xff,
-0x00,0xff,0x3c,0xff,0xff,0xff,0xe5,0xff,0x21,0xff,0x14,0xff,0xff,0xff,0x5e,0xff,
-0x00,0xff,0x40,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x58,0xff,0xff,0xff,0x03,0xff,
-0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,0x08,0xff,0x40,0xff,0xff,0xff,0x10,0xff,
-0x47,0xff,0x90,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x04,0xff,0xff,0xff,0x1c,0xff,
-0x00,0xff,0x04,0xff,0xff,0xff,0x1c,0xff,0x00,0xff,0x04,0xff,0xff,0xff,0x1c,0xff,
-0x00,0xff,0x04,0xff,0xff,0xff,0x1c,0xff,0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,
-0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,
-0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,
-0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,
-0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,
-0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,
-0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,0x02,0xff,0x40,0xff,0xff,0xff,0x40,0xff,
-0x11,0xff,0x90,0xff,0xff,0xff,0x20,0xff,0x78,0xff,0x42,0xff,0xff,0xff,0x50,0xff,
-0x48,0xff,0x90,0xff,0xff,0xff,0xa0,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
-0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
-0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
-0xb0,0xff,0x40,0xff,0xff,0xff,0x00,0xff,0x47,0xff,0x90,0xff,0xff,0xff,0x50,0xff,
-0x00,0xff,0x40,0xff,0xff,0xff,0x00,0xff,0x8d,0xff,0x93,0xff,0xff,0xff,0x40,0xff,
-0x8d,0xff,0x93,0xff,0xff,0xff,0x50,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x01,0xff,
-0x8b,0xff,0x93,0xff,0xff,0xff,0x51,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x00,0xff,
-0x46,0xff,0x90,0xff,0xff,0xff,0x70,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0xd0,0xff,
-0x78,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x0c,0xff,0x18,0xff,0xff,0xff,0x90,0xff,
-0x0c,0xff,0x18,0xff,0xff,0xff,0x6f,0xff,0x20,0xff,0x0c,0xff,0xff,0xff,0x00,0xff,
-0x00,0xff,0x34,0xff,0xff,0xff,0x09,0xff,0x00,0xff,0x34,0xff,0xff,0xff,0x08,0xff,
-0x00,0xff,0x38,0xff,0xff,0xff,0x08,0xff,0x00,0xff,0x38,0xff,0xff,0xff,0x09,0xff,
-0x00,0xff,0x38,0xff,0xff,0xff,0x06,0xff,0x00,0xff,0x34,0xff,0xff,0xff,0x26,0xff,
-0x98,0xff,0xcc,0xff,0xff,0xff,0x37,0xff,0x00,0xff,0x3c,0xff,0xff,0xff,0xa5,0xff,
-0x24,0xff,0x14,0xff,0xff,0xff,0xfe,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x73,0xff,
-0x08,0xff,0x0d,0xff,0xff,0xff,0x14,0xff,0x98,0xff,0x20,0xff,0xff,0xff,0x0f,0xff,
-0x00,0xff,0x50,0xff,0xff,0xff,0xc6,0xff,0x69,0xff,0xcc,0xff,0xff,0xff,0x37,0xff,
-0x00,0xff,0x05,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x58,0xff,0xff,0xff,0xc6,0xff,
-0x98,0xff,0x20,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x72,0xff,
-0x08,0xff,0x0d,0xff,0xff,0xff,0x14,0xff,0x00,0xff,0x50,0xff,0xff,0xff,0xc6,0xff,
-0x69,0xff,0xcc,0xff,0xff,0xff,0x37,0xff,0x00,0xff,0x05,0xff,0xff,0xff,0x00,0xff,
-0x00,0xff,0x58,0xff,0xff,0xff,0xc6,0xff,0x98,0xff,0x20,0xff,0xff,0xff,0x0f,0xff,
-0x00,0xff,0x60,0xff,0xff,0xff,0x73,0xff,0x08,0xff,0x0d,0xff,0xff,0xff,0x14,0xff,
-0x00,0xff,0x50,0xff,0xff,0xff,0xc6,0xff,0x69,0xff,0x20,0xff,0xff,0xff,0x0f,0xff,
-0x00,0xff,0x05,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x58,0xff,0xff,0xff,0xc6,0xff,
-0x30,0xff,0x0c,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,
-0x00,0xff,0x0c,0xff,0xff,0xff,0x30,0xff,0x47,0xff,0x80,0xff,0xff,0xff,0x58,0xff,
-0x10,0xff,0x0f,0xff,0xff,0xff,0x01,0xff,0x66,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,
-0x26,0xff,0x18,0xff,0xff,0xff,0x94,0xff,0x00,0xff,0x48,0xff,0xff,0xff,0x00,0xff,
-0x8b,0xff,0x93,0xff,0xff,0xff,0x40,0xff,0x80,0xff,0x40,0xff,0xff,0xff,0x00,0xff,
-0x49,0xff,0x90,0xff,0xff,0xff,0x40,0xff,0x16,0xff,0x0f,0xff,0xff,0xff,0x02,0xff,
-0x66,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x38,0xff,0x18,0xff,0xff,0xff,0xb4,0xff,
-0x0f,0xff,0x40,0xff,0xff,0xff,0xf4,0xff,0x47,0xff,0x80,0xff,0xff,0xff,0x0a,0xff,
-0x82,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x8d,0xff,0x93,0xff,0xff,0xff,0x7a,0xff,
-0x7a,0xff,0x26,0xff,0xff,0xff,0x0f,0xff,0x10,0xff,0x27,0xff,0xff,0xff,0x0f,0xff,
-0x38,0xff,0x18,0xff,0xff,0xff,0xb4,0xff,0x27,0xff,0x18,0xff,0xff,0xff,0xd2,0xff,
-0x00,0xff,0x48,0xff,0xff,0xff,0x00,0xff,0x8b,0xff,0x93,0xff,0xff,0xff,0x30,0xff,
-0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,0x47,0xff,0x90,0xff,0xff,0xff,0x00,0xff,
-0x00,0xff,0x48,0xff,0xff,0xff,0x04,0xff,0xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,
-0x46,0xff,0x90,0xff,0xff,0xff,0x6a,0xff,0x00,0xff,0x0c,0xff,0xff,0xff,0x20,0xff,
-0x00,0xff,0x0a,0xff,0xff,0xff,0x1f,0xff,0x10,0xff,0x27,0xff,0xff,0xff,0x0f,0xff,
-0x29,0xff,0x18,0xff,0xff,0xff,0x92,0xff,0x46,0xff,0x80,0xff,0xff,0xff,0x00,0xff,
-0x8b,0xff,0x93,0xff,0xff,0xff,0x20,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,
-0x47,0xff,0x90,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x48,0xff,0xff,0xff,0x04,0xff,
-0xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x6a,0xff,
-0x00,0xff,0x0c,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x04,0xff,0xff,0xff,0x1c,0xff,
-0x00,0xff,0x04,0xff,0xff,0xff,0x1c,0xff,0x00,0xff,0x04,0xff,0xff,0xff,0x1c,0xff,
-0x00,0xff,0x04,0xff,0xff,0xff,0x1c,0xff,0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,
-0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,
-0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,
-0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,
-0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,
-0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,
-0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,0x00,0xff,0x04,0xff,0xff,0xff,0x03,0xff,
-0x0d,0xff,0x18,0xff,0xff,0xff,0x0f,0xff,0x10,0xff,0x27,0xff,0xff,0xff,0x0f,0xff,
-0x31,0xff,0x18,0xff,0xff,0xff,0x12,0xff,0x30,0xff,0x0c,0xff,0xff,0xff,0x00,0xff,
-0x08,0xff,0x0c,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x4f,0xff,0xff,0xff,0x89,0xff,
-0x90,0xff,0x37,0xff,0xff,0xff,0x00,0xff,0x02,0xff,0x34,0xff,0xff,0xff,0x08,0xff,
-0x00,0xff,0x34,0xff,0xff,0xff,0x34,0xff,0x00,0xff,0x34,0xff,0xff,0xff,0x55,0xff,
-0x46,0xff,0x80,0xff,0xff,0xff,0x08,0xff,0x00,0xff,0x0e,0xff,0xff,0xff,0x0f,0xff,
-0x00,0xff,0x0d,0xff,0xff,0xff,0x4e,0xff,0xa7,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,
-0x00,0xff,0x68,0xff,0xff,0xff,0xa3,0xff,0x00,0xff,0x0d,0xff,0xff,0xff,0x4a,0xff,
-0x46,0xff,0x80,0xff,0xff,0xff,0x18,0xff,0x00,0xff,0x0e,0xff,0xff,0xff,0x0f,0xff,
-0x00,0xff,0x0d,0xff,0xff,0xff,0x5e,0xff,0xaf,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,
-0x00,0xff,0x68,0xff,0xff,0xff,0xa0,0xff,0x00,0xff,0x0d,0xff,0xff,0xff,0x5a,0xff,
-0x46,0xff,0x80,0xff,0xff,0xff,0x48,0xff,0x10,0xff,0x0f,0xff,0xff,0xff,0xfe,0xff,
-0x87,0xff,0x93,0xff,0xff,0xff,0xfe,0xff,0x00,0xff,0x0d,0xff,0xff,0xff,0x2e,0xff,
-0x02,0xff,0x40,0xff,0xff,0xff,0x06,0xff,0xe0,0xff,0x20,0xff,0xff,0xff,0x0f,0xff,
-0x00,0xff,0x40,0xff,0xff,0xff,0x01,0xff,0x63,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,
-0x00,0xff,0x0d,0xff,0xff,0xff,0x4a,0xff,0x49,0xff,0x6a,0xff,0xff,0xff,0xa3,0xff,
-0x00,0xff,0x0d,0xff,0xff,0xff,0x5a,0xff,0x00,0xff,0x68,0xff,0xff,0xff,0xa0,0xff,
-0x00,0xff,0x0d,0xff,0xff,0xff,0x5a,0xff,0x63,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,
-0x00,0xff,0x0d,0xff,0xff,0xff,0x4a,0xff,0x49,0xff,0x6a,0xff,0xff,0xff,0xa3,0xff,
-0x00,0xff,0x0d,0xff,0xff,0xff,0x5a,0xff,0x00,0xff,0x68,0xff,0xff,0xff,0xa0,0xff,
-0x63,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x0d,0xff,0xff,0xff,0x4a,0xff,
-0x49,0xff,0x6a,0xff,0xff,0xff,0xa3,0xff,0x00,0xff,0x0d,0xff,0xff,0xff,0x5a,0xff,
-0x00,0xff,0x68,0xff,0xff,0xff,0xa0,0xff,0x63,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,
-0x00,0xff,0x0d,0xff,0xff,0xff,0x4a,0xff,0x49,0xff,0x6a,0xff,0xff,0xff,0xa3,0xff,
-0x00,0xff,0x0d,0xff,0xff,0xff,0x5a,0xff,0x00,0xff,0x68,0xff,0xff,0xff,0xa0,0xff,
-0x63,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x0d,0xff,0xff,0xff,0x4a,0xff,
-0x49,0xff,0x6a,0xff,0xff,0xff,0xa3,0xff,0x00,0xff,0x0d,0xff,0xff,0xff,0x5a,0xff,
-0x00,0xff,0x68,0xff,0xff,0xff,0xa0,0xff,0x63,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,
-0x00,0xff,0x0d,0xff,0xff,0xff,0x4a,0xff,0x49,0xff,0x6a,0xff,0xff,0xff,0xa3,0xff,
-0x00,0xff,0x0d,0xff,0xff,0xff,0x5a,0xff,0x00,0xff,0x68,0xff,0xff,0xff,0xa0,0xff,
-0x63,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x0d,0xff,0xff,0xff,0x4a,0xff,
-0x49,0xff,0x6a,0xff,0xff,0xff,0xa3,0xff,0x00,0xff,0x0d,0xff,0xff,0xff,0x5a,0xff,
-0x00,0xff,0x68,0xff,0xff,0xff,0xa1,0xff,0x46,0xff,0x80,0xff,0xff,0xff,0x28,0xff,
-0x00,0xff,0x0e,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x0d,0xff,0xff,0xff,0x4e,0xff,
-0xa7,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x68,0xff,0xff,0xff,0xa3,0xff,
-0x00,0xff,0x0d,0xff,0xff,0xff,0x4a,0xff,0x46,0xff,0x80,0xff,0xff,0xff,0x38,0xff,
-0x00,0xff,0x0e,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x0d,0xff,0xff,0xff,0x5e,0xff,
-0xaf,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x68,0xff,0xff,0xff,0xa0,0xff,
-0x00,0xff,0x0d,0xff,0xff,0xff,0x5a,0xff,0x63,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,
-0x00,0xff,0x0d,0xff,0xff,0xff,0x4a,0xff,0x49,0xff,0x6a,0xff,0xff,0xff,0xa3,0xff,
-0x00,0xff,0x0d,0xff,0xff,0xff,0x5a,0xff,0x00,0xff,0x68,0xff,0xff,0xff,0xa0,0xff,
-0x63,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x0d,0xff,0xff,0xff,0x4a,0xff,
-0x49,0xff,0x6a,0xff,0xff,0xff,0xa3,0xff,0x00,0xff,0x0d,0xff,0xff,0xff,0x5a,0xff,
-0x00,0xff,0x68,0xff,0xff,0xff,0xa0,0xff,0x63,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,
-0x00,0xff,0x0d,0xff,0xff,0xff,0x4a,0xff,0x49,0xff,0x6a,0xff,0xff,0xff,0xa3,0xff,
-0x00,0xff,0x0d,0xff,0xff,0xff,0x5a,0xff,0x00,0xff,0x68,0xff,0xff,0xff,0xa0,0xff,
-0x63,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x0d,0xff,0xff,0xff,0x4a,0xff,
-0x49,0xff,0x6a,0xff,0xff,0xff,0xa3,0xff,0x00,0xff,0x0d,0xff,0xff,0xff,0x5a,0xff,
-0x00,0xff,0x68,0xff,0xff,0xff,0xa0,0xff,0x63,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,
-0x00,0xff,0x0d,0xff,0xff,0xff,0x4a,0xff,0x49,0xff,0x6a,0xff,0xff,0xff,0xa3,0xff,
-0x00,0xff,0x0d,0xff,0xff,0xff,0x5a,0xff,0x00,0xff,0x68,0xff,0xff,0xff,0xa0,0xff,
-0x63,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x0d,0xff,0xff,0xff,0x4a,0xff,
-0x49,0xff,0x6a,0xff,0xff,0xff,0xa3,0xff,0x00,0xff,0x0d,0xff,0xff,0xff,0x5a,0xff,
-0x00,0xff,0x68,0xff,0xff,0xff,0xa0,0xff,0x63,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,
-0x00,0xff,0x0d,0xff,0xff,0xff,0x4a,0xff,0x49,0xff,0x6a,0xff,0xff,0xff,0xa3,0xff,
-0x00,0xff,0x0d,0xff,0xff,0xff,0x5a,0xff,0x00,0xff,0x68,0xff,0xff,0xff,0xa3,0xff,
-0xff,0xff,0x4f,0xff,0xff,0xff,0xf0,0xff,0x86,0xff,0x93,0xff,0xff,0xff,0x50,0xff,
-0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,0x47,0xff,0x90,0xff,0xff,0xff,0x00,0xff,
-0x00,0xff,0x48,0xff,0xff,0xff,0x04,0xff,0xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,
-0x46,0xff,0x90,0xff,0xff,0xff,0x6a,0xff,0x00,0xff,0x0c,0xff,0xff,0xff,0x20,0xff,
-0x00,0xff,0x0a,0xff,0xff,0xff,0x1f,0xff,0x10,0xff,0x27,0xff,0xff,0xff,0x0f,0xff,
-0x32,0xff,0x18,0xff,0xff,0xff,0x42,0xff,0x8b,0xff,0x83,0xff,0xff,0xff,0xe4,0xff,
-0x8b,0xff,0x83,0xff,0xff,0xff,0xf5,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x44,0xff,
-0x08,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0xff,0xff,0x4f,0xff,0xff,0xff,0x89,0xff,
-0x00,0xff,0x0d,0xff,0xff,0xff,0x8a,0xff,0x00,0xff,0x0e,0xff,0xff,0xff,0x0f,0xff,
-0x00,0xff,0x0d,0xff,0xff,0xff,0x4e,0xff,0xa7,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,
-0x46,0xff,0x90,0xff,0xff,0xff,0x5a,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,
-0x47,0xff,0x90,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x48,0xff,0xff,0xff,0x04,0xff,
-0xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x6a,0xff,
-0x00,0xff,0x0c,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x1f,0xff,
-0x10,0xff,0x27,0xff,0xff,0xff,0x0f,0xff,0x35,0xff,0x18,0xff,0xff,0xff,0xd2,0xff,
-0x00,0xff,0x4c,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x93,0xff,0xff,0xff,0x00,0xff,
-0x0b,0xff,0x40,0xff,0xff,0xff,0x80,0xff,0x11,0xff,0x90,0xff,0xff,0xff,0xf0,0xff,
-0x00,0xff,0x40,0xff,0xff,0xff,0x10,0xff,0x11,0xff,0x90,0xff,0xff,0xff,0xe0,0xff,
-0x46,0xff,0x80,0xff,0xff,0xff,0x0a,0xff,0x7a,0xff,0x26,0xff,0xff,0xff,0x0f,0xff,
-0x35,0xff,0x1c,0xff,0xff,0xff,0x24,0xff,0x10,0xff,0x27,0xff,0xff,0xff,0x0f,0xff,
-0x33,0xff,0x18,0xff,0xff,0xff,0xc5,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0xc0,0xff,
-0x11,0xff,0x90,0xff,0xff,0xff,0x60,0xff,0x8d,0xff,0x93,0xff,0xff,0xff,0xd0,0xff,
-0x00,0xff,0x48,0xff,0xff,0xff,0x00,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,
-0x47,0xff,0x90,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x48,0xff,0xff,0xff,0x04,0xff,
-0xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x6a,0xff,
-0x00,0xff,0x0c,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x1f,0xff,
-0x10,0xff,0x27,0xff,0xff,0xff,0x0f,0xff,0x34,0xff,0x18,0xff,0xff,0xff,0x85,0xff,
-0x00,0xff,0x40,0xff,0xff,0xff,0x40,0xff,0x11,0xff,0x90,0xff,0xff,0xff,0x60,0xff,
-0x8d,0xff,0x93,0xff,0xff,0xff,0xd0,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,
-0x47,0xff,0x90,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x48,0xff,0xff,0xff,0x04,0xff,
-0xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x6a,0xff,
-0x00,0xff,0x0c,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x1f,0xff,
-0x00,0xff,0x40,0xff,0xff,0xff,0x00,0xff,0x11,0xff,0x90,0xff,0xff,0xff,0x60,0xff,
-0x8d,0xff,0x93,0xff,0xff,0xff,0xd0,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,
-0x47,0xff,0x90,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x48,0xff,0xff,0xff,0x04,0xff,
-0xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x6a,0xff,
-0x00,0xff,0x0c,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x1f,0xff,
-0x00,0xff,0x48,0xff,0xff,0xff,0x00,0xff,0x8d,0xff,0x93,0xff,0xff,0xff,0x80,0xff,
-0x00,0xff,0x48,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x93,0xff,0xff,0xff,0x00,0xff,
-0x0d,0xff,0x40,0xff,0xff,0xff,0xf0,0xff,0x11,0xff,0x90,0xff,0xff,0xff,0xf0,0xff,
-0x00,0xff,0x40,0xff,0xff,0xff,0x10,0xff,0x11,0xff,0x90,0xff,0xff,0xff,0xe0,0xff,
-0xff,0xff,0x40,0xff,0xff,0xff,0xf0,0xff,0x90,0xff,0x27,0xff,0xff,0xff,0x0f,0xff,
-0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,0x10,0xff,0x27,0xff,0xff,0xff,0x0f,0xff,
-0x37,0xff,0x18,0xff,0xff,0xff,0x42,0xff,0x46,0xff,0x80,0xff,0xff,0xff,0x00,0xff,
-0x89,0xff,0x93,0xff,0xff,0xff,0xa0,0xff,0x46,0xff,0x80,0xff,0xff,0xff,0x10,0xff,
-0x89,0xff,0x93,0xff,0xff,0xff,0xb0,0xff,0x46,0xff,0x80,0xff,0xff,0xff,0x20,0xff,
-0x89,0xff,0x93,0xff,0xff,0xff,0xc0,0xff,0x46,0xff,0x80,0xff,0xff,0xff,0x30,0xff,
-0x89,0xff,0x93,0xff,0xff,0xff,0xd0,0xff,0x46,0xff,0x80,0xff,0xff,0xff,0x40,0xff,
-0x89,0xff,0x93,0xff,0xff,0xff,0xe0,0xff,0x46,0xff,0x80,0xff,0xff,0xff,0x50,0xff,
-0x89,0xff,0x93,0xff,0xff,0xff,0xf0,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x10,0xff,
-0x86,0xff,0x93,0xff,0xff,0xff,0x60,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,
-0x47,0xff,0x90,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x48,0xff,0xff,0xff,0x04,0xff,
-0xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x6a,0xff,
-0x00,0xff,0x0c,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x1f,0xff,
-0x10,0xff,0x27,0xff,0xff,0xff,0x0f,0xff,0x39,0xff,0x18,0xff,0xff,0xff,0x22,0xff,
-0x46,0xff,0x80,0xff,0xff,0xff,0x00,0xff,0x8d,0xff,0x93,0xff,0xff,0xff,0x20,0xff,
-0x46,0xff,0x80,0xff,0xff,0xff,0x10,0xff,0x8d,0xff,0x93,0xff,0xff,0xff,0x30,0xff,
-0x46,0xff,0x80,0xff,0xff,0xff,0x20,0xff,0x78,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,
-0x38,0xff,0x1c,0xff,0xff,0xff,0x84,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x00,0xff,
-0x46,0xff,0x90,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x48,0xff,0xff,0xff,0x00,0xff,
-0x8d,0xff,0x93,0xff,0xff,0xff,0x40,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,
-0x47,0xff,0x90,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x48,0xff,0xff,0xff,0x04,0xff,
-0xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x6a,0xff,
-0x00,0xff,0x0c,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x1f,0xff,
-0x00,0xff,0x48,0xff,0xff,0xff,0x00,0xff,0x8d,0xff,0x93,0xff,0xff,0xff,0x50,0xff,
-0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x0c,0xff,0xff,0xff,0x20,0xff,
-0x00,0xff,0x0a,0xff,0xff,0xff,0x1f,0xff,0x00,0xff,0x0c,0xff,0xff,0xff,0x30,0xff,
-0x00,0xff,0x48,0xff,0xff,0xff,0x00,0xff,0x8b,0xff,0x93,0xff,0xff,0xff,0x50,0xff,
-0x00,0xff,0x0c,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x1f,0xff,
-0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,0x0f,0xff,0x40,0xff,0xff,0xff,0xf4,0xff,
-0xe0,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x41,0xff,0x18,0xff,0xff,0xff,0x30,0xff,
-0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,0x0f,0xff,0x40,0xff,0xff,0xff,0xe4,0xff,
-0xe0,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x42,0xff,0x18,0xff,0xff,0xff,0x40,0xff,
-0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,0x0f,0xff,0x40,0xff,0xff,0xff,0xd4,0xff,
-0xe0,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x47,0xff,0x18,0xff,0xff,0xff,0xa0,0xff,
-0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,0x0f,0xff,0x40,0xff,0xff,0xff,0xc4,0xff,
-0xe0,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x46,0xff,0x18,0xff,0xff,0xff,0xd0,0xff,
-0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,0x0f,0xff,0x40,0xff,0xff,0xff,0xb4,0xff,
-0xe0,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x48,0xff,0x18,0xff,0xff,0xff,0xe0,0xff,
-0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,0x0f,0xff,0x40,0xff,0xff,0xff,0xa4,0xff,
-0xe0,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x4a,0xff,0x18,0xff,0xff,0xff,0x60,0xff,
-0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,0x0f,0xff,0x40,0xff,0xff,0xff,0x94,0xff,
-0xe0,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x4c,0xff,0x18,0xff,0xff,0xff,0x00,0xff,
-0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,0x0f,0xff,0x40,0xff,0xff,0xff,0x84,0xff,
-0xe0,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x4d,0xff,0x18,0xff,0xff,0xff,0xe0,0xff,
-0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,0x0f,0xff,0x40,0xff,0xff,0xff,0x74,0xff,
-0xe0,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x4f,0xff,0x18,0xff,0xff,0xff,0x20,0xff,
-0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,0x0f,0xff,0x40,0xff,0xff,0xff,0x64,0xff,
-0xe0,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x4f,0xff,0x18,0xff,0xff,0xff,0xf0,0xff,
-0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,0x0e,0xff,0x40,0xff,0xff,0xff,0xf4,0xff,
-0xe0,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x44,0xff,0x18,0xff,0xff,0xff,0x40,0xff,
-0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,0x0e,0xff,0x40,0xff,0xff,0xff,0xe4,0xff,
-0xe0,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x45,0xff,0x18,0xff,0xff,0xff,0x50,0xff,
-0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,0x0a,0xff,0x40,0xff,0xff,0xff,0x04,0xff,
-0xe0,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x3d,0xff,0x18,0xff,0xff,0xff,0xd0,0xff,
-0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,0x0a,0xff,0x40,0xff,0xff,0xff,0x14,0xff,
-0xe0,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x3f,0xff,0x18,0xff,0xff,0xff,0x10,0xff,
-0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,0x0a,0xff,0x40,0xff,0xff,0xff,0x24,0xff,
-0xe0,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x3f,0xff,0x18,0xff,0xff,0xff,0x80,0xff,
-0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,0x0a,0xff,0x40,0xff,0xff,0xff,0x34,0xff,
-0xe0,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x3f,0xff,0x18,0xff,0xff,0xff,0xf0,0xff,
-0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,0x0a,0xff,0x40,0xff,0xff,0xff,0x44,0xff,
-0xe0,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x40,0xff,0x18,0xff,0xff,0xff,0x60,0xff,
-0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,0x47,0xff,0x90,0xff,0xff,0xff,0x00,0xff,
-0x00,0xff,0x48,0xff,0xff,0xff,0x04,0xff,0xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,
-0x46,0xff,0x90,0xff,0xff,0xff,0x6a,0xff,0x00,0xff,0x0c,0xff,0xff,0xff,0x20,0xff,
-0x00,0xff,0x0a,0xff,0xff,0xff,0x1f,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,
-0x47,0xff,0x90,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x48,0xff,0xff,0xff,0x04,0xff,
-0xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x6a,0xff,
-0x00,0xff,0x0c,0xff,0xff,0xff,0x08,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x00,0xff,
-0xff,0xff,0x93,0xff,0xff,0xff,0xf0,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x00,0xff,
-0x44,0xff,0x90,0xff,0xff,0xff,0x60,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
-0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
-0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
-0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
-0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x21,0xff,0x40,0xff,0xff,0xff,0x80,0xff,
-0xff,0xff,0x93,0xff,0xff,0xff,0xf0,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,
-0x47,0xff,0x90,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x48,0xff,0xff,0xff,0x04,0xff,
-0xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x6a,0xff,
-0x25,0xff,0x40,0xff,0xff,0xff,0x80,0xff,0xff,0xff,0x93,0xff,0xff,0xff,0xf0,0xff,
-0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,0x47,0xff,0x90,0xff,0xff,0xff,0x00,0xff,
-0x00,0xff,0x48,0xff,0xff,0xff,0x04,0xff,0xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,
-0x46,0xff,0x90,0xff,0xff,0xff,0x6a,0xff,0xe9,0xff,0x41,0xff,0xff,0xff,0x80,0xff,
-0xff,0xff,0x93,0xff,0xff,0xff,0xf0,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,
-0x47,0xff,0x90,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x48,0xff,0xff,0xff,0x04,0xff,
-0xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x6a,0xff,
-0xed,0xff,0x41,0xff,0xff,0xff,0x80,0xff,0xff,0xff,0x93,0xff,0xff,0xff,0xf0,0xff,
-0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,0x47,0xff,0x90,0xff,0xff,0xff,0x00,0xff,
-0x00,0xff,0x48,0xff,0xff,0xff,0x04,0xff,0xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,
-0x46,0xff,0x90,0xff,0xff,0xff,0x6a,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x00,0xff,
-0x44,0xff,0x90,0xff,0xff,0xff,0x60,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
-0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
-0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xf1,0xff,0x41,0xff,0xff,0xff,0x80,0xff,
-0xff,0xff,0x93,0xff,0xff,0xff,0xf0,0xff,0x46,0xff,0x84,0xff,0xff,0xff,0x00,0xff,
-0x00,0xff,0x34,0xff,0xff,0xff,0x08,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x03,0xff,
-0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
-0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
-0x46,0xff,0x90,0xff,0xff,0xff,0x60,0xff,0xf7,0xff,0x4f,0xff,0xff,0xff,0xf4,0xff,
-0x46,0xff,0x90,0xff,0xff,0xff,0x74,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,
-0x47,0xff,0x90,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x48,0xff,0xff,0xff,0x04,0xff,
-0xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x6a,0xff,
-0x00,0xff,0x0c,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x1f,0xff,
-0x46,0xff,0x84,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x34,0xff,0xff,0xff,0x08,0xff,
-0x00,0xff,0x34,0xff,0xff,0xff,0x06,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
-0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
-0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x46,0xff,0x80,0xff,0xff,0xff,0x10,0xff,
-0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
-0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
-0x00,0xff,0x68,0xff,0xff,0xff,0x02,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
-0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
-0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x22,0xff,
-0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
-0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
-0x46,0xff,0x90,0xff,0xff,0xff,0x62,0xff,0xf7,0xff,0x4f,0xff,0xff,0xff,0xf4,0xff,
-0x46,0xff,0x90,0xff,0xff,0xff,0x74,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,
-0x47,0xff,0x90,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x48,0xff,0xff,0xff,0x04,0xff,
-0xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x6a,0xff,
-0x00,0xff,0x0c,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x1f,0xff,
-0x46,0xff,0x88,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x38,0xff,0xff,0xff,0x08,0xff,
-0x00,0xff,0x50,0xff,0xff,0xff,0x03,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
-0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
-0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x60,0xff,
-0xf7,0xff,0x4f,0xff,0xff,0xff,0xf4,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x74,0xff,
-0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,0x47,0xff,0x90,0xff,0xff,0xff,0x00,0xff,
-0x00,0xff,0x48,0xff,0xff,0xff,0x04,0xff,0xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,
-0x46,0xff,0x90,0xff,0xff,0xff,0x6a,0xff,0x00,0xff,0x0c,0xff,0xff,0xff,0x20,0xff,
-0x00,0xff,0x0a,0xff,0xff,0xff,0x1f,0xff,0x46,0xff,0x88,0xff,0xff,0xff,0x00,0xff,
-0x00,0xff,0x38,0xff,0xff,0xff,0x08,0xff,0x00,0xff,0x38,0xff,0xff,0xff,0x04,0xff,
-0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
-0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
-0x46,0xff,0x80,0xff,0xff,0xff,0x10,0xff,0x00,0xff,0x58,0xff,0xff,0xff,0x03,0xff,
-0x00,0xff,0x50,0xff,0xff,0xff,0x23,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
-0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
-0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x62,0xff,
-0xf7,0xff,0x4f,0xff,0xff,0xff,0xf4,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x74,0xff,
-0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,0x47,0xff,0x90,0xff,0xff,0xff,0x00,0xff,
-0x00,0xff,0x48,0xff,0xff,0xff,0x04,0xff,0xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,
-0x46,0xff,0x90,0xff,0xff,0xff,0x6a,0xff,0x00,0xff,0x0c,0xff,0xff,0xff,0x20,0xff,
-0x00,0xff,0x0a,0xff,0xff,0xff,0x1f,0xff,0x46,0xff,0x80,0xff,0xff,0xff,0x00,0xff,
-0xff,0xff,0x93,0xff,0xff,0xff,0xe0,0xff,0xff,0xff,0x83,0xff,0xff,0xff,0xe2,0xff,
-0x46,0xff,0x90,0xff,0xff,0xff,0x62,0xff,0xf7,0xff,0x4f,0xff,0xff,0xff,0xf4,0xff,
-0x46,0xff,0x90,0xff,0xff,0xff,0x74,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,
-0x47,0xff,0x90,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x48,0xff,0xff,0xff,0x04,0xff,
-0xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x6a,0xff,
-0x00,0xff,0x0c,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x1f,0xff,
-0x03,0xff,0x0d,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
-0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
-0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x60,0xff,
-0x0c,0xff,0x0d,0xff,0xff,0xff,0xf0,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
-0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
-0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xf7,0xff,0x4f,0xff,0xff,0xff,0xf4,0xff,
-0x46,0xff,0x90,0xff,0xff,0xff,0x74,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,
-0x47,0xff,0x90,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x48,0xff,0xff,0xff,0x04,0xff,
-0xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x6a,0xff,
-0x00,0xff,0x0c,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x1f,0xff,
-0x46,0xff,0x80,0xff,0xff,0xff,0x02,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
-0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
-0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
-0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
-0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x46,0xff,0x80,0xff,0xff,0xff,0x13,0xff,
-0x00,0xff,0x40,0xff,0xff,0xff,0x00,0xff,0x11,0xff,0x90,0xff,0xff,0xff,0x60,0xff,
-0x8d,0xff,0x93,0xff,0xff,0xff,0xd0,0xff,0x11,0xff,0x90,0xff,0xff,0xff,0xf2,0xff,
-0x11,0xff,0x90,0xff,0xff,0xff,0xe3,0xff,0xf7,0xff,0x4f,0xff,0xff,0xff,0xf4,0xff,
-0x46,0xff,0x90,0xff,0xff,0xff,0x74,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,
-0x47,0xff,0x90,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x48,0xff,0xff,0xff,0x04,0xff,
-0xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x6a,0xff,
-0x00,0xff,0x0c,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x1f,0xff,
-0x46,0xff,0x84,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x34,0xff,0xff,0xff,0x08,0xff,
-0x00,0xff,0x34,0xff,0xff,0xff,0x06,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
-0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
-0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x46,0xff,0x80,0xff,0xff,0xff,0x10,0xff,
-0xff,0xff,0x93,0xff,0xff,0xff,0xe0,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x22,0xff,
-0x67,0xff,0x40,0xff,0xff,0xff,0x40,0xff,0xff,0xff,0x93,0xff,0xff,0xff,0xe0,0xff,
-0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
-0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
-0x46,0xff,0x90,0xff,0xff,0xff,0x62,0xff,0xf7,0xff,0x4f,0xff,0xff,0xff,0xf4,0xff,
-0x46,0xff,0x90,0xff,0xff,0xff,0x74,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,
-0x47,0xff,0x90,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x48,0xff,0xff,0xff,0x04,0xff,
-0xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x6a,0xff,
-0x00,0xff,0x0c,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x1f,0xff,
-0x46,0xff,0x84,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x34,0xff,0xff,0xff,0x08,0xff,
-0x00,0xff,0x34,0xff,0xff,0xff,0x06,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
-0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x46,0xff,0x80,0xff,0xff,0xff,0x10,0xff,
-0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
-0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
-0x46,0xff,0x80,0xff,0xff,0xff,0x23,0xff,0xff,0xff,0x93,0xff,0xff,0xff,0xe0,0xff,
-0x00,0xff,0x68,0xff,0xff,0xff,0x32,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x72,0xff,
-0x67,0xff,0x40,0xff,0xff,0xff,0x40,0xff,0xff,0xff,0x93,0xff,0xff,0xff,0xe0,0xff,
-0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
-0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
-0x46,0xff,0x90,0xff,0xff,0xff,0x67,0xff,0xf7,0xff,0x4f,0xff,0xff,0xff,0xf4,0xff,
-0x46,0xff,0x90,0xff,0xff,0xff,0x74,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,
-0x47,0xff,0x90,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x48,0xff,0xff,0xff,0x04,0xff,
-0xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x6a,0xff,
-0x00,0xff,0x0c,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x1f,0xff,
-0x46,0xff,0x80,0xff,0xff,0xff,0x05,0xff,0x03,0xff,0x0d,0xff,0xff,0xff,0x0f,0xff,
-0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
-0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
-0x0c,0xff,0x0d,0xff,0xff,0xff,0xf5,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
-0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
-0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xf7,0xff,0x4f,0xff,0xff,0xff,0xf4,0xff,
-0x46,0xff,0x90,0xff,0xff,0xff,0x74,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,
-0x47,0xff,0x90,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x48,0xff,0xff,0xff,0x04,0xff,
-0xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x6a,0xff,
-0x00,0xff,0x0c,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x1f,0xff,
-0x46,0xff,0x80,0xff,0xff,0xff,0x00,0xff,0x8d,0xff,0x93,0xff,0xff,0xff,0xc0,0xff,
-0x8d,0xff,0x83,0xff,0xff,0xff,0xc7,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x67,0xff,
-0xf7,0xff,0x4f,0xff,0xff,0xff,0xf4,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x74,0xff,
-0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,0x47,0xff,0x90,0xff,0xff,0xff,0x00,0xff,
-0x00,0xff,0x48,0xff,0xff,0xff,0x04,0xff,0xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,
-0x46,0xff,0x90,0xff,0xff,0xff,0x6a,0xff,0x00,0xff,0x0c,0xff,0xff,0xff,0x20,0xff,
-0x00,0xff,0x0a,0xff,0xff,0xff,0x1f,0xff,0x46,0xff,0x80,0xff,0xff,0xff,0x00,0xff,
-0x8d,0xff,0x93,0xff,0xff,0xff,0xe0,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0xe7,0xff,
-0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
-0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
-0x46,0xff,0x90,0xff,0xff,0xff,0x67,0xff,0xf7,0xff,0x4f,0xff,0xff,0xff,0xf4,0xff,
-0x46,0xff,0x90,0xff,0xff,0xff,0x74,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,
-0x47,0xff,0x90,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x48,0xff,0xff,0xff,0x04,0xff,
-0xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x6a,0xff,
-0x00,0xff,0x0c,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x1f,0xff,
-0x8d,0xff,0x83,0xff,0xff,0xff,0xd0,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x24,0xff,
-0xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x11,0xff,0x90,0xff,0xff,0xff,0x6a,0xff,
-0x00,0xff,0x40,0xff,0xff,0xff,0x14,0xff,0x18,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,
-0x51,0xff,0x14,0xff,0xff,0xff,0x81,0xff,0x90,0xff,0x80,0xff,0xff,0xff,0x60,0xff,
-0x80,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0xd0,0xff,
-0x00,0xff,0x40,0xff,0xff,0xff,0x14,0xff,0xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,
-0x11,0xff,0x90,0xff,0xff,0xff,0x6a,0xff,0x30,0xff,0x0c,0xff,0xff,0xff,0x00,0xff,
-0x00,0xff,0x40,0xff,0xff,0xff,0x16,0xff,0x10,0xff,0x40,0xff,0xff,0xff,0x07,0xff,
-0x90,0xff,0x34,0xff,0xff,0xff,0x71,0xff,0x00,0xff,0x34,0xff,0xff,0xff,0x09,0xff,
-0x0f,0xff,0x40,0xff,0xff,0xff,0xf5,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x07,0xff,
-0x88,0xff,0x63,0xff,0xff,0xff,0x27,0xff,0xe8,0xff,0x60,0xff,0xff,0xff,0x07,0xff,
-0x62,0xff,0x61,0xff,0xff,0xff,0x27,0xff,0x88,0xff,0x2b,0xff,0xff,0xff,0x8b,0xff,
-0xe8,0xff,0x60,0xff,0xff,0xff,0x07,0xff,0x62,0xff,0x61,0xff,0xff,0xff,0x17,0xff,
-0x88,0xff,0x2f,0xff,0xff,0xff,0xfb,0xff,0x89,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,
-0x98,0xff,0x20,0xff,0xff,0xff,0x0f,0xff,0xea,0xff,0x20,0xff,0xff,0xff,0x0f,0xff,
-0x00,0xff,0x0d,0xff,0xff,0xff,0xab,0xff,0x00,0xff,0x0d,0xff,0xff,0xff,0xb8,0xff,
-0x00,0xff,0x0d,0xff,0xff,0xff,0xcf,0xff,0x62,0xff,0x21,0xff,0xff,0xff,0x0f,0xff,
-0x10,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x62,0xff,0x21,0xff,0xff,0xff,0x0f,0xff,
-0x00,0xff,0x40,0xff,0xff,0xff,0x24,0xff,0x90,0xff,0x80,0xff,0xff,0xff,0x60,0xff,
-0x80,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x51,0xff,0x18,0xff,0xff,0xff,0x00,0xff,
-0x8b,0xff,0x93,0xff,0xff,0xff,0xeb,0xff,0x8b,0xff,0x93,0xff,0xff,0xff,0xfc,0xff,
-0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,0x51,0xff,0x1c,0xff,0xff,0xff,0x0f,0xff,
-0x8d,0xff,0x93,0xff,0xff,0xff,0xac,0xff,0x82,0xff,0x3c,0xff,0xff,0xff,0x45,0xff,
-0x54,0xff,0x14,0xff,0xff,0xff,0x2e,0xff,0xff,0xff,0x3f,0xff,0xff,0xff,0xf5,0xff,
-0x54,0xff,0x14,0xff,0xff,0xff,0x1e,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
-0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x51,0xff,0x1c,0xff,0xff,0xff,0x0f,0xff,
-0x00,0xff,0x0d,0xff,0xff,0xff,0x0c,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0xa4,0xff,
-0xe0,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x53,0xff,0x18,0xff,0xff,0xff,0xb3,0xff,
-0x8d,0xff,0x83,0xff,0xff,0xff,0xd0,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x24,0xff,
-0xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x0d,0xff,0xff,0xff,0xba,0xff,
-0x8b,0xff,0x83,0xff,0xff,0xff,0xf5,0xff,0x11,0xff,0x90,0xff,0xff,0xff,0x6b,0xff,
-0x00,0xff,0x40,0xff,0xff,0xff,0x14,0xff,0x18,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,
-0x55,0xff,0x14,0xff,0xff,0xff,0x21,0xff,0x90,0xff,0x80,0xff,0xff,0xff,0x60,0xff,
-0x80,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x20,0xff,
-0x00,0xff,0x40,0xff,0xff,0xff,0x01,0xff,0x8b,0xff,0x83,0xff,0xff,0xff,0xe4,0xff,
-0x8b,0xff,0x83,0xff,0xff,0xff,0xf5,0xff,0x08,0xff,0x0c,0xff,0xff,0xff,0x00,0xff,
-0x60,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x49,0xff,0x2a,0xff,0xff,0xff,0xea,0xff,
-0x00,0xff,0x0d,0xff,0xff,0xff,0x4e,0xff,0x8b,0xff,0x93,0xff,0xff,0xff,0xee,0xff,
-0x00,0xff,0x0d,0xff,0xff,0xff,0x5a,0xff,0x8b,0xff,0x93,0xff,0xff,0xff,0xfa,0xff,
-0x8d,0xff,0x83,0xff,0xff,0xff,0x20,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0x31,0xff,
-0xe0,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0xc9,0xff,0x2a,0xff,0xff,0xff,0xea,0xff,
-0x54,0xff,0x18,0xff,0xff,0xff,0xd5,0xff,0x00,0xff,0x0d,0xff,0xff,0xff,0x4e,0xff,
-0x00,0xff,0x0d,0xff,0xff,0xff,0x5a,0xff,0x82,0xff,0x4f,0xff,0xff,0xff,0xf0,0xff,
-0xff,0xff,0x4f,0xff,0xff,0xff,0xf1,0xff,0xe0,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,
-0xc9,0xff,0x2a,0xff,0xff,0xff,0xea,0xff,0x56,0xff,0x18,0xff,0xff,0xff,0xb4,0xff,
-0x54,0xff,0x18,0xff,0xff,0xff,0xdf,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x20,0xff,
-0x47,0xff,0x90,0xff,0xff,0xff,0x20,0xff,0x0c,0xff,0x0c,0xff,0xff,0xff,0x00,0xff,
-0x02,0xff,0x40,0xff,0xff,0xff,0x60,0xff,0x11,0xff,0x90,0xff,0xff,0xff,0x20,0xff,
-0x16,0xff,0x18,0xff,0xff,0xff,0x4f,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0xd0,0xff,
-0x00,0xff,0x40,0xff,0xff,0xff,0x24,0xff,0xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,
-0x11,0xff,0x90,0xff,0xff,0xff,0x6a,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x14,0xff,
-0x18,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x57,0xff,0x14,0xff,0xff,0xff,0x91,0xff,
-0x90,0xff,0x80,0xff,0xff,0xff,0x60,0xff,0x80,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,
-0x8d,0xff,0x83,0xff,0xff,0xff,0xd0,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x14,0xff,
-0xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x11,0xff,0x90,0xff,0xff,0xff,0x6a,0xff,
-0x30,0xff,0x0c,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x16,0xff,
-0x10,0xff,0x40,0xff,0xff,0xff,0x07,0xff,0x90,0xff,0x34,0xff,0xff,0xff,0x71,0xff,
-0x00,0xff,0x34,0xff,0xff,0xff,0x09,0xff,0x0f,0xff,0x40,0xff,0xff,0xff,0xf5,0xff,
-0x00,0xff,0x60,0xff,0xff,0xff,0x07,0xff,0x88,0xff,0x63,0xff,0xff,0xff,0x27,0xff,
-0xe8,0xff,0x60,0xff,0xff,0xff,0x07,0xff,0x62,0xff,0x61,0xff,0xff,0xff,0x27,0xff,
-0x88,0xff,0x2b,0xff,0xff,0xff,0x8b,0xff,0xe8,0xff,0x60,0xff,0xff,0xff,0x07,0xff,
-0x62,0xff,0x61,0xff,0xff,0xff,0x17,0xff,0x88,0xff,0x2f,0xff,0xff,0xff,0xfb,0xff,
-0x89,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x98,0xff,0x20,0xff,0xff,0xff,0x0f,0xff,
-0xea,0xff,0x20,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x0d,0xff,0xff,0xff,0xab,0xff,
-0x00,0xff,0x0d,0xff,0xff,0xff,0xb8,0xff,0x00,0xff,0x0d,0xff,0xff,0xff,0xcf,0xff,
-0x62,0xff,0x21,0xff,0xff,0xff,0x0f,0xff,0x10,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,
-0x62,0xff,0x21,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x24,0xff,
-0x90,0xff,0x80,0xff,0xff,0xff,0x60,0xff,0x80,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,
-0x57,0xff,0x18,0xff,0xff,0xff,0x10,0xff,0x8b,0xff,0x93,0xff,0xff,0xff,0xeb,0xff,
-0x8b,0xff,0x93,0xff,0xff,0xff,0xfc,0xff,0x5c,0xff,0x1c,0xff,0xff,0xff,0x3f,0xff,
-0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,0x57,0xff,0x1c,0xff,0xff,0xff,0x1f,0xff,
-0x8d,0xff,0x93,0xff,0xff,0xff,0xac,0xff,0x82,0xff,0x3c,0xff,0xff,0xff,0x45,0xff,
-0x5a,0xff,0x14,0xff,0xff,0xff,0x4e,0xff,0xff,0xff,0x3f,0xff,0xff,0xff,0xf5,0xff,
-0x5a,0xff,0x14,0xff,0xff,0xff,0x3e,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
-0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x57,0xff,0x1c,0xff,0xff,0xff,0x1f,0xff,
-0x00,0xff,0x0d,0xff,0xff,0xff,0x0c,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0xa4,0xff,
-0xe0,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x59,0xff,0x18,0xff,0xff,0xff,0xd3,0xff,
-0x5c,0xff,0x1c,0xff,0xff,0xff,0x3f,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0xd0,0xff,
-0x00,0xff,0x40,0xff,0xff,0xff,0x24,0xff,0xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,
-0x00,0xff,0x0d,0xff,0xff,0xff,0xba,0xff,0x8b,0xff,0x83,0xff,0xff,0xff,0xf5,0xff,
-0x5c,0xff,0x1c,0xff,0xff,0xff,0x3f,0xff,0x11,0xff,0x90,0xff,0xff,0xff,0x6b,0xff,
-0x00,0xff,0x40,0xff,0xff,0xff,0x14,0xff,0x18,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,
-0x5b,0xff,0x14,0xff,0xff,0xff,0x61,0xff,0x90,0xff,0x80,0xff,0xff,0xff,0x60,0xff,
-0x80,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x20,0xff,
-0x00,0xff,0x40,0xff,0xff,0xff,0x01,0xff,0x8b,0xff,0x83,0xff,0xff,0xff,0xe4,0xff,
-0x8b,0xff,0x83,0xff,0xff,0xff,0xf5,0xff,0x08,0xff,0x0c,0xff,0xff,0xff,0x00,0xff,
-0x60,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x49,0xff,0x2a,0xff,0xff,0xff,0xea,0xff,
-0x00,0xff,0x0d,0xff,0xff,0xff,0x4e,0xff,0x8b,0xff,0x93,0xff,0xff,0xff,0xee,0xff,
-0x8b,0xff,0x93,0xff,0xff,0xff,0xfa,0xff,0x5e,0xff,0x1c,0xff,0xff,0xff,0x0f,0xff,
-0x5b,0xff,0x18,0xff,0xff,0xff,0x0f,0xff,0x8b,0xff,0x83,0xff,0xff,0xff,0x20,0xff,
-0x78,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x0d,0xff,0x18,0xff,0xff,0xff,0x05,0xff,
-0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,0x08,0xff,0x0c,0xff,0xff,0xff,0x00,0xff,
-0x00,0xff,0x40,0xff,0xff,0xff,0x14,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x05,0xff,
-0x8b,0xff,0x83,0xff,0xff,0xff,0xe0,0xff,0x8b,0xff,0x83,0xff,0xff,0xff,0xf1,0xff,
-0x60,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x49,0xff,0x2a,0xff,0xff,0xff,0xea,0xff,
-0x8b,0xff,0x93,0xff,0xff,0xff,0xfa,0xff,0x8b,0xff,0x93,0xff,0xff,0xff,0xee,0xff,
-0x0c,0xff,0x0c,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,
-0x08,0xff,0x0c,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x14,0xff,
-0x00,0xff,0x40,0xff,0xff,0xff,0x05,0xff,0x8b,0xff,0x83,0xff,0xff,0xff,0xe0,0xff,
-0x8b,0xff,0x83,0xff,0xff,0xff,0xf1,0xff,0x60,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,
-0x49,0xff,0x2a,0xff,0xff,0xff,0xea,0xff,0x8b,0xff,0x93,0xff,0xff,0xff,0xfa,0xff,
-0x8b,0xff,0x93,0xff,0xff,0xff,0xee,0xff,0x0c,0xff,0x0c,0xff,0xff,0xff,0x00,0xff,
-0x8d,0xff,0x83,0xff,0xff,0xff,0x40,0xff,0x78,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,
-0x5e,0xff,0x1c,0xff,0xff,0xff,0x04,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,
-0x08,0xff,0x0c,0xff,0xff,0xff,0x00,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0x50,0xff,
-0x78,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x5f,0xff,0x1c,0xff,0xff,0xff,0x54,0xff,
-0x0f,0xff,0x40,0xff,0xff,0xff,0xf5,0xff,0x90,0xff,0x80,0xff,0xff,0xff,0xa8,0xff,
-0x10,0xff,0x0f,0xff,0xff,0xff,0x08,0xff,0x90,0xff,0x80,0xff,0xff,0xff,0x90,0xff,
-0x88,0xff,0x27,0xff,0xff,0xff,0x0f,0xff,0xb6,0xff,0x27,0xff,0xff,0xff,0x0f,0xff,
-0x8b,0xff,0x83,0xff,0xff,0xff,0xfa,0xff,0xf2,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,
-0x00,0xff,0x0d,0xff,0xff,0xff,0x0a,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x14,0xff,
-0xe2,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x74,0xff,0x18,0xff,0xff,0xff,0xe2,0xff,
-0x38,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x24,0xff,
-0xe2,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x74,0xff,0x18,0xff,0xff,0xff,0xe2,0xff,
-0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,0x0f,0xff,0x40,0xff,0xff,0xff,0xf5,0xff,
-0x90,0xff,0x80,0xff,0xff,0xff,0x80,0xff,0x8b,0xff,0x83,0xff,0xff,0xff,0xe2,0xff,
-0x88,0xff,0x27,0xff,0xff,0xff,0x0f,0xff,0x98,0xff,0x20,0xff,0xff,0xff,0x0f,0xff,
-0x10,0xff,0x40,0xff,0xff,0xff,0x07,0xff,0xe8,0xff,0x20,0xff,0xff,0xff,0x0f,0xff,
-0x00,0xff,0x0d,0xff,0xff,0xff,0xac,0xff,0xf2,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,
-0x00,0xff,0x0d,0xff,0xff,0xff,0x0a,0xff,0x01,0xff,0x40,0xff,0xff,0xff,0x04,0xff,
-0xe2,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x74,0xff,0x18,0xff,0xff,0xff,0xe2,0xff,
-0x38,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x02,0xff,0x40,0xff,0xff,0xff,0x04,0xff,
-0xe2,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x74,0xff,0x18,0xff,0xff,0xff,0xe2,0xff,
-0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x34,0xff,0xff,0xff,0x08,0xff,
-0x00,0xff,0x34,0xff,0xff,0xff,0xd4,0xff,0x00,0xff,0x34,0xff,0xff,0xff,0x85,0xff,
-0xff,0xff,0x4f,0xff,0xff,0xff,0x89,0xff,0x00,0xff,0x09,0xff,0xff,0xff,0x01,0xff,
-0x89,0xff,0x83,0xff,0xff,0xff,0xb8,0xff,0x00,0xff,0x0e,0xff,0xff,0xff,0x0f,0xff,
-0x00,0xff,0x0d,0xff,0xff,0xff,0x4e,0xff,0xa7,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,
-0x00,0xff,0x68,0xff,0xff,0xff,0xa3,0xff,0x89,0xff,0x83,0xff,0xff,0xff,0xa8,0xff,
-0x00,0xff,0x0e,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x0d,0xff,0xff,0xff,0x4e,0xff,
-0xa7,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x68,0xff,0xff,0xff,0xa3,0xff,
-0x00,0xff,0x09,0xff,0xff,0xff,0x03,0xff,0x8b,0xff,0x83,0xff,0xff,0xff,0xb0,0xff,
-0x00,0xff,0x68,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,
-0x02,0xff,0x35,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x34,0xff,0xff,0xff,0x08,0xff,
-0x00,0xff,0x34,0xff,0xff,0xff,0x26,0xff,0x89,0xff,0x83,0xff,0xff,0xff,0xd8,0xff,
-0x00,0xff,0x0e,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x0d,0xff,0xff,0xff,0x4e,0xff,
-0xa7,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x68,0xff,0xff,0xff,0xa3,0xff,
-0x89,0xff,0x83,0xff,0xff,0xff,0xc8,0xff,0x00,0xff,0x0e,0xff,0xff,0xff,0x0f,0xff,
-0x00,0xff,0x0d,0xff,0xff,0xff,0x4e,0xff,0xa7,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,
-0x00,0xff,0x68,0xff,0xff,0xff,0xa3,0xff,0x00,0xff,0x09,0xff,0xff,0xff,0x03,0xff,
-0x8b,0xff,0x83,0xff,0xff,0xff,0xd0,0xff,0x00,0xff,0x68,0xff,0xff,0xff,0x02,0xff,
-0x01,0xff,0x40,0xff,0xff,0xff,0x80,0xff,0x00,0xff,0x68,0xff,0xff,0xff,0x02,0xff,
-0x00,0xff,0x40,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x68,0xff,0xff,0xff,0x03,0xff,
-0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x10,0xff,
-0x8b,0xff,0x93,0xff,0xff,0xff,0x40,0xff,0x30,0xff,0x40,0xff,0xff,0xff,0x00,0xff,
-0x49,0xff,0x90,0xff,0xff,0xff,0x40,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,
-0x00,0xff,0x40,0xff,0xff,0xff,0x60,0xff,0x00,0xff,0x91,0xff,0xff,0xff,0xf0,0xff,
-0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,0x01,0xff,0x42,0xff,0xff,0xff,0x80,0xff,
-0x00,0xff,0x91,0xff,0xff,0xff,0x70,0xff,0x07,0xff,0x42,0xff,0xff,0xff,0x80,0xff,
-0x03,0xff,0x91,0xff,0xff,0xff,0x70,0xff,0x02,0xff,0x42,0xff,0xff,0xff,0x00,0xff,
-0x00,0xff,0x91,0xff,0xff,0xff,0xf0,0xff,0x08,0xff,0x42,0xff,0xff,0xff,0x00,0xff,
-0x03,0xff,0x91,0xff,0xff,0xff,0xf0,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x20,0xff,
-0x01,0xff,0x91,0xff,0xff,0xff,0x70,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x20,0xff,
-0x04,0xff,0x91,0xff,0xff,0xff,0x70,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,
-0x04,0xff,0x42,0xff,0xff,0xff,0x00,0xff,0x49,0xff,0x90,0xff,0xff,0xff,0x20,0xff,
-0x62,0xff,0x1c,0xff,0xff,0xff,0xff,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,
-0x00,0xff,0x40,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x91,0xff,0xff,0xff,0xf0,0xff,
-0x01,0xff,0x42,0xff,0xff,0xff,0x00,0xff,0x49,0xff,0x90,0xff,0xff,0xff,0x20,0xff,
-0x62,0xff,0x1c,0xff,0xff,0xff,0xff,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,
-0x00,0xff,0x40,0xff,0xff,0xff,0x40,0xff,0x8b,0xff,0x93,0xff,0xff,0xff,0x80,0xff,
-0x05,0xff,0x35,0xff,0xff,0xff,0x00,0xff,0x92,0xff,0x3b,0xff,0xff,0xff,0x00,0xff,
-0x00,0xff,0x34,0xff,0xff,0xff,0x08,0xff,0x00,0xff,0x38,0xff,0xff,0xff,0x08,0xff,
-0x00,0xff,0x3c,0xff,0xff,0xff,0x65,0xff,0x65,0xff,0x14,0xff,0xff,0xff,0x9e,0xff,
-0x00,0xff,0x60,0xff,0xff,0xff,0x03,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x13,0xff,
-0x00,0xff,0x78,0xff,0xff,0xff,0x13,0xff,0x00,0xff,0x78,0xff,0xff,0xff,0x03,0xff,
-0x01,0xff,0x42,0xff,0xff,0xff,0x00,0xff,0x49,0xff,0x90,0xff,0xff,0xff,0x20,0xff,
-0x62,0xff,0x1c,0xff,0xff,0xff,0xff,0xff,0x05,0xff,0x81,0xff,0xff,0xff,0xc0,0xff,
-0x78,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x21,0xff,0x18,0xff,0xff,0xff,0x71,0xff,
-0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,0x49,0xff,0x80,0xff,0xff,0xff,0x48,0xff,
-0x10,0xff,0x0f,0xff,0xff,0xff,0x03,0xff,0x66,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,
-0x74,0xff,0x18,0xff,0xff,0xff,0x54,0xff,0x86,0xff,0x83,0xff,0xff,0xff,0xc0,0xff,
-0x49,0xff,0x90,0xff,0xff,0xff,0x20,0xff,0x62,0xff,0x1c,0xff,0xff,0xff,0xff,0xff,
-0x86,0xff,0x83,0xff,0xff,0xff,0x80,0xff,0x01,0xff,0x40,0xff,0xff,0xff,0x04,0xff,
-0xe0,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x86,0xff,0x93,0xff,0xff,0xff,0x8a,0xff,
-0x67,0xff,0x1c,0xff,0xff,0xff,0x00,0xff,0x86,0xff,0x87,0xff,0xff,0xff,0xd0,0xff,
-0x75,0xff,0x1c,0xff,0xff,0xff,0x1f,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,
-0x00,0xff,0x48,0xff,0xff,0xff,0x00,0xff,0x82,0xff,0x93,0xff,0xff,0xff,0x40,0xff,
-0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,0x08,0xff,0x0c,0xff,0xff,0xff,0x00,0xff,
-0x86,0xff,0x8b,0xff,0xff,0xff,0xb0,0xff,0x00,0xff,0x38,0xff,0xff,0xff,0x08,0xff,
-0x00,0xff,0x38,0xff,0xff,0xff,0xf4,0xff,0xff,0xff,0x4f,0xff,0xff,0xff,0x89,0xff,
-0x8d,0xff,0x83,0xff,0xff,0xff,0x60,0xff,0x89,0xff,0x83,0xff,0xff,0xff,0x44,0xff,
-0x00,0xff,0x40,0xff,0xff,0xff,0x01,0xff,0x89,0xff,0x83,0xff,0xff,0xff,0x55,0xff,
-0x60,0xff,0x26,0xff,0xff,0xff,0x0f,0xff,0x49,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,
-0x00,0xff,0x78,0xff,0xff,0xff,0xa3,0xff,0x10,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,
-0x00,0xff,0x78,0xff,0xff,0xff,0xa0,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0x60,0xff,
-0x89,0xff,0x83,0xff,0xff,0xff,0x24,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x01,0xff,
-0x89,0xff,0x83,0xff,0xff,0xff,0x35,0xff,0x60,0xff,0x26,0xff,0xff,0xff,0x0f,0xff,
-0x49,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x78,0xff,0xff,0xff,0xa3,0xff,
-0x10,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x78,0xff,0xff,0xff,0xa3,0xff,
-0x8d,0xff,0x83,0xff,0xff,0xff,0x60,0xff,0x20,0xff,0x40,0xff,0xff,0xff,0x04,0xff,
-0x60,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x8d,0xff,0x93,0xff,0xff,0xff,0x6a,0xff,
-0x0c,0xff,0x0c,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,
-0x08,0xff,0x0c,0xff,0xff,0xff,0x00,0xff,0x86,0xff,0x87,0xff,0xff,0xff,0xb0,0xff,
-0x00,0xff,0x34,0xff,0xff,0xff,0x08,0xff,0x01,0xff,0x34,0xff,0xff,0xff,0x04,0xff,
-0x00,0xff,0x34,0xff,0xff,0xff,0x35,0xff,0xff,0xff,0x4f,0xff,0xff,0xff,0x89,0xff,
-0x00,0xff,0x09,0xff,0xff,0xff,0x01,0xff,0x87,0xff,0x8b,0xff,0xff,0xff,0xe0,0xff,
-0x00,0xff,0x38,0xff,0xff,0xff,0x88,0xff,0x00,0xff,0x70,0xff,0xff,0xff,0x03,0xff,
-0x00,0xff,0x68,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x70,0xff,0xff,0xff,0x03,0xff,
-0x00,0xff,0x68,0xff,0xff,0xff,0x03,0xff,0x87,0xff,0x9b,0xff,0xff,0xff,0xe0,0xff,
-0x0c,0xff,0x0c,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,
-0x01,0xff,0x3c,0xff,0xff,0xff,0x05,0xff,0x6a,0xff,0x14,0xff,0xff,0xff,0x9e,0xff,
-0x67,0xff,0x1c,0xff,0xff,0xff,0x3f,0xff,0x69,0xff,0x1c,0xff,0xff,0xff,0x0f,0xff,
-0x66,0xff,0x1c,0xff,0xff,0xff,0x1f,0xff,0x38,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,
-0x6a,0xff,0x14,0xff,0xff,0xff,0x85,0xff,0x8b,0xff,0x83,0xff,0xff,0xff,0x40,0xff,
-0x78,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,
-0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,0x82,0xff,0x83,0xff,0xff,0xff,0x40,0xff,
-0x78,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x6a,0xff,0x1c,0xff,0xff,0xff,0xf4,0xff,
-0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x10,0xff,
-0x47,0xff,0x90,0xff,0xff,0xff,0x20,0xff,0x87,0xff,0x83,0xff,0xff,0xff,0xf0,0xff,
-0x86,0xff,0x93,0xff,0xff,0xff,0x80,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x00,0xff,
-0x8d,0xff,0x93,0xff,0xff,0xff,0x60,0xff,0x82,0xff,0x93,0xff,0xff,0xff,0x40,0xff,
-0x86,0xff,0x87,0xff,0xff,0xff,0x90,0xff,0x02,0xff,0x34,0xff,0xff,0xff,0x08,0xff,
-0x00,0xff,0x60,0xff,0xff,0xff,0x03,0xff,0x89,0xff,0x93,0xff,0xff,0xff,0x20,0xff,
-0x00,0xff,0x60,0xff,0xff,0xff,0x03,0xff,0x89,0xff,0x93,0xff,0xff,0xff,0x30,0xff,
-0x00,0xff,0x60,0xff,0xff,0xff,0x03,0xff,0x89,0xff,0x93,0xff,0xff,0xff,0x40,0xff,
-0x00,0xff,0x60,0xff,0xff,0xff,0x03,0xff,0x89,0xff,0x93,0xff,0xff,0xff,0x50,0xff,
-0x86,0xff,0x97,0xff,0xff,0xff,0x90,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,
-0x00,0xff,0x34,0xff,0xff,0xff,0x64,0xff,0x00,0xff,0x34,0xff,0xff,0xff,0x35,0xff,
-0x01,0xff,0x34,0xff,0xff,0xff,0x96,0xff,0x00,0xff,0x38,0xff,0xff,0xff,0x34,0xff,
-0x00,0xff,0x38,0xff,0xff,0xff,0x65,0xff,0x01,0xff,0x38,0xff,0xff,0xff,0x96,0xff,
-0x00,0xff,0x38,0xff,0xff,0xff,0x08,0xff,0x02,0xff,0x34,0xff,0xff,0xff,0x49,0xff,
-0x02,0xff,0x38,0xff,0xff,0xff,0x49,0xff,0x10,0xff,0x40,0xff,0xff,0xff,0x06,0xff,
-0x10,0xff,0x40,0xff,0xff,0xff,0x02,0xff,0x30,0xff,0x0c,0xff,0xff,0xff,0x00,0xff,
-0x00,0xff,0x3c,0xff,0xff,0xff,0x25,0xff,0x6d,0xff,0x14,0xff,0xff,0xff,0xbe,0xff,
-0x98,0xff,0x50,0xff,0xff,0xff,0x73,0xff,0x88,0xff,0x50,0xff,0xff,0xff,0x73,0xff,
-0x83,0xff,0x68,0xff,0xff,0xff,0xc5,0xff,0x88,0xff,0x68,0xff,0xff,0xff,0xc4,0xff,
-0x83,0xff,0x68,0xff,0xff,0xff,0xc5,0xff,0x00,0xff,0x68,0xff,0xff,0xff,0xc6,0xff,
-0x98,0xff,0x50,0xff,0xff,0xff,0x73,0xff,0x88,0xff,0x50,0xff,0xff,0xff,0x73,0xff,
-0x83,0xff,0x78,0xff,0xff,0xff,0xc4,0xff,0x88,0xff,0x78,0xff,0xff,0xff,0xc5,0xff,
-0x83,0xff,0x78,0xff,0xff,0xff,0xc4,0xff,0x00,0xff,0x78,0xff,0xff,0xff,0xc6,0xff,
-0x98,0xff,0x50,0xff,0xff,0xff,0x73,0xff,0x88,0xff,0x50,0xff,0xff,0xff,0x73,0xff,
-0x83,0xff,0x68,0xff,0xff,0xff,0xc5,0xff,0x88,0xff,0x68,0xff,0xff,0xff,0xc4,0xff,
-0x83,0xff,0x68,0xff,0xff,0xff,0xc5,0xff,0x00,0xff,0x68,0xff,0xff,0xff,0xc6,0xff,
-0x00,0xff,0x3c,0xff,0xff,0xff,0x25,0xff,0x6e,0xff,0x14,0xff,0xff,0xff,0x8e,0xff,
-0x98,0xff,0x50,0xff,0xff,0xff,0x73,0xff,0x88,0xff,0x50,0xff,0xff,0xff,0x73,0xff,
-0x83,0xff,0x78,0xff,0xff,0xff,0xc4,0xff,0x88,0xff,0x78,0xff,0xff,0xff,0xc4,0xff,
-0x00,0xff,0x78,0xff,0xff,0xff,0xc4,0xff,0x20,0xff,0x0c,0xff,0xff,0xff,0x00,0xff,
-0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x34,0xff,0xff,0xff,0xe9,0xff,
-0x01,0xff,0x38,0xff,0xff,0xff,0x28,0xff,0x01,0xff,0x38,0xff,0xff,0xff,0x29,0xff,
-0x00,0xff,0x38,0xff,0xff,0xff,0x66,0xff,0x00,0xff,0x38,0xff,0xff,0xff,0x34,0xff,
-0x00,0xff,0x38,0xff,0xff,0xff,0x75,0xff,0x10,0xff,0x40,0xff,0xff,0xff,0x06,0xff,
-0x00,0xff,0x41,0xff,0xff,0xff,0x07,0xff,0x30,0xff,0x0c,0xff,0xff,0xff,0x00,0xff,
-0x98,0xff,0x70,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x3c,0xff,0xff,0xff,0x25,0xff,
-0x70,0xff,0x14,0xff,0xff,0xff,0x2e,0xff,0x80,0xff,0x70,0xff,0xff,0xff,0x42,0xff,
-0x63,0xff,0x72,0xff,0xff,0xff,0x20,0xff,0x80,0xff,0x68,0xff,0xff,0xff,0xa7,0xff,
-0x00,0xff,0x70,0xff,0xff,0xff,0x41,0xff,0x63,0xff,0x72,0xff,0xff,0xff,0x24,0xff,
-0x80,0xff,0x68,0xff,0xff,0xff,0xa7,0xff,0x00,0xff,0x70,0xff,0xff,0xff,0x46,0xff,
-0x63,0xff,0x72,0xff,0xff,0xff,0x24,0xff,0x80,0xff,0x68,0xff,0xff,0xff,0xa7,0xff,
-0x00,0xff,0x70,0xff,0xff,0xff,0x45,0xff,0x63,0xff,0x72,0xff,0xff,0xff,0x20,0xff,
-0x00,0xff,0x68,0xff,0xff,0xff,0xa7,0xff,0x80,0xff,0x70,0xff,0xff,0xff,0x42,0xff,
-0x63,0xff,0x72,0xff,0xff,0xff,0x20,0xff,0x80,0xff,0x70,0xff,0xff,0xff,0x41,0xff,
-0x63,0xff,0x6a,0xff,0xff,0xff,0xa7,0xff,0x00,0xff,0x70,0xff,0xff,0xff,0x24,0xff,
-0x80,0xff,0x68,0xff,0xff,0xff,0xa7,0xff,0x00,0xff,0x70,0xff,0xff,0xff,0x44,0xff,
-0x63,0xff,0x72,0xff,0xff,0xff,0x24,0xff,0x80,0xff,0x68,0xff,0xff,0xff,0xa7,0xff,
-0xf0,0xff,0x40,0xff,0xff,0xff,0x05,0xff,0x00,0xff,0x4f,0xff,0xff,0xff,0x04,0xff,
-0x00,0xff,0x0d,0xff,0xff,0xff,0x0b,0xff,0x80,0xff,0x27,0xff,0xff,0xff,0x0f,0xff,
-0x88,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0xea,0xff,0x20,0xff,0xff,0xff,0x0f,0xff,
-0x74,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x68,0xff,0xff,0xff,0xa7,0xff,
-0x00,0xff,0x70,0xff,0xff,0xff,0x24,0xff,0x80,0xff,0x70,0xff,0xff,0xff,0x44,0xff,
-0x63,0xff,0x72,0xff,0xff,0xff,0x24,0xff,0x80,0xff,0x68,0xff,0xff,0xff,0xa7,0xff,
-0x00,0xff,0x4f,0xff,0xff,0xff,0x04,0xff,0x00,0xff,0x0d,0xff,0xff,0xff,0x0b,0xff,
-0x80,0xff,0x27,0xff,0xff,0xff,0x0f,0xff,0x88,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,
-0xea,0xff,0x20,0xff,0xff,0xff,0x0f,0xff,0x74,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,
-0x00,0xff,0x68,0xff,0xff,0xff,0xa7,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,
-0x38,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x72,0xff,0x14,0xff,0xff,0xff,0x35,0xff,
-0x8b,0xff,0x83,0xff,0xff,0xff,0x30,0xff,0x78,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,
-0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,0x0e,0xff,0x40,0xff,0xff,0xff,0x00,0xff,
-0x10,0xff,0x90,0xff,0xff,0xff,0x10,0xff,0x08,0xff,0x40,0xff,0xff,0xff,0x00,0xff,
-0x10,0xff,0x90,0xff,0xff,0xff,0x90,0xff,0x02,0xff,0x40,0xff,0xff,0xff,0x40,0xff,
-0x11,0xff,0x90,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x00,0xff,
-0x10,0xff,0x90,0xff,0xff,0xff,0xb0,0xff,0xb0,0xff,0x40,0xff,0xff,0xff,0x00,0xff,
-0x47,0xff,0x90,0xff,0xff,0xff,0x50,0xff,0x30,0xff,0x40,0xff,0xff,0xff,0x00,0xff,
-0x47,0xff,0x90,0xff,0xff,0xff,0x40,0xff,0x78,0xff,0x42,0xff,0xff,0xff,0x50,0xff,
-0x48,0xff,0x90,0xff,0xff,0xff,0xa0,0xff,0x40,0xff,0x40,0xff,0xff,0xff,0x00,0xff,
-0x49,0xff,0x90,0xff,0xff,0xff,0x70,0xff,0x18,0xff,0x40,0xff,0xff,0xff,0x00,0xff,
-0x47,0xff,0x90,0xff,0xff,0xff,0x70,0xff,0x18,0xff,0x40,0xff,0xff,0xff,0x10,0xff,
-0x47,0xff,0x90,0xff,0xff,0xff,0x70,0xff,0x18,0xff,0x40,0xff,0xff,0xff,0x00,0xff,
-0x47,0xff,0x90,0xff,0xff,0xff,0x70,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x00,0xff,
-0x11,0xff,0x90,0xff,0xff,0xff,0x60,0xff,0x8d,0xff,0x93,0xff,0xff,0xff,0xd0,0xff,
-0x0b,0xff,0x40,0xff,0xff,0xff,0x80,0xff,0x11,0xff,0x90,0xff,0xff,0xff,0xf0,0xff,
-0x00,0xff,0x40,0xff,0xff,0xff,0x10,0xff,0x11,0xff,0x90,0xff,0xff,0xff,0xe0,0xff,
-0x00,0xff,0x48,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x93,0xff,0xff,0xff,0x00,0xff,
-0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,0x08,0xff,0x40,0xff,0xff,0xff,0x00,0xff,
-0x47,0xff,0x90,0xff,0xff,0xff,0x20,0xff,0x22,0xff,0x18,0xff,0xff,0xff,0x9f,0xff,
-0x00,0xff,0x48,0xff,0xff,0xff,0x10,0xff,0x86,0xff,0x93,0xff,0xff,0xff,0x70,0xff,
-0x22,0xff,0x18,0xff,0xff,0xff,0x9f,0xff,0x00,0xff,0x48,0xff,0xff,0xff,0x00,0xff,
-0x86,0xff,0x93,0xff,0xff,0xff,0x70,0xff,0x22,0xff,0x18,0xff,0xff,0xff,0x9f,0xff,
-0x00,0xff,0x48,0xff,0xff,0xff,0x20,0xff,0x86,0xff,0x93,0xff,0xff,0xff,0x70,0xff,
-0x22,0xff,0x18,0xff,0xff,0xff,0x9f,0xff,0x00,0xff,0x34,0xff,0xff,0xff,0x48,0xff,
-0x00,0xff,0x60,0xff,0xff,0xff,0x03,0xff,0x86,0xff,0x93,0xff,0xff,0xff,0xb0,0xff,
-0x00,0xff,0x60,0xff,0xff,0xff,0x03,0xff,0x86,0xff,0x93,0xff,0xff,0xff,0xc0,0xff,
-0x86,0xff,0x97,0xff,0xff,0xff,0xd0,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,
-0x80,0xff,0x37,0xff,0xff,0xff,0x02,0xff,0x84,0xff,0x3b,0xff,0xff,0xff,0x02,0xff,
-0x00,0xff,0x60,0xff,0xff,0xff,0x0b,0xff,0x0c,0xff,0x0d,0xff,0xff,0xff,0x90,0xff,
-0x00,0xff,0x70,0xff,0xff,0xff,0x0b,0xff,0x0c,0xff,0x0d,0xff,0xff,0xff,0xb0,0xff,
-0x88,0xff,0x37,0xff,0xff,0xff,0x03,0xff,0x8c,0xff,0x3b,0xff,0xff,0xff,0x03,0xff,
-0x00,0xff,0x40,0xff,0xff,0xff,0x01,0xff,0x8b,0xff,0x93,0xff,0xff,0xff,0x51,0xff,
-0x82,0xff,0x43,0xff,0xff,0xff,0x80,0xff,0x8b,0xff,0x93,0xff,0xff,0xff,0x60,0xff,
-0x00,0xff,0x34,0xff,0xff,0xff,0x89,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x00,0xff,
-0x0c,0xff,0x0d,0xff,0xff,0xff,0x80,0xff,0x0c,0xff,0x0d,0xff,0xff,0xff,0xa0,0xff,
-0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,0x80,0xff,0x37,0xff,0xff,0xff,0x00,0xff,
-0x00,0xff,0x34,0xff,0xff,0xff,0x08,0xff,0x02,0xff,0x3c,0xff,0xff,0xff,0x45,0xff,
-0x76,0xff,0x14,0xff,0xff,0xff,0xde,0xff,0x00,0xff,0xa0,0xff,0xff,0xff,0x03,0xff,
-0x84,0xff,0x37,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x34,0xff,0xff,0xff,0x08,0xff,
-0x02,0xff,0x3c,0xff,0xff,0xff,0x45,0xff,0x77,0xff,0x14,0xff,0xff,0xff,0x2e,0xff,
-0x00,0xff,0xa0,0xff,0xff,0xff,0x03,0xff,0x7e,0xff,0x38,0xff,0xff,0xff,0x00,0xff,
-0x00,0xff,0x38,0xff,0xff,0xff,0x08,0xff,0x00,0xff,0x3c,0xff,0xff,0xff,0xe5,0xff,
-0x77,0xff,0x14,0xff,0xff,0xff,0x8e,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x00,0xff,
-0x00,0xff,0x58,0xff,0xff,0xff,0x03,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,
-0x64,0xff,0x1c,0xff,0xff,0xff,0x4f,0xff,0x38,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,
-0x77,0xff,0x14,0xff,0xff,0xff,0xe5,0xff,0x8b,0xff,0x83,0xff,0xff,0xff,0x40,0xff,
-0x78,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x64,0xff,0x1c,0xff,0xff,0xff,0x8f,0xff,
-0x38,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x78,0xff,0x14,0xff,0xff,0xff,0x35,0xff,
-0x8b,0xff,0x83,0xff,0xff,0xff,0x40,0xff,0x78,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,
-0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x34,0xff,0xff,0xff,0x09,0xff,
-0x00,0xff,0x34,0xff,0xff,0xff,0x85,0xff,0x00,0xff,0x34,0xff,0xff,0xff,0x56,0xff,
-0x00,0xff,0x09,0xff,0xff,0xff,0x06,0xff,0x20,0xff,0x40,0xff,0xff,0xff,0x00,0xff,
-0x01,0xff,0x40,0xff,0xff,0xff,0xc1,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x44,0xff,
-0x00,0xff,0x68,0xff,0xff,0xff,0x05,0xff,0x00,0xff,0x68,0xff,0xff,0xff,0x15,0xff,
-0x00,0xff,0x68,0xff,0xff,0xff,0x05,0xff,0x00,0xff,0x68,0xff,0xff,0xff,0x45,0xff,
-0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,0x86,0xff,0x87,0xff,0xff,0xff,0xf0,0xff,
-0x86,0xff,0x8b,0xff,0xff,0xff,0xe0,0xff,0x00,0xff,0x34,0xff,0xff,0xff,0xc8,0xff,
-0x00,0xff,0x38,0xff,0xff,0xff,0xc8,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x03,0xff,
-0x00,0xff,0x60,0xff,0xff,0xff,0x13,0xff,0x00,0xff,0x78,0xff,0xff,0xff,0x13,0xff,
-0x00,0xff,0x78,0xff,0xff,0xff,0x03,0xff,0x86,0xff,0x97,0xff,0xff,0xff,0xf0,0xff,
-0x86,0xff,0x9b,0xff,0xff,0xff,0xe0,0xff,0x05,0xff,0x81,0xff,0xff,0xff,0xc0,0xff,
-0x78,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x21,0xff,0x18,0xff,0xff,0xff,0x71,0xff,
-0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,0x7f,0xff,0x38,0xff,0xff,0xff,0x01,0xff,
-0x00,0xff,0x38,0xff,0xff,0xff,0x09,0xff,0x00,0xff,0x38,0xff,0xff,0xff,0x06,0xff,
-0x7e,0xff,0x40,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0xb1,0xff,
-0x08,0xff,0x0c,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x3c,0xff,0xff,0xff,0xc5,0xff,
-0x7a,0xff,0x14,0xff,0xff,0xff,0xbe,0xff,0x00,0xff,0x50,0xff,0xff,0xff,0x46,0xff,
-0xe1,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x7a,0xff,0x1c,0xff,0xff,0xff,0xe0,0xff,
-0x60,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x58,0xff,0xff,0xff,0xa7,0xff,
-0x0c,0xff,0x0c,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,
-0x00,0xff,0x40,0xff,0xff,0xff,0xc4,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,
-0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
-0xff,0xff,0xff,0xff };
diff --git a/sound/pci/korg1212/korg1212.c b/sound/pci/korg1212/korg1212.c
index f4c85b52bde3..5f8006b42750 100644
--- a/sound/pci/korg1212/korg1212.c
+++ b/sound/pci/korg1212/korg1212.c
@@ -260,14 +260,6 @@ enum MonitorModeSelector {
#define COMMAND_ACK_DELAY 13 // number of RTC ticks to wait for an acknowledgement
// from the card after sending a command.
-#ifdef CONFIG_SND_KORG1212_FIRMWARE_IN_KERNEL
-#include "korg1212-firmware.h"
-static const struct firmware static_dsp_code = {
- .data = (u8 *)dspCode,
- .size = sizeof dspCode
-};
-#endif
-
enum ClockSourceIndex {
K1212_CLKIDX_AdatAt44_1K = 0, // selects source as ADAT at 44.1 kHz
K1212_CLKIDX_AdatAt48K, // selects source as ADAT at 48 kHz
@@ -412,9 +404,7 @@ struct snd_korg1212 {
MODULE_DESCRIPTION("korg1212");
MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("{{KORG,korg1212}}");
-#ifndef CONFIG_SND_KORG1212_FIRMWARE_IN_KERNEL
MODULE_FIRMWARE("korg/k1212.dsp");
-#endif
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
@@ -1291,7 +1281,8 @@ static int snd_korg1212_silence(struct snd_korg1212 *korg1212, int pos, int coun
K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: snd_korg1212_silence pos=%d offset=%d size=%d count=%d\n",
pos, offset, size, count);
- snd_assert(pos + count <= K1212_MAX_SAMPLES, return -EINVAL);
+ if (snd_BUG_ON(pos + count > K1212_MAX_SAMPLES))
+ return -EINVAL;
for (i=0; i < count; i++) {
#if K1212_DEBUG_LEVEL > 0
@@ -1316,7 +1307,8 @@ static int snd_korg1212_copy_to(struct snd_korg1212 *korg1212, void __user *dst,
K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: snd_korg1212_copy_to pos=%d offset=%d size=%d\n",
pos, offset, size);
- snd_assert(pos + count <= K1212_MAX_SAMPLES, return -EINVAL);
+ if (snd_BUG_ON(pos + count > K1212_MAX_SAMPLES))
+ return -EINVAL;
for (i=0; i < count; i++) {
#if K1212_DEBUG_LEVEL > 0
@@ -1346,7 +1338,8 @@ static int snd_korg1212_copy_from(struct snd_korg1212 *korg1212, void __user *sr
K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: snd_korg1212_copy_from pos=%d offset=%d size=%d count=%d\n",
pos, offset, size, count);
- snd_assert(pos + count <= K1212_MAX_SAMPLES, return -EINVAL);
+ if (snd_BUG_ON(pos + count > K1212_MAX_SAMPLES))
+ return -EINVAL;
for (i=0; i < count; i++) {
#if K1212_DEBUG_LEVEL > 0
@@ -2348,9 +2341,6 @@ static int __devinit snd_korg1212_create(struct snd_card *card, struct pci_dev *
korg1212->AdatTimeCodePhy = korg1212->sharedBufferPhy +
offsetof(struct KorgSharedBuffer, AdatTimeCode);
-#ifdef CONFIG_SND_KORG1212_FIRMWARE_IN_KERNEL
- dsp_code = &static_dsp_code;
-#else
err = request_firmware(&dsp_code, "korg/k1212.dsp", &pci->dev);
if (err < 0) {
release_firmware(dsp_code);
@@ -2358,15 +2348,12 @@ static int __devinit snd_korg1212_create(struct snd_card *card, struct pci_dev *
snd_korg1212_free(korg1212);
return err;
}
-#endif
if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
dsp_code->size, &korg1212->dma_dsp) < 0) {
snd_printk(KERN_ERR "korg1212: cannot allocate dsp code memory (%zd bytes)\n", dsp_code->size);
snd_korg1212_free(korg1212);
-#ifndef CONFIG_SND_KORG1212_FIRMWARE_IN_KERNEL
release_firmware(dsp_code);
-#endif
return -ENOMEM;
}
@@ -2376,9 +2363,7 @@ static int __devinit snd_korg1212_create(struct snd_card *card, struct pci_dev *
memcpy(korg1212->dma_dsp.area, dsp_code->data, dsp_code->size);
-#ifndef CONFIG_SND_KORG1212_FIRMWARE_IN_KERNEL
release_firmware(dsp_code);
-#endif
rc = snd_korg1212_Send1212Command(korg1212, K1212_DB_RebootCard, 0, 0, 0, 0);
diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c
index a536c59fbea1..9ff3f9e34404 100644
--- a/sound/pci/maestro3.c
+++ b/sound/pci/maestro3.c
@@ -58,10 +58,8 @@ MODULE_SUPPORTED_DEVICE("{{ESS,Maestro3 PCI},"
"{ESS,Allegro PCI},"
"{ESS,Allegro-1 PCI},"
"{ESS,Canyon3D-2/LE PCI}}");
-#ifndef CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL
MODULE_FIRMWARE("ess/maestro3_assp_kernel.fw");
MODULE_FIRMWARE("ess/maestro3_assp_minisrc.fw");
-#endif
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
@@ -1177,7 +1175,8 @@ snd_m3_pcm_trigger(struct snd_pcm_substream *subs, int cmd)
struct m3_dma *s = subs->runtime->private_data;
int err = -EINVAL;
- snd_assert(s != NULL, return -ENXIO);
+ if (snd_BUG_ON(!s))
+ return -ENXIO;
spin_lock(&chip->reg_lock);
switch (cmd) {
@@ -1489,7 +1488,8 @@ snd_m3_pcm_prepare(struct snd_pcm_substream *subs)
struct snd_pcm_runtime *runtime = subs->runtime;
struct m3_dma *s = runtime->private_data;
- snd_assert(s != NULL, return -ENXIO);
+ if (snd_BUG_ON(!s))
+ return -ENXIO;
if (runtime->format != SNDRV_PCM_FORMAT_U8 &&
runtime->format != SNDRV_PCM_FORMAT_S16_LE)
@@ -1548,7 +1548,9 @@ snd_m3_pcm_pointer(struct snd_pcm_substream *subs)
struct snd_m3 *chip = snd_pcm_substream_chip(subs);
unsigned int ptr;
struct m3_dma *s = subs->runtime->private_data;
- snd_assert(s != NULL, return 0);
+
+ if (snd_BUG_ON(!s))
+ return 0;
spin_lock(&chip->reg_lock);
ptr = snd_m3_get_pointer(chip, s, subs);
@@ -2101,163 +2103,6 @@ static int __devinit snd_m3_mixer(struct snd_m3 *chip)
}
-#ifdef CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL
-
-/*
- * DSP Code images
- */
-
-static const u16 assp_kernel_image[] = {
- 0x7980, 0x0030, 0x7980, 0x03B4, 0x7980, 0x03B4, 0x7980, 0x00FB, 0x7980, 0x00DD, 0x7980, 0x03B4,
- 0x7980, 0x0332, 0x7980, 0x0287, 0x7980, 0x03B4, 0x7980, 0x03B4, 0x7980, 0x03B4, 0x7980, 0x03B4,
- 0x7980, 0x031A, 0x7980, 0x03B4, 0x7980, 0x022F, 0x7980, 0x03B4, 0x7980, 0x03B4, 0x7980, 0x03B4,
- 0x7980, 0x03B4, 0x7980, 0x03B4, 0x7980, 0x0063, 0x7980, 0x006B, 0x7980, 0x03B4, 0x7980, 0x03B4,
- 0xBF80, 0x2C7C, 0x8806, 0x8804, 0xBE40, 0xBC20, 0xAE09, 0x1000, 0xAE0A, 0x0001, 0x6938, 0xEB08,
- 0x0053, 0x695A, 0xEB08, 0x00D6, 0x0009, 0x8B88, 0x6980, 0xE388, 0x0036, 0xBE30, 0xBC20, 0x6909,
- 0xB801, 0x9009, 0xBE41, 0xBE41, 0x6928, 0xEB88, 0x0078, 0xBE41, 0xBE40, 0x7980, 0x0038, 0xBE41,
- 0xBE41, 0x903A, 0x6938, 0xE308, 0x0056, 0x903A, 0xBE41, 0xBE40, 0xEF00, 0x903A, 0x6939, 0xE308,
- 0x005E, 0x903A, 0xEF00, 0x690B, 0x660C, 0xEF8C, 0x690A, 0x660C, 0x620B, 0x6609, 0xEF00, 0x6910,
- 0x660F, 0xEF04, 0xE388, 0x0075, 0x690E, 0x660F, 0x6210, 0x660D, 0xEF00, 0x690E, 0x660D, 0xEF00,
- 0xAE70, 0x0001, 0xBC20, 0xAE27, 0x0001, 0x6939, 0xEB08, 0x005D, 0x6926, 0xB801, 0x9026, 0x0026,
- 0x8B88, 0x6980, 0xE388, 0x00CB, 0x9028, 0x0D28, 0x4211, 0xE100, 0x007A, 0x4711, 0xE100, 0x00A0,
- 0x7A80, 0x0063, 0xB811, 0x660A, 0x6209, 0xE304, 0x007A, 0x0C0B, 0x4005, 0x100A, 0xBA01, 0x9012,
- 0x0C12, 0x4002, 0x7980, 0x00AF, 0x7A80, 0x006B, 0xBE02, 0x620E, 0x660D, 0xBA10, 0xE344, 0x007A,
- 0x0C10, 0x4005, 0x100E, 0xBA01, 0x9012, 0x0C12, 0x4002, 0x1003, 0xBA02, 0x9012, 0x0C12, 0x4000,
- 0x1003, 0xE388, 0x00BA, 0x1004, 0x7980, 0x00BC, 0x1004, 0xBA01, 0x9012, 0x0C12, 0x4001, 0x0C05,
- 0x4003, 0x0C06, 0x4004, 0x1011, 0xBFB0, 0x01FF, 0x9012, 0x0C12, 0x4006, 0xBC20, 0xEF00, 0xAE26,
- 0x1028, 0x6970, 0xBFD0, 0x0001, 0x9070, 0xE388, 0x007A, 0xAE28, 0x0000, 0xEF00, 0xAE70, 0x0300,
- 0x0C70, 0xB00C, 0xAE5A, 0x0000, 0xEF00, 0x7A80, 0x038A, 0x697F, 0xB801, 0x907F, 0x0056, 0x8B88,
- 0x0CA0, 0xB008, 0xAF71, 0xB000, 0x4E71, 0xE200, 0x00F3, 0xAE56, 0x1057, 0x0056, 0x0CA0, 0xB008,
- 0x8056, 0x7980, 0x03A1, 0x0810, 0xBFA0, 0x1059, 0xE304, 0x03A1, 0x8056, 0x7980, 0x03A1, 0x7A80,
- 0x038A, 0xBF01, 0xBE43, 0xBE59, 0x907C, 0x6937, 0xE388, 0x010D, 0xBA01, 0xE308, 0x010C, 0xAE71,
- 0x0004, 0x0C71, 0x5000, 0x6936, 0x9037, 0xBF0A, 0x109E, 0x8B8A, 0xAF80, 0x8014, 0x4C80, 0xBF0A,
- 0x0560, 0xF500, 0xBF0A, 0x0520, 0xB900, 0xBB17, 0x90A0, 0x6917, 0xE388, 0x0148, 0x0D17, 0xE100,
- 0x0127, 0xBF0C, 0x0578, 0xBF0D, 0x057C, 0x7980, 0x012B, 0xBF0C, 0x0538, 0xBF0D, 0x053C, 0x6900,
- 0xE308, 0x0135, 0x8B8C, 0xBE59, 0xBB07, 0x90A0, 0xBC20, 0x7980, 0x0157, 0x030C, 0x8B8B, 0xB903,
- 0x8809, 0xBEC6, 0x013E, 0x69AC, 0x90AB, 0x69AD, 0x90AB, 0x0813, 0x660A, 0xE344, 0x0144, 0x0309,
- 0x830C, 0xBC20, 0x7980, 0x0157, 0x6955, 0xE388, 0x0157, 0x7C38, 0xBF0B, 0x0578, 0xF500, 0xBF0B,
- 0x0538, 0xB907, 0x8809, 0xBEC6, 0x0156, 0x10AB, 0x90AA, 0x6974, 0xE388, 0x0163, 0xAE72, 0x0540,
- 0xF500, 0xAE72, 0x0500, 0xAE61, 0x103B, 0x7A80, 0x02F6, 0x6978, 0xE388, 0x0182, 0x8B8C, 0xBF0C,
- 0x0560, 0xE500, 0x7C40, 0x0814, 0xBA20, 0x8812, 0x733D, 0x7A80, 0x0380, 0x733E, 0x7A80, 0x0380,
- 0x8B8C, 0xBF0C, 0x056C, 0xE500, 0x7C40, 0x0814, 0xBA2C, 0x8812, 0x733F, 0x7A80, 0x0380, 0x7340,
- 0x7A80, 0x0380, 0x6975, 0xE388, 0x018E, 0xAE72, 0x0548, 0xF500, 0xAE72, 0x0508, 0xAE61, 0x1041,
- 0x7A80, 0x02F6, 0x6979, 0xE388, 0x01AD, 0x8B8C, 0xBF0C, 0x0560, 0xE500, 0x7C40, 0x0814, 0xBA18,
- 0x8812, 0x7343, 0x7A80, 0x0380, 0x7344, 0x7A80, 0x0380, 0x8B8C, 0xBF0C, 0x056C, 0xE500, 0x7C40,
- 0x0814, 0xBA24, 0x8812, 0x7345, 0x7A80, 0x0380, 0x7346, 0x7A80, 0x0380, 0x6976, 0xE388, 0x01B9,
- 0xAE72, 0x0558, 0xF500, 0xAE72, 0x0518, 0xAE61, 0x1047, 0x7A80, 0x02F6, 0x697A, 0xE388, 0x01D8,
- 0x8B8C, 0xBF0C, 0x0560, 0xE500, 0x7C40, 0x0814, 0xBA08, 0x8812, 0x7349, 0x7A80, 0x0380, 0x734A,
- 0x7A80, 0x0380, 0x8B8C, 0xBF0C, 0x056C, 0xE500, 0x7C40, 0x0814, 0xBA14, 0x8812, 0x734B, 0x7A80,
- 0x0380, 0x734C, 0x7A80, 0x0380, 0xBC21, 0xAE1C, 0x1090, 0x8B8A, 0xBF0A, 0x0560, 0xE500, 0x7C40,
- 0x0812, 0xB804, 0x8813, 0x8B8D, 0xBF0D, 0x056C, 0xE500, 0x7C40, 0x0815, 0xB804, 0x8811, 0x7A80,
- 0x034A, 0x8B8A, 0xBF0A, 0x0560, 0xE500, 0x7C40, 0x731F, 0xB903, 0x8809, 0xBEC6, 0x01F9, 0x548A,
- 0xBE03, 0x98A0, 0x7320, 0xB903, 0x8809, 0xBEC6, 0x0201, 0x548A, 0xBE03, 0x98A0, 0x1F20, 0x2F1F,
- 0x9826, 0xBC20, 0x6935, 0xE388, 0x03A1, 0x6933, 0xB801, 0x9033, 0xBFA0, 0x02EE, 0xE308, 0x03A1,
- 0x9033, 0xBF00, 0x6951, 0xE388, 0x021F, 0x7334, 0xBE80, 0x5760, 0xBE03, 0x9F7E, 0xBE59, 0x9034,
- 0x697E, 0x0D51, 0x9013, 0xBC20, 0x695C, 0xE388, 0x03A1, 0x735E, 0xBE80, 0x5760, 0xBE03, 0x9F7E,
- 0xBE59, 0x905E, 0x697E, 0x0D5C, 0x9013, 0x7980, 0x03A1, 0x7A80, 0x038A, 0xBF01, 0xBE43, 0x6977,
- 0xE388, 0x024E, 0xAE61, 0x104D, 0x0061, 0x8B88, 0x6980, 0xE388, 0x024E, 0x9071, 0x0D71, 0x000B,
- 0xAFA0, 0x8010, 0xAFA0, 0x8010, 0x0810, 0x660A, 0xE308, 0x0249, 0x0009, 0x0810, 0x660C, 0xE388,
- 0x024E, 0x800B, 0xBC20, 0x697B, 0xE388, 0x03A1, 0xBF0A, 0x109E, 0x8B8A, 0xAF80, 0x8014, 0x4C80,
- 0xE100, 0x0266, 0x697C, 0xBF90, 0x0560, 0x9072, 0x0372, 0x697C, 0xBF90, 0x0564, 0x9073, 0x0473,
- 0x7980, 0x0270, 0x697C, 0xBF90, 0x0520, 0x9072, 0x0372, 0x697C, 0xBF90, 0x0524, 0x9073, 0x0473,
- 0x697C, 0xB801, 0x907C, 0xBF0A, 0x10FD, 0x8B8A, 0xAF80, 0x8010, 0x734F, 0x548A, 0xBE03, 0x9880,
- 0xBC21, 0x7326, 0x548B, 0xBE03, 0x618B, 0x988C, 0xBE03, 0x6180, 0x9880, 0x7980, 0x03A1, 0x7A80,
- 0x038A, 0x0D28, 0x4711, 0xE100, 0x02BE, 0xAF12, 0x4006, 0x6912, 0xBFB0, 0x0C00, 0xE388, 0x02B6,
- 0xBFA0, 0x0800, 0xE388, 0x02B2, 0x6912, 0xBFB0, 0x0C00, 0xBFA0, 0x0400, 0xE388, 0x02A3, 0x6909,
- 0x900B, 0x7980, 0x02A5, 0xAF0B, 0x4005, 0x6901, 0x9005, 0x6902, 0x9006, 0x4311, 0xE100, 0x02ED,
- 0x6911, 0xBFC0, 0x2000, 0x9011, 0x7980, 0x02ED, 0x6909, 0x900B, 0x7980, 0x02B8, 0xAF0B, 0x4005,
- 0xAF05, 0x4003, 0xAF06, 0x4004, 0x7980, 0x02ED, 0xAF12, 0x4006, 0x6912, 0xBFB0, 0x0C00, 0xE388,
- 0x02E7, 0xBFA0, 0x0800, 0xE388, 0x02E3, 0x6912, 0xBFB0, 0x0C00, 0xBFA0, 0x0400, 0xE388, 0x02D4,
- 0x690D, 0x9010, 0x7980, 0x02D6, 0xAF10, 0x4005, 0x6901, 0x9005, 0x6902, 0x9006, 0x4311, 0xE100,
- 0x02ED, 0x6911, 0xBFC0, 0x2000, 0x9011, 0x7980, 0x02ED, 0x690D, 0x9010, 0x7980, 0x02E9, 0xAF10,
- 0x4005, 0xAF05, 0x4003, 0xAF06, 0x4004, 0xBC20, 0x6970, 0x9071, 0x7A80, 0x0078, 0x6971, 0x9070,
- 0x7980, 0x03A1, 0xBC20, 0x0361, 0x8B8B, 0x6980, 0xEF88, 0x0272, 0x0372, 0x7804, 0x9071, 0x0D71,
- 0x8B8A, 0x000B, 0xB903, 0x8809, 0xBEC6, 0x0309, 0x69A8, 0x90AB, 0x69A8, 0x90AA, 0x0810, 0x660A,
- 0xE344, 0x030F, 0x0009, 0x0810, 0x660C, 0xE388, 0x0314, 0x800B, 0xBC20, 0x6961, 0xB801, 0x9061,
- 0x7980, 0x02F7, 0x7A80, 0x038A, 0x5D35, 0x0001, 0x6934, 0xB801, 0x9034, 0xBF0A, 0x109E, 0x8B8A,
- 0xAF80, 0x8014, 0x4880, 0xAE72, 0x0550, 0xF500, 0xAE72, 0x0510, 0xAE61, 0x1051, 0x7A80, 0x02F6,
- 0x7980, 0x03A1, 0x7A80, 0x038A, 0x5D35, 0x0002, 0x695E, 0xB801, 0x905E, 0xBF0A, 0x109E, 0x8B8A,
- 0xAF80, 0x8014, 0x4780, 0xAE72, 0x0558, 0xF500, 0xAE72, 0x0518, 0xAE61, 0x105C, 0x7A80, 0x02F6,
- 0x7980, 0x03A1, 0x001C, 0x8B88, 0x6980, 0xEF88, 0x901D, 0x0D1D, 0x100F, 0x6610, 0xE38C, 0x0358,
- 0x690E, 0x6610, 0x620F, 0x660D, 0xBA0F, 0xE301, 0x037A, 0x0410, 0x8B8A, 0xB903, 0x8809, 0xBEC6,
- 0x036C, 0x6A8C, 0x61AA, 0x98AB, 0x6A8C, 0x61AB, 0x98AD, 0x6A8C, 0x61AD, 0x98A9, 0x6A8C, 0x61A9,
- 0x98AA, 0x7C04, 0x8B8B, 0x7C04, 0x8B8D, 0x7C04, 0x8B89, 0x7C04, 0x0814, 0x660E, 0xE308, 0x0379,
- 0x040D, 0x8410, 0xBC21, 0x691C, 0xB801, 0x901C, 0x7980, 0x034A, 0xB903, 0x8809, 0x8B8A, 0xBEC6,
- 0x0388, 0x54AC, 0xBE03, 0x618C, 0x98AA, 0xEF00, 0xBC20, 0xBE46, 0x0809, 0x906B, 0x080A, 0x906C,
- 0x080B, 0x906D, 0x081A, 0x9062, 0x081B, 0x9063, 0x081E, 0x9064, 0xBE59, 0x881E, 0x8065, 0x8166,
- 0x8267, 0x8368, 0x8469, 0x856A, 0xEF00, 0xBC20, 0x696B, 0x8809, 0x696C, 0x880A, 0x696D, 0x880B,
- 0x6962, 0x881A, 0x6963, 0x881B, 0x6964, 0x881E, 0x0065, 0x0166, 0x0267, 0x0368, 0x0469, 0x056A,
- 0xBE3A,
-};
-
-/*
- * Mini sample rate converter code image
- * that is to be loaded at 0x400 on the DSP.
- */
-static const u16 assp_minisrc_image[] = {
-
- 0xBF80, 0x101E, 0x906E, 0x006E, 0x8B88, 0x6980, 0xEF88, 0x906F, 0x0D6F, 0x6900, 0xEB08, 0x0412,
- 0xBC20, 0x696E, 0xB801, 0x906E, 0x7980, 0x0403, 0xB90E, 0x8807, 0xBE43, 0xBF01, 0xBE47, 0xBE41,
- 0x7A80, 0x002A, 0xBE40, 0x3029, 0xEFCC, 0xBE41, 0x7A80, 0x0028, 0xBE40, 0x3028, 0xEFCC, 0x6907,
- 0xE308, 0x042A, 0x6909, 0x902C, 0x7980, 0x042C, 0x690D, 0x902C, 0x1009, 0x881A, 0x100A, 0xBA01,
- 0x881B, 0x100D, 0x881C, 0x100E, 0xBA01, 0x881D, 0xBF80, 0x00ED, 0x881E, 0x050C, 0x0124, 0xB904,
- 0x9027, 0x6918, 0xE308, 0x04B3, 0x902D, 0x6913, 0xBFA0, 0x7598, 0xF704, 0xAE2D, 0x00FF, 0x8B8D,
- 0x6919, 0xE308, 0x0463, 0x691A, 0xE308, 0x0456, 0xB907, 0x8809, 0xBEC6, 0x0453, 0x10A9, 0x90AD,
- 0x7980, 0x047C, 0xB903, 0x8809, 0xBEC6, 0x0460, 0x1889, 0x6C22, 0x90AD, 0x10A9, 0x6E23, 0x6C22,
- 0x90AD, 0x7980, 0x047C, 0x101A, 0xE308, 0x046F, 0xB903, 0x8809, 0xBEC6, 0x046C, 0x10A9, 0x90A0,
- 0x90AD, 0x7980, 0x047C, 0xB901, 0x8809, 0xBEC6, 0x047B, 0x1889, 0x6C22, 0x90A0, 0x90AD, 0x10A9,
- 0x6E23, 0x6C22, 0x90A0, 0x90AD, 0x692D, 0xE308, 0x049C, 0x0124, 0xB703, 0xB902, 0x8818, 0x8B89,
- 0x022C, 0x108A, 0x7C04, 0x90A0, 0x692B, 0x881F, 0x7E80, 0x055B, 0x692A, 0x8809, 0x8B89, 0x99A0,
- 0x108A, 0x90A0, 0x692B, 0x881F, 0x7E80, 0x055B, 0x692A, 0x8809, 0x8B89, 0x99AF, 0x7B99, 0x0484,
- 0x0124, 0x060F, 0x101B, 0x2013, 0x901B, 0xBFA0, 0x7FFF, 0xE344, 0x04AC, 0x901B, 0x8B89, 0x7A80,
- 0x051A, 0x6927, 0xBA01, 0x9027, 0x7A80, 0x0523, 0x6927, 0xE308, 0x049E, 0x7980, 0x050F, 0x0624,
- 0x1026, 0x2013, 0x9026, 0xBFA0, 0x7FFF, 0xE304, 0x04C0, 0x8B8D, 0x7A80, 0x051A, 0x7980, 0x04B4,
- 0x9026, 0x1013, 0x3026, 0x901B, 0x8B8D, 0x7A80, 0x051A, 0x7A80, 0x0523, 0x1027, 0xBA01, 0x9027,
- 0xE308, 0x04B4, 0x0124, 0x060F, 0x8B89, 0x691A, 0xE308, 0x04EA, 0x6919, 0xE388, 0x04E0, 0xB903,
- 0x8809, 0xBEC6, 0x04DD, 0x1FA0, 0x2FAE, 0x98A9, 0x7980, 0x050F, 0xB901, 0x8818, 0xB907, 0x8809,
- 0xBEC6, 0x04E7, 0x10EE, 0x90A9, 0x7980, 0x050F, 0x6919, 0xE308, 0x04FE, 0xB903, 0x8809, 0xBE46,
- 0xBEC6, 0x04FA, 0x17A0, 0xBE1E, 0x1FAE, 0xBFBF, 0xFF00, 0xBE13, 0xBFDF, 0x8080, 0x99A9, 0xBE47,
- 0x7980, 0x050F, 0xB901, 0x8809, 0xBEC6, 0x050E, 0x16A0, 0x26A0, 0xBFB7, 0xFF00, 0xBE1E, 0x1EA0,
- 0x2EAE, 0xBFBF, 0xFF00, 0xBE13, 0xBFDF, 0x8080, 0x99A9, 0x850C, 0x860F, 0x6907, 0xE388, 0x0516,
- 0x0D07, 0x8510, 0xBE59, 0x881E, 0xBE4A, 0xEF00, 0x101E, 0x901C, 0x101F, 0x901D, 0x10A0, 0x901E,
- 0x10A0, 0x901F, 0xEF00, 0x101E, 0x301C, 0x9020, 0x731B, 0x5420, 0xBE03, 0x9825, 0x1025, 0x201C,
- 0x9025, 0x7325, 0x5414, 0xBE03, 0x8B8E, 0x9880, 0x692F, 0xE388, 0x0539, 0xBE59, 0xBB07, 0x6180,
- 0x9880, 0x8BA0, 0x101F, 0x301D, 0x9021, 0x731B, 0x5421, 0xBE03, 0x982E, 0x102E, 0x201D, 0x902E,
- 0x732E, 0x5415, 0xBE03, 0x9880, 0x692F, 0xE388, 0x054F, 0xBE59, 0xBB07, 0x6180, 0x9880, 0x8BA0,
- 0x6918, 0xEF08, 0x7325, 0x5416, 0xBE03, 0x98A0, 0x732E, 0x5417, 0xBE03, 0x98A0, 0xEF00, 0x8BA0,
- 0xBEC6, 0x056B, 0xBE59, 0xBB04, 0xAA90, 0xBE04, 0xBE1E, 0x99E0, 0x8BE0, 0x69A0, 0x90D0, 0x69A0,
- 0x90D0, 0x081F, 0xB805, 0x881F, 0x8B90, 0x69A0, 0x90D0, 0x69A0, 0x9090, 0x8BD0, 0x8BD8, 0xBE1F,
- 0xEF00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
-};
-
-static const struct firmware assp_kernel = {
- .data = (u8 *)assp_kernel_image,
- .size = sizeof assp_kernel_image
-};
-static const struct firmware assp_minisrc = {
- .data = (u8 *)assp_minisrc_image,
- .size = sizeof assp_minisrc_image
-};
-
-#else /* CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL */
-
-#ifdef __LITTLE_ENDIAN
-static inline void snd_m3_convert_from_le(const struct firmware *fw) { }
-#else
-static void snd_m3_convert_from_le(const struct firmware *fw)
-{
- int i;
- u16 *data = (u16 *)fw->data;
-
- for (i = 0; i < fw->size / 2; ++i)
- le16_to_cpus(&data[i]);
-}
-#endif
-
-#endif /* CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL */
-
-
/*
* initialize ASSP
*/
@@ -2271,7 +2116,7 @@ static const u16 minisrc_lpf[MINISRC_LPF_LEN] = {
static void snd_m3_assp_init(struct snd_m3 *chip)
{
unsigned int i;
- u16 *data;
+ const u16 *data;
/* zero kernel data */
for (i = 0; i < (REV_B_DATA_MEMORY_UNIT_LENGTH * NUM_UNITS_KERNEL_DATA) / 2; i++)
@@ -2289,10 +2134,11 @@ static void snd_m3_assp_init(struct snd_m3 *chip)
KDATA_DMA_XFER0);
/* write kernel into code memory.. */
- data = (u16 *)chip->assp_kernel_image->data;
+ data = (const u16 *)chip->assp_kernel_image->data;
for (i = 0 ; i * 2 < chip->assp_kernel_image->size; i++) {
snd_m3_assp_write(chip, MEMTYPE_INTERNAL_CODE,
- REV_B_CODE_MEMORY_BEGIN + i, data[i]);
+ REV_B_CODE_MEMORY_BEGIN + i,
+ le16_to_cpu(data[i]));
}
/*
@@ -2301,10 +2147,10 @@ static void snd_m3_assp_init(struct snd_m3 *chip)
* drop it there. It seems that the minisrc doesn't
* need vectors, so we won't bother with them..
*/
- data = (u16 *)chip->assp_minisrc_image->data;
+ data = (const u16 *)chip->assp_minisrc_image->data;
for (i = 0; i * 2 < chip->assp_minisrc_image->size; i++) {
snd_m3_assp_write(chip, MEMTYPE_INTERNAL_CODE,
- 0x400 + i, data[i]);
+ 0x400 + i, le16_to_cpu(data[i]));
}
/*
@@ -2427,6 +2273,29 @@ snd_m3_amp_enable(struct snd_m3 *chip, int enable)
outw(0xffff, io + GPIO_MASK);
}
+static void
+snd_m3_hv_init(struct snd_m3 *chip)
+{
+ unsigned long io = chip->iobase;
+ u16 val = GPI_VOL_DOWN | GPI_VOL_UP;
+
+ if (!chip->is_omnibook)
+ return;
+
+ /*
+ * Volume buttons on some HP OmniBook laptops
+ * require some GPIO magic to work correctly.
+ */
+ outw(0xffff, io + GPIO_MASK);
+ outw(0x0000, io + GPIO_DATA);
+
+ outw(~val, io + GPIO_MASK);
+ outw(inw(io + GPIO_DIRECTION) & ~val, io + GPIO_DIRECTION);
+ outw(val, io + GPIO_MASK);
+
+ outw(0xffff, io + GPIO_MASK);
+}
+
static int
snd_m3_chip_init(struct snd_m3 *chip)
{
@@ -2442,21 +2311,6 @@ snd_m3_chip_init(struct snd_m3 *chip)
DISABLE_LEGACY);
pci_write_config_word(pcidev, PCI_LEGACY_AUDIO_CTRL, w);
- if (chip->is_omnibook) {
- /*
- * Volume buttons on some HP OmniBook laptops don't work
- * correctly. This makes them work for the most part.
- *
- * Volume up and down buttons on the laptop side work.
- * Fn+cursor_up (volme up) works.
- * Fn+cursor_down (volume down) doesn't work.
- * Fn+F7 (mute) works acts as volume up.
- */
- outw(~(GPI_VOL_DOWN|GPI_VOL_UP), io + GPIO_MASK);
- outw(inw(io + GPIO_DIRECTION) & ~(GPI_VOL_DOWN|GPI_VOL_UP), io + GPIO_DIRECTION);
- outw((GPI_VOL_DOWN|GPI_VOL_UP), io + GPIO_DATA);
- outw(0xffff, io + GPIO_MASK);
- }
pci_read_config_dword(pcidev, PCI_ALLEGRO_CONFIG, &n);
n &= ~(HV_CTRL_ENABLE | REDUCED_DEBOUNCE | HV_BUTTON_FROM_GD);
n |= chip->hv_config;
@@ -2548,10 +2402,8 @@ static int snd_m3_free(struct snd_m3 *chip)
if (chip->iobase)
pci_release_regions(chip->pci);
-#ifndef CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL
release_firmware(chip->assp_kernel_image);
release_firmware(chip->assp_minisrc_image);
-#endif
pci_disable_device(chip->pci);
kfree(chip);
@@ -2642,6 +2494,8 @@ static int m3_resume(struct pci_dev *pci)
snd_m3_enable_ints(chip);
snd_m3_amp_enable(chip, 1);
+ snd_m3_hv_init(chip);
+
snd_power_change_state(card, SNDRV_CTL_POWER_D0);
return 0;
}
@@ -2741,29 +2595,19 @@ snd_m3_create(struct snd_card *card, struct pci_dev *pci,
return -ENOMEM;
}
-#ifdef CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL
- chip->assp_kernel_image = &assp_kernel;
-#else
err = request_firmware(&chip->assp_kernel_image,
"ess/maestro3_assp_kernel.fw", &pci->dev);
if (err < 0) {
snd_m3_free(chip);
return err;
- } else
- snd_m3_convert_from_le(chip->assp_kernel_image);
-#endif
+ }
-#ifdef CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL
- chip->assp_minisrc_image = &assp_minisrc;
-#else
err = request_firmware(&chip->assp_minisrc_image,
"ess/maestro3_assp_minisrc.fw", &pci->dev);
if (err < 0) {
snd_m3_free(chip);
return err;
- } else
- snd_m3_convert_from_le(chip->assp_minisrc_image);
-#endif
+ }
if ((err = pci_request_regions(pci, card->driver)) < 0) {
snd_m3_free(chip);
@@ -2781,6 +2625,8 @@ snd_m3_create(struct snd_card *card, struct pci_dev *pci,
snd_m3_amp_enable(chip, 1);
+ snd_m3_hv_init(chip);
+
tasklet_init(&chip->hwvol_tq, snd_m3_update_hw_volume, (unsigned long)chip);
if (request_irq(pci->irq, snd_m3_interrupt, IRQF_SHARED,
diff --git a/sound/pci/mixart/mixart.c b/sound/pci/mixart/mixart.c
index 3dd0c7963273..2d0dce649a64 100644
--- a/sound/pci/mixart/mixart.c
+++ b/sound/pci/mixart/mixart.c
@@ -708,7 +708,7 @@ static int snd_mixart_playback_open(struct snd_pcm_substream *subs)
pcm_number = MIXART_PCM_ANALOG;
runtime->hw = snd_mixart_analog_caps;
} else {
- snd_assert ( pcm == chip->pcm_dig );
+ snd_BUG_ON(pcm != chip->pcm_dig);
pcm_number = MIXART_PCM_DIGITAL;
runtime->hw = snd_mixart_digital_caps;
}
@@ -783,7 +783,7 @@ static int snd_mixart_capture_open(struct snd_pcm_substream *subs)
pcm_number = MIXART_PCM_ANALOG;
runtime->hw = snd_mixart_analog_caps;
} else {
- snd_assert ( pcm == chip->pcm_dig );
+ snd_BUG_ON(pcm != chip->pcm_dig);
pcm_number = MIXART_PCM_DIGITAL;
runtime->hw = snd_mixart_digital_caps;
}
diff --git a/sound/pci/mixart/mixart_core.c b/sound/pci/mixart/mixart_core.c
index 785085e48353..b9a06c279397 100644
--- a/sound/pci/mixart/mixart_core.c
+++ b/sound/pci/mixart/mixart_core.c
@@ -56,8 +56,10 @@ static int retrieve_msg_frame(struct mixart_mgr *mgr, u32 *msg_frame)
if (tailptr == headptr)
return 0; /* no message posted */
- snd_assert( tailptr >= MSG_OUTBOUND_POST_STACK, return 0); /* error */
- snd_assert( tailptr < (MSG_OUTBOUND_POST_STACK+MSG_BOUND_STACK_SIZE), return 0); /* error */
+ if (tailptr < MSG_OUTBOUND_POST_STACK)
+ return 0; /* error */
+ if (tailptr >= MSG_OUTBOUND_POST_STACK + MSG_BOUND_STACK_SIZE)
+ return 0; /* error */
*msg_frame = readl_be(MIXART_MEM(mgr, tailptr));
@@ -149,7 +151,8 @@ static int send_msg( struct mixart_mgr *mgr,
u32 msg_frame_address;
int err, i;
- snd_assert(msg->size % 4 == 0, return -EINVAL);
+ if (snd_BUG_ON(msg->size % 4))
+ return -EINVAL;
err = 0;
@@ -289,9 +292,12 @@ int snd_mixart_send_msg_wait_notif(struct mixart_mgr *mgr,
wait_queue_t wait;
long timeout;
- snd_assert(notif_event != 0, return -EINVAL);
- snd_assert((notif_event & MSG_TYPE_MASK) == MSG_TYPE_NOTIFY, return -EINVAL);
- snd_assert((notif_event & MSG_CANCEL_NOTIFY_MASK) == 0, return -EINVAL);
+ if (snd_BUG_ON(!notif_event))
+ return -EINVAL;
+ if (snd_BUG_ON((notif_event & MSG_TYPE_MASK) != MSG_TYPE_NOTIFY))
+ return -EINVAL;
+ if (snd_BUG_ON(notif_event & MSG_CANCEL_NOTIFY_MASK))
+ return -EINVAL;
mutex_lock(&mgr->msg_mutex);
diff --git a/sound/pci/mixart/mixart_hwdep.c b/sound/pci/mixart/mixart_hwdep.c
index 122c28efc483..3782b52bc0e8 100644
--- a/sound/pci/mixart/mixart_hwdep.c
+++ b/sound/pci/mixart/mixart_hwdep.c
@@ -288,7 +288,9 @@ static int mixart_enum_physio(struct mixart_mgr *mgr)
return -EINVAL;
}
- snd_assert(phys_io.nb_uid >= (MIXART_MAX_CARDS * 2), return -EINVAL); /* min 2 phys io per card (analog in + analog out) */
+ /* min 2 phys io per card (analog in + analog out) */
+ if (phys_io.nb_uid < MIXART_MAX_CARDS * 2)
+ return -EINVAL;
for(k=0; k<mgr->num_cards; k++) {
mgr->chip[k]->uid_in_analog_physio = phys_io.uid[k];
@@ -363,8 +365,10 @@ static int mixart_dsp_load(struct mixart_mgr* mgr, int index, const struct firmw
}
/* check xilinx validity */
- snd_assert(((u32*)(dsp->data))[0]==0xFFFFFFFF, return -EINVAL);
- snd_assert(dsp->size % 4 == 0, return -EINVAL);
+ if (((u32*)(dsp->data))[0] == 0xffffffff)
+ return -EINVAL;
+ if (dsp->size % 4)
+ return -EINVAL;
/* set xilinx status to copying */
writel_be( 1, MIXART_MEM( mgr, MIXART_PSEUDOREG_MXLX_STATUS_OFFSET ));
@@ -462,8 +466,10 @@ static int mixart_dsp_load(struct mixart_mgr* mgr, int index, const struct firmw
}
/* check daughterboard xilinx validity */
- snd_assert(((u32*)(dsp->data))[0]==0xFFFFFFFF, return -EINVAL);
- snd_assert(dsp->size % 4 == 0, return -EINVAL);
+ if (((u32*)(dsp->data))[0] == 0xffffffff)
+ return -EINVAL;
+ if (dsp->size % 4)
+ return -EINVAL;
/* inform mixart about the size of the file */
writel_be( dsp->size, MIXART_MEM( mgr, MIXART_PSEUDOREG_DXLX_SIZE_OFFSET ));
@@ -480,7 +486,8 @@ static int mixart_dsp_load(struct mixart_mgr* mgr, int index, const struct firmw
/* get the address where to write the file */
val = readl_be( MIXART_MEM( mgr, MIXART_PSEUDOREG_DXLX_BASE_ADDR_OFFSET ));
- snd_assert(val != 0, return -EINVAL);
+ if (!val)
+ return -EINVAL;
/* copy daughterboard xilinx code */
memcpy_toio( MIXART_MEM( mgr, val), dsp->data, dsp->size);
@@ -613,7 +620,7 @@ static int mixart_hwdep_dsp_load(struct snd_hwdep *hw,
(int)dsp->length);
return -ENOMEM;
}
- if (copy_from_user(fw.data, dsp->image, dsp->length)) {
+ if (copy_from_user((void *) fw.data, dsp->image, dsp->length)) {
vfree(fw.data);
return -EFAULT;
}
diff --git a/sound/pci/mixart/mixart_mixer.c b/sound/pci/mixart/mixart_mixer.c
index 6fdda1f70b25..3ba6174c3df1 100644
--- a/sound/pci/mixart/mixart_mixer.c
+++ b/sound/pci/mixart/mixart_mixer.c
@@ -837,7 +837,7 @@ static int mixart_pcm_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem
if(is_aes) stored_volume = chip->digital_capture_volume[1]; /* AES capture */
else stored_volume = chip->digital_capture_volume[0]; /* analog capture */
} else {
- snd_assert ( idx < MIXART_PLAYBACK_STREAMS );
+ snd_BUG_ON(idx >= MIXART_PLAYBACK_STREAMS);
if(is_aes) stored_volume = chip->digital_playback_volume[MIXART_PLAYBACK_STREAMS + idx]; /* AES playback */
else stored_volume = chip->digital_playback_volume[idx]; /* analog playback */
}
@@ -863,7 +863,7 @@ static int mixart_pcm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem
else /* analog capture */
stored_volume = chip->digital_capture_volume[0];
} else {
- snd_assert ( idx < MIXART_PLAYBACK_STREAMS );
+ snd_BUG_ON(idx >= MIXART_PLAYBACK_STREAMS);
if (is_aes) /* AES playback */
stored_volume = chip->digital_playback_volume[MIXART_PLAYBACK_STREAMS + idx];
else /* analog playback */
@@ -909,7 +909,7 @@ static int mixart_pcm_sw_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_
{
struct snd_mixart *chip = snd_kcontrol_chip(kcontrol);
int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); /* index */
- snd_assert ( idx < MIXART_PLAYBACK_STREAMS );
+ snd_BUG_ON(idx >= MIXART_PLAYBACK_STREAMS);
mutex_lock(&chip->mgr->mixer_mutex);
if(kcontrol->private_value & MIXART_VOL_AES_MASK) /* AES playback */
idx += MIXART_PLAYBACK_STREAMS;
@@ -926,7 +926,7 @@ static int mixart_pcm_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_
int is_aes = kcontrol->private_value & MIXART_VOL_AES_MASK;
int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); /* index */
int i, j;
- snd_assert ( idx < MIXART_PLAYBACK_STREAMS );
+ snd_BUG_ON(idx >= MIXART_PLAYBACK_STREAMS);
mutex_lock(&chip->mgr->mixer_mutex);
j = idx;
if (is_aes)
diff --git a/sound/pci/nm256/nm256.c b/sound/pci/nm256/nm256.c
index 7efb838d18a6..50c9f8a05082 100644
--- a/sound/pci/nm256/nm256.c
+++ b/sound/pci/nm256/nm256.c
@@ -562,7 +562,8 @@ snd_nm256_playback_trigger(struct snd_pcm_substream *substream, int cmd)
struct nm256_stream *s = substream->runtime->private_data;
int err = 0;
- snd_assert(s != NULL, return -ENXIO);
+ if (snd_BUG_ON(!s))
+ return -ENXIO;
spin_lock(&chip->reg_lock);
switch (cmd) {
@@ -599,7 +600,8 @@ snd_nm256_capture_trigger(struct snd_pcm_substream *substream, int cmd)
struct nm256_stream *s = substream->runtime->private_data;
int err = 0;
- snd_assert(s != NULL, return -ENXIO);
+ if (snd_BUG_ON(!s))
+ return -ENXIO;
spin_lock(&chip->reg_lock);
switch (cmd) {
@@ -635,7 +637,8 @@ static int snd_nm256_pcm_prepare(struct snd_pcm_substream *substream)
struct snd_pcm_runtime *runtime = substream->runtime;
struct nm256_stream *s = runtime->private_data;
- snd_assert(s, return -ENXIO);
+ if (snd_BUG_ON(!s))
+ return -ENXIO;
s->dma_size = frames_to_bytes(runtime, substream->runtime->buffer_size);
s->period_size = frames_to_bytes(runtime, substream->runtime->period_size);
s->periods = substream->runtime->periods;
@@ -660,7 +663,8 @@ snd_nm256_playback_pointer(struct snd_pcm_substream *substream)
struct nm256_stream *s = substream->runtime->private_data;
unsigned long curp;
- snd_assert(s, return 0);
+ if (snd_BUG_ON(!s))
+ return 0;
curp = snd_nm256_readl(chip, NM_PBUFFER_CURRP) - (unsigned long)s->buf;
curp %= s->dma_size;
return bytes_to_frames(substream->runtime, curp);
@@ -673,7 +677,8 @@ snd_nm256_capture_pointer(struct snd_pcm_substream *substream)
struct nm256_stream *s = substream->runtime->private_data;
unsigned long curp;
- snd_assert(s != NULL, return 0);
+ if (snd_BUG_ON(!s))
+ return 0;
curp = snd_nm256_readl(chip, NM_RBUFFER_CURRP) - (unsigned long)s->buf;
curp %= s->dma_size;
return bytes_to_frames(substream->runtime, curp);
@@ -1302,8 +1307,8 @@ snd_nm256_mixer(struct nm256 *chip)
.read = snd_nm256_ac97_read,
};
- chip->ac97_regs = kcalloc(sizeof(short),
- ARRAY_SIZE(nm256_ac97_init_val), GFP_KERNEL);
+ chip->ac97_regs = kcalloc(ARRAY_SIZE(nm256_ac97_init_val),
+ sizeof(short), GFP_KERNEL);
if (! chip->ac97_regs)
return -ENOMEM;
diff --git a/sound/pci/oxygen/hifier.c b/sound/pci/oxygen/hifier.c
index 090dd4354a28..1ab833f843eb 100644
--- a/sound/pci/oxygen/hifier.c
+++ b/sound/pci/oxygen/hifier.c
@@ -17,6 +17,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#include <linux/delay.h>
#include <linux/pci.h>
#include <sound/control.h>
#include <sound/core.h>
@@ -28,7 +29,7 @@
MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
MODULE_DESCRIPTION("TempoTec HiFier driver");
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
@@ -62,16 +63,28 @@ static void ak4396_write(struct oxygen *chip, u8 reg, u8 value)
AK4396_WRITE | (reg << 8) | value);
}
-static void hifier_init(struct oxygen *chip)
+static void update_ak4396_volume(struct oxygen *chip)
+{
+ ak4396_write(chip, AK4396_LCH_ATT, chip->dac_volume[0]);
+ ak4396_write(chip, AK4396_RCH_ATT, chip->dac_volume[1]);
+}
+
+static void hifier_registers_init(struct oxygen *chip)
{
struct hifier_data *data = chip->model_data;
- data->ak4396_ctl2 = AK4396_SMUTE | AK4396_DEM_OFF | AK4396_DFS_NORMAL;
ak4396_write(chip, AK4396_CONTROL_1, AK4396_DIF_24_MSB | AK4396_RSTN);
ak4396_write(chip, AK4396_CONTROL_2, data->ak4396_ctl2);
ak4396_write(chip, AK4396_CONTROL_3, AK4396_PCM);
- ak4396_write(chip, AK4396_LCH_ATT, 0);
- ak4396_write(chip, AK4396_RCH_ATT, 0);
+ update_ak4396_volume(chip);
+}
+
+static void hifier_init(struct oxygen *chip)
+{
+ struct hifier_data *data = chip->model_data;
+
+ data->ak4396_ctl2 = AK4396_SMUTE | AK4396_DEM_OFF | AK4396_DFS_NORMAL;
+ hifier_registers_init(chip);
snd_component_add(chip->card, "AK4396");
snd_component_add(chip->card, "CS5340");
@@ -81,6 +94,11 @@ static void hifier_cleanup(struct oxygen *chip)
{
}
+static void hifier_resume(struct oxygen *chip)
+{
+ hifier_registers_init(chip);
+}
+
static void set_ak4396_params(struct oxygen *chip,
struct snd_pcm_hw_params *params)
{
@@ -95,17 +113,14 @@ static void set_ak4396_params(struct oxygen *chip,
else
value |= AK4396_DFS_QUAD;
data->ak4396_ctl2 = value;
+
+ msleep(1); /* wait for the new MCLK to become stable */
+
ak4396_write(chip, AK4396_CONTROL_1, AK4396_DIF_24_MSB);
ak4396_write(chip, AK4396_CONTROL_2, value);
ak4396_write(chip, AK4396_CONTROL_1, AK4396_DIF_24_MSB | AK4396_RSTN);
}
-static void update_ak4396_volume(struct oxygen *chip)
-{
- ak4396_write(chip, AK4396_LCH_ATT, chip->dac_volume[0]);
- ak4396_write(chip, AK4396_RCH_ATT, chip->dac_volume[1]);
-}
-
static void update_ak4396_mute(struct oxygen *chip)
{
struct hifier_data *data = chip->model_data;
@@ -140,15 +155,16 @@ static const struct oxygen_model model_hifier = {
.init = hifier_init,
.control_filter = hifier_control_filter,
.cleanup = hifier_cleanup,
+ .resume = hifier_resume,
.set_dac_params = set_ak4396_params,
.set_adc_params = set_cs5340_params,
.update_dac_volume = update_ak4396_volume,
.update_dac_mute = update_ak4396_mute,
.dac_tlv = ak4396_db_scale,
.model_data_size = sizeof(struct hifier_data),
- .pcm_dev_cfg = PLAYBACK_0_TO_I2S |
- PLAYBACK_1_TO_SPDIF |
- CAPTURE_0_FROM_I2S_1,
+ .device_config = PLAYBACK_0_TO_I2S |
+ PLAYBACK_1_TO_SPDIF |
+ CAPTURE_0_FROM_I2S_1,
.dac_channels = 2,
.dac_volume_min = 0,
.dac_volume_max = 255,
@@ -169,7 +185,7 @@ static int __devinit hifier_probe(struct pci_dev *pci,
++dev;
return -ENOENT;
}
- err = oxygen_pci_probe(pci, index[dev], id[dev], &model_hifier);
+ err = oxygen_pci_probe(pci, index[dev], id[dev], &model_hifier, 0);
if (err >= 0)
++dev;
return err;
@@ -180,6 +196,10 @@ static struct pci_driver hifier_driver = {
.id_table = hifier_ids,
.probe = hifier_probe,
.remove = __devexit_p(oxygen_pci_remove),
+#ifdef CONFIG_PM
+ .suspend = oxygen_pci_suspend,
+ .resume = oxygen_pci_resume,
+#endif
};
static int __init alsa_card_hifier_init(void)
diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c
index 63f185c1ed1e..b60f6212745a 100644
--- a/sound/pci/oxygen/oxygen.c
+++ b/sound/pci/oxygen/oxygen.c
@@ -28,6 +28,7 @@
* GPIO 1 -> DFS1 of AK5385
*/
+#include <linux/delay.h>
#include <linux/mutex.h>
#include <linux/pci.h>
#include <sound/ac97_codec.h>
@@ -43,7 +44,7 @@
MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
MODULE_DESCRIPTION("C-Media CMI8788 driver");
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
MODULE_SUPPORTED_DEVICE("{{C-Media,CMI8788}}");
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
@@ -57,17 +58,22 @@ MODULE_PARM_DESC(id, "ID string");
module_param_array(enable, bool, NULL, 0444);
MODULE_PARM_DESC(enable, "enable card");
+enum {
+ MODEL_CMEDIA_REF, /* C-Media's reference design */
+ MODEL_MERIDIAN, /* AuzenTech X-Meridian */
+};
+
static struct pci_device_id oxygen_ids[] __devinitdata = {
- { OXYGEN_PCI_SUBID(0x10b0, 0x0216) },
- { OXYGEN_PCI_SUBID(0x10b0, 0x0218) },
- { OXYGEN_PCI_SUBID(0x10b0, 0x0219) },
- { OXYGEN_PCI_SUBID(0x13f6, 0x0001) },
- { OXYGEN_PCI_SUBID(0x13f6, 0x0010) },
- { OXYGEN_PCI_SUBID(0x13f6, 0x8788) },
- { OXYGEN_PCI_SUBID(0x147a, 0xa017) },
- { OXYGEN_PCI_SUBID(0x1a58, 0x0910) },
- { OXYGEN_PCI_SUBID(0x415a, 0x5431), .driver_data = 1 },
- { OXYGEN_PCI_SUBID(0x7284, 0x9761) },
+ { OXYGEN_PCI_SUBID(0x10b0, 0x0216), .driver_data = MODEL_CMEDIA_REF },
+ { OXYGEN_PCI_SUBID(0x10b0, 0x0218), .driver_data = MODEL_CMEDIA_REF },
+ { OXYGEN_PCI_SUBID(0x10b0, 0x0219), .driver_data = MODEL_CMEDIA_REF },
+ { OXYGEN_PCI_SUBID(0x13f6, 0x0001), .driver_data = MODEL_CMEDIA_REF },
+ { OXYGEN_PCI_SUBID(0x13f6, 0x0010), .driver_data = MODEL_CMEDIA_REF },
+ { OXYGEN_PCI_SUBID(0x13f6, 0x8788), .driver_data = MODEL_CMEDIA_REF },
+ { OXYGEN_PCI_SUBID(0x147a, 0xa017), .driver_data = MODEL_CMEDIA_REF },
+ { OXYGEN_PCI_SUBID(0x1a58, 0x0910), .driver_data = MODEL_CMEDIA_REF },
+ { OXYGEN_PCI_SUBID(0x415a, 0x5431), .driver_data = MODEL_MERIDIAN },
+ { OXYGEN_PCI_SUBID(0x7284, 0x9761), .driver_data = MODEL_CMEDIA_REF },
{ }
};
MODULE_DEVICE_TABLE(pci, oxygen_ids);
@@ -80,6 +86,7 @@ MODULE_DEVICE_TABLE(pci, oxygen_ids);
struct generic_data {
u8 ak4396_ctl2;
+ u16 saved_wm8785_registers[2];
};
static void ak4396_write(struct oxygen *chip, unsigned int codec,
@@ -99,20 +106,35 @@ static void ak4396_write(struct oxygen *chip, unsigned int codec,
static void wm8785_write(struct oxygen *chip, u8 reg, unsigned int value)
{
+ struct generic_data *data = chip->model_data;
+
oxygen_write_spi(chip, OXYGEN_SPI_TRIGGER |
OXYGEN_SPI_DATA_LENGTH_2 |
OXYGEN_SPI_CLOCK_160 |
(3 << OXYGEN_SPI_CODEC_SHIFT) |
OXYGEN_SPI_CEN_LATCH_CLOCK_LO,
(reg << 9) | value);
+ if (reg < ARRAY_SIZE(data->saved_wm8785_registers))
+ data->saved_wm8785_registers[reg] = value;
}
-static void ak4396_init(struct oxygen *chip)
+static void update_ak4396_volume(struct oxygen *chip)
+{
+ unsigned int i;
+
+ for (i = 0; i < 4; ++i) {
+ ak4396_write(chip, i,
+ AK4396_LCH_ATT, chip->dac_volume[i * 2]);
+ ak4396_write(chip, i,
+ AK4396_RCH_ATT, chip->dac_volume[i * 2 + 1]);
+ }
+}
+
+static void ak4396_registers_init(struct oxygen *chip)
{
struct generic_data *data = chip->model_data;
unsigned int i;
- data->ak4396_ctl2 = AK4396_SMUTE | AK4396_DEM_OFF | AK4396_DFS_NORMAL;
for (i = 0; i < 4; ++i) {
ak4396_write(chip, i,
AK4396_CONTROL_1, AK4396_DIF_24_MSB | AK4396_RSTN);
@@ -120,9 +142,16 @@ static void ak4396_init(struct oxygen *chip)
AK4396_CONTROL_2, data->ak4396_ctl2);
ak4396_write(chip, i,
AK4396_CONTROL_3, AK4396_PCM);
- ak4396_write(chip, i, AK4396_LCH_ATT, 0);
- ak4396_write(chip, i, AK4396_RCH_ATT, 0);
}
+ update_ak4396_volume(chip);
+}
+
+static void ak4396_init(struct oxygen *chip)
+{
+ struct generic_data *data = chip->model_data;
+
+ data->ak4396_ctl2 = AK4396_SMUTE | AK4396_DEM_OFF | AK4396_DFS_NORMAL;
+ ak4396_registers_init(chip);
snd_component_add(chip->card, "AK4396");
}
@@ -133,12 +162,23 @@ static void ak5385_init(struct oxygen *chip)
snd_component_add(chip->card, "AK5385");
}
-static void wm8785_init(struct oxygen *chip)
+static void wm8785_registers_init(struct oxygen *chip)
{
+ struct generic_data *data = chip->model_data;
+
wm8785_write(chip, WM8785_R7, 0);
- wm8785_write(chip, WM8785_R0, WM8785_MCR_SLAVE |
- WM8785_OSR_SINGLE | WM8785_FORMAT_LJUST);
- wm8785_write(chip, WM8785_R1, WM8785_WL_24);
+ wm8785_write(chip, WM8785_R0, data->saved_wm8785_registers[0]);
+ wm8785_write(chip, WM8785_R1, data->saved_wm8785_registers[1]);
+}
+
+static void wm8785_init(struct oxygen *chip)
+{
+ struct generic_data *data = chip->model_data;
+
+ data->saved_wm8785_registers[0] = WM8785_MCR_SLAVE |
+ WM8785_OSR_SINGLE | WM8785_FORMAT_LJUST;
+ data->saved_wm8785_registers[1] = WM8785_WL_24;
+ wm8785_registers_init(chip);
snd_component_add(chip->card, "WM8785");
}
@@ -158,6 +198,17 @@ static void generic_cleanup(struct oxygen *chip)
{
}
+static void generic_resume(struct oxygen *chip)
+{
+ ak4396_registers_init(chip);
+ wm8785_registers_init(chip);
+}
+
+static void meridian_resume(struct oxygen *chip)
+{
+ ak4396_registers_init(chip);
+}
+
static void set_ak4396_params(struct oxygen *chip,
struct snd_pcm_hw_params *params)
{
@@ -173,6 +224,9 @@ static void set_ak4396_params(struct oxygen *chip,
else
value |= AK4396_DFS_QUAD;
data->ak4396_ctl2 = value;
+
+ msleep(1); /* wait for the new MCLK to become stable */
+
for (i = 0; i < 4; ++i) {
ak4396_write(chip, i,
AK4396_CONTROL_1, AK4396_DIF_24_MSB);
@@ -183,18 +237,6 @@ static void set_ak4396_params(struct oxygen *chip,
}
}
-static void update_ak4396_volume(struct oxygen *chip)
-{
- unsigned int i;
-
- for (i = 0; i < 4; ++i) {
- ak4396_write(chip, i,
- AK4396_LCH_ATT, chip->dac_volume[i * 2]);
- ak4396_write(chip, i,
- AK4396_RCH_ATT, chip->dac_volume[i * 2 + 1]);
- }
-}
-
static void update_ak4396_mute(struct oxygen *chip)
{
struct generic_data *data = chip->model_data;
@@ -249,56 +291,46 @@ static void set_ak5385_params(struct oxygen *chip,
static const DECLARE_TLV_DB_LINEAR(ak4396_db_scale, TLV_DB_GAIN_MUTE, 0);
+static int generic_probe(struct oxygen *chip, unsigned long driver_data)
+{
+ if (driver_data == MODEL_MERIDIAN) {
+ chip->model.init = meridian_init;
+ chip->model.resume = meridian_resume;
+ chip->model.set_adc_params = set_ak5385_params;
+ chip->model.device_config = PLAYBACK_0_TO_I2S |
+ PLAYBACK_1_TO_SPDIF |
+ CAPTURE_0_FROM_I2S_2 |
+ CAPTURE_1_FROM_SPDIF;
+ chip->model.misc_flags = OXYGEN_MISC_MIDI;
+ chip->model.device_config |= MIDI_OUTPUT | MIDI_INPUT;
+ }
+ return 0;
+}
+
static const struct oxygen_model model_generic = {
.shortname = "C-Media CMI8788",
.longname = "C-Media Oxygen HD Audio",
.chip = "CMI8788",
.owner = THIS_MODULE,
+ .probe = generic_probe,
.init = generic_init,
.cleanup = generic_cleanup,
+ .resume = generic_resume,
.set_dac_params = set_ak4396_params,
.set_adc_params = set_wm8785_params,
.update_dac_volume = update_ak4396_volume,
.update_dac_mute = update_ak4396_mute,
.dac_tlv = ak4396_db_scale,
.model_data_size = sizeof(struct generic_data),
- .pcm_dev_cfg = PLAYBACK_0_TO_I2S |
- PLAYBACK_1_TO_SPDIF |
- PLAYBACK_2_TO_AC97_1 |
- CAPTURE_0_FROM_I2S_1 |
- CAPTURE_1_FROM_SPDIF |
- CAPTURE_2_FROM_AC97_1,
- .dac_channels = 8,
- .dac_volume_min = 0,
- .dac_volume_max = 255,
- .function_flags = OXYGEN_FUNCTION_SPI |
- OXYGEN_FUNCTION_ENABLE_SPI_4_5,
- .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
- .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
-};
-static const struct oxygen_model model_meridian = {
- .shortname = "C-Media CMI8788",
- .longname = "C-Media Oxygen HD Audio",
- .chip = "CMI8788",
- .owner = THIS_MODULE,
- .init = meridian_init,
- .cleanup = generic_cleanup,
- .set_dac_params = set_ak4396_params,
- .set_adc_params = set_ak5385_params,
- .update_dac_volume = update_ak4396_volume,
- .update_dac_mute = update_ak4396_mute,
- .dac_tlv = ak4396_db_scale,
- .model_data_size = sizeof(struct generic_data),
- .pcm_dev_cfg = PLAYBACK_0_TO_I2S |
- PLAYBACK_1_TO_SPDIF |
- PLAYBACK_2_TO_AC97_1 |
- CAPTURE_0_FROM_I2S_2 |
- CAPTURE_1_FROM_SPDIF |
- CAPTURE_2_FROM_AC97_1,
+ .device_config = PLAYBACK_0_TO_I2S |
+ PLAYBACK_1_TO_SPDIF |
+ PLAYBACK_2_TO_AC97_1 |
+ CAPTURE_0_FROM_I2S_1 |
+ CAPTURE_1_FROM_SPDIF |
+ CAPTURE_2_FROM_AC97_1,
.dac_channels = 8,
.dac_volume_min = 0,
.dac_volume_max = 255,
- .misc_flags = OXYGEN_MISC_MIDI,
.function_flags = OXYGEN_FUNCTION_SPI |
OXYGEN_FUNCTION_ENABLE_SPI_4_5,
.dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
@@ -309,7 +341,6 @@ static int __devinit generic_oxygen_probe(struct pci_dev *pci,
const struct pci_device_id *pci_id)
{
static int dev;
- int is_meridian;
int err;
if (dev >= SNDRV_CARDS)
@@ -318,9 +349,8 @@ static int __devinit generic_oxygen_probe(struct pci_dev *pci,
++dev;
return -ENOENT;
}
- is_meridian = pci_id->driver_data;
err = oxygen_pci_probe(pci, index[dev], id[dev],
- is_meridian ? &model_meridian : &model_generic);
+ &model_generic, pci_id->driver_data);
if (err >= 0)
++dev;
return err;
@@ -331,6 +361,10 @@ static struct pci_driver oxygen_driver = {
.id_table = oxygen_ids,
.probe = generic_oxygen_probe,
.remove = __devexit_p(oxygen_pci_remove),
+#ifdef CONFIG_PM
+ .suspend = oxygen_pci_suspend,
+ .resume = oxygen_pci_resume,
+#endif
};
static int __init alsa_card_oxygen_init(void)
diff --git a/sound/pci/oxygen/oxygen.h b/sound/pci/oxygen/oxygen.h
index a71c6e059260..19107c6307e5 100644
--- a/sound/pci/oxygen/oxygen.h
+++ b/sound/pci/oxygen/oxygen.h
@@ -16,15 +16,22 @@
#define PCM_AC97 5
#define PCM_COUNT 6
+#define OXYGEN_IO_SIZE 0x100
+
/* model-specific configuration of outputs/inputs */
-#define PLAYBACK_0_TO_I2S 0x001
-#define PLAYBACK_1_TO_SPDIF 0x004
-#define PLAYBACK_2_TO_AC97_1 0x008
-#define CAPTURE_0_FROM_I2S_1 0x010
-#define CAPTURE_0_FROM_I2S_2 0x020
-#define CAPTURE_1_FROM_SPDIF 0x080
-#define CAPTURE_2_FROM_I2S_2 0x100
-#define CAPTURE_2_FROM_AC97_1 0x200
+#define PLAYBACK_0_TO_I2S 0x0001
+ /* PLAYBACK_0_TO_AC97_0 not implemented */
+#define PLAYBACK_1_TO_SPDIF 0x0004
+#define PLAYBACK_2_TO_AC97_1 0x0008
+#define CAPTURE_0_FROM_I2S_1 0x0010
+#define CAPTURE_0_FROM_I2S_2 0x0020
+ /* CAPTURE_0_FROM_AC97_0 not implemented */
+#define CAPTURE_1_FROM_SPDIF 0x0080
+#define CAPTURE_2_FROM_I2S_2 0x0100
+#define CAPTURE_2_FROM_AC97_1 0x0200
+ /* CAPTURE_3_FROM_I2S_3 not implemented */
+#define MIDI_OUTPUT 0x0800
+#define MIDI_INPUT 0x1000
enum {
CONTROL_SPDIF_PCM,
@@ -49,46 +56,20 @@ struct snd_pcm_hardware;
struct snd_pcm_hw_params;
struct snd_kcontrol_new;
struct snd_rawmidi;
-struct oxygen_model;
-
-struct oxygen {
- unsigned long addr;
- spinlock_t reg_lock;
- struct mutex mutex;
- struct snd_card *card;
- struct pci_dev *pci;
- struct snd_rawmidi *midi;
- int irq;
- const struct oxygen_model *model;
- void *model_data;
- unsigned int interrupt_mask;
- u8 dac_volume[8];
- u8 dac_mute;
- u8 pcm_active;
- u8 pcm_running;
- u8 dac_routing;
- u8 spdif_playback_enable;
- u8 revision;
- u8 has_ac97_0;
- u8 has_ac97_1;
- u32 spdif_bits;
- u32 spdif_pcm_bits;
- struct snd_pcm_substream *streams[PCM_COUNT];
- struct snd_kcontrol *controls[CONTROL_COUNT];
- struct work_struct spdif_input_bits_work;
- struct work_struct gpio_work;
- wait_queue_head_t ac97_waitqueue;
-};
+struct oxygen;
struct oxygen_model {
const char *shortname;
const char *longname;
const char *chip;
struct module *owner;
+ int (*probe)(struct oxygen *chip, unsigned long driver_data);
void (*init)(struct oxygen *chip);
int (*control_filter)(struct snd_kcontrol_new *template);
int (*mixer_init)(struct oxygen *chip);
void (*cleanup)(struct oxygen *chip);
+ void (*suspend)(struct oxygen *chip);
+ void (*resume)(struct oxygen *chip);
void (*pcm_hardware_filter)(unsigned int channel,
struct snd_pcm_hardware *hardware);
void (*set_dac_params)(struct oxygen *chip,
@@ -98,11 +79,12 @@ struct oxygen_model {
void (*update_dac_volume)(struct oxygen *chip);
void (*update_dac_mute)(struct oxygen *chip);
void (*gpio_changed)(struct oxygen *chip);
+ void (*uart_input)(struct oxygen *chip);
void (*ac97_switch)(struct oxygen *chip,
unsigned int reg, unsigned int mute);
const unsigned int *dac_tlv;
size_t model_data_size;
- unsigned int pcm_dev_cfg;
+ unsigned int device_config;
u8 dac_channels;
u8 dac_volume_min;
u8 dac_volume_max;
@@ -112,11 +94,53 @@ struct oxygen_model {
u16 adc_i2s_format;
};
+struct oxygen {
+ unsigned long addr;
+ spinlock_t reg_lock;
+ struct mutex mutex;
+ struct snd_card *card;
+ struct pci_dev *pci;
+ struct snd_rawmidi *midi;
+ int irq;
+ void *model_data;
+ unsigned int interrupt_mask;
+ u8 dac_volume[8];
+ u8 dac_mute;
+ u8 pcm_active;
+ u8 pcm_running;
+ u8 dac_routing;
+ u8 spdif_playback_enable;
+ u8 revision;
+ u8 has_ac97_0;
+ u8 has_ac97_1;
+ u32 spdif_bits;
+ u32 spdif_pcm_bits;
+ struct snd_pcm_substream *streams[PCM_COUNT];
+ struct snd_kcontrol *controls[CONTROL_COUNT];
+ struct work_struct spdif_input_bits_work;
+ struct work_struct gpio_work;
+ wait_queue_head_t ac97_waitqueue;
+ union {
+ u8 _8[OXYGEN_IO_SIZE];
+ __le16 _16[OXYGEN_IO_SIZE / 2];
+ __le32 _32[OXYGEN_IO_SIZE / 4];
+ } saved_registers;
+ u16 saved_ac97_registers[2][0x40];
+ unsigned int uart_input_count;
+ u8 uart_input[32];
+ struct oxygen_model model;
+};
+
/* oxygen_lib.c */
int oxygen_pci_probe(struct pci_dev *pci, int index, char *id,
- const struct oxygen_model *model);
+ const struct oxygen_model *model,
+ unsigned long driver_data);
void oxygen_pci_remove(struct pci_dev *pci);
+#ifdef CONFIG_PM
+int oxygen_pci_suspend(struct pci_dev *pci, pm_message_t state);
+int oxygen_pci_resume(struct pci_dev *pci);
+#endif
/* oxygen_mixer.c */
@@ -153,6 +177,9 @@ void oxygen_write_ac97_masked(struct oxygen *chip, unsigned int codec,
void oxygen_write_spi(struct oxygen *chip, u8 control, unsigned int data);
void oxygen_write_i2c(struct oxygen *chip, u8 device, u8 map, u8 data);
+void oxygen_reset_uart(struct oxygen *chip);
+void oxygen_write_uart(struct oxygen *chip, u8 data);
+
static inline void oxygen_set_bits8(struct oxygen *chip,
unsigned int reg, u8 value)
{
diff --git a/sound/pci/oxygen/oxygen_io.c b/sound/pci/oxygen/oxygen_io.c
index 5569606ee87f..3126c4b403dd 100644
--- a/sound/pci/oxygen/oxygen_io.c
+++ b/sound/pci/oxygen/oxygen_io.c
@@ -20,6 +20,7 @@
#include <linux/delay.h>
#include <linux/sched.h>
#include <sound/core.h>
+#include <sound/mpu401.h>
#include <asm/io.h>
#include "oxygen.h"
@@ -44,18 +45,21 @@ EXPORT_SYMBOL(oxygen_read32);
void oxygen_write8(struct oxygen *chip, unsigned int reg, u8 value)
{
outb(value, chip->addr + reg);
+ chip->saved_registers._8[reg] = value;
}
EXPORT_SYMBOL(oxygen_write8);
void oxygen_write16(struct oxygen *chip, unsigned int reg, u16 value)
{
outw(value, chip->addr + reg);
+ chip->saved_registers._16[reg / 2] = cpu_to_le16(value);
}
EXPORT_SYMBOL(oxygen_write16);
void oxygen_write32(struct oxygen *chip, unsigned int reg, u32 value)
{
outl(value, chip->addr + reg);
+ chip->saved_registers._32[reg / 4] = cpu_to_le32(value);
}
EXPORT_SYMBOL(oxygen_write32);
@@ -63,7 +67,10 @@ void oxygen_write8_masked(struct oxygen *chip, unsigned int reg,
u8 value, u8 mask)
{
u8 tmp = inb(chip->addr + reg);
- outb((tmp & ~mask) | (value & mask), chip->addr + reg);
+ tmp &= ~mask;
+ tmp |= value & mask;
+ outb(tmp, chip->addr + reg);
+ chip->saved_registers._8[reg] = tmp;
}
EXPORT_SYMBOL(oxygen_write8_masked);
@@ -71,7 +78,10 @@ void oxygen_write16_masked(struct oxygen *chip, unsigned int reg,
u16 value, u16 mask)
{
u16 tmp = inw(chip->addr + reg);
- outw((tmp & ~mask) | (value & mask), chip->addr + reg);
+ tmp &= ~mask;
+ tmp |= value & mask;
+ outw(tmp, chip->addr + reg);
+ chip->saved_registers._16[reg / 2] = cpu_to_le16(tmp);
}
EXPORT_SYMBOL(oxygen_write16_masked);
@@ -79,7 +89,10 @@ void oxygen_write32_masked(struct oxygen *chip, unsigned int reg,
u32 value, u32 mask)
{
u32 tmp = inl(chip->addr + reg);
- outl((tmp & ~mask) | (value & mask), chip->addr + reg);
+ tmp &= ~mask;
+ tmp |= value & mask;
+ outl(tmp, chip->addr + reg);
+ chip->saved_registers._32[reg / 4] = cpu_to_le32(tmp);
}
EXPORT_SYMBOL(oxygen_write32_masked);
@@ -128,8 +141,10 @@ void oxygen_write_ac97(struct oxygen *chip, unsigned int codec,
oxygen_write32(chip, OXYGEN_AC97_REGS, reg);
/* require two "completed" writes, just to be sure */
if (oxygen_ac97_wait(chip, OXYGEN_AC97_INT_WRITE_DONE) >= 0 &&
- ++succeeded >= 2)
+ ++succeeded >= 2) {
+ chip->saved_ac97_registers[codec][index / 2] = data;
return;
+ }
}
snd_printk(KERN_ERR "AC'97 write timeout\n");
}
@@ -218,3 +233,24 @@ void oxygen_write_i2c(struct oxygen *chip, u8 device, u8 map, u8 data)
device | OXYGEN_2WIRE_DIR_WRITE);
}
EXPORT_SYMBOL(oxygen_write_i2c);
+
+static void _write_uart(struct oxygen *chip, unsigned int port, u8 data)
+{
+ if (oxygen_read8(chip, OXYGEN_MPU401 + 1) & MPU401_TX_FULL)
+ msleep(1);
+ oxygen_write8(chip, OXYGEN_MPU401 + port, data);
+}
+
+void oxygen_reset_uart(struct oxygen *chip)
+{
+ _write_uart(chip, 1, MPU401_RESET);
+ msleep(1); /* wait for ACK */
+ _write_uart(chip, 1, MPU401_ENTER_UART);
+}
+EXPORT_SYMBOL(oxygen_reset_uart);
+
+void oxygen_write_uart(struct oxygen *chip, u8 data)
+{
+ _write_uart(chip, 0, data);
+}
+EXPORT_SYMBOL(oxygen_write_uart);
diff --git a/sound/pci/oxygen/oxygen_lib.c b/sound/pci/oxygen/oxygen_lib.c
index 897697d43506..84f481d41efa 100644
--- a/sound/pci/oxygen/oxygen_lib.c
+++ b/sound/pci/oxygen/oxygen_lib.c
@@ -32,9 +32,33 @@
MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
MODULE_DESCRIPTION("C-Media CMI8788 helper library");
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
+static inline int oxygen_uart_input_ready(struct oxygen *chip)
+{
+ return !(oxygen_read8(chip, OXYGEN_MPU401 + 1) & MPU401_RX_EMPTY);
+}
+
+static void oxygen_read_uart(struct oxygen *chip)
+{
+ if (unlikely(!oxygen_uart_input_ready(chip))) {
+ /* no data, but read it anyway to clear the interrupt */
+ oxygen_read8(chip, OXYGEN_MPU401);
+ return;
+ }
+ do {
+ u8 data = oxygen_read8(chip, OXYGEN_MPU401);
+ if (data == MPU401_ACK)
+ continue;
+ if (chip->uart_input_count >= ARRAY_SIZE(chip->uart_input))
+ chip->uart_input_count = 0;
+ chip->uart_input[chip->uart_input_count++] = data;
+ } while (oxygen_uart_input_ready(chip));
+ if (chip->model.uart_input)
+ chip->model.uart_input(chip);
+}
+
static irqreturn_t oxygen_interrupt(int dummy, void *dev_id)
{
struct oxygen *chip = dev_id;
@@ -87,8 +111,12 @@ static irqreturn_t oxygen_interrupt(int dummy, void *dev_id)
if (status & OXYGEN_INT_GPIO)
schedule_work(&chip->gpio_work);
- if ((status & OXYGEN_INT_MIDI) && chip->midi)
- snd_mpu401_uart_interrupt(0, chip->midi->private_data);
+ if (status & OXYGEN_INT_MIDI) {
+ if (chip->midi)
+ snd_mpu401_uart_interrupt(0, chip->midi->private_data);
+ else
+ oxygen_read_uart(chip);
+ }
if (status & OXYGEN_INT_AC97)
wake_up(&chip->ac97_waitqueue);
@@ -161,8 +189,8 @@ static void oxygen_gpio_changed(struct work_struct *work)
{
struct oxygen *chip = container_of(work, struct oxygen, gpio_work);
- if (chip->model->gpio_changed)
- chip->model->gpio_changed(chip);
+ if (chip->model.gpio_changed)
+ chip->model.gpio_changed(chip);
}
#ifdef CONFIG_PROC_FS
@@ -173,7 +201,7 @@ static void oxygen_proc_read(struct snd_info_entry *entry,
int i, j;
snd_iprintf(buffer, "CMI8788\n\n");
- for (i = 0; i < 0x100; i += 0x10) {
+ for (i = 0; i < OXYGEN_IO_SIZE; i += 0x10) {
snd_iprintf(buffer, "%02x:", i);
for (j = 0; j < 0x10; ++j)
snd_iprintf(buffer, " %02x", oxygen_read8(chip, i + j));
@@ -221,7 +249,7 @@ static void oxygen_init(struct oxygen *chip)
chip->dac_routing = 1;
for (i = 0; i < 8; ++i)
- chip->dac_volume[i] = chip->model->dac_volume_min;
+ chip->dac_volume[i] = chip->model.dac_volume_min;
chip->dac_mute = 1;
chip->spdif_playback_enable = 1;
chip->spdif_bits = OXYGEN_SPDIF_C | OXYGEN_SPDIF_ORIGINAL |
@@ -243,7 +271,7 @@ static void oxygen_init(struct oxygen *chip)
oxygen_write8_masked(chip, OXYGEN_FUNCTION,
OXYGEN_FUNCTION_RESET_CODEC |
- chip->model->function_flags,
+ chip->model.function_flags,
OXYGEN_FUNCTION_RESET_CODEC |
OXYGEN_FUNCTION_2WIRE_SPI_MASK |
OXYGEN_FUNCTION_ENABLE_SPI_4_5);
@@ -255,7 +283,7 @@ static void oxygen_init(struct oxygen *chip)
OXYGEN_DMA_MULTICH_BURST_8);
oxygen_write16(chip, OXYGEN_INTERRUPT_MASK, 0);
oxygen_write8_masked(chip, OXYGEN_MISC,
- chip->model->misc_flags,
+ chip->model.misc_flags,
OXYGEN_MISC_WRITE_PCI_SUBID |
OXYGEN_MISC_REC_C_FROM_SPDIF |
OXYGEN_MISC_REC_B_FROM_AC97 |
@@ -270,21 +298,21 @@ static void oxygen_init(struct oxygen *chip)
(OXYGEN_FORMAT_16 << OXYGEN_MULTICH_FORMAT_SHIFT));
oxygen_write8(chip, OXYGEN_REC_CHANNELS, OXYGEN_REC_CHANNELS_2_2_2);
oxygen_write16(chip, OXYGEN_I2S_MULTICH_FORMAT,
- OXYGEN_RATE_48000 | chip->model->dac_i2s_format |
+ OXYGEN_RATE_48000 | chip->model.dac_i2s_format |
OXYGEN_I2S_MCLK_256 | OXYGEN_I2S_BITS_16 |
OXYGEN_I2S_MASTER | OXYGEN_I2S_BCLK_64);
- if (chip->model->pcm_dev_cfg & CAPTURE_0_FROM_I2S_1)
+ if (chip->model.device_config & CAPTURE_0_FROM_I2S_1)
oxygen_write16(chip, OXYGEN_I2S_A_FORMAT,
- OXYGEN_RATE_48000 | chip->model->adc_i2s_format |
+ OXYGEN_RATE_48000 | chip->model.adc_i2s_format |
OXYGEN_I2S_MCLK_256 | OXYGEN_I2S_BITS_16 |
OXYGEN_I2S_MASTER | OXYGEN_I2S_BCLK_64);
else
oxygen_write16(chip, OXYGEN_I2S_A_FORMAT,
OXYGEN_I2S_MASTER | OXYGEN_I2S_MUTE_MCLK);
- if (chip->model->pcm_dev_cfg & (CAPTURE_0_FROM_I2S_2 |
- CAPTURE_2_FROM_I2S_2))
+ if (chip->model.device_config & (CAPTURE_0_FROM_I2S_2 |
+ CAPTURE_2_FROM_I2S_2))
oxygen_write16(chip, OXYGEN_I2S_B_FORMAT,
- OXYGEN_RATE_48000 | chip->model->adc_i2s_format |
+ OXYGEN_RATE_48000 | chip->model.adc_i2s_format |
OXYGEN_I2S_MCLK_256 | OXYGEN_I2S_BITS_16 |
OXYGEN_I2S_MASTER | OXYGEN_I2S_BCLK_64);
else
@@ -295,7 +323,7 @@ static void oxygen_init(struct oxygen *chip)
oxygen_clear_bits32(chip, OXYGEN_SPDIF_CONTROL,
OXYGEN_SPDIF_OUT_ENABLE |
OXYGEN_SPDIF_LOOPBACK);
- if (chip->model->pcm_dev_cfg & CAPTURE_1_FROM_SPDIF)
+ if (chip->model.device_config & CAPTURE_1_FROM_SPDIF)
oxygen_write32_masked(chip, OXYGEN_SPDIF_CONTROL,
OXYGEN_SPDIF_SENSE_MASK |
OXYGEN_SPDIF_LOCK_MASK |
@@ -314,6 +342,10 @@ static void oxygen_init(struct oxygen *chip)
OXYGEN_SPDIF_LOCK_MASK |
OXYGEN_SPDIF_RATE_MASK);
oxygen_write32(chip, OXYGEN_SPDIF_OUTPUT_BITS, chip->spdif_bits);
+ oxygen_write16(chip, OXYGEN_2WIRE_BUS_STATUS,
+ OXYGEN_2WIRE_LENGTH_8 |
+ OXYGEN_2WIRE_INTERRUPT_MASK |
+ OXYGEN_2WIRE_SPEED_STANDARD);
oxygen_clear_bits8(chip, OXYGEN_MPU401_CONTROL, OXYGEN_MPU401_LOOPBACK);
oxygen_write8(chip, OXYGEN_GPI_INTERRUPT_MASK, 0);
oxygen_write16(chip, OXYGEN_GPIO_INTERRUPT_MASK, 0);
@@ -413,14 +445,15 @@ static void oxygen_card_free(struct snd_card *card)
if (chip->irq >= 0)
free_irq(chip->irq, chip);
flush_scheduled_work();
- chip->model->cleanup(chip);
+ chip->model.cleanup(chip);
mutex_destroy(&chip->mutex);
pci_release_regions(chip->pci);
pci_disable_device(chip->pci);
}
int oxygen_pci_probe(struct pci_dev *pci, int index, char *id,
- const struct oxygen_model *model)
+ const struct oxygen_model *model,
+ unsigned long driver_data)
{
struct snd_card *card;
struct oxygen *chip;
@@ -435,7 +468,7 @@ int oxygen_pci_probe(struct pci_dev *pci, int index, char *id,
chip->card = card;
chip->pci = pci;
chip->irq = -1;
- chip->model = model;
+ chip->model = *model;
chip->model_data = chip + 1;
spin_lock_init(&chip->reg_lock);
mutex_init(&chip->mutex);
@@ -455,7 +488,7 @@ int oxygen_pci_probe(struct pci_dev *pci, int index, char *id,
}
if (!(pci_resource_flags(pci, 0) & IORESOURCE_IO) ||
- pci_resource_len(pci, 0) < 0x100) {
+ pci_resource_len(pci, 0) < OXYGEN_IO_SIZE) {
snd_printk(KERN_ERR "invalid PCI I/O range\n");
err = -ENXIO;
goto err_pci_regions;
@@ -466,23 +499,28 @@ int oxygen_pci_probe(struct pci_dev *pci, int index, char *id,
snd_card_set_dev(card, &pci->dev);
card->private_free = oxygen_card_free;
+ if (chip->model.probe) {
+ err = chip->model.probe(chip, driver_data);
+ if (err < 0)
+ goto err_card;
+ }
oxygen_init(chip);
- model->init(chip);
+ chip->model.init(chip);
err = request_irq(pci->irq, oxygen_interrupt, IRQF_SHARED,
- model->chip, chip);
+ chip->model.chip, chip);
if (err < 0) {
snd_printk(KERN_ERR "cannot grab interrupt %d\n", pci->irq);
goto err_card;
}
chip->irq = pci->irq;
- strcpy(card->driver, model->chip);
- strcpy(card->shortname, model->shortname);
+ strcpy(card->driver, chip->model.chip);
+ strcpy(card->shortname, chip->model.shortname);
sprintf(card->longname, "%s (rev %u) at %#lx, irq %i",
- model->longname, chip->revision, chip->addr, chip->irq);
- strcpy(card->mixername, model->chip);
- snd_component_add(card, model->chip);
+ chip->model.longname, chip->revision, chip->addr, chip->irq);
+ strcpy(card->mixername, chip->model.chip);
+ snd_component_add(card, chip->model.chip);
err = oxygen_pcm_init(chip);
if (err < 0)
@@ -492,10 +530,15 @@ int oxygen_pci_probe(struct pci_dev *pci, int index, char *id,
if (err < 0)
goto err_card;
- if (model->misc_flags & OXYGEN_MISC_MIDI) {
+ if (chip->model.device_config & (MIDI_OUTPUT | MIDI_INPUT)) {
+ unsigned int info_flags = MPU401_INFO_INTEGRATED;
+ if (chip->model.device_config & MIDI_OUTPUT)
+ info_flags |= MPU401_INFO_OUTPUT;
+ if (chip->model.device_config & MIDI_INPUT)
+ info_flags |= MPU401_INFO_INPUT;
err = snd_mpu401_uart_new(card, 0, MPU401_HW_CMIPCI,
chip->addr + OXYGEN_MPU401,
- MPU401_INFO_INTEGRATED, 0, 0,
+ info_flags, 0, 0,
&chip->midi);
if (err < 0)
goto err_card;
@@ -504,7 +547,7 @@ int oxygen_pci_probe(struct pci_dev *pci, int index, char *id,
oxygen_proc_init(chip);
spin_lock_irq(&chip->reg_lock);
- if (chip->model->pcm_dev_cfg & CAPTURE_1_FROM_SPDIF)
+ if (chip->model.device_config & CAPTURE_1_FROM_SPDIF)
chip->interrupt_mask |= OXYGEN_INT_SPDIF_IN_DETECT;
if (chip->has_ac97_0 | chip->has_ac97_1)
chip->interrupt_mask |= OXYGEN_INT_AC97;
@@ -534,3 +577,99 @@ void oxygen_pci_remove(struct pci_dev *pci)
pci_set_drvdata(pci, NULL);
}
EXPORT_SYMBOL(oxygen_pci_remove);
+
+#ifdef CONFIG_PM
+int oxygen_pci_suspend(struct pci_dev *pci, pm_message_t state)
+{
+ struct snd_card *card = pci_get_drvdata(pci);
+ struct oxygen *chip = card->private_data;
+ unsigned int i, saved_interrupt_mask;
+
+ snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
+
+ for (i = 0; i < PCM_COUNT; ++i)
+ if (chip->streams[i])
+ snd_pcm_suspend(chip->streams[i]);
+
+ if (chip->model.suspend)
+ chip->model.suspend(chip);
+
+ spin_lock_irq(&chip->reg_lock);
+ saved_interrupt_mask = chip->interrupt_mask;
+ chip->interrupt_mask = 0;
+ oxygen_write16(chip, OXYGEN_DMA_STATUS, 0);
+ oxygen_write16(chip, OXYGEN_INTERRUPT_MASK, 0);
+ spin_unlock_irq(&chip->reg_lock);
+
+ synchronize_irq(chip->irq);
+ flush_scheduled_work();
+ chip->interrupt_mask = saved_interrupt_mask;
+
+ pci_disable_device(pci);
+ pci_save_state(pci);
+ pci_set_power_state(pci, pci_choose_state(pci, state));
+ return 0;
+}
+EXPORT_SYMBOL(oxygen_pci_suspend);
+
+static const u32 registers_to_restore[OXYGEN_IO_SIZE / 32] = {
+ 0xffffffff, 0x00ff077f, 0x00011d08, 0x007f00ff,
+ 0x00300000, 0x00000fe4, 0x0ff7001f, 0x00000000
+};
+static const u32 ac97_registers_to_restore[2][0x40 / 32] = {
+ { 0x18284fa2, 0x03060000 },
+ { 0x00007fa6, 0x00200000 }
+};
+
+static inline int is_bit_set(const u32 *bitmap, unsigned int bit)
+{
+ return bitmap[bit / 32] & (1 << (bit & 31));
+}
+
+static void oxygen_restore_ac97(struct oxygen *chip, unsigned int codec)
+{
+ unsigned int i;
+
+ oxygen_write_ac97(chip, codec, AC97_RESET, 0);
+ msleep(1);
+ for (i = 1; i < 0x40; ++i)
+ if (is_bit_set(ac97_registers_to_restore[codec], i))
+ oxygen_write_ac97(chip, codec, i * 2,
+ chip->saved_ac97_registers[codec][i]);
+}
+
+int oxygen_pci_resume(struct pci_dev *pci)
+{
+ struct snd_card *card = pci_get_drvdata(pci);
+ struct oxygen *chip = card->private_data;
+ unsigned int i;
+
+ pci_set_power_state(pci, PCI_D0);
+ pci_restore_state(pci);
+ if (pci_enable_device(pci) < 0) {
+ snd_printk(KERN_ERR "cannot reenable device");
+ snd_card_disconnect(card);
+ return -EIO;
+ }
+ pci_set_master(pci);
+
+ oxygen_write16(chip, OXYGEN_DMA_STATUS, 0);
+ oxygen_write16(chip, OXYGEN_INTERRUPT_MASK, 0);
+ for (i = 0; i < OXYGEN_IO_SIZE; ++i)
+ if (is_bit_set(registers_to_restore, i))
+ oxygen_write8(chip, i, chip->saved_registers._8[i]);
+ if (chip->has_ac97_0)
+ oxygen_restore_ac97(chip, 0);
+ if (chip->has_ac97_1)
+ oxygen_restore_ac97(chip, 1);
+
+ if (chip->model.resume)
+ chip->model.resume(chip);
+
+ oxygen_write16(chip, OXYGEN_INTERRUPT_MASK, chip->interrupt_mask);
+
+ snd_power_change_state(card, SNDRV_CTL_POWER_D0);
+ return 0;
+}
+EXPORT_SYMBOL(oxygen_pci_resume);
+#endif /* CONFIG_PM */
diff --git a/sound/pci/oxygen/oxygen_mixer.c b/sound/pci/oxygen/oxygen_mixer.c
index 6facac5aed90..304da169bfdc 100644
--- a/sound/pci/oxygen/oxygen_mixer.c
+++ b/sound/pci/oxygen/oxygen_mixer.c
@@ -31,9 +31,9 @@ static int dac_volume_info(struct snd_kcontrol *ctl,
struct oxygen *chip = ctl->private_data;
info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- info->count = chip->model->dac_channels;
- info->value.integer.min = chip->model->dac_volume_min;
- info->value.integer.max = chip->model->dac_volume_max;
+ info->count = chip->model.dac_channels;
+ info->value.integer.min = chip->model.dac_volume_min;
+ info->value.integer.max = chip->model.dac_volume_max;
return 0;
}
@@ -44,7 +44,7 @@ static int dac_volume_get(struct snd_kcontrol *ctl,
unsigned int i;
mutex_lock(&chip->mutex);
- for (i = 0; i < chip->model->dac_channels; ++i)
+ for (i = 0; i < chip->model.dac_channels; ++i)
value->value.integer.value[i] = chip->dac_volume[i];
mutex_unlock(&chip->mutex);
return 0;
@@ -59,13 +59,13 @@ static int dac_volume_put(struct snd_kcontrol *ctl,
changed = 0;
mutex_lock(&chip->mutex);
- for (i = 0; i < chip->model->dac_channels; ++i)
+ for (i = 0; i < chip->model.dac_channels; ++i)
if (value->value.integer.value[i] != chip->dac_volume[i]) {
chip->dac_volume[i] = value->value.integer.value[i];
changed = 1;
}
if (changed)
- chip->model->update_dac_volume(chip);
+ chip->model.update_dac_volume(chip);
mutex_unlock(&chip->mutex);
return changed;
}
@@ -91,7 +91,7 @@ static int dac_mute_put(struct snd_kcontrol *ctl,
changed = !value->value.integer.value[0] != chip->dac_mute;
if (changed) {
chip->dac_mute = !value->value.integer.value[0];
- chip->model->update_dac_mute(chip);
+ chip->model.update_dac_mute(chip);
}
mutex_unlock(&chip->mutex);
return changed;
@@ -103,7 +103,7 @@ static int upmix_info(struct snd_kcontrol *ctl, struct snd_ctl_elem_info *info)
"Front", "Front+Surround", "Front+Surround+Back"
};
struct oxygen *chip = ctl->private_data;
- unsigned int count = 2 + (chip->model->dac_channels == 8);
+ unsigned int count = 2 + (chip->model.dac_channels == 8);
info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
info->count = 1;
@@ -172,7 +172,7 @@ void oxygen_update_dac_routing(struct oxygen *chip)
static int upmix_put(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value)
{
struct oxygen *chip = ctl->private_data;
- unsigned int count = 2 + (chip->model->dac_channels == 8);
+ unsigned int count = 2 + (chip->model.dac_channels == 8);
int changed;
mutex_lock(&chip->mutex);
@@ -211,13 +211,13 @@ static unsigned int oxygen_spdif_rate(unsigned int oxygen_rate)
case OXYGEN_RATE_64000:
return 0xb << OXYGEN_SPDIF_CS_RATE_SHIFT;
case OXYGEN_RATE_88200:
- return 0x8 << OXYGEN_SPDIF_CS_RATE_SHIFT;
+ return IEC958_AES3_CON_FS_88200 << OXYGEN_SPDIF_CS_RATE_SHIFT;
case OXYGEN_RATE_96000:
- return 0xa << OXYGEN_SPDIF_CS_RATE_SHIFT;
+ return IEC958_AES3_CON_FS_96000 << OXYGEN_SPDIF_CS_RATE_SHIFT;
case OXYGEN_RATE_176400:
- return 0xc << OXYGEN_SPDIF_CS_RATE_SHIFT;
+ return IEC958_AES3_CON_FS_176400 << OXYGEN_SPDIF_CS_RATE_SHIFT;
case OXYGEN_RATE_192000:
- return 0xe << OXYGEN_SPDIF_CS_RATE_SHIFT;
+ return IEC958_AES3_CON_FS_192000 << OXYGEN_SPDIF_CS_RATE_SHIFT;
}
}
@@ -512,14 +512,17 @@ static int ac97_switch_get(struct snd_kcontrol *ctl,
static void mute_ac97_ctl(struct oxygen *chip, unsigned int control)
{
- unsigned int priv_idx = chip->controls[control]->private_value & 0xff;
+ unsigned int priv_idx;
u16 value;
+ if (!chip->controls[control])
+ return;
+ priv_idx = chip->controls[control]->private_value & 0xff;
value = oxygen_read_ac97(chip, 0, priv_idx);
if (!(value & 0x8000)) {
oxygen_write_ac97(chip, 0, priv_idx, value | 0x8000);
- if (chip->model->ac97_switch)
- chip->model->ac97_switch(chip, priv_idx, 0x8000);
+ if (chip->model.ac97_switch)
+ chip->model.ac97_switch(chip, priv_idx, 0x8000);
snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
&chip->controls[control]->id);
}
@@ -546,8 +549,8 @@ static int ac97_switch_put(struct snd_kcontrol *ctl,
change = newreg != oldreg;
if (change) {
oxygen_write_ac97(chip, codec, index, newreg);
- if (codec == 0 && chip->model->ac97_switch)
- chip->model->ac97_switch(chip, index, newreg & 0x8000);
+ if (codec == 0 && chip->model.ac97_switch)
+ chip->model.ac97_switch(chip, index, newreg & 0x8000);
if (index == AC97_LINE) {
oxygen_write_ac97_masked(chip, 0, CM9780_GPIO_STATUS,
newreg & 0x8000 ?
@@ -936,16 +939,16 @@ static int add_controls(struct oxygen *chip,
for (i = 0; i < count; ++i) {
template = controls[i];
- if (chip->model->control_filter) {
- err = chip->model->control_filter(&template);
+ if (chip->model.control_filter) {
+ err = chip->model.control_filter(&template);
if (err < 0)
return err;
if (err == 1)
continue;
}
if (!strcmp(template.name, "Master Playback Volume") &&
- chip->model->dac_tlv) {
- template.tlv.p = chip->model->dac_tlv;
+ chip->model.dac_tlv) {
+ template.tlv.p = chip->model.dac_tlv;
template.access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ;
}
ctl = snd_ctl_new1(&template, chip);
@@ -971,14 +974,14 @@ int oxygen_mixer_init(struct oxygen *chip)
err = add_controls(chip, controls, ARRAY_SIZE(controls));
if (err < 0)
return err;
- if (chip->model->pcm_dev_cfg & CAPTURE_1_FROM_SPDIF) {
+ if (chip->model.device_config & CAPTURE_1_FROM_SPDIF) {
err = add_controls(chip, spdif_input_controls,
ARRAY_SIZE(spdif_input_controls));
if (err < 0)
return err;
}
for (i = 0; i < ARRAY_SIZE(monitor_controls); ++i) {
- if (!(chip->model->pcm_dev_cfg & monitor_controls[i].pcm_dev))
+ if (!(chip->model.device_config & monitor_controls[i].pcm_dev))
continue;
err = add_controls(chip, monitor_controls[i].controls,
ARRAY_SIZE(monitor_controls[i].controls));
@@ -997,5 +1000,5 @@ int oxygen_mixer_init(struct oxygen *chip)
if (err < 0)
return err;
}
- return chip->model->mixer_init ? chip->model->mixer_init(chip) : 0;
+ return chip->model.mixer_init ? chip->model.mixer_init(chip) : 0;
}
diff --git a/sound/pci/oxygen/oxygen_pcm.c b/sound/pci/oxygen/oxygen_pcm.c
index b17c405e069d..c262049961e1 100644
--- a/sound/pci/oxygen/oxygen_pcm.c
+++ b/sound/pci/oxygen/oxygen_pcm.c
@@ -24,6 +24,16 @@
#include <sound/pcm_params.h>
#include "oxygen.h"
+/* most DMA channels have a 16-bit counter for 32-bit words */
+#define BUFFER_BYTES_MAX ((1 << 16) * 4)
+/* the multichannel DMA channel has a 24-bit counter */
+#define BUFFER_BYTES_MAX_MULTICH ((1 << 24) * 4)
+
+#define PERIOD_BYTES_MIN 64
+
+#define DEFAULT_BUFFER_BYTES (BUFFER_BYTES_MAX / 2)
+#define DEFAULT_BUFFER_BYTES_MULTICH (1024 * 1024)
+
static const struct snd_pcm_hardware oxygen_stereo_hardware = {
.info = SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_MMAP_VALID |
@@ -44,11 +54,11 @@ static const struct snd_pcm_hardware oxygen_stereo_hardware = {
.rate_max = 192000,
.channels_min = 2,
.channels_max = 2,
- .buffer_bytes_max = 256 * 1024,
- .period_bytes_min = 128,
- .period_bytes_max = 128 * 1024,
+ .buffer_bytes_max = BUFFER_BYTES_MAX,
+ .period_bytes_min = PERIOD_BYTES_MIN,
+ .period_bytes_max = BUFFER_BYTES_MAX / 2,
.periods_min = 2,
- .periods_max = 2048,
+ .periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN,
};
static const struct snd_pcm_hardware oxygen_multichannel_hardware = {
.info = SNDRV_PCM_INFO_MMAP |
@@ -70,11 +80,11 @@ static const struct snd_pcm_hardware oxygen_multichannel_hardware = {
.rate_max = 192000,
.channels_min = 2,
.channels_max = 8,
- .buffer_bytes_max = 2048 * 1024,
- .period_bytes_min = 128,
- .period_bytes_max = 256 * 1024,
+ .buffer_bytes_max = BUFFER_BYTES_MAX_MULTICH,
+ .period_bytes_min = PERIOD_BYTES_MIN,
+ .period_bytes_max = BUFFER_BYTES_MAX_MULTICH / 2,
.periods_min = 2,
- .periods_max = 16384,
+ .periods_max = BUFFER_BYTES_MAX_MULTICH / PERIOD_BYTES_MIN,
};
static const struct snd_pcm_hardware oxygen_ac97_hardware = {
.info = SNDRV_PCM_INFO_MMAP |
@@ -88,11 +98,11 @@ static const struct snd_pcm_hardware oxygen_ac97_hardware = {
.rate_max = 48000,
.channels_min = 2,
.channels_max = 2,
- .buffer_bytes_max = 256 * 1024,
- .period_bytes_min = 128,
- .period_bytes_max = 128 * 1024,
+ .buffer_bytes_max = BUFFER_BYTES_MAX,
+ .period_bytes_min = PERIOD_BYTES_MIN,
+ .period_bytes_max = BUFFER_BYTES_MAX / 2,
.periods_min = 2,
- .periods_max = 2048,
+ .periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN,
};
static const struct snd_pcm_hardware *const oxygen_hardware[PCM_COUNT] = {
@@ -119,7 +129,7 @@ static int oxygen_open(struct snd_pcm_substream *substream,
runtime->private_data = (void *)(uintptr_t)channel;
if (channel == PCM_B && chip->has_ac97_1 &&
- (chip->model->pcm_dev_cfg & CAPTURE_2_FROM_AC97_1))
+ (chip->model.device_config & CAPTURE_2_FROM_AC97_1))
runtime->hw = oxygen_ac97_hardware;
else
runtime->hw = *oxygen_hardware[channel];
@@ -130,11 +140,11 @@ static int oxygen_open(struct snd_pcm_substream *substream,
runtime->hw.rate_min = 44100;
break;
case PCM_MULTICH:
- runtime->hw.channels_max = chip->model->dac_channels;
+ runtime->hw.channels_max = chip->model.dac_channels;
break;
}
- if (chip->model->pcm_hardware_filter)
- chip->model->pcm_hardware_filter(channel, &runtime->hw);
+ if (chip->model.pcm_hardware_filter)
+ chip->model.pcm_hardware_filter(channel, &runtime->hw);
err = snd_pcm_hw_constraint_step(runtime, 0,
SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 32);
if (err < 0)
@@ -155,6 +165,12 @@ static int oxygen_open(struct snd_pcm_substream *substream,
if (err < 0)
return err;
}
+ if (channel == PCM_MULTICH) {
+ err = snd_pcm_hw_constraint_minmax
+ (runtime, SNDRV_PCM_HW_PARAM_PERIOD_TIME, 0, 8192000);
+ if (err < 0)
+ return err;
+ }
snd_pcm_set_sync(substream);
chip->streams[channel] = substream;
@@ -339,7 +355,7 @@ static int oxygen_rec_a_hw_params(struct snd_pcm_substream *substream,
oxygen_write16_masked(chip, OXYGEN_I2S_A_FORMAT,
oxygen_rate(hw_params) |
oxygen_i2s_mclk(hw_params) |
- chip->model->adc_i2s_format |
+ chip->model.adc_i2s_format |
oxygen_i2s_bits(hw_params),
OXYGEN_I2S_RATE_MASK |
OXYGEN_I2S_FORMAT_MASK |
@@ -348,7 +364,7 @@ static int oxygen_rec_a_hw_params(struct snd_pcm_substream *substream,
spin_unlock_irq(&chip->reg_lock);
mutex_lock(&chip->mutex);
- chip->model->set_adc_params(chip, hw_params);
+ chip->model.set_adc_params(chip, hw_params);
mutex_unlock(&chip->mutex);
return 0;
}
@@ -365,7 +381,7 @@ static int oxygen_rec_b_hw_params(struct snd_pcm_substream *substream,
return err;
is_ac97 = chip->has_ac97_1 &&
- (chip->model->pcm_dev_cfg & CAPTURE_2_FROM_AC97_1);
+ (chip->model.device_config & CAPTURE_2_FROM_AC97_1);
spin_lock_irq(&chip->reg_lock);
oxygen_write8_masked(chip, OXYGEN_REC_FORMAT,
@@ -375,7 +391,7 @@ static int oxygen_rec_b_hw_params(struct snd_pcm_substream *substream,
oxygen_write16_masked(chip, OXYGEN_I2S_B_FORMAT,
oxygen_rate(hw_params) |
oxygen_i2s_mclk(hw_params) |
- chip->model->adc_i2s_format |
+ chip->model.adc_i2s_format |
oxygen_i2s_bits(hw_params),
OXYGEN_I2S_RATE_MASK |
OXYGEN_I2S_FORMAT_MASK |
@@ -385,7 +401,7 @@ static int oxygen_rec_b_hw_params(struct snd_pcm_substream *substream,
if (!is_ac97) {
mutex_lock(&chip->mutex);
- chip->model->set_adc_params(chip, hw_params);
+ chip->model.set_adc_params(chip, hw_params);
mutex_unlock(&chip->mutex);
}
return 0;
@@ -452,7 +468,7 @@ static int oxygen_multich_hw_params(struct snd_pcm_substream *substream,
OXYGEN_MULTICH_FORMAT_MASK);
oxygen_write16_masked(chip, OXYGEN_I2S_MULTICH_FORMAT,
oxygen_rate(hw_params) |
- chip->model->dac_i2s_format |
+ chip->model.dac_i2s_format |
oxygen_i2s_bits(hw_params),
OXYGEN_I2S_RATE_MASK |
OXYGEN_I2S_FORMAT_MASK |
@@ -462,7 +478,7 @@ static int oxygen_multich_hw_params(struct snd_pcm_substream *substream,
spin_unlock_irq(&chip->reg_lock);
mutex_lock(&chip->mutex);
- chip->model->set_dac_params(chip, hw_params);
+ chip->model.set_dac_params(chip, hw_params);
mutex_unlock(&chip->mutex);
return 0;
}
@@ -517,6 +533,7 @@ static int oxygen_trigger(struct snd_pcm_substream *substream, int cmd)
switch (cmd) {
case SNDRV_PCM_TRIGGER_STOP:
case SNDRV_PCM_TRIGGER_START:
+ case SNDRV_PCM_TRIGGER_SUSPEND:
pausing = 0;
break;
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
@@ -640,39 +657,42 @@ int oxygen_pcm_init(struct oxygen *chip)
int outs, ins;
int err;
- outs = !!(chip->model->pcm_dev_cfg & PLAYBACK_0_TO_I2S);
- ins = !!(chip->model->pcm_dev_cfg & (CAPTURE_0_FROM_I2S_1 |
- CAPTURE_0_FROM_I2S_2));
+ outs = !!(chip->model.device_config & PLAYBACK_0_TO_I2S);
+ ins = !!(chip->model.device_config & (CAPTURE_0_FROM_I2S_1 |
+ CAPTURE_0_FROM_I2S_2));
if (outs | ins) {
- err = snd_pcm_new(chip->card, "Analog", 0, outs, ins, &pcm);
+ err = snd_pcm_new(chip->card, "Multichannel",
+ 0, outs, ins, &pcm);
if (err < 0)
return err;
if (outs)
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
&oxygen_multich_ops);
- if (chip->model->pcm_dev_cfg & CAPTURE_0_FROM_I2S_1)
+ if (chip->model.device_config & CAPTURE_0_FROM_I2S_1)
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
&oxygen_rec_a_ops);
- else if (chip->model->pcm_dev_cfg & CAPTURE_0_FROM_I2S_2)
+ else if (chip->model.device_config & CAPTURE_0_FROM_I2S_2)
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
&oxygen_rec_b_ops);
pcm->private_data = chip;
pcm->private_free = oxygen_pcm_free;
- strcpy(pcm->name, "Analog");
+ strcpy(pcm->name, "Multichannel");
if (outs)
snd_pcm_lib_preallocate_pages(pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream,
SNDRV_DMA_TYPE_DEV,
snd_dma_pci_data(chip->pci),
- 512 * 1024, 2048 * 1024);
+ DEFAULT_BUFFER_BYTES_MULTICH,
+ BUFFER_BYTES_MAX_MULTICH);
if (ins)
snd_pcm_lib_preallocate_pages(pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream,
SNDRV_DMA_TYPE_DEV,
snd_dma_pci_data(chip->pci),
- 128 * 1024, 256 * 1024);
+ DEFAULT_BUFFER_BYTES,
+ BUFFER_BYTES_MAX);
}
- outs = !!(chip->model->pcm_dev_cfg & PLAYBACK_1_TO_SPDIF);
- ins = !!(chip->model->pcm_dev_cfg & CAPTURE_1_FROM_SPDIF);
+ outs = !!(chip->model.device_config & PLAYBACK_1_TO_SPDIF);
+ ins = !!(chip->model.device_config & CAPTURE_1_FROM_SPDIF);
if (outs | ins) {
err = snd_pcm_new(chip->card, "Digital", 1, outs, ins, &pcm);
if (err < 0)
@@ -688,15 +708,16 @@ int oxygen_pcm_init(struct oxygen *chip)
strcpy(pcm->name, "Digital");
snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
snd_dma_pci_data(chip->pci),
- 128 * 1024, 256 * 1024);
+ DEFAULT_BUFFER_BYTES,
+ BUFFER_BYTES_MAX);
}
if (chip->has_ac97_1) {
- outs = !!(chip->model->pcm_dev_cfg & PLAYBACK_2_TO_AC97_1);
- ins = !!(chip->model->pcm_dev_cfg & CAPTURE_2_FROM_AC97_1);
+ outs = !!(chip->model.device_config & PLAYBACK_2_TO_AC97_1);
+ ins = !!(chip->model.device_config & CAPTURE_2_FROM_AC97_1);
} else {
outs = 0;
- ins = !!(chip->model->pcm_dev_cfg & CAPTURE_2_FROM_I2S_2);
+ ins = !!(chip->model.device_config & CAPTURE_2_FROM_I2S_2);
}
if (outs | ins) {
err = snd_pcm_new(chip->card, outs ? "AC97" : "Analog2",
@@ -718,7 +739,8 @@ int oxygen_pcm_init(struct oxygen *chip)
strcpy(pcm->name, outs ? "Front Panel" : "Analog 2");
snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
snd_dma_pci_data(chip->pci),
- 128 * 1024, 256 * 1024);
+ DEFAULT_BUFFER_BYTES,
+ BUFFER_BYTES_MAX);
}
return 0;
}
diff --git a/sound/pci/oxygen/virtuoso.c b/sound/pci/oxygen/virtuoso.c
index 7f84fa5deca2..98c6a8c65d81 100644
--- a/sound/pci/oxygen/virtuoso.c
+++ b/sound/pci/oxygen/virtuoso.c
@@ -36,15 +36,15 @@
*/
/*
- * Xonar DX
- * --------
+ * Xonar D1/DX
+ * -----------
*
* CMI8788:
*
* I²C <-> CS4398 (front)
* <-> CS4362A (surround, center/LFE, back)
*
- * GPI 0 <- external power present
+ * GPI 0 <- external power present (DX only)
*
* GPIO 0 -> enable output to speakers
* GPIO 1 -> enable front panel I/O
@@ -62,14 +62,66 @@
* AD0 <- 0
*/
+/*
+ * Xonar HDAV1.3 (Deluxe)
+ * ----------------------
+ *
+ * CMI8788:
+ *
+ * I²C <-> PCM1796 (front)
+ *
+ * GPI 0 <- external power present
+ *
+ * GPIO 0 -> enable output to speakers
+ * GPIO 2 -> M0 of CS5381
+ * GPIO 3 -> M1 of CS5381
+ * GPIO 8 -> route input jack to line-in (0) or mic-in (1)
+ *
+ * TXD -> HDMI controller
+ * RXD <- HDMI controller
+ *
+ * PCM1796 front: AD1,0 <- 0,0
+ *
+ * no daughterboard
+ * ----------------
+ *
+ * GPIO 4 <- 1
+ *
+ * H6 daughterboard
+ * ----------------
+ *
+ * GPIO 4 <- 0
+ * GPIO 5 <- 0
+ *
+ * I²C <-> PCM1796 (surround)
+ * <-> PCM1796 (center/LFE)
+ * <-> PCM1796 (back)
+ *
+ * PCM1796 surround: AD1,0 <- 0,1
+ * PCM1796 center/LFE: AD1,0 <- 1,0
+ * PCM1796 back: AD1,0 <- 1,1
+ *
+ * unknown daughterboard
+ * ---------------------
+ *
+ * GPIO 4 <- 0
+ * GPIO 5 <- 1
+ *
+ * I²C <-> CS4362A (surround, center/LFE, back)
+ *
+ * CS4362A: AD0 <- 0
+ */
+
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/mutex.h>
#include <sound/ac97_codec.h>
+#include <sound/asoundef.h>
#include <sound/control.h>
#include <sound/core.h>
#include <sound/initval.h>
#include <sound/pcm.h>
+#include <sound/pcm_params.h>
#include <sound/tlv.h>
#include "oxygen.h"
#include "cm9780.h"
@@ -79,7 +131,7 @@
MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
MODULE_DESCRIPTION("Asus AVx00 driver");
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
MODULE_SUPPORTED_DEVICE("{{Asus,AV100},{Asus,AV200}}");
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
@@ -96,13 +148,18 @@ MODULE_PARM_DESC(enable, "enable card");
enum {
MODEL_D2,
MODEL_D2X,
+ MODEL_D1,
MODEL_DX,
+ MODEL_HDAV, /* without daughterboard */
+ MODEL_HDAV_H6, /* with H6 daughterboard */
};
static struct pci_device_id xonar_ids[] __devinitdata = {
{ OXYGEN_PCI_SUBID(0x1043, 0x8269), .driver_data = MODEL_D2 },
{ OXYGEN_PCI_SUBID(0x1043, 0x8275), .driver_data = MODEL_DX },
{ OXYGEN_PCI_SUBID(0x1043, 0x82b7), .driver_data = MODEL_D2X },
+ { OXYGEN_PCI_SUBID(0x1043, 0x8314), .driver_data = MODEL_HDAV },
+ { OXYGEN_PCI_SUBID(0x1043, 0x834f), .driver_data = MODEL_D1 },
{ }
};
MODULE_DEVICE_TABLE(pci, xonar_ids);
@@ -122,20 +179,33 @@ MODULE_DEVICE_TABLE(pci, xonar_ids);
#define GPIO_DX_FRONT_PANEL 0x0002
#define GPIO_DX_INPUT_ROUTE 0x0100
+#define GPIO_HDAV_DB_MASK 0x0030
+#define GPIO_HDAV_DB_H6 0x0000
+#define GPIO_HDAV_DB_XX 0x0020
+
+#define I2C_DEVICE_PCM1796(i) (0x98 + ((i) << 1)) /* 10011, ADx=i, /W=0 */
#define I2C_DEVICE_CS4398 0x9e /* 10011, AD1=1, AD0=1, /W=0 */
#define I2C_DEVICE_CS4362A 0x30 /* 001100, AD0=0, /W=0 */
struct xonar_data {
+ unsigned int model;
unsigned int anti_pop_delay;
+ unsigned int dacs;
u16 output_enable_bit;
u8 ext_power_reg;
u8 ext_power_int_reg;
u8 ext_power_bit;
u8 has_power;
+ u8 pcm1796_oversampling;
+ u8 cs4398_fm;
+ u8 cs4362a_fm;
+ u8 hdmi_params[5];
};
-static void pcm1796_write(struct oxygen *chip, unsigned int codec,
- u8 reg, u8 value)
+static void xonar_gpio_changed(struct oxygen *chip);
+
+static inline void pcm1796_write_spi(struct oxygen *chip, unsigned int codec,
+ u8 reg, u8 value)
{
/* maps ALSA channel pair number to SPI output */
static const u8 codec_map[4] = {
@@ -149,6 +219,22 @@ static void pcm1796_write(struct oxygen *chip, unsigned int codec,
(reg << 8) | value);
}
+static inline void pcm1796_write_i2c(struct oxygen *chip, unsigned int codec,
+ u8 reg, u8 value)
+{
+ oxygen_write_i2c(chip, I2C_DEVICE_PCM1796(codec), reg, value);
+}
+
+static void pcm1796_write(struct oxygen *chip, unsigned int codec,
+ u8 reg, u8 value)
+{
+ if ((chip->model.function_flags & OXYGEN_FUNCTION_2WIRE_SPI_MASK) ==
+ OXYGEN_FUNCTION_SPI)
+ pcm1796_write_spi(chip, codec, reg, value);
+ else
+ pcm1796_write_i2c(chip, codec, reg, value);
+}
+
static void cs4398_write(struct oxygen *chip, u8 reg, u8 value)
{
oxygen_write_i2c(chip, I2C_DEVICE_CS4398, reg, value);
@@ -159,6 +245,32 @@ static void cs4362a_write(struct oxygen *chip, u8 reg, u8 value)
oxygen_write_i2c(chip, I2C_DEVICE_CS4362A, reg, value);
}
+static void hdmi_write_command(struct oxygen *chip, u8 command,
+ unsigned int count, const u8 *params)
+{
+ unsigned int i;
+ u8 checksum;
+
+ oxygen_write_uart(chip, 0xfb);
+ oxygen_write_uart(chip, 0xef);
+ oxygen_write_uart(chip, command);
+ oxygen_write_uart(chip, count);
+ for (i = 0; i < count; ++i)
+ oxygen_write_uart(chip, params[i]);
+ checksum = 0xfb + 0xef + command + count;
+ for (i = 0; i < count; ++i)
+ checksum += params[i];
+ oxygen_write_uart(chip, checksum);
+}
+
+static void xonar_enable_output(struct oxygen *chip)
+{
+ struct xonar_data *data = chip->model_data;
+
+ msleep(data->anti_pop_delay);
+ oxygen_set_bits16(chip, OXYGEN_GPIO_DATA, data->output_enable_bit);
+}
+
static void xonar_common_init(struct oxygen *chip)
{
struct xonar_data *data = chip->model_data;
@@ -167,35 +279,72 @@ static void xonar_common_init(struct oxygen *chip)
oxygen_set_bits8(chip, data->ext_power_int_reg,
data->ext_power_bit);
chip->interrupt_mask |= OXYGEN_INT_GPIO;
+ chip->model.gpio_changed = xonar_gpio_changed;
data->has_power = !!(oxygen_read8(chip, data->ext_power_reg)
& data->ext_power_bit);
}
- oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_CS53x1_M_MASK);
+ oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL,
+ GPIO_CS53x1_M_MASK | data->output_enable_bit);
oxygen_write16_masked(chip, OXYGEN_GPIO_DATA,
GPIO_CS53x1_M_SINGLE, GPIO_CS53x1_M_MASK);
oxygen_ac97_set_bits(chip, 0, CM9780_JACK, CM9780_FMIC2MIC);
- msleep(data->anti_pop_delay);
- oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, data->output_enable_bit);
- oxygen_set_bits16(chip, OXYGEN_GPIO_DATA, data->output_enable_bit);
+ xonar_enable_output(chip);
}
-static void xonar_d2_init(struct oxygen *chip)
+static void update_pcm1796_volume(struct oxygen *chip)
{
struct xonar_data *data = chip->model_data;
unsigned int i;
- data->anti_pop_delay = 300;
- data->output_enable_bit = GPIO_D2_OUTPUT_ENABLE;
+ for (i = 0; i < data->dacs; ++i) {
+ pcm1796_write(chip, i, 16, chip->dac_volume[i * 2]);
+ pcm1796_write(chip, i, 17, chip->dac_volume[i * 2 + 1]);
+ }
+}
+
+static void update_pcm1796_mute(struct oxygen *chip)
+{
+ struct xonar_data *data = chip->model_data;
+ unsigned int i;
+ u8 value;
- for (i = 0; i < 4; ++i) {
- pcm1796_write(chip, i, 18, PCM1796_MUTE | PCM1796_DMF_DISABLED |
- PCM1796_FMT_24_LJUST | PCM1796_ATLD);
+ value = PCM1796_DMF_DISABLED | PCM1796_FMT_24_LJUST | PCM1796_ATLD;
+ if (chip->dac_mute)
+ value |= PCM1796_MUTE;
+ for (i = 0; i < data->dacs; ++i)
+ pcm1796_write(chip, i, 18, value);
+}
+
+static void pcm1796_init(struct oxygen *chip)
+{
+ struct xonar_data *data = chip->model_data;
+ unsigned int i;
+
+ for (i = 0; i < data->dacs; ++i) {
pcm1796_write(chip, i, 19, PCM1796_FLT_SHARP | PCM1796_ATS_1);
- pcm1796_write(chip, i, 20, PCM1796_OS_64);
+ pcm1796_write(chip, i, 20, data->pcm1796_oversampling);
pcm1796_write(chip, i, 21, 0);
- pcm1796_write(chip, i, 16, 0x0f); /* set ATL/ATR after ATLD */
- pcm1796_write(chip, i, 17, 0x0f);
}
+ update_pcm1796_mute(chip); /* set ATLD before ATL/ATR */
+ update_pcm1796_volume(chip);
+}
+
+static void xonar_d2_init(struct oxygen *chip)
+{
+ struct xonar_data *data = chip->model_data;
+
+ data->anti_pop_delay = 300;
+ data->output_enable_bit = GPIO_D2_OUTPUT_ENABLE;
+ data->pcm1796_oversampling = PCM1796_OS_64;
+ if (data->model == MODEL_D2X) {
+ data->ext_power_reg = OXYGEN_GPIO_DATA;
+ data->ext_power_int_reg = OXYGEN_GPIO_INTERRUPT_MASK;
+ data->ext_power_bit = GPIO_D2X_EXT_POWER;
+ oxygen_clear_bits16(chip, OXYGEN_GPIO_CONTROL,
+ GPIO_D2X_EXT_POWER);
+ }
+
+ pcm1796_init(chip);
oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_D2_ALT);
oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, GPIO_D2_ALT);
@@ -206,42 +355,47 @@ static void xonar_d2_init(struct oxygen *chip)
snd_component_add(chip->card, "CS5381");
}
-static void xonar_d2x_init(struct oxygen *chip)
+static void update_cs4362a_volumes(struct oxygen *chip)
{
- struct xonar_data *data = chip->model_data;
+ u8 mute;
- data->ext_power_reg = OXYGEN_GPIO_DATA;
- data->ext_power_int_reg = OXYGEN_GPIO_INTERRUPT_MASK;
- data->ext_power_bit = GPIO_D2X_EXT_POWER;
- oxygen_clear_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_D2X_EXT_POWER);
- xonar_d2_init(chip);
+ mute = chip->dac_mute ? CS4362A_MUTE : 0;
+ cs4362a_write(chip, 7, (127 - chip->dac_volume[2]) | mute);
+ cs4362a_write(chip, 8, (127 - chip->dac_volume[3]) | mute);
+ cs4362a_write(chip, 10, (127 - chip->dac_volume[4]) | mute);
+ cs4362a_write(chip, 11, (127 - chip->dac_volume[5]) | mute);
+ cs4362a_write(chip, 13, (127 - chip->dac_volume[6]) | mute);
+ cs4362a_write(chip, 14, (127 - chip->dac_volume[7]) | mute);
}
-static void xonar_dx_init(struct oxygen *chip)
+static void update_cs43xx_volume(struct oxygen *chip)
{
- struct xonar_data *data = chip->model_data;
+ cs4398_write(chip, 5, (127 - chip->dac_volume[0]) * 2);
+ cs4398_write(chip, 6, (127 - chip->dac_volume[1]) * 2);
+ update_cs4362a_volumes(chip);
+}
- data->anti_pop_delay = 800;
- data->output_enable_bit = GPIO_DX_OUTPUT_ENABLE;
- data->ext_power_reg = OXYGEN_GPI_DATA;
- data->ext_power_int_reg = OXYGEN_GPI_INTERRUPT_MASK;
- data->ext_power_bit = GPI_DX_EXT_POWER;
+static void update_cs43xx_mute(struct oxygen *chip)
+{
+ u8 reg;
- oxygen_write16(chip, OXYGEN_2WIRE_BUS_STATUS,
- OXYGEN_2WIRE_LENGTH_8 |
- OXYGEN_2WIRE_INTERRUPT_MASK |
- OXYGEN_2WIRE_SPEED_FAST);
+ reg = CS4398_MUTEP_LOW | CS4398_PAMUTE;
+ if (chip->dac_mute)
+ reg |= CS4398_MUTE_B | CS4398_MUTE_A;
+ cs4398_write(chip, 4, reg);
+ update_cs4362a_volumes(chip);
+}
+
+static void cs43xx_init(struct oxygen *chip)
+{
+ struct xonar_data *data = chip->model_data;
/* set CPEN (control port mode) and power down */
cs4398_write(chip, 8, CS4398_CPEN | CS4398_PDN);
cs4362a_write(chip, 0x01, CS4362A_PDN | CS4362A_CPEN);
/* configure */
- cs4398_write(chip, 2, CS4398_FM_SINGLE |
- CS4398_DEM_NONE | CS4398_DIF_LJUST);
+ cs4398_write(chip, 2, data->cs4398_fm);
cs4398_write(chip, 3, CS4398_ATAPI_B_R | CS4398_ATAPI_A_L);
- cs4398_write(chip, 4, CS4398_MUTEP_LOW | CS4398_PAMUTE);
- cs4398_write(chip, 5, 0xfe);
- cs4398_write(chip, 6, 0xfe);
cs4398_write(chip, 7, CS4398_RMP_DN | CS4398_RMP_UP |
CS4398_ZERO_CROSS | CS4398_SOFT_RAMP);
cs4362a_write(chip, 0x02, CS4362A_DIF_LJUST);
@@ -249,21 +403,37 @@ static void xonar_dx_init(struct oxygen *chip)
CS4362A_RMP_UP | CS4362A_ZERO_CROSS | CS4362A_SOFT_RAMP);
cs4362a_write(chip, 0x04, CS4362A_RMP_DN | CS4362A_DEM_NONE);
cs4362a_write(chip, 0x05, 0);
- cs4362a_write(chip, 0x06, CS4362A_FM_SINGLE |
- CS4362A_ATAPI_B_R | CS4362A_ATAPI_A_L);
- cs4362a_write(chip, 0x07, 0x7f | CS4362A_MUTE);
- cs4362a_write(chip, 0x08, 0x7f | CS4362A_MUTE);
- cs4362a_write(chip, 0x09, CS4362A_FM_SINGLE |
- CS4362A_ATAPI_B_R | CS4362A_ATAPI_A_L);
- cs4362a_write(chip, 0x0a, 0x7f | CS4362A_MUTE);
- cs4362a_write(chip, 0x0b, 0x7f | CS4362A_MUTE);
- cs4362a_write(chip, 0x0c, CS4362A_FM_SINGLE |
- CS4362A_ATAPI_B_R | CS4362A_ATAPI_A_L);
- cs4362a_write(chip, 0x0d, 0x7f | CS4362A_MUTE);
- cs4362a_write(chip, 0x0e, 0x7f | CS4362A_MUTE);
+ cs4362a_write(chip, 0x06, data->cs4362a_fm);
+ cs4362a_write(chip, 0x09, data->cs4362a_fm);
+ cs4362a_write(chip, 0x0c, data->cs4362a_fm);
+ update_cs43xx_volume(chip);
+ update_cs43xx_mute(chip);
/* clear power down */
cs4398_write(chip, 8, CS4398_CPEN);
cs4362a_write(chip, 0x01, CS4362A_CPEN);
+}
+
+static void xonar_d1_init(struct oxygen *chip)
+{
+ struct xonar_data *data = chip->model_data;
+
+ data->anti_pop_delay = 800;
+ data->output_enable_bit = GPIO_DX_OUTPUT_ENABLE;
+ data->cs4398_fm = CS4398_FM_SINGLE | CS4398_DEM_NONE | CS4398_DIF_LJUST;
+ data->cs4362a_fm = CS4362A_FM_SINGLE |
+ CS4362A_ATAPI_B_R | CS4362A_ATAPI_A_L;
+ if (data->model == MODEL_DX) {
+ data->ext_power_reg = OXYGEN_GPI_DATA;
+ data->ext_power_int_reg = OXYGEN_GPI_INTERRUPT_MASK;
+ data->ext_power_bit = GPI_DX_EXT_POWER;
+ }
+
+ oxygen_write16(chip, OXYGEN_2WIRE_BUS_STATUS,
+ OXYGEN_2WIRE_LENGTH_8 |
+ OXYGEN_2WIRE_INTERRUPT_MASK |
+ OXYGEN_2WIRE_SPEED_FAST);
+
+ cs43xx_init(chip);
oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL,
GPIO_DX_FRONT_PANEL | GPIO_DX_INPUT_ROUTE);
@@ -277,51 +447,135 @@ static void xonar_dx_init(struct oxygen *chip)
snd_component_add(chip->card, "CS5361");
}
-static void xonar_cleanup(struct oxygen *chip)
+static void xonar_hdav_init(struct oxygen *chip)
+{
+ struct xonar_data *data = chip->model_data;
+ u8 param;
+
+ oxygen_write16(chip, OXYGEN_2WIRE_BUS_STATUS,
+ OXYGEN_2WIRE_LENGTH_8 |
+ OXYGEN_2WIRE_INTERRUPT_MASK |
+ OXYGEN_2WIRE_SPEED_FAST);
+
+ data->anti_pop_delay = 100;
+ data->output_enable_bit = GPIO_DX_OUTPUT_ENABLE;
+ data->ext_power_reg = OXYGEN_GPI_DATA;
+ data->ext_power_int_reg = OXYGEN_GPI_INTERRUPT_MASK;
+ data->ext_power_bit = GPI_DX_EXT_POWER;
+ data->pcm1796_oversampling = PCM1796_OS_64;
+
+ pcm1796_init(chip);
+
+ oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_DX_INPUT_ROUTE);
+ oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, GPIO_DX_INPUT_ROUTE);
+
+ oxygen_reset_uart(chip);
+ param = 0;
+ hdmi_write_command(chip, 0x61, 1, &param);
+ param = 1;
+ hdmi_write_command(chip, 0x74, 1, &param);
+ data->hdmi_params[1] = IEC958_AES3_CON_FS_48000;
+ data->hdmi_params[4] = 1;
+ hdmi_write_command(chip, 0x54, 5, data->hdmi_params);
+
+ xonar_common_init(chip);
+
+ snd_component_add(chip->card, "PCM1796");
+ snd_component_add(chip->card, "CS5381");
+}
+
+static void xonar_disable_output(struct oxygen *chip)
{
struct xonar_data *data = chip->model_data;
oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, data->output_enable_bit);
}
-static void xonar_dx_cleanup(struct oxygen *chip)
+static void xonar_d2_cleanup(struct oxygen *chip)
{
- xonar_cleanup(chip);
+ xonar_disable_output(chip);
+}
+
+static void xonar_d1_cleanup(struct oxygen *chip)
+{
+ xonar_disable_output(chip);
cs4362a_write(chip, 0x01, CS4362A_PDN | CS4362A_CPEN);
oxygen_clear_bits8(chip, OXYGEN_FUNCTION, OXYGEN_FUNCTION_RESET_CODEC);
}
-static void set_pcm1796_params(struct oxygen *chip,
- struct snd_pcm_hw_params *params)
+static void xonar_hdav_cleanup(struct oxygen *chip)
{
- unsigned int i;
- u8 value;
+ u8 param = 0;
- value = params_rate(params) >= 96000 ? PCM1796_OS_32 : PCM1796_OS_64;
- for (i = 0; i < 4; ++i)
- pcm1796_write(chip, i, 20, value);
+ hdmi_write_command(chip, 0x74, 1, &param);
+ xonar_disable_output(chip);
}
-static void update_pcm1796_volume(struct oxygen *chip)
+static void xonar_d2_suspend(struct oxygen *chip)
{
- unsigned int i;
+ xonar_d2_cleanup(chip);
+}
- for (i = 0; i < 4; ++i) {
- pcm1796_write(chip, i, 16, chip->dac_volume[i * 2]);
- pcm1796_write(chip, i, 17, chip->dac_volume[i * 2 + 1]);
+static void xonar_d1_suspend(struct oxygen *chip)
+{
+ xonar_d1_cleanup(chip);
+}
+
+static void xonar_hdav_suspend(struct oxygen *chip)
+{
+ xonar_hdav_cleanup(chip);
+ msleep(2);
+}
+
+static void xonar_d2_resume(struct oxygen *chip)
+{
+ pcm1796_init(chip);
+ xonar_enable_output(chip);
+}
+
+static void xonar_d1_resume(struct oxygen *chip)
+{
+ cs43xx_init(chip);
+ xonar_enable_output(chip);
+}
+
+static void xonar_hdav_resume(struct oxygen *chip)
+{
+ struct xonar_data *data = chip->model_data;
+ u8 param;
+
+ oxygen_reset_uart(chip);
+ param = 0;
+ hdmi_write_command(chip, 0x61, 1, &param);
+ param = 1;
+ hdmi_write_command(chip, 0x74, 1, &param);
+ hdmi_write_command(chip, 0x54, 5, data->hdmi_params);
+ pcm1796_init(chip);
+ xonar_enable_output(chip);
+}
+
+static void xonar_hdav_pcm_hardware_filter(unsigned int channel,
+ struct snd_pcm_hardware *hardware)
+{
+ if (channel == PCM_MULTICH) {
+ hardware->rates = SNDRV_PCM_RATE_44100 |
+ SNDRV_PCM_RATE_48000 |
+ SNDRV_PCM_RATE_96000 |
+ SNDRV_PCM_RATE_192000;
+ hardware->rate_min = 44100;
}
}
-static void update_pcm1796_mute(struct oxygen *chip)
+static void set_pcm1796_params(struct oxygen *chip,
+ struct snd_pcm_hw_params *params)
{
+ struct xonar_data *data = chip->model_data;
unsigned int i;
- u8 value;
- value = PCM1796_FMT_24_LJUST | PCM1796_ATLD;
- if (chip->dac_mute)
- value |= PCM1796_MUTE;
- for (i = 0; i < 4; ++i)
- pcm1796_write(chip, i, 18, value);
+ data->pcm1796_oversampling =
+ params_rate(params) >= 96000 ? PCM1796_OS_32 : PCM1796_OS_64;
+ for (i = 0; i < data->dacs; ++i)
+ pcm1796_write(chip, i, 20, data->pcm1796_oversampling);
}
static void set_cs53x1_params(struct oxygen *chip,
@@ -342,55 +596,60 @@ static void set_cs53x1_params(struct oxygen *chip,
static void set_cs43xx_params(struct oxygen *chip,
struct snd_pcm_hw_params *params)
{
- u8 fm_cs4398, fm_cs4362a;
+ struct xonar_data *data = chip->model_data;
- fm_cs4398 = CS4398_DEM_NONE | CS4398_DIF_LJUST;
- fm_cs4362a = CS4362A_ATAPI_B_R | CS4362A_ATAPI_A_L;
+ data->cs4398_fm = CS4398_DEM_NONE | CS4398_DIF_LJUST;
+ data->cs4362a_fm = CS4362A_ATAPI_B_R | CS4362A_ATAPI_A_L;
if (params_rate(params) <= 50000) {
- fm_cs4398 |= CS4398_FM_SINGLE;
- fm_cs4362a |= CS4362A_FM_SINGLE;
+ data->cs4398_fm |= CS4398_FM_SINGLE;
+ data->cs4362a_fm |= CS4362A_FM_SINGLE;
} else if (params_rate(params) <= 100000) {
- fm_cs4398 |= CS4398_FM_DOUBLE;
- fm_cs4362a |= CS4362A_FM_DOUBLE;
+ data->cs4398_fm |= CS4398_FM_DOUBLE;
+ data->cs4362a_fm |= CS4362A_FM_DOUBLE;
} else {
- fm_cs4398 |= CS4398_FM_QUAD;
- fm_cs4362a |= CS4362A_FM_QUAD;
+ data->cs4398_fm |= CS4398_FM_QUAD;
+ data->cs4362a_fm |= CS4362A_FM_QUAD;
}
- cs4398_write(chip, 2, fm_cs4398);
- cs4362a_write(chip, 0x06, fm_cs4362a);
- cs4362a_write(chip, 0x09, fm_cs4362a);
- cs4362a_write(chip, 0x0c, fm_cs4362a);
+ cs4398_write(chip, 2, data->cs4398_fm);
+ cs4362a_write(chip, 0x06, data->cs4362a_fm);
+ cs4362a_write(chip, 0x09, data->cs4362a_fm);
+ cs4362a_write(chip, 0x0c, data->cs4362a_fm);
}
-static void update_cs4362a_volumes(struct oxygen *chip)
+static void set_hdmi_params(struct oxygen *chip,
+ struct snd_pcm_hw_params *params)
{
- u8 mute;
-
- mute = chip->dac_mute ? CS4362A_MUTE : 0;
- cs4362a_write(chip, 7, (127 - chip->dac_volume[2]) | mute);
- cs4362a_write(chip, 8, (127 - chip->dac_volume[3]) | mute);
- cs4362a_write(chip, 10, (127 - chip->dac_volume[4]) | mute);
- cs4362a_write(chip, 11, (127 - chip->dac_volume[5]) | mute);
- cs4362a_write(chip, 13, (127 - chip->dac_volume[6]) | mute);
- cs4362a_write(chip, 14, (127 - chip->dac_volume[7]) | mute);
-}
+ struct xonar_data *data = chip->model_data;
-static void update_cs43xx_volume(struct oxygen *chip)
-{
- cs4398_write(chip, 5, (127 - chip->dac_volume[0]) * 2);
- cs4398_write(chip, 6, (127 - chip->dac_volume[1]) * 2);
- update_cs4362a_volumes(chip);
+ data->hdmi_params[0] = 0; /* 1 = non-audio */
+ switch (params_rate(params)) {
+ case 44100:
+ data->hdmi_params[1] = IEC958_AES3_CON_FS_44100;
+ break;
+ case 48000:
+ data->hdmi_params[1] = IEC958_AES3_CON_FS_48000;
+ break;
+ default: /* 96000 */
+ data->hdmi_params[1] = IEC958_AES3_CON_FS_96000;
+ break;
+ case 192000:
+ data->hdmi_params[1] = IEC958_AES3_CON_FS_192000;
+ break;
+ }
+ data->hdmi_params[2] = params_channels(params) / 2 - 1;
+ if (params_format(params) == SNDRV_PCM_FORMAT_S16_LE)
+ data->hdmi_params[3] = 0;
+ else
+ data->hdmi_params[3] = 0xc0;
+ data->hdmi_params[4] = 1; /* ? */
+ hdmi_write_command(chip, 0x54, 5, data->hdmi_params);
}
-static void update_cs43xx_mute(struct oxygen *chip)
+static void set_hdav_params(struct oxygen *chip,
+ struct snd_pcm_hw_params *params)
{
- u8 reg;
-
- reg = CS4398_MUTEP_LOW | CS4398_PAMUTE;
- if (chip->dac_mute)
- reg |= CS4398_MUTE_B | CS4398_MUTE_A;
- cs4398_write(chip, 4, reg);
- update_cs4362a_volumes(chip);
+ set_pcm1796_params(chip, params);
+ set_hdmi_params(chip, params);
}
static void xonar_gpio_changed(struct oxygen *chip)
@@ -412,29 +671,43 @@ static void xonar_gpio_changed(struct oxygen *chip)
}
}
-static int alt_switch_get(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_value *value)
+static void xonar_hdav_uart_input(struct oxygen *chip)
+{
+ if (chip->uart_input_count >= 2 &&
+ chip->uart_input[chip->uart_input_count - 2] == 'O' &&
+ chip->uart_input[chip->uart_input_count - 1] == 'K') {
+ printk(KERN_DEBUG "message from Xonar HDAV HDMI chip received:");
+ print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
+ chip->uart_input, chip->uart_input_count);
+ chip->uart_input_count = 0;
+ }
+}
+
+static int gpio_bit_switch_get(struct snd_kcontrol *ctl,
+ struct snd_ctl_elem_value *value)
{
struct oxygen *chip = ctl->private_data;
+ u16 bit = ctl->private_value;
value->value.integer.value[0] =
- !!(oxygen_read16(chip, OXYGEN_GPIO_DATA) & GPIO_D2_ALT);
+ !!(oxygen_read16(chip, OXYGEN_GPIO_DATA) & bit);
return 0;
}
-static int alt_switch_put(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_value *value)
+static int gpio_bit_switch_put(struct snd_kcontrol *ctl,
+ struct snd_ctl_elem_value *value)
{
struct oxygen *chip = ctl->private_data;
+ u16 bit = ctl->private_value;
u16 old_bits, new_bits;
int changed;
spin_lock_irq(&chip->reg_lock);
old_bits = oxygen_read16(chip, OXYGEN_GPIO_DATA);
if (value->value.integer.value[0])
- new_bits = old_bits | GPIO_D2_ALT;
+ new_bits = old_bits | bit;
else
- new_bits = old_bits & ~GPIO_D2_ALT;
+ new_bits = old_bits & ~bit;
changed = new_bits != old_bits;
if (changed)
oxygen_write16(chip, OXYGEN_GPIO_DATA, new_bits);
@@ -446,47 +719,22 @@ static const struct snd_kcontrol_new alt_switch = {
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "Analog Loopback Switch",
.info = snd_ctl_boolean_mono_info,
- .get = alt_switch_get,
- .put = alt_switch_put,
+ .get = gpio_bit_switch_get,
+ .put = gpio_bit_switch_put,
+ .private_value = GPIO_D2_ALT,
};
-static int front_panel_get(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_value *value)
-{
- struct oxygen *chip = ctl->private_data;
-
- value->value.integer.value[0] =
- !!(oxygen_read16(chip, OXYGEN_GPIO_DATA) & GPIO_DX_FRONT_PANEL);
- return 0;
-}
-
-static int front_panel_put(struct snd_kcontrol *ctl,
- struct snd_ctl_elem_value *value)
-{
- struct oxygen *chip = ctl->private_data;
- u16 old_reg, new_reg;
-
- spin_lock_irq(&chip->reg_lock);
- old_reg = oxygen_read16(chip, OXYGEN_GPIO_DATA);
- if (value->value.integer.value[0])
- new_reg = old_reg | GPIO_DX_FRONT_PANEL;
- else
- new_reg = old_reg & ~GPIO_DX_FRONT_PANEL;
- oxygen_write16(chip, OXYGEN_GPIO_DATA, new_reg);
- spin_unlock_irq(&chip->reg_lock);
- return old_reg != new_reg;
-}
-
static const struct snd_kcontrol_new front_panel_switch = {
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "Front Panel Switch",
.info = snd_ctl_boolean_mono_info,
- .get = front_panel_get,
- .put = front_panel_put,
+ .get = gpio_bit_switch_get,
+ .put = gpio_bit_switch_put,
+ .private_value = GPIO_DX_FRONT_PANEL,
};
-static void xonar_dx_ac97_switch(struct oxygen *chip,
- unsigned int reg, unsigned int mute)
+static void xonar_line_mic_ac97_switch(struct oxygen *chip,
+ unsigned int reg, unsigned int mute)
{
if (reg == AC97_LINE) {
spin_lock_irq(&chip->reg_lock);
@@ -508,113 +756,164 @@ static int xonar_d2_control_filter(struct snd_kcontrol_new *template)
return 0;
}
-static int xonar_dx_control_filter(struct snd_kcontrol_new *template)
+static int xonar_d1_control_filter(struct snd_kcontrol_new *template)
{
if (!strncmp(template->name, "CD Capture ", 11))
return 1; /* no CD input */
return 0;
}
-static int xonar_mixer_init(struct oxygen *chip)
+static int xonar_d2_mixer_init(struct oxygen *chip)
{
return snd_ctl_add(chip->card, snd_ctl_new1(&alt_switch, chip));
}
-static int xonar_dx_mixer_init(struct oxygen *chip)
+static int xonar_d1_mixer_init(struct oxygen *chip)
{
return snd_ctl_add(chip->card, snd_ctl_new1(&front_panel_switch, chip));
}
-static const struct oxygen_model xonar_models[] = {
- [MODEL_D2] = {
- .shortname = "Xonar D2",
- .longname = "Asus Virtuoso 200",
- .chip = "AV200",
- .owner = THIS_MODULE,
- .init = xonar_d2_init,
- .control_filter = xonar_d2_control_filter,
- .mixer_init = xonar_mixer_init,
- .cleanup = xonar_cleanup,
- .set_dac_params = set_pcm1796_params,
- .set_adc_params = set_cs53x1_params,
- .update_dac_volume = update_pcm1796_volume,
- .update_dac_mute = update_pcm1796_mute,
- .dac_tlv = pcm1796_db_scale,
- .model_data_size = sizeof(struct xonar_data),
- .pcm_dev_cfg = PLAYBACK_0_TO_I2S |
- PLAYBACK_1_TO_SPDIF |
- CAPTURE_0_FROM_I2S_2 |
- CAPTURE_1_FROM_SPDIF,
- .dac_channels = 8,
- .dac_volume_min = 0x0f,
- .dac_volume_max = 0xff,
- .misc_flags = OXYGEN_MISC_MIDI,
- .function_flags = OXYGEN_FUNCTION_SPI |
- OXYGEN_FUNCTION_ENABLE_SPI_4_5,
- .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
- .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
- },
- [MODEL_D2X] = {
- .shortname = "Xonar D2X",
- .longname = "Asus Virtuoso 200",
- .chip = "AV200",
- .owner = THIS_MODULE,
- .init = xonar_d2x_init,
- .control_filter = xonar_d2_control_filter,
- .mixer_init = xonar_mixer_init,
- .cleanup = xonar_cleanup,
- .set_dac_params = set_pcm1796_params,
- .set_adc_params = set_cs53x1_params,
- .update_dac_volume = update_pcm1796_volume,
- .update_dac_mute = update_pcm1796_mute,
- .gpio_changed = xonar_gpio_changed,
- .dac_tlv = pcm1796_db_scale,
- .model_data_size = sizeof(struct xonar_data),
- .pcm_dev_cfg = PLAYBACK_0_TO_I2S |
- PLAYBACK_1_TO_SPDIF |
- CAPTURE_0_FROM_I2S_2 |
- CAPTURE_1_FROM_SPDIF,
- .dac_channels = 8,
- .dac_volume_min = 0x0f,
- .dac_volume_max = 0xff,
- .misc_flags = OXYGEN_MISC_MIDI,
- .function_flags = OXYGEN_FUNCTION_SPI |
- OXYGEN_FUNCTION_ENABLE_SPI_4_5,
- .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
- .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
- },
- [MODEL_DX] = {
- .shortname = "Xonar DX",
- .longname = "Asus Virtuoso 100",
- .chip = "AV200",
- .owner = THIS_MODULE,
- .init = xonar_dx_init,
- .control_filter = xonar_dx_control_filter,
- .mixer_init = xonar_dx_mixer_init,
- .cleanup = xonar_dx_cleanup,
- .set_dac_params = set_cs43xx_params,
- .set_adc_params = set_cs53x1_params,
- .update_dac_volume = update_cs43xx_volume,
- .update_dac_mute = update_cs43xx_mute,
- .gpio_changed = xonar_gpio_changed,
- .ac97_switch = xonar_dx_ac97_switch,
- .dac_tlv = cs4362a_db_scale,
- .model_data_size = sizeof(struct xonar_data),
- .pcm_dev_cfg = PLAYBACK_0_TO_I2S |
- PLAYBACK_1_TO_SPDIF |
- CAPTURE_0_FROM_I2S_2,
- .dac_channels = 8,
- .dac_volume_min = 0,
- .dac_volume_max = 127,
- .function_flags = OXYGEN_FUNCTION_2WIRE,
- .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
- .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
- },
+static int xonar_model_probe(struct oxygen *chip, unsigned long driver_data)
+{
+ static const char *const names[] = {
+ [MODEL_D1] = "Xonar D1",
+ [MODEL_DX] = "Xonar DX",
+ [MODEL_D2] = "Xonar D2",
+ [MODEL_D2X] = "Xonar D2X",
+ [MODEL_HDAV] = "Xonar HDAV1.3",
+ [MODEL_HDAV_H6] = "Xonar HDAV1.3+H6",
+ };
+ static const u8 dacs[] = {
+ [MODEL_D1] = 2,
+ [MODEL_DX] = 2,
+ [MODEL_D2] = 4,
+ [MODEL_D2X] = 4,
+ [MODEL_HDAV] = 1,
+ [MODEL_HDAV_H6] = 4,
+ };
+ struct xonar_data *data = chip->model_data;
+
+ data->model = driver_data;
+ if (data->model == MODEL_HDAV) {
+ oxygen_clear_bits16(chip, OXYGEN_GPIO_CONTROL,
+ GPIO_HDAV_DB_MASK);
+ switch (oxygen_read16(chip, OXYGEN_GPIO_DATA) &
+ GPIO_HDAV_DB_MASK) {
+ case GPIO_HDAV_DB_H6:
+ data->model = MODEL_HDAV_H6;
+ break;
+ case GPIO_HDAV_DB_XX:
+ snd_printk(KERN_ERR "unknown daughterboard\n");
+ return -ENODEV;
+ }
+ }
+
+ data->dacs = dacs[data->model];
+ chip->model.shortname = names[data->model];
+ return 0;
+}
+
+static const struct oxygen_model model_xonar_d2 = {
+ .longname = "Asus Virtuoso 200",
+ .chip = "AV200",
+ .owner = THIS_MODULE,
+ .probe = xonar_model_probe,
+ .init = xonar_d2_init,
+ .control_filter = xonar_d2_control_filter,
+ .mixer_init = xonar_d2_mixer_init,
+ .cleanup = xonar_d2_cleanup,
+ .suspend = xonar_d2_suspend,
+ .resume = xonar_d2_resume,
+ .set_dac_params = set_pcm1796_params,
+ .set_adc_params = set_cs53x1_params,
+ .update_dac_volume = update_pcm1796_volume,
+ .update_dac_mute = update_pcm1796_mute,
+ .dac_tlv = pcm1796_db_scale,
+ .model_data_size = sizeof(struct xonar_data),
+ .device_config = PLAYBACK_0_TO_I2S |
+ PLAYBACK_1_TO_SPDIF |
+ CAPTURE_0_FROM_I2S_2 |
+ CAPTURE_1_FROM_SPDIF |
+ MIDI_OUTPUT |
+ MIDI_INPUT,
+ .dac_channels = 8,
+ .dac_volume_min = 0x0f,
+ .dac_volume_max = 0xff,
+ .misc_flags = OXYGEN_MISC_MIDI,
+ .function_flags = OXYGEN_FUNCTION_SPI |
+ OXYGEN_FUNCTION_ENABLE_SPI_4_5,
+ .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
+ .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
+};
+
+static const struct oxygen_model model_xonar_d1 = {
+ .longname = "Asus Virtuoso 100",
+ .chip = "AV200",
+ .owner = THIS_MODULE,
+ .probe = xonar_model_probe,
+ .init = xonar_d1_init,
+ .control_filter = xonar_d1_control_filter,
+ .mixer_init = xonar_d1_mixer_init,
+ .cleanup = xonar_d1_cleanup,
+ .suspend = xonar_d1_suspend,
+ .resume = xonar_d1_resume,
+ .set_dac_params = set_cs43xx_params,
+ .set_adc_params = set_cs53x1_params,
+ .update_dac_volume = update_cs43xx_volume,
+ .update_dac_mute = update_cs43xx_mute,
+ .ac97_switch = xonar_line_mic_ac97_switch,
+ .dac_tlv = cs4362a_db_scale,
+ .model_data_size = sizeof(struct xonar_data),
+ .device_config = PLAYBACK_0_TO_I2S |
+ PLAYBACK_1_TO_SPDIF |
+ CAPTURE_0_FROM_I2S_2,
+ .dac_channels = 8,
+ .dac_volume_min = 0,
+ .dac_volume_max = 127,
+ .function_flags = OXYGEN_FUNCTION_2WIRE,
+ .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
+ .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
+};
+
+static const struct oxygen_model model_xonar_hdav = {
+ .longname = "Asus Virtuoso 200",
+ .chip = "AV200",
+ .owner = THIS_MODULE,
+ .probe = xonar_model_probe,
+ .init = xonar_hdav_init,
+ .cleanup = xonar_hdav_cleanup,
+ .suspend = xonar_hdav_suspend,
+ .resume = xonar_hdav_resume,
+ .pcm_hardware_filter = xonar_hdav_pcm_hardware_filter,
+ .set_dac_params = set_hdav_params,
+ .set_adc_params = set_cs53x1_params,
+ .update_dac_volume = update_pcm1796_volume,
+ .update_dac_mute = update_pcm1796_mute,
+ .uart_input = xonar_hdav_uart_input,
+ .ac97_switch = xonar_line_mic_ac97_switch,
+ .dac_tlv = pcm1796_db_scale,
+ .model_data_size = sizeof(struct xonar_data),
+ .device_config = PLAYBACK_0_TO_I2S |
+ PLAYBACK_1_TO_SPDIF |
+ CAPTURE_0_FROM_I2S_2,
+ .dac_channels = 8,
+ .dac_volume_min = 0x0f,
+ .dac_volume_max = 0xff,
+ .function_flags = OXYGEN_FUNCTION_2WIRE,
+ .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
+ .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
};
static int __devinit xonar_probe(struct pci_dev *pci,
const struct pci_device_id *pci_id)
{
+ static const struct oxygen_model *const models[] = {
+ [MODEL_D1] = &model_xonar_d1,
+ [MODEL_DX] = &model_xonar_d1,
+ [MODEL_D2] = &model_xonar_d2,
+ [MODEL_D2X] = &model_xonar_d2,
+ [MODEL_HDAV] = &model_xonar_hdav,
+ };
static int dev;
int err;
@@ -624,8 +923,10 @@ static int __devinit xonar_probe(struct pci_dev *pci,
++dev;
return -ENOENT;
}
+ BUG_ON(pci_id->driver_data >= ARRAY_SIZE(models));
err = oxygen_pci_probe(pci, index[dev], id[dev],
- &xonar_models[pci_id->driver_data]);
+ models[pci_id->driver_data],
+ pci_id->driver_data);
if (err >= 0)
++dev;
return err;
@@ -636,6 +937,10 @@ static struct pci_driver xonar_driver = {
.id_table = xonar_ids,
.probe = xonar_probe,
.remove = __devexit_p(oxygen_pci_remove),
+#ifdef CONFIG_PM
+ .suspend = oxygen_pci_suspend,
+ .resume = oxygen_pci_resume,
+#endif
};
static int __init alsa_card_xonar_init(void)
diff --git a/sound/pci/pcxhr/pcxhr.c b/sound/pci/pcxhr/pcxhr.c
index 7fdcdc8c6b64..0e06c6c9fcc0 100644
--- a/sound/pci/pcxhr/pcxhr.c
+++ b/sound/pci/pcxhr/pcxhr.c
@@ -464,7 +464,8 @@ static int pcxhr_update_r_buffer(struct pcxhr_stream *stream)
pcxhr_init_rmh(&rmh, CMD_UPDATE_R_BUFFERS);
pcxhr_set_pipe_cmd_params(&rmh, is_capture, stream->pipe->first_audio, stream_num, 0);
- snd_assert(subs->runtime->dma_bytes < 0x200000); /* max buffer size is 2 MByte */
+ /* max buffer size is 2 MByte */
+ snd_BUG_ON(subs->runtime->dma_bytes >= 0x200000);
rmh.cmd[1] = subs->runtime->dma_bytes * 8; /* size in bits */
rmh.cmd[2] = subs->runtime->dma_addr >> 24; /* most significant byte */
rmh.cmd[2] |= 1<<19; /* this is a circular buffer */
@@ -516,7 +517,7 @@ static void pcxhr_trigger_tasklet(unsigned long arg)
int capture_mask = 0;
int playback_mask = 0;
-#ifdef CONFIG_SND_DEBUG_DETECT
+#ifdef CONFIG_SND_DEBUG_VERBOSE
struct timeval my_tv1, my_tv2;
do_gettimeofday(&my_tv1);
#endif
@@ -623,7 +624,7 @@ static void pcxhr_trigger_tasklet(unsigned long arg)
mutex_unlock(&mgr->setup_mutex);
-#ifdef CONFIG_SND_DEBUG_DETECT
+#ifdef CONFIG_SND_DEBUG_VERBOSE
do_gettimeofday(&my_tv2);
snd_printdd("***TRIGGER TASKLET*** TIME = %ld (err = %x)\n",
(long)(my_tv2.tv_usec - my_tv1.tv_usec), err);
@@ -1228,7 +1229,8 @@ static int __devinit pcxhr_probe(struct pci_dev *pci, const struct pci_device_id
return -ENOMEM;
}
- snd_assert(pci_id->driver_data < PCI_ID_LAST, return -ENODEV);
+ if (snd_BUG_ON(pci_id->driver_data >= PCI_ID_LAST))
+ return -ENODEV;
card_name = pcxhr_board_params[pci_id->driver_data].board_name;
mgr->playback_chips = pcxhr_board_params[pci_id->driver_data].playback_chips;
mgr->capture_chips = pcxhr_board_params[pci_id->driver_data].capture_chips;
diff --git a/sound/pci/pcxhr/pcxhr_core.c b/sound/pci/pcxhr/pcxhr_core.c
index 78aa81feaa4a..7143259cfe34 100644
--- a/sound/pci/pcxhr/pcxhr_core.c
+++ b/sound/pci/pcxhr/pcxhr_core.c
@@ -269,7 +269,7 @@ int pcxhr_load_xilinx_binary(struct pcxhr_mgr *mgr, const struct firmware *xilin
unsigned int chipsc;
unsigned char data;
unsigned char mask;
- unsigned char *image;
+ const unsigned char *image;
/* test first xilinx */
chipsc = PCXHR_INPL(mgr, PCXHR_PLX_CHIPSC);
@@ -316,19 +316,23 @@ static int pcxhr_download_dsp(struct pcxhr_mgr *mgr, const struct firmware *dsp)
int err;
unsigned int i;
unsigned int len;
- unsigned char *data;
+ const unsigned char *data;
unsigned char dummy;
/* check the length of boot image */
- snd_assert(dsp->size > 0, return -EINVAL);
- snd_assert(dsp->size % 3 == 0, return -EINVAL);
- snd_assert(dsp->data, return -EINVAL);
+ if (dsp->size <= 0)
+ return -EINVAL;
+ if (dsp->size % 3)
+ return -EINVAL;
+ if (snd_BUG_ON(!dsp->data))
+ return -EINVAL;
/* transfert data buffer from PC to DSP */
for (i = 0; i < dsp->size; i += 3) {
data = dsp->data + i;
if (i == 0) {
/* test data header consistency */
len = (unsigned int)((data[0]<<16) + (data[1]<<8) + data[2]);
- snd_assert((len==0) || (dsp->size == (len+2)*3), return -EINVAL);
+ if (len && dsp->size != (len + 2) * 3)
+ return -EINVAL;
}
/* wait DSP ready for new transfer */
err = pcxhr_check_reg_bit(mgr, PCXHR_DSP_ISR, PCXHR_ISR_HI08_TRDY,
@@ -389,7 +393,8 @@ int pcxhr_load_boot_binary(struct pcxhr_mgr *mgr, const struct firmware *boot)
unsigned char dummy;
/* send the hostport address to the DSP (only the upper 24 bit !) */
- snd_assert((physaddr & 0xff) == 0, return -EINVAL);
+ if (snd_BUG_ON(physaddr & 0xff))
+ return -EINVAL;
PCXHR_OUTPL(mgr, PCXHR_PLX_MBOX1, (physaddr >> 8));
err = pcxhr_send_it_dsp(mgr, PCXHR_IT_DOWNLOAD_BOOT, 0);
@@ -473,7 +478,7 @@ static struct pcxhr_cmd_info pcxhr_dsp_cmds[] = {
[CMD_AUDIO_LEVEL_ADJUST] = { 0xc22000, 0, RMH_SSIZE_FIXED },
};
-#ifdef CONFIG_SND_DEBUG_DETECT
+#ifdef CONFIG_SND_DEBUG_VERBOSE
static char* cmd_names[] = {
[CMD_VERSION] = "CMD_VERSION",
[CMD_SUPPORTED] = "CMD_SUPPORTED",
@@ -549,7 +554,7 @@ static int pcxhr_read_rmh_status(struct pcxhr_mgr *mgr, struct pcxhr_rmh *rmh)
}
}
}
-#ifdef CONFIG_SND_DEBUG_DETECT
+#ifdef CONFIG_SND_DEBUG_VERBOSE
if (rmh->cmd_idx < CMD_LAST_INDEX)
snd_printdd(" stat[%d]=%x\n", i, data);
#endif
@@ -570,7 +575,8 @@ static int pcxhr_send_msg_nolock(struct pcxhr_mgr *mgr, struct pcxhr_rmh *rmh)
u32 data;
unsigned char reg;
- snd_assert(rmh->cmd_len<PCXHR_SIZE_MAX_CMD, return -EINVAL);
+ if (snd_BUG_ON(rmh->cmd_len >= PCXHR_SIZE_MAX_CMD))
+ return -EINVAL;
err = pcxhr_send_it_dsp(mgr, PCXHR_IT_MESSAGE, 1);
if (err) {
snd_printk(KERN_ERR "pcxhr_send_message : ED_DSP_CRASHED\n");
@@ -597,7 +603,7 @@ static int pcxhr_send_msg_nolock(struct pcxhr_mgr *mgr, struct pcxhr_rmh *rmh)
data |= 0x008000; /* MASK_MORE_THAN_1_WORD_COMMAND */
else
data &= 0xff7fff; /* MASK_1_WORD_COMMAND */
-#ifdef CONFIG_SND_DEBUG_DETECT
+#ifdef CONFIG_SND_DEBUG_VERBOSE
if (rmh->cmd_idx < CMD_LAST_INDEX)
snd_printdd("MSG cmd[0]=%x (%s)\n", data, cmd_names[rmh->cmd_idx]);
#endif
@@ -624,7 +630,7 @@ static int pcxhr_send_msg_nolock(struct pcxhr_mgr *mgr, struct pcxhr_rmh *rmh)
for (i=1; i < rmh->cmd_len; i++) {
/* send other words */
data = rmh->cmd[i];
-#ifdef CONFIG_SND_DEBUG_DETECT
+#ifdef CONFIG_SND_DEBUG_VERBOSE
if (rmh->cmd_idx < CMD_LAST_INDEX)
snd_printdd(" cmd[%d]=%x\n", i, data);
#endif
@@ -677,7 +683,8 @@ static int pcxhr_send_msg_nolock(struct pcxhr_mgr *mgr, struct pcxhr_rmh *rmh)
*/
void pcxhr_init_rmh(struct pcxhr_rmh *rmh, int cmd)
{
- snd_assert(cmd < CMD_LAST_INDEX, return);
+ if (snd_BUG_ON(cmd >= CMD_LAST_INDEX))
+ return;
rmh->cmd[0] = pcxhr_dsp_cmds[cmd].opcode;
rmh->cmd_len = 1;
rmh->stat_len = pcxhr_dsp_cmds[cmd].st_length;
@@ -690,17 +697,17 @@ void pcxhr_set_pipe_cmd_params(struct pcxhr_rmh *rmh, int capture,
unsigned int param1, unsigned int param2,
unsigned int param3)
{
- snd_assert(param1 <= MASK_FIRST_FIELD);
+ snd_BUG_ON(param1 > MASK_FIRST_FIELD);
if (capture)
rmh->cmd[0] |= 0x800; /* COMMAND_RECORD_MASK */
if (param1)
rmh->cmd[0] |= (param1 << FIELD_SIZE);
if (param2) {
- snd_assert(param2 <= MASK_FIRST_FIELD);
+ snd_BUG_ON(param2 > MASK_FIRST_FIELD);
rmh->cmd[0] |= param2;
}
if(param3) {
- snd_assert(param3 <= MASK_DSP_WORD);
+ snd_BUG_ON(param3 > MASK_DSP_WORD);
rmh->cmd[1] = param3;
rmh->cmd_len = 2;
}
@@ -847,7 +854,7 @@ int pcxhr_set_pipe_state(struct pcxhr_mgr *mgr, int playback_mask, int capture_m
int state, i, err;
int audio_mask;
-#ifdef CONFIG_SND_DEBUG_DETECT
+#ifdef CONFIG_SND_DEBUG_VERBOSE
struct timeval my_tv1, my_tv2;
do_gettimeofday(&my_tv1);
#endif
@@ -894,7 +901,7 @@ int pcxhr_set_pipe_state(struct pcxhr_mgr *mgr, int playback_mask, int capture_m
if (err)
return err;
}
-#ifdef CONFIG_SND_DEBUG_DETECT
+#ifdef CONFIG_SND_DEBUG_VERBOSE
do_gettimeofday(&my_tv2);
snd_printdd("***SET PIPE STATE*** TIME = %ld (err = %x)\n",
(long)(my_tv2.tv_usec - my_tv1.tv_usec), err);
@@ -951,7 +958,7 @@ static int pcxhr_handle_async_err(struct pcxhr_mgr *mgr, u32 err,
enum pcxhr_async_err_src err_src, int pipe,
int is_capture)
{
-#ifdef CONFIG_SND_DEBUG_DETECT
+#ifdef CONFIG_SND_DEBUG_VERBOSE
static char* err_src_name[] = {
[PCXHR_ERR_PIPE] = "Pipe",
[PCXHR_ERR_STREAM] = "Stream",
@@ -1169,7 +1176,7 @@ irqreturn_t pcxhr_interrupt(int irq, void *dev_id)
mgr->dsp_time_last, dsp_time_new);
mgr->dsp_time_err++;
}
-#ifdef CONFIG_SND_DEBUG_DETECT
+#ifdef CONFIG_SND_DEBUG_VERBOSE
if (dsp_time_diff == 0)
snd_printdd("ERROR DSP TIME NO DIFF time(%d)\n", dsp_time_new);
else if (dsp_time_diff >= (2*PCXHR_GRANULARITY))
@@ -1208,7 +1215,7 @@ irqreturn_t pcxhr_interrupt(int irq, void *dev_id)
mgr->src_it_dsp = reg;
tasklet_hi_schedule(&mgr->msg_taskq);
}
-#ifdef CONFIG_SND_DEBUG_DETECT
+#ifdef CONFIG_SND_DEBUG_VERBOSE
if (reg & PCXHR_FATAL_DSP_ERR)
snd_printdd("FATAL DSP ERROR : %x\n", reg);
#endif
diff --git a/sound/pci/pcxhr/pcxhr_hwdep.c b/sound/pci/pcxhr/pcxhr_hwdep.c
index e6a4bfbb91bb..96640d9c227d 100644
--- a/sound/pci/pcxhr/pcxhr_hwdep.c
+++ b/sound/pci/pcxhr/pcxhr_hwdep.c
@@ -65,15 +65,18 @@ static int pcxhr_init_board(struct pcxhr_mgr *mgr)
if (err)
return err;
/* test 8 or 12 phys out */
- snd_assert((rmh.stat[0] & MASK_FIRST_FIELD) == mgr->playback_chips*2,
- return -EINVAL);
+ if ((rmh.stat[0] & MASK_FIRST_FIELD) != mgr->playback_chips * 2)
+ return -EINVAL;
/* test 8 or 2 phys in */
- snd_assert(((rmh.stat[0] >> (2*FIELD_SIZE)) & MASK_FIRST_FIELD) ==
- mgr->capture_chips * 2, return -EINVAL);
+ if (((rmh.stat[0] >> (2 * FIELD_SIZE)) & MASK_FIRST_FIELD) !=
+ mgr->capture_chips * 2)
+ return -EINVAL;
/* test max nb substream per board */
- snd_assert((rmh.stat[1] & 0x5F) >= card_streams, return -EINVAL);
+ if ((rmh.stat[1] & 0x5F) < card_streams)
+ return -EINVAL;
/* test max nb substream per pipe */
- snd_assert(((rmh.stat[1]>>7)&0x5F) >= PCXHR_PLAYBACK_STREAMS, return -EINVAL);
+ if (((rmh.stat[1] >> 7) & 0x5F) < PCXHR_PLAYBACK_STREAMS)
+ return -EINVAL;
pcxhr_init_rmh(&rmh, CMD_VERSION);
/* firmware num for DSP */
@@ -394,7 +397,7 @@ static int pcxhr_hwdep_dsp_load(struct snd_hwdep *hw,
(unsigned long)fw.size);
return -ENOMEM;
}
- if (copy_from_user(fw.data, dsp->image, dsp->length)) {
+ if (copy_from_user((void *)fw.data, dsp->image, dsp->length)) {
vfree(fw.data);
return -EFAULT;
}
diff --git a/sound/pci/riptide/riptide.c b/sound/pci/riptide/riptide.c
index 979f7da641ce..e9f0706ed3e4 100644
--- a/sound/pci/riptide/riptide.c
+++ b/sound/pci/riptide/riptide.c
@@ -682,7 +682,7 @@ static union firmware_version firmware_versions[] = {
},
};
-static u32 atoh(unsigned char *in, unsigned int len)
+static u32 atoh(const unsigned char *in, unsigned int len)
{
u32 sum = 0;
unsigned int mult = 1;
@@ -702,12 +702,12 @@ static u32 atoh(unsigned char *in, unsigned int len)
return sum;
}
-static int senddata(struct cmdif *cif, unsigned char *in, u32 offset)
+static int senddata(struct cmdif *cif, const unsigned char *in, u32 offset)
{
u32 addr;
u32 data;
u32 i;
- unsigned char *p;
+ const unsigned char *p;
i = atoh(&in[1], 2);
addr = offset + atoh(&in[3], 4);
@@ -726,10 +726,10 @@ static int senddata(struct cmdif *cif, unsigned char *in, u32 offset)
return 0;
}
-static int loadfirmware(struct cmdif *cif, unsigned char *img,
+static int loadfirmware(struct cmdif *cif, const unsigned char *img,
unsigned int size)
{
- unsigned char *in;
+ const unsigned char *in;
u32 laddr, saddr, t, val;
int err = 0;
@@ -865,7 +865,8 @@ static int sendcmd(struct cmdif *cif, u32 flags, u32 cmd, u32 parm,
struct riptideport *hwport;
struct cmdport *cmdport = NULL;
- snd_assert(cif, return -EINVAL);
+ if (snd_BUG_ON(!cif))
+ return -EINVAL;
hwport = cif->hwport;
if (cif->errcnt > MAX_ERROR_COUNT) {
@@ -1482,7 +1483,6 @@ static int snd_riptide_prepare(struct snd_pcm_substream *substream)
{
struct snd_riptide *chip = snd_pcm_substream_chip(substream);
struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_sg_buf *sgbuf = snd_pcm_substream_sgbuf(substream);
struct pcmhw *data = get_pcmhwdev(substream);
struct cmdif *cif = chip->cif;
unsigned char *lbuspath = NULL;
@@ -1490,7 +1490,8 @@ static int snd_riptide_prepare(struct snd_pcm_substream *substream)
int err = 0;
snd_pcm_format_t format;
- snd_assert(cif && data, return -EINVAL);
+ if (snd_BUG_ON(!cif || !data))
+ return -EINVAL;
snd_printdd("prepare id %d ch: %d f:0x%x r:%d\n", data->id,
runtime->channels, runtime->format, runtime->rate);
@@ -1513,9 +1514,9 @@ static int snd_riptide_prepare(struct snd_pcm_substream *substream)
lbuspath = data->paths.stereo;
break;
}
- snd_printdd("use sgdlist at 0x%p and buffer at 0x%p\n",
- data->sgdlist.area, sgbuf);
- if (data->sgdlist.area && sgbuf) {
+ snd_printdd("use sgdlist at 0x%p\n",
+ data->sgdlist.area);
+ if (data->sgdlist.area) {
unsigned int i, j, size, pages, f, pt, period;
struct sgd *c, *p = NULL;
@@ -1533,6 +1534,7 @@ static int snd_riptide_prepare(struct snd_pcm_substream *substream)
pt = 0;
j = 0;
for (i = 0; i < pages; i++) {
+ unsigned int ofs, addr;
c = &data->sgdbuf[i];
if (p)
p->dwNextLink = cpu_to_le32(data->sgdlist.addr +
@@ -1540,8 +1542,9 @@ static int snd_riptide_prepare(struct snd_pcm_substream *substream)
sizeof(struct
sgd)));
c->dwNextLink = cpu_to_le32(data->sgdlist.addr);
- c->dwSegPtrPhys =
- cpu_to_le32(sgbuf->table[j].addr + pt);
+ ofs = j << PAGE_SHIFT;
+ addr = snd_pcm_sgbuf_get_addr(substream, ofs) + pt;
+ c->dwSegPtrPhys = cpu_to_le32(addr);
pt = (pt + f) % PAGE_SIZE;
if (pt == 0)
j++;
@@ -1772,7 +1775,8 @@ snd_riptide_codec_write(struct snd_ac97 *ac97, unsigned short reg,
union cmdret rptr = CMDRET_ZERO;
int i = 0;
- snd_assert(cif, return);
+ if (snd_BUG_ON(!cif))
+ return;
snd_printdd("Write AC97 reg 0x%x 0x%x\n", reg, val);
do {
@@ -1790,7 +1794,8 @@ static unsigned short snd_riptide_codec_read(struct snd_ac97 *ac97,
struct cmdif *cif = chip->cif;
union cmdret rptr = CMDRET_ZERO;
- snd_assert(cif, return 0);
+ if (snd_BUG_ON(!cif))
+ return 0;
if (SEND_RACR(cif, reg, &rptr) != 0)
SEND_RACR(cif, reg, &rptr);
@@ -1804,7 +1809,8 @@ static int snd_riptide_initialize(struct snd_riptide *chip)
unsigned int device_id;
int err;
- snd_assert(chip, return -EINVAL);
+ if (snd_BUG_ON(!chip))
+ return -EINVAL;
cif = chip->cif;
if (!cif) {
@@ -1836,7 +1842,8 @@ static int snd_riptide_free(struct snd_riptide *chip)
{
struct cmdif *cif;
- snd_assert(chip, return 0);
+ if (!chip)
+ return 0;
if ((cif = chip->cif)) {
SET_GRESET(cif->hwport);
diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
index 4d6fbb36ab8a..d723543beadd 100644
--- a/sound/pci/rme9652/hdsp.c
+++ b/sound/pci/rme9652/hdsp.c
@@ -1036,7 +1036,7 @@ static void hdsp_set_dds_value(struct hdsp *hdsp, int rate)
n = DDS_NUMERATOR;
div64_32(&n, rate, &r);
/* n should be less than 2^32 for being written to FREQ register */
- snd_assert((n >> 32) == 0);
+ snd_BUG_ON(n >> 32);
/* HDSP_freqReg and HDSP_resetPointer are the same, so keep the DDS
value to write it after a reset */
hdsp->dds_value = n;
@@ -3043,7 +3043,7 @@ static int snd_hdsp_get_adat_sync_check(struct snd_kcontrol *kcontrol, struct sn
struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
offset = ucontrol->id.index - 1;
- snd_assert(offset >= 0);
+ snd_BUG_ON(offset < 0);
switch (hdsp->io_type) {
case Digiface:
@@ -3767,7 +3767,8 @@ static char *hdsp_channel_buffer_location(struct hdsp *hdsp,
{
int mapped_channel;
- snd_assert(channel >= 0 && channel < hdsp->max_channels, return NULL);
+ if (snd_BUG_ON(channel < 0 || channel >= hdsp->max_channels))
+ return NULL;
if ((mapped_channel = hdsp->channel_map[channel]) < 0)
return NULL;
@@ -3784,10 +3785,12 @@ static int snd_hdsp_playback_copy(struct snd_pcm_substream *substream, int chann
struct hdsp *hdsp = snd_pcm_substream_chip(substream);
char *channel_buf;
- snd_assert(pos + count <= HDSP_CHANNEL_BUFFER_BYTES / 4, return -EINVAL);
+ if (snd_BUG_ON(pos + count > HDSP_CHANNEL_BUFFER_BYTES / 4))
+ return -EINVAL;
channel_buf = hdsp_channel_buffer_location (hdsp, substream->pstr->stream, channel);
- snd_assert(channel_buf != NULL, return -EIO);
+ if (snd_BUG_ON(!channel_buf))
+ return -EIO;
if (copy_from_user(channel_buf + pos * 4, src, count * 4))
return -EFAULT;
return count;
@@ -3799,10 +3802,12 @@ static int snd_hdsp_capture_copy(struct snd_pcm_substream *substream, int channe
struct hdsp *hdsp = snd_pcm_substream_chip(substream);
char *channel_buf;
- snd_assert(pos + count <= HDSP_CHANNEL_BUFFER_BYTES / 4, return -EINVAL);
+ if (snd_BUG_ON(pos + count > HDSP_CHANNEL_BUFFER_BYTES / 4))
+ return -EINVAL;
channel_buf = hdsp_channel_buffer_location (hdsp, substream->pstr->stream, channel);
- snd_assert(channel_buf != NULL, return -EIO);
+ if (snd_BUG_ON(!channel_buf))
+ return -EIO;
if (copy_to_user(dst, channel_buf + pos * 4, count * 4))
return -EFAULT;
return count;
@@ -3815,7 +3820,8 @@ static int snd_hdsp_hw_silence(struct snd_pcm_substream *substream, int channel,
char *channel_buf;
channel_buf = hdsp_channel_buffer_location (hdsp, substream->pstr->stream, channel);
- snd_assert(channel_buf != NULL, return -EIO);
+ if (snd_BUG_ON(!channel_buf))
+ return -EIO;
memset(channel_buf + pos * 4, 0, count * 4);
return count;
}
@@ -3927,7 +3933,8 @@ static int snd_hdsp_channel_info(struct snd_pcm_substream *substream,
struct hdsp *hdsp = snd_pcm_substream_chip(substream);
int mapped_channel;
- snd_assert(info->channel < hdsp->max_channels, return -EINVAL);
+ if (snd_BUG_ON(info->channel >= hdsp->max_channels))
+ return -EINVAL;
if ((mapped_channel = hdsp->channel_map[info->channel]) < 0)
return -EINVAL;
diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c
index ab423bc82342..98762f909d64 100644
--- a/sound/pci/rme9652/hdspm.c
+++ b/sound/pci/rme9652/hdspm.c
@@ -535,7 +535,8 @@ static inline void snd_hdspm_initialize_midi_flush(struct hdspm * hdspm);
static int hdspm_update_simple_mixer_controls(struct hdspm * hdspm);
static int hdspm_autosync_ref(struct hdspm * hdspm);
static int snd_hdspm_set_defaults(struct hdspm * hdspm);
-static void hdspm_set_sgbuf(struct hdspm * hdspm, struct snd_sg_buf *sgbuf,
+static void hdspm_set_sgbuf(struct hdspm * hdspm,
+ struct snd_pcm_substream *substream,
unsigned int reg, int channels);
static inline int HDSPM_bit2freq(int n)
@@ -845,7 +846,7 @@ static void hdspm_set_dds_value(struct hdspm *hdspm, int rate)
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 */
- snd_assert((n >> 32) == 0);
+ snd_BUG_ON(n >> 32);
hdspm_write(hdspm, HDSPM_freqReg, (u32)n);
}
@@ -2617,8 +2618,8 @@ static int snd_hdspm_get_playback_mixer(struct snd_kcontrol *kcontrol,
channel = ucontrol->id.index - 1;
- snd_assert(channel >= 0
- || channel < HDSPM_MAX_CHANNELS, return -EINVAL);
+ if (snd_BUG_ON(channel < 0 || channel >= HDSPM_MAX_CHANNELS))
+ return -EINVAL;
mapped_channel = hdspm->channel_map[channel];
if (mapped_channel < 0)
@@ -2652,8 +2653,8 @@ static int snd_hdspm_put_playback_mixer(struct snd_kcontrol *kcontrol,
channel = ucontrol->id.index - 1;
- snd_assert(channel >= 0
- || channel < HDSPM_MAX_CHANNELS, return -EINVAL);
+ if (snd_BUG_ON(channel < 0 || channel >= HDSPM_MAX_CHANNELS))
+ return -EINVAL;
mapped_channel = hdspm->channel_map[channel];
if (mapped_channel < 0)
@@ -3496,8 +3497,8 @@ static char *hdspm_channel_buffer_location(struct hdspm * hdspm,
{
int mapped_channel;
- snd_assert(channel >= 0
- || channel < HDSPM_MAX_CHANNELS, return NULL);
+ if (snd_BUG_ON(channel < 0 || channel >= HDSPM_MAX_CHANNELS))
+ return NULL;
mapped_channel = hdspm->channel_map[channel];
if (mapped_channel < 0)
@@ -3520,14 +3521,15 @@ static int snd_hdspm_playback_copy(struct snd_pcm_substream *substream,
struct hdspm *hdspm = snd_pcm_substream_chip(substream);
char *channel_buf;
- snd_assert(pos + count <= HDSPM_CHANNEL_BUFFER_BYTES / 4,
- return -EINVAL);
+ if (snd_BUG_ON(pos + count > HDSPM_CHANNEL_BUFFER_BYTES / 4))
+ return -EINVAL;
channel_buf =
hdspm_channel_buffer_location(hdspm, substream->pstr->stream,
channel);
- snd_assert(channel_buf != NULL, return -EIO);
+ if (snd_BUG_ON(!channel_buf))
+ return -EIO;
return copy_from_user(channel_buf + pos * 4, src, count * 4);
}
@@ -3539,13 +3541,14 @@ static int snd_hdspm_capture_copy(struct snd_pcm_substream *substream,
struct hdspm *hdspm = snd_pcm_substream_chip(substream);
char *channel_buf;
- snd_assert(pos + count <= HDSPM_CHANNEL_BUFFER_BYTES / 4,
- return -EINVAL);
+ if (snd_BUG_ON(pos + count > HDSPM_CHANNEL_BUFFER_BYTES / 4))
+ return -EINVAL;
channel_buf =
hdspm_channel_buffer_location(hdspm, substream->pstr->stream,
channel);
- snd_assert(channel_buf != NULL, return -EIO);
+ if (snd_BUG_ON(!channel_buf))
+ return -EIO;
return copy_to_user(dst, channel_buf + pos * 4, count * 4);
}
@@ -3559,7 +3562,8 @@ static int snd_hdspm_hw_silence(struct snd_pcm_substream *substream,
channel_buf =
hdspm_channel_buffer_location(hdspm, substream->pstr->stream,
channel);
- snd_assert(channel_buf != NULL, return -EIO);
+ if (snd_BUG_ON(!channel_buf))
+ return -EIO;
memset(channel_buf + pos * 4, 0, count * 4);
return 0;
}
@@ -3601,8 +3605,6 @@ static int snd_hdspm_hw_params(struct snd_pcm_substream *substream,
int i;
pid_t this_pid;
pid_t other_pid;
- struct snd_sg_buf *sgbuf;
-
spin_lock_irq(&hdspm->lock);
@@ -3670,11 +3672,9 @@ static int snd_hdspm_hw_params(struct snd_pcm_substream *substream,
if (err < 0)
return err;
- sgbuf = snd_pcm_substream_sgbuf(substream);
-
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- hdspm_set_sgbuf(hdspm, sgbuf, HDSPM_pageAddressBufferOut,
+ hdspm_set_sgbuf(hdspm, substream, HDSPM_pageAddressBufferOut,
params_channels(params));
for (i = 0; i < params_channels(params); ++i)
@@ -3685,7 +3685,7 @@ static int snd_hdspm_hw_params(struct snd_pcm_substream *substream,
snd_printdd("Allocated sample buffer for playback at %p\n",
hdspm->playback_buffer);
} else {
- hdspm_set_sgbuf(hdspm, sgbuf, HDSPM_pageAddressBufferIn,
+ hdspm_set_sgbuf(hdspm, substream, HDSPM_pageAddressBufferIn,
params_channels(params));
for (i = 0; i < params_channels(params); ++i)
@@ -3700,7 +3700,7 @@ static int snd_hdspm_hw_params(struct snd_pcm_substream *substream,
snd_printdd("Allocated sample buffer for %s at 0x%08X\n",
substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
"playback" : "capture",
- snd_pcm_sgbuf_get_addr(sgbuf, 0));
+ snd_pcm_sgbuf_get_addr(substream, 0));
*/
/*
snd_printdd("set_hwparams: %s %d Hz, %d channels, bs = %d\n",
@@ -3744,7 +3744,8 @@ static int snd_hdspm_channel_info(struct snd_pcm_substream *substream,
struct hdspm *hdspm = snd_pcm_substream_chip(substream);
int mapped_channel;
- snd_assert(info->channel < HDSPM_MAX_CHANNELS, return -EINVAL);
+ if (snd_BUG_ON(info->channel >= HDSPM_MAX_CHANNELS))
+ return -EINVAL;
mapped_channel = hdspm->channel_map[info->channel];
if (mapped_channel < 0)
@@ -4249,13 +4250,14 @@ static int __devinit snd_hdspm_preallocate_memory(struct hdspm * hdspm)
return 0;
}
-static void hdspm_set_sgbuf(struct hdspm * hdspm, struct snd_sg_buf *sgbuf,
+static void hdspm_set_sgbuf(struct hdspm * hdspm,
+ struct snd_pcm_substream *substream,
unsigned int reg, int channels)
{
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(substream, 4096 * i));
}
/* ------------- ALSA Devices ---------------------------- */
diff --git a/sound/pci/rme9652/rme9652.c b/sound/pci/rme9652/rme9652.c
index a123f0e6ba23..2570907134d7 100644
--- a/sound/pci/rme9652/rme9652.c
+++ b/sound/pci/rme9652/rme9652.c
@@ -595,8 +595,6 @@ static void rme9652_set_thru(struct snd_rme9652 *rme9652, int channel, int enabl
} else {
int mapped_channel;
- snd_assert(channel == RME9652_NCHANNELS, return);
-
mapped_channel = rme9652->channel_map[channel];
if (enable) {
@@ -1893,7 +1891,8 @@ static char *rme9652_channel_buffer_location(struct snd_rme9652 *rme9652,
{
int mapped_channel;
- snd_assert(channel >= 0 || channel < RME9652_NCHANNELS, return NULL);
+ if (snd_BUG_ON(channel < 0 || channel >= RME9652_NCHANNELS))
+ return NULL;
if ((mapped_channel = rme9652->channel_map[channel]) < 0) {
return NULL;
@@ -1914,12 +1913,14 @@ static int snd_rme9652_playback_copy(struct snd_pcm_substream *substream, int ch
struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream);
char *channel_buf;
- snd_assert(pos + count <= RME9652_CHANNEL_BUFFER_BYTES / 4, return -EINVAL);
+ if (snd_BUG_ON(pos + count > RME9652_CHANNEL_BUFFER_BYTES / 4))
+ return -EINVAL;
channel_buf = rme9652_channel_buffer_location (rme9652,
substream->pstr->stream,
channel);
- snd_assert(channel_buf != NULL, return -EIO);
+ if (snd_BUG_ON(!channel_buf))
+ return -EIO;
if (copy_from_user(channel_buf + pos * 4, src, count * 4))
return -EFAULT;
return count;
@@ -1931,12 +1932,14 @@ static int snd_rme9652_capture_copy(struct snd_pcm_substream *substream, int cha
struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream);
char *channel_buf;
- snd_assert(pos + count <= RME9652_CHANNEL_BUFFER_BYTES / 4, return -EINVAL);
+ if (snd_BUG_ON(pos + count > RME9652_CHANNEL_BUFFER_BYTES / 4))
+ return -EINVAL;
channel_buf = rme9652_channel_buffer_location (rme9652,
substream->pstr->stream,
channel);
- snd_assert(channel_buf != NULL, return -EIO);
+ if (snd_BUG_ON(!channel_buf))
+ return -EIO;
if (copy_to_user(dst, channel_buf + pos * 4, count * 4))
return -EFAULT;
return count;
@@ -1951,7 +1954,8 @@ static int snd_rme9652_hw_silence(struct snd_pcm_substream *substream, int chann
channel_buf = rme9652_channel_buffer_location (rme9652,
substream->pstr->stream,
channel);
- snd_assert(channel_buf != NULL, return -EIO);
+ if (snd_BUG_ON(!channel_buf))
+ return -EIO;
memset(channel_buf + pos * 4, 0, count * 4);
return count;
}
@@ -2053,7 +2057,8 @@ static int snd_rme9652_channel_info(struct snd_pcm_substream *substream,
struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream);
int chn;
- snd_assert(info->channel < RME9652_NCHANNELS, return -EINVAL);
+ if (snd_BUG_ON(info->channel >= RME9652_NCHANNELS))
+ return -EINVAL;
if ((chn = rme9652->channel_map[info->channel]) < 0) {
return -EINVAL;
diff --git a/sound/pci/sonicvibes.c b/sound/pci/sonicvibes.c
index 0d3d305b0a0b..cd408b86c839 100644
--- a/sound/pci/sonicvibes.c
+++ b/sound/pci/sonicvibes.c
@@ -534,8 +534,8 @@ static int snd_sonicvibes_hw_constraint_dac_rate(struct snd_pcm_hw_params *param
params->rate_den = 1;
} else {
snd_sonicvibes_pll(rate, &r, &m, &n);
- snd_assert((SV_REFFREQUENCY % 16) == 0, return -EINVAL);
- snd_assert((SV_ADCMULT % 512) == 0, return -EINVAL);
+ snd_BUG_ON(SV_REFFREQUENCY % 16);
+ snd_BUG_ON(SV_ADCMULT % 512);
params->rate_num = (SV_REFFREQUENCY/16) * (n+2) * r;
params->rate_den = (SV_ADCMULT/512) * (m+2);
}
@@ -849,7 +849,8 @@ static int __devinit snd_sonicvibes_pcm(struct sonicvibes * sonic, int device, s
if ((err = snd_pcm_new(sonic->card, "s3_86c617", device, 1, 1, &pcm)) < 0)
return err;
- snd_assert(pcm != NULL, return -EINVAL);
+ if (snd_BUG_ON(!pcm))
+ return -EINVAL;
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_sonicvibes_playback_ops);
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_sonicvibes_capture_ops);
@@ -1089,7 +1090,8 @@ static int __devinit snd_sonicvibes_mixer(struct sonicvibes * sonic)
unsigned int idx;
int err;
- snd_assert(sonic != NULL && sonic->card != NULL, return -EINVAL);
+ if (snd_BUG_ON(!sonic || !sonic->card))
+ return -EINVAL;
card = sonic->card;
strcpy(card->mixername, "S3 SonicVibes");
diff --git a/sound/pci/trident/trident_main.c b/sound/pci/trident/trident_main.c
index bbcee2c09ae4..c612b435ca2b 100644
--- a/sound/pci/trident/trident_main.c
+++ b/sound/pci/trident/trident_main.c
@@ -1590,7 +1590,10 @@ static int snd_trident_trigger(struct snd_pcm_substream *substream,
if (spdif_flag) {
if (trident->device != TRIDENT_DEVICE_ID_SI7018) {
outl(trident->spdif_pcm_bits, TRID_REG(trident, NX_SPCSTATUS));
- outb(trident->spdif_pcm_ctrl, TRID_REG(trident, NX_SPCTRL_SPCSO + 3));
+ val = trident->spdif_pcm_ctrl;
+ if (!go)
+ val &= ~(0x28);
+ outb(val, TRID_REG(trident, NX_SPCTRL_SPCSO + 3));
} else {
outl(trident->spdif_pcm_bits, TRID_REG(trident, SI_SPDIF_CS));
val = inl(TRID_REG(trident, SI_SERIAL_INTF_CTRL)) | SPDIF_EN;
@@ -2928,7 +2931,8 @@ static int snd_trident_pcm_mixer_build(struct snd_trident *trident,
{
struct snd_trident_pcm_mixer *tmix;
- snd_assert(trident != NULL && voice != NULL && substream != NULL, return -EINVAL);
+ if (snd_BUG_ON(!trident || !voice || !substream))
+ return -EINVAL;
tmix = &trident->pcm_mixer[substream->number];
tmix->voice = voice;
tmix->vol = T4D_DEFAULT_PCM_VOL;
@@ -2943,7 +2947,8 @@ static int snd_trident_pcm_mixer_free(struct snd_trident *trident, struct snd_tr
{
struct snd_trident_pcm_mixer *tmix;
- snd_assert(trident != NULL && substream != NULL, return -EINVAL);
+ if (snd_BUG_ON(!trident || !substream))
+ return -EINVAL;
tmix = &trident->pcm_mixer[substream->number];
tmix->voice = NULL;
snd_trident_notify_pcm_change(trident, tmix, substream->number, 0);
@@ -3128,7 +3133,8 @@ static unsigned char snd_trident_gameport_read(struct gameport *gameport)
{
struct snd_trident *chip = gameport_get_port_data(gameport);
- snd_assert(chip, return 0);
+ if (snd_BUG_ON(!chip))
+ return 0;
return inb(TRID_REG(chip, GAMEPORT_LEGACY));
}
@@ -3136,7 +3142,8 @@ static void snd_trident_gameport_trigger(struct gameport *gameport)
{
struct snd_trident *chip = gameport_get_port_data(gameport);
- snd_assert(chip, return);
+ if (snd_BUG_ON(!chip))
+ return;
outb(0xff, TRID_REG(chip, GAMEPORT_LEGACY));
}
@@ -3145,7 +3152,8 @@ static int snd_trident_gameport_cooked_read(struct gameport *gameport, int *axes
struct snd_trident *chip = gameport_get_port_data(gameport);
int i;
- snd_assert(chip, return 0);
+ if (snd_BUG_ON(!chip))
+ return 0;
*buttons = (~inb(TRID_REG(chip, GAMEPORT_LEGACY)) >> 4) & 0xf;
@@ -3161,7 +3169,8 @@ static int snd_trident_gameport_open(struct gameport *gameport, int mode)
{
struct snd_trident *chip = gameport_get_port_data(gameport);
- snd_assert(chip, return 0);
+ if (snd_BUG_ON(!chip))
+ return 0;
switch (mode) {
case GAMEPORT_MODE_COOKED:
@@ -3888,8 +3897,8 @@ static void snd_trident_clear_voices(struct snd_trident * trident, unsigned shor
{
unsigned int i, val, mask[2] = { 0, 0 };
- snd_assert(v_min <= 63, return);
- snd_assert(v_max <= 63, return);
+ if (snd_BUG_ON(v_min > 63 || v_max > 63))
+ return;
for (i = v_min; i <= v_max; i++)
mask[i >> 5] |= 1 << (i & 0x1f);
if (mask[0]) {
diff --git a/sound/pci/trident/trident_memory.c b/sound/pci/trident/trident_memory.c
index df9b487fa17e..f9779e23fe57 100644
--- a/sound/pci/trident/trident_memory.c
+++ b/sound/pci/trident/trident_memory.c
@@ -194,11 +194,14 @@ snd_trident_alloc_sg_pages(struct snd_trident *trident,
struct snd_util_memblk *blk;
struct snd_pcm_runtime *runtime = substream->runtime;
int idx, page;
- struct snd_sg_buf *sgbuf = snd_pcm_substream_sgbuf(substream);
- snd_assert(runtime->dma_bytes > 0 && runtime->dma_bytes <= SNDRV_TRIDENT_MAX_PAGES * SNDRV_TRIDENT_PAGE_SIZE, return NULL);
+ if (snd_BUG_ON(runtime->dma_bytes <= 0 ||
+ runtime->dma_bytes > SNDRV_TRIDENT_MAX_PAGES *
+ SNDRV_TRIDENT_PAGE_SIZE))
+ return NULL;
hdr = trident->tlb.memhdr;
- snd_assert(hdr != NULL, return NULL);
+ if (snd_BUG_ON(!hdr))
+ return NULL;
@@ -208,18 +211,14 @@ snd_trident_alloc_sg_pages(struct snd_trident *trident,
mutex_unlock(&hdr->block_mutex);
return NULL;
}
- if (lastpg(blk) - firstpg(blk) >= sgbuf->pages) {
- snd_printk(KERN_ERR "page calculation doesn't match: allocated pages = %d, trident = %d/%d\n", sgbuf->pages, firstpg(blk), lastpg(blk));
- __snd_util_mem_free(hdr, blk);
- mutex_unlock(&hdr->block_mutex);
- return NULL;
- }
/* set TLB entries */
idx = 0;
for (page = firstpg(blk); page <= lastpg(blk); page++, idx++) {
- dma_addr_t addr = sgbuf->table[idx].addr;
- unsigned long ptr = (unsigned long)sgbuf->table[idx].buf;
+ unsigned long ofs = idx << PAGE_SHIFT;
+ dma_addr_t addr = snd_pcm_sgbuf_get_addr(substream, ofs);
+ unsigned long ptr = (unsigned long)
+ snd_pcm_sgbuf_get_ptr(substream, ofs);
if (! is_valid_page(addr)) {
__snd_util_mem_free(hdr, blk);
mutex_unlock(&hdr->block_mutex);
@@ -245,9 +244,13 @@ snd_trident_alloc_cont_pages(struct snd_trident *trident,
dma_addr_t addr;
unsigned long ptr;
- snd_assert(runtime->dma_bytes> 0 && runtime->dma_bytes <= SNDRV_TRIDENT_MAX_PAGES * SNDRV_TRIDENT_PAGE_SIZE, return NULL);
+ if (snd_BUG_ON(runtime->dma_bytes <= 0 ||
+ runtime->dma_bytes > SNDRV_TRIDENT_MAX_PAGES *
+ SNDRV_TRIDENT_PAGE_SIZE))
+ return NULL;
hdr = trident->tlb.memhdr;
- snd_assert(hdr != NULL, return NULL);
+ if (snd_BUG_ON(!hdr))
+ return NULL;
mutex_lock(&hdr->block_mutex);
blk = search_empty(hdr, runtime->dma_bytes);
@@ -279,8 +282,8 @@ struct snd_util_memblk *
snd_trident_alloc_pages(struct snd_trident *trident,
struct snd_pcm_substream *substream)
{
- snd_assert(trident != NULL, return NULL);
- snd_assert(substream != NULL, return NULL);
+ if (snd_BUG_ON(!trident || !substream))
+ return NULL;
if (substream->dma_buffer.dev.type == SNDRV_DMA_TYPE_DEV_SG)
return snd_trident_alloc_sg_pages(trident, substream);
else
@@ -297,8 +300,8 @@ int snd_trident_free_pages(struct snd_trident *trident,
struct snd_util_memhdr *hdr;
int page;
- snd_assert(trident != NULL, return -EINVAL);
- snd_assert(blk != NULL, return -EINVAL);
+ if (snd_BUG_ON(!trident || !blk))
+ return -EINVAL;
hdr = trident->tlb.memhdr;
mutex_lock(&hdr->block_mutex);
@@ -310,181 +313,3 @@ int snd_trident_free_pages(struct snd_trident *trident,
mutex_unlock(&hdr->block_mutex);
return 0;
}
-
-
-/*----------------------------------------------------------------
- * memory allocation using multiple pages (for synth)
- *----------------------------------------------------------------
- * Unlike the DMA allocation above, non-contiguous pages are
- * assigned to TLB.
- *----------------------------------------------------------------*/
-
-/*
- */
-static int synth_alloc_pages(struct snd_trident *hw, struct snd_util_memblk *blk);
-static int synth_free_pages(struct snd_trident *hw, struct snd_util_memblk *blk);
-
-/*
- * allocate a synth sample area
- */
-struct snd_util_memblk *
-snd_trident_synth_alloc(struct snd_trident *hw, unsigned int size)
-{
- struct snd_util_memblk *blk;
- struct snd_util_memhdr *hdr = hw->tlb.memhdr;
-
- mutex_lock(&hdr->block_mutex);
- blk = __snd_util_mem_alloc(hdr, size);
- if (blk == NULL) {
- mutex_unlock(&hdr->block_mutex);
- return NULL;
- }
- if (synth_alloc_pages(hw, blk)) {
- __snd_util_mem_free(hdr, blk);
- mutex_unlock(&hdr->block_mutex);
- return NULL;
- }
- mutex_unlock(&hdr->block_mutex);
- return blk;
-}
-
-EXPORT_SYMBOL(snd_trident_synth_alloc);
-
-/*
- * free a synth sample area
- */
-int
-snd_trident_synth_free(struct snd_trident *hw, struct snd_util_memblk *blk)
-{
- struct snd_util_memhdr *hdr = hw->tlb.memhdr;
-
- mutex_lock(&hdr->block_mutex);
- synth_free_pages(hw, blk);
- __snd_util_mem_free(hdr, blk);
- mutex_unlock(&hdr->block_mutex);
- return 0;
-}
-
-EXPORT_SYMBOL(snd_trident_synth_free);
-
-/*
- * reset TLB entry and free kernel page
- */
-static void clear_tlb(struct snd_trident *trident, int page)
-{
- void *ptr = page_to_ptr(trident, page);
- dma_addr_t addr = page_to_addr(trident, page);
- set_silent_tlb(trident, page);
- if (ptr) {
- struct snd_dma_buffer dmab;
- dmab.dev.type = SNDRV_DMA_TYPE_DEV;
- dmab.dev.dev = snd_dma_pci_data(trident->pci);
- dmab.area = ptr;
- dmab.addr = addr;
- dmab.bytes = ALIGN_PAGE_SIZE;
- snd_dma_free_pages(&dmab);
- }
-}
-
-/* check new allocation range */
-static void get_single_page_range(struct snd_util_memhdr *hdr,
- struct snd_util_memblk *blk,
- int *first_page_ret, int *last_page_ret)
-{
- struct list_head *p;
- struct snd_util_memblk *q;
- int first_page, last_page;
- first_page = firstpg(blk);
- if ((p = blk->list.prev) != &hdr->block) {
- q = list_entry(p, struct snd_util_memblk, list);
- if (lastpg(q) == first_page)
- first_page++; /* first page was already allocated */
- }
- last_page = lastpg(blk);
- if ((p = blk->list.next) != &hdr->block) {
- q = list_entry(p, struct snd_util_memblk, list);
- if (firstpg(q) == last_page)
- last_page--; /* last page was already allocated */
- }
- *first_page_ret = first_page;
- *last_page_ret = last_page;
-}
-
-/*
- * allocate kernel pages and assign them to TLB
- */
-static int synth_alloc_pages(struct snd_trident *hw, struct snd_util_memblk *blk)
-{
- int page, first_page, last_page;
- struct snd_dma_buffer dmab;
-
- firstpg(blk) = get_aligned_page(blk->offset);
- lastpg(blk) = get_aligned_page(blk->offset + blk->size - 1);
- get_single_page_range(hw->tlb.memhdr, blk, &first_page, &last_page);
-
- /* allocate a kernel page for each Trident page -
- * fortunately Trident page size and kernel PAGE_SIZE is identical!
- */
- for (page = first_page; page <= last_page; page++) {
- if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(hw->pci),
- ALIGN_PAGE_SIZE, &dmab) < 0)
- goto __fail;
- if (! is_valid_page(dmab.addr)) {
- snd_dma_free_pages(&dmab);
- goto __fail;
- }
- set_tlb_bus(hw, page, (unsigned long)dmab.area, dmab.addr);
- }
- return 0;
-
-__fail:
- /* release allocated pages */
- last_page = page - 1;
- for (page = first_page; page <= last_page; page++)
- clear_tlb(hw, page);
-
- return -ENOMEM;
-}
-
-/*
- * free pages
- */
-static int synth_free_pages(struct snd_trident *trident, struct snd_util_memblk *blk)
-{
- int page, first_page, last_page;
-
- get_single_page_range(trident->tlb.memhdr, blk, &first_page, &last_page);
- for (page = first_page; page <= last_page; page++)
- clear_tlb(trident, page);
-
- return 0;
-}
-
-/*
- * copy_from_user(blk + offset, data, size)
- */
-int snd_trident_synth_copy_from_user(struct snd_trident *trident,
- struct snd_util_memblk *blk,
- int offset, const char __user *data, int size)
-{
- int page, nextofs, end_offset, temp, temp1;
-
- offset += blk->offset;
- end_offset = offset + size;
- page = get_aligned_page(offset) + 1;
- do {
- nextofs = aligned_page_offset(page);
- temp = nextofs - offset;
- temp1 = end_offset - offset;
- if (temp1 < temp)
- temp = temp1;
- if (copy_from_user(offset_ptr(trident, offset), data, temp))
- return -EFAULT;
- offset = nextofs;
- data += temp;
- page++;
- } while (offset < end_offset);
- return 0;
-}
-
-EXPORT_SYMBOL(snd_trident_synth_copy_from_user);
diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c
index b585cc3e4c47..1aafe956ee2b 100644
--- a/sound/pci/via82xx.c
+++ b/sound/pci/via82xx.c
@@ -313,6 +313,7 @@ struct snd_via_sg_table {
} ;
#define VIA_TABLE_SIZE 255
+#define VIA_MAX_BUFSIZE (1<<24)
struct viadev {
unsigned int reg_offset;
@@ -420,7 +421,6 @@ static int build_via_table(struct viadev *dev, struct snd_pcm_substream *substre
{
unsigned int i, idx, ofs, rest;
struct via82xx *chip = snd_pcm_substream_chip(substream);
- struct snd_sg_buf *sgbuf = snd_pcm_substream_sgbuf(substream);
if (dev->table.area == NULL) {
/* the start of each lists must be aligned to 8 bytes,
@@ -449,15 +449,15 @@ static int build_via_table(struct viadev *dev, struct snd_pcm_substream *substre
do {
unsigned int r;
unsigned int flag;
+ unsigned int addr;
if (idx >= VIA_TABLE_SIZE) {
snd_printk(KERN_ERR "via82xx: too much table size!\n");
return -EINVAL;
}
- ((u32 *)dev->table.area)[idx << 1] = cpu_to_le32((u32)snd_pcm_sgbuf_get_addr(sgbuf, ofs));
- r = PAGE_SIZE - (ofs % PAGE_SIZE);
- if (rest < r)
- r = rest;
+ addr = snd_pcm_sgbuf_get_addr(substream, ofs);
+ ((u32 *)dev->table.area)[idx << 1] = cpu_to_le32(addr);
+ r = snd_pcm_sgbuf_get_chunk_size(substream, ofs, rest);
rest -= r;
if (! rest) {
if (i == periods - 1)
@@ -824,7 +824,8 @@ static snd_pcm_uframes_t snd_via686_pcm_pointer(struct snd_pcm_substream *substr
struct viadev *viadev = substream->runtime->private_data;
unsigned int idx, ptr, count, res;
- snd_assert(viadev->tbl_entries, return 0);
+ if (snd_BUG_ON(!viadev->tbl_entries))
+ return 0;
if (!(inb(VIADEV_REG(viadev, OFFSET_STATUS)) & VIA_REG_STAT_ACTIVE))
return 0;
@@ -855,7 +856,8 @@ static snd_pcm_uframes_t snd_via8233_pcm_pointer(struct snd_pcm_substream *subst
unsigned int idx, count, res;
int status;
- snd_assert(viadev->tbl_entries, return 0);
+ if (snd_BUG_ON(!viadev->tbl_entries))
+ return 0;
spin_lock(&chip->reg_lock);
count = inl(VIADEV_REG(viadev, OFFSET_CURR_COUNT));
@@ -1037,7 +1039,7 @@ static int snd_via8233_playback_prepare(struct snd_pcm_substream *substream)
else
rbits = (0x100000 / 48000) * runtime->rate +
((0x100000 % 48000) * runtime->rate) / 48000;
- snd_assert((rbits & ~0xfffff) == 0, return -EINVAL);
+ snd_BUG_ON(rbits & ~0xfffff);
snd_via82xx_channel_reset(chip, viadev);
snd_via82xx_set_table_ptr(chip, viadev);
outb(chip->playback_volume[viadev->reg_offset / 0x10][0],
@@ -1144,9 +1146,9 @@ static struct snd_pcm_hardware snd_via82xx_hw =
.rate_max = 48000,
.channels_min = 1,
.channels_max = 2,
- .buffer_bytes_max = 128 * 1024,
+ .buffer_bytes_max = VIA_MAX_BUFSIZE,
.period_bytes_min = 32,
- .period_bytes_max = 128 * 1024,
+ .period_bytes_max = VIA_MAX_BUFSIZE / 2,
.periods_min = 2,
.periods_max = VIA_TABLE_SIZE / 2,
.fifo_size = 0,
@@ -1398,10 +1400,9 @@ static int __devinit snd_via8233_pcm_new(struct via82xx *chip)
/* capture */
init_viadev(chip, chip->capture_devno, VIA_REG_CAPTURE_8233_STATUS, 6, 1);
- if ((err = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
- snd_dma_pci_data(chip->pci),
- 64*1024, 128*1024)) < 0)
- return err;
+ snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
+ snd_dma_pci_data(chip->pci),
+ 64*1024, VIA_MAX_BUFSIZE);
/* PCM #1: multi-channel playback and 2nd capture */
err = snd_pcm_new(chip->card, chip->card->shortname, 1, 1, 1, &pcm);
@@ -1417,11 +1418,9 @@ static int __devinit snd_via8233_pcm_new(struct via82xx *chip)
/* set up capture */
init_viadev(chip, chip->capture_devno + 1, VIA_REG_CAPTURE_8233_STATUS + 0x10, 7, 1);
- if ((err = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
- snd_dma_pci_data(chip->pci),
- 64*1024, 128*1024)) < 0)
- return err;
-
+ snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
+ snd_dma_pci_data(chip->pci),
+ 64*1024, VIA_MAX_BUFSIZE);
return 0;
}
@@ -1453,10 +1452,9 @@ static int __devinit snd_via8233a_pcm_new(struct via82xx *chip)
/* capture */
init_viadev(chip, chip->capture_devno, VIA_REG_CAPTURE_8233_STATUS, 6, 1);
- if ((err = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
- snd_dma_pci_data(chip->pci),
- 64*1024, 128*1024)) < 0)
- return err;
+ snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
+ snd_dma_pci_data(chip->pci),
+ 64*1024, VIA_MAX_BUFSIZE);
/* SPDIF supported? */
if (! ac97_can_spdif(chip->ac97))
@@ -1473,11 +1471,9 @@ static int __devinit snd_via8233a_pcm_new(struct via82xx *chip)
/* set up playback */
init_viadev(chip, chip->playback_devno, 0x30, 3, 0);
- if ((err = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
- snd_dma_pci_data(chip->pci),
- 64*1024, 128*1024)) < 0)
- return err;
-
+ snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
+ snd_dma_pci_data(chip->pci),
+ 64*1024, VIA_MAX_BUFSIZE);
return 0;
}
@@ -1505,11 +1501,9 @@ static int __devinit snd_via686_pcm_new(struct via82xx *chip)
init_viadev(chip, 0, VIA_REG_PLAYBACK_STATUS, 0, 0);
init_viadev(chip, 1, VIA_REG_CAPTURE_STATUS, 0, 1);
- if ((err = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
- snd_dma_pci_data(chip->pci),
- 64*1024, 128*1024)) < 0)
- return err;
-
+ snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
+ snd_dma_pci_data(chip->pci),
+ 64*1024, VIA_MAX_BUFSIZE);
return 0;
}
@@ -1757,6 +1751,12 @@ static struct ac97_quirk ac97_quirks[] = {
.type = AC97_TUNE_HP_ONLY
},
{
+ .subvendor = 0x1019,
+ .subdevice = 0x1841,
+ .name = "ECS K7VTA3",
+ .type = AC97_TUNE_HP_ONLY
+ },
+ {
.subvendor = 0x1849,
.subdevice = 0x3059,
.name = "ASRock K7VM2",
diff --git a/sound/pci/via82xx_modem.c b/sound/pci/via82xx_modem.c
index 31f64ee39882..5bd79d2a5a15 100644
--- a/sound/pci/via82xx_modem.c
+++ b/sound/pci/via82xx_modem.c
@@ -281,7 +281,6 @@ static int build_via_table(struct viadev *dev, struct snd_pcm_substream *substre
{
unsigned int i, idx, ofs, rest;
struct via82xx_modem *chip = snd_pcm_substream_chip(substream);
- struct snd_sg_buf *sgbuf = snd_pcm_substream_sgbuf(substream);
if (dev->table.area == NULL) {
/* the start of each lists must be aligned to 8 bytes,
@@ -310,12 +309,14 @@ static int build_via_table(struct viadev *dev, struct snd_pcm_substream *substre
do {
unsigned int r;
unsigned int flag;
+ unsigned int addr;
if (idx >= VIA_TABLE_SIZE) {
snd_printk(KERN_ERR "via82xx: too much table size!\n");
return -EINVAL;
}
- ((u32 *)dev->table.area)[idx << 1] = cpu_to_le32((u32)snd_pcm_sgbuf_get_addr(sgbuf, ofs));
+ addr = snd_pcm_sgbuf_get_addr(substream, ofs);
+ ((u32 *)dev->table.area)[idx << 1] = cpu_to_le32(addr);
r = PAGE_SIZE - (ofs % PAGE_SIZE);
if (rest < r)
r = rest;
@@ -612,7 +613,8 @@ static snd_pcm_uframes_t snd_via686_pcm_pointer(struct snd_pcm_substream *substr
struct viadev *viadev = substream->runtime->private_data;
unsigned int idx, ptr, count, res;
- snd_assert(viadev->tbl_entries, return 0);
+ if (snd_BUG_ON(!viadev->tbl_entries))
+ return 0;
if (!(inb(VIADEV_REG(viadev, OFFSET_STATUS)) & VIA_REG_STAT_ACTIVE))
return 0;
diff --git a/sound/pci/vx222/vx222_ops.c b/sound/pci/vx222/vx222_ops.c
index b4bfc1acde88..7e87f398ff0b 100644
--- a/sound/pci/vx222/vx222_ops.c
+++ b/sound/pci/vx222/vx222_ops.c
@@ -253,7 +253,8 @@ static void vx2_dma_write(struct vx_core *chip, struct snd_pcm_runtime *runtime,
int offset = pipe->hw_ptr;
u32 *addr = (u32 *)(runtime->dma_area + offset);
- snd_assert(count % 4 == 0, return);
+ if (snd_BUG_ON(count % 4))
+ return;
vx2_setup_pseudo_dma(chip, 1);
@@ -291,7 +292,8 @@ static void vx2_dma_read(struct vx_core *chip, struct snd_pcm_runtime *runtime,
u32 *addr = (u32 *)(runtime->dma_area + offset);
unsigned long port = vx2_reg_addr(chip, VX_DMA);
- snd_assert(count % 4 == 0, return);
+ if (snd_BUG_ON(count % 4))
+ return;
vx2_setup_pseudo_dma(chip, 0);
/* Transfer using pseudo-dma.
@@ -359,7 +361,7 @@ static int vx2_load_xilinx_binary(struct vx_core *chip, const struct firmware *x
{
unsigned int i;
unsigned int port;
- unsigned char *image;
+ const unsigned char *image;
/* XILINX reset (wait at least 1 milisecond between reset on and off). */
vx_outl(chip, CNTRL, VX_CNTRL_REGISTER_VALUE | VX_XILINX_RESET_MASK);
@@ -675,7 +677,8 @@ static void vx2_write_akm(struct vx_core *chip, int reg, unsigned int data)
a look up table, as there is no linear matching between the driver codec values
and the real dBu value
*/
- snd_assert(data < sizeof(vx2_akm_gains_lut), return);
+ if (snd_BUG_ON(data >= sizeof(vx2_akm_gains_lut)))
+ return;
switch (reg) {
case XX_CODEC_LEVEL_LEFT_REGISTER:
@@ -823,7 +826,8 @@ static void vx2_set_input_level(struct snd_vx222 *chip)
preamp++; /* raise pre ampli + 18dB */
miclevel -= (18 * 2); /* lower level 18 dB (*2 because of 0.5 dB steps !) */
}
- snd_assert(preamp < 4, return);
+ if (snd_BUG_ON(preamp >= 4))
+ return;
/* set pre-amp level */
chip->regSELMIC &= ~MICRO_SELECT_PREAMPLI_MASK;
diff --git a/sound/pci/ymfpci/ymfpci_image.h b/sound/pci/ymfpci/ymfpci_image.h
deleted file mode 100644
index 112f2fff6c8e..000000000000
--- a/sound/pci/ymfpci/ymfpci_image.h
+++ /dev/null
@@ -1,1565 +0,0 @@
-#ifndef _HWMCODE_
-#define _HWMCODE_
-
-static u32 DspInst[YDSXG_DSPLENGTH / 4] = {
- 0x00000081, 0x000001a4, 0x0000000a, 0x0000002f,
- 0x00080253, 0x01800317, 0x0000407b, 0x0000843f,
- 0x0001483c, 0x0001943c, 0x0005d83c, 0x00001c3c,
- 0x0000c07b, 0x00050c3f, 0x0121503c, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000
-};
-
-static u32 CntrlInst[YDSXG_CTRLLENGTH / 4] = {
- 0x000007, 0x240007, 0x0C0007, 0x1C0007,
- 0x060007, 0x700002, 0x000020, 0x030040,
- 0x007104, 0x004286, 0x030040, 0x000F0D,
- 0x000810, 0x20043A, 0x000282, 0x00020D,
- 0x000810, 0x20043A, 0x001282, 0x200E82,
- 0x001A82, 0x032D0D, 0x000810, 0x10043A,
- 0x02D38D, 0x000810, 0x18043A, 0x00010D,
- 0x020015, 0x0000FD, 0x000020, 0x038860,
- 0x039060, 0x038060, 0x038040, 0x038040,
- 0x038040, 0x018040, 0x000A7D, 0x038040,
- 0x038040, 0x018040, 0x200402, 0x000882,
- 0x08001A, 0x000904, 0x015986, 0x000007,
- 0x260007, 0x000007, 0x000007, 0x018A06,
- 0x000007, 0x030C8D, 0x000810, 0x18043A,
- 0x260007, 0x00087D, 0x018042, 0x00160A,
- 0x04A206, 0x000007, 0x00218D, 0x000810,
- 0x08043A, 0x21C206, 0x000007, 0x0007FD,
- 0x018042, 0x08000A, 0x000904, 0x029386,
- 0x000195, 0x090D04, 0x000007, 0x000820,
- 0x0000F5, 0x000B7D, 0x01F060, 0x0000FD,
- 0x032206, 0x018040, 0x000A7D, 0x038042,
- 0x13804A, 0x18000A, 0x001820, 0x059060,
- 0x058860, 0x018040, 0x0000FD, 0x018042,
- 0x70000A, 0x000115, 0x071144, 0x032386,
- 0x030000, 0x007020, 0x034A06, 0x018040,
- 0x00348D, 0x000810, 0x08043A, 0x21EA06,
- 0x000007, 0x02D38D, 0x000810, 0x18043A,
- 0x018206, 0x000007, 0x240007, 0x000F8D,
- 0x000810, 0x00163A, 0x002402, 0x005C02,
- 0x0028FD, 0x000020, 0x018040, 0x08000D,
- 0x000815, 0x510984, 0x000007, 0x00004D,
- 0x000E5D, 0x000E02, 0x00418D, 0x000810,
- 0x08043A, 0x2C8A06, 0x000007, 0x00008D,
- 0x000924, 0x000F02, 0x00458D, 0x000810,
- 0x08043A, 0x2C8A06, 0x000007, 0x00387D,
- 0x018042, 0x08000A, 0x001015, 0x010984,
- 0x018386, 0x000007, 0x01AA06, 0x000007,
- 0x0008FD, 0x018042, 0x18000A, 0x001904,
- 0x218086, 0x280007, 0x001810, 0x28043A,
- 0x280C02, 0x00000D, 0x000810, 0x28143A,
- 0x08808D, 0x000820, 0x0002FD, 0x018040,
- 0x200007, 0x00020D, 0x189904, 0x000007,
- 0x00402D, 0x0000BD, 0x0002FD, 0x018042,
- 0x08000A, 0x000904, 0x055A86, 0x000007,
- 0x000100, 0x000A20, 0x00047D, 0x018040,
- 0x018042, 0x20000A, 0x003015, 0x012144,
- 0x034986, 0x000007, 0x002104, 0x034986,
- 0x000007, 0x000F8D, 0x000810, 0x280C3A,
- 0x023944, 0x06C986, 0x000007, 0x001810,
- 0x28043A, 0x08810D, 0x000820, 0x0002FD,
- 0x018040, 0x200007, 0x002810, 0x78003A,
- 0x00688D, 0x000810, 0x08043A, 0x288A06,
- 0x000007, 0x00400D, 0x001015, 0x189904,
- 0x292904, 0x393904, 0x000007, 0x060206,
- 0x000007, 0x0004F5, 0x00007D, 0x000020,
- 0x00008D, 0x010860, 0x018040, 0x00047D,
- 0x038042, 0x21804A, 0x18000A, 0x021944,
- 0x215886, 0x000007, 0x004075, 0x71F104,
- 0x000007, 0x010042, 0x28000A, 0x002904,
- 0x212086, 0x000007, 0x003C0D, 0x30A904,
- 0x000007, 0x00077D, 0x018042, 0x08000A,
- 0x000904, 0x07DA86, 0x00057D, 0x002820,
- 0x03B060, 0x07F206, 0x018040, 0x003020,
- 0x03A860, 0x018040, 0x0002FD, 0x018042,
- 0x08000A, 0x000904, 0x07FA86, 0x000007,
- 0x00057D, 0x018042, 0x28040A, 0x000E8D,
- 0x000810, 0x280C3A, 0x00000D, 0x000810,
- 0x28143A, 0x09000D, 0x000820, 0x0002FD,
- 0x018040, 0x200007, 0x003DFD, 0x000020,
- 0x018040, 0x00107D, 0x008D8D, 0x000810,
- 0x08043A, 0x288A06, 0x000007, 0x000815,
- 0x08001A, 0x010984, 0x095186, 0x00137D,
- 0x200500, 0x280F20, 0x338F60, 0x3B8F60,
- 0x438F60, 0x4B8F60, 0x538F60, 0x5B8F60,
- 0x038A60, 0x018040, 0x007FBD, 0x383DC4,
- 0x000007, 0x001A7D, 0x001375, 0x018042,
- 0x09004A, 0x10000A, 0x0B8D04, 0x139504,
- 0x000007, 0x000820, 0x019060, 0x001104,
- 0x212086, 0x010040, 0x0017FD, 0x018042,
- 0x08000A, 0x000904, 0x212286, 0x000007,
- 0x00197D, 0x038042, 0x09804A, 0x10000A,
- 0x000924, 0x001664, 0x0011FD, 0x038042,
- 0x2B804A, 0x19804A, 0x00008D, 0x218944,
- 0x000007, 0x002244, 0x0AE186, 0x000007,
- 0x001A64, 0x002A24, 0x00197D, 0x080102,
- 0x100122, 0x000820, 0x039060, 0x018040,
- 0x003DFD, 0x00008D, 0x000820, 0x018040,
- 0x001375, 0x001A7D, 0x010042, 0x09804A,
- 0x10000A, 0x00021D, 0x0189E4, 0x2992E4,
- 0x309144, 0x000007, 0x00060D, 0x000A15,
- 0x000C1D, 0x001025, 0x00A9E4, 0x012BE4,
- 0x000464, 0x01B3E4, 0x0232E4, 0x000464,
- 0x000464, 0x000464, 0x000464, 0x00040D,
- 0x08B1C4, 0x000007, 0x000820, 0x000BF5,
- 0x030040, 0x00197D, 0x038042, 0x09804A,
- 0x000A24, 0x08000A, 0x080E64, 0x000007,
- 0x100122, 0x000820, 0x031060, 0x010040,
- 0x0064AC, 0x00027D, 0x000020, 0x018040,
- 0x00107D, 0x018042, 0x0011FD, 0x3B804A,
- 0x09804A, 0x20000A, 0x000095, 0x1A1144,
- 0x00A144, 0x0D2086, 0x00040D, 0x00B984,
- 0x0D2186, 0x0018FD, 0x018042, 0x0010FD,
- 0x09804A, 0x28000A, 0x000095, 0x010924,
- 0x002A64, 0x0D1186, 0x000007, 0x002904,
- 0x0D2286, 0x000007, 0x0D2A06, 0x080002,
- 0x00008D, 0x00387D, 0x000820, 0x018040,
- 0x00127D, 0x018042, 0x10000A, 0x003904,
- 0x0DD186, 0x00080D, 0x7FFFB5, 0x00B984,
- 0x0DA186, 0x000025, 0x0E7A06, 0x00002D,
- 0x000015, 0x00082D, 0x02C78D, 0x000820,
- 0x0EC206, 0x00000D, 0x7F8035, 0x00B984,
- 0x0E7186, 0x400025, 0x00008D, 0x110944,
- 0x000007, 0x00018D, 0x109504, 0x000007,
- 0x009164, 0x000424, 0x000424, 0x000424,
- 0x100102, 0x280002, 0x02C68D, 0x000820,
- 0x0EC206, 0x00018D, 0x00042D, 0x00008D,
- 0x109504, 0x000007, 0x00020D, 0x109184,
- 0x000007, 0x02C70D, 0x000820, 0x00008D,
- 0x0038FD, 0x018040, 0x003BFD, 0x001020,
- 0x03A860, 0x000815, 0x313184, 0x212184,
- 0x000007, 0x03B060, 0x03A060, 0x018040,
- 0x0022FD, 0x000095, 0x010924, 0x000424,
- 0x000424, 0x001264, 0x100102, 0x000820,
- 0x039060, 0x018040, 0x001924, 0x00FB8D,
- 0x00397D, 0x000820, 0x058040, 0x038042,
- 0x09844A, 0x000606, 0x08040A, 0x000424,
- 0x000424, 0x00117D, 0x018042, 0x08000A,
- 0x000A24, 0x280502, 0x280C02, 0x09800D,
- 0x000820, 0x0002FD, 0x018040, 0x200007,
- 0x0022FD, 0x018042, 0x08000A, 0x000095,
- 0x280DC4, 0x011924, 0x00197D, 0x018042,
- 0x0011FD, 0x09804A, 0x10000A, 0x0000B5,
- 0x113144, 0x0A8D04, 0x000007, 0x080A44,
- 0x129504, 0x000007, 0x0023FD, 0x001020,
- 0x038040, 0x101244, 0x000007, 0x000820,
- 0x039060, 0x018040, 0x0002FD, 0x018042,
- 0x08000A, 0x000904, 0x10FA86, 0x000007,
- 0x003BFD, 0x000100, 0x000A10, 0x0B807A,
- 0x13804A, 0x090984, 0x000007, 0x000095,
- 0x013D04, 0x118086, 0x10000A, 0x100002,
- 0x090984, 0x000007, 0x038042, 0x11804A,
- 0x090D04, 0x000007, 0x10000A, 0x090D84,
- 0x000007, 0x00257D, 0x000820, 0x018040,
- 0x00010D, 0x000810, 0x28143A, 0x00127D,
- 0x018042, 0x20000A, 0x00197D, 0x018042,
- 0x00117D, 0x31804A, 0x10000A, 0x003124,
- 0x01280D, 0x00397D, 0x000820, 0x058040,
- 0x038042, 0x09844A, 0x000606, 0x08040A,
- 0x300102, 0x003124, 0x000424, 0x000424,
- 0x001224, 0x280502, 0x001A4C, 0x130186,
- 0x700002, 0x00002D, 0x030000, 0x00387D,
- 0x018042, 0x10000A, 0x132A06, 0x002124,
- 0x0000AD, 0x100002, 0x00010D, 0x000924,
- 0x006B24, 0x01368D, 0x00397D, 0x000820,
- 0x058040, 0x038042, 0x09844A, 0x000606,
- 0x08040A, 0x003264, 0x00008D, 0x000A24,
- 0x001020, 0x00227D, 0x018040, 0x013C0D,
- 0x000810, 0x08043A, 0x29D206, 0x000007,
- 0x002820, 0x00207D, 0x018040, 0x00117D,
- 0x038042, 0x13804A, 0x33800A, 0x00387D,
- 0x018042, 0x08000A, 0x000904, 0x163A86,
- 0x000007, 0x00008D, 0x030964, 0x01478D,
- 0x00397D, 0x000820, 0x058040, 0x038042,
- 0x09844A, 0x000606, 0x08040A, 0x380102,
- 0x000424, 0x000424, 0x001224, 0x0002FD,
- 0x018042, 0x08000A, 0x000904, 0x14A286,
- 0x000007, 0x280502, 0x001A4C, 0x163986,
- 0x000007, 0x032164, 0x00632C, 0x003DFD,
- 0x018042, 0x08000A, 0x000095, 0x090904,
- 0x000007, 0x000820, 0x001A4C, 0x156186,
- 0x018040, 0x030000, 0x157A06, 0x002124,
- 0x00010D, 0x000924, 0x006B24, 0x015B8D,
- 0x00397D, 0x000820, 0x058040, 0x038042,
- 0x09844A, 0x000606, 0x08040A, 0x003A64,
- 0x000095, 0x001224, 0x0002FD, 0x018042,
- 0x08000A, 0x000904, 0x15DA86, 0x000007,
- 0x01628D, 0x000810, 0x08043A, 0x29D206,
- 0x000007, 0x14D206, 0x000007, 0x007020,
- 0x08010A, 0x10012A, 0x0020FD, 0x038860,
- 0x039060, 0x018040, 0x00227D, 0x018042,
- 0x003DFD, 0x08000A, 0x31844A, 0x000904,
- 0x16D886, 0x18008B, 0x00008D, 0x189904,
- 0x00312C, 0x17AA06, 0x000007, 0x00324C,
- 0x173386, 0x000007, 0x001904, 0x173086,
- 0x000007, 0x000095, 0x199144, 0x00222C,
- 0x003124, 0x00636C, 0x000E3D, 0x001375,
- 0x000BFD, 0x010042, 0x09804A, 0x10000A,
- 0x038AEC, 0x0393EC, 0x00224C, 0x17A986,
- 0x000007, 0x00008D, 0x189904, 0x00226C,
- 0x00322C, 0x30050A, 0x301DAB, 0x002083,
- 0x0018FD, 0x018042, 0x08000A, 0x018924,
- 0x300502, 0x001083, 0x001875, 0x010042,
- 0x10000A, 0x00008D, 0x010924, 0x001375,
- 0x330542, 0x330CCB, 0x332CCB, 0x3334CB,
- 0x333CCB, 0x3344CB, 0x334CCB, 0x3354CB,
- 0x305C8B, 0x006083, 0x0002F5, 0x010042,
- 0x08000A, 0x000904, 0x187A86, 0x000007,
- 0x001E2D, 0x0005FD, 0x018042, 0x08000A,
- 0x028924, 0x280502, 0x00060D, 0x000810,
- 0x280C3A, 0x00008D, 0x000810, 0x28143A,
- 0x0A808D, 0x000820, 0x0002F5, 0x010040,
- 0x220007, 0x001275, 0x030042, 0x21004A,
- 0x00008D, 0x1A0944, 0x000007, 0x01980D,
- 0x000810, 0x08043A, 0x2B2206, 0x000007,
- 0x0001F5, 0x030042, 0x0D004A, 0x10000A,
- 0x089144, 0x000007, 0x000820, 0x010040,
- 0x0025F5, 0x0A3144, 0x000007, 0x000820,
- 0x032860, 0x030040, 0x00217D, 0x038042,
- 0x0B804A, 0x10000A, 0x000820, 0x031060,
- 0x030040, 0x00008D, 0x000124, 0x00012C,
- 0x000E64, 0x001A64, 0x00636C, 0x08010A,
- 0x10012A, 0x000820, 0x031060, 0x030040,
- 0x0020FD, 0x018042, 0x08000A, 0x00227D,
- 0x018042, 0x10000A, 0x000820, 0x031060,
- 0x030040, 0x00197D, 0x018042, 0x08000A,
- 0x0022FD, 0x038042, 0x10000A, 0x000820,
- 0x031060, 0x030040, 0x090D04, 0x000007,
- 0x000820, 0x030040, 0x038042, 0x0B804A,
- 0x10000A, 0x000820, 0x031060, 0x030040,
- 0x038042, 0x13804A, 0x19804A, 0x110D04,
- 0x198D04, 0x000007, 0x08000A, 0x001020,
- 0x031860, 0x030860, 0x030040, 0x00008D,
- 0x0B0944, 0x000007, 0x000820, 0x010040,
- 0x0005F5, 0x030042, 0x08000A, 0x000820,
- 0x010040, 0x0000F5, 0x010042, 0x08000A,
- 0x000904, 0x1C6086, 0x001E75, 0x030042,
- 0x01044A, 0x000C0A, 0x1C7206, 0x000007,
- 0x000402, 0x000C02, 0x00177D, 0x001AF5,
- 0x018042, 0x03144A, 0x031C4A, 0x03244A,
- 0x032C4A, 0x03344A, 0x033C4A, 0x03444A,
- 0x004C0A, 0x00043D, 0x0013F5, 0x001AFD,
- 0x030042, 0x0B004A, 0x1B804A, 0x13804A,
- 0x20000A, 0x089144, 0x19A144, 0x0389E4,
- 0x0399EC, 0x005502, 0x005D0A, 0x030042,
- 0x0B004A, 0x1B804A, 0x13804A, 0x20000A,
- 0x089144, 0x19A144, 0x0389E4, 0x0399EC,
- 0x006502, 0x006D0A, 0x030042, 0x0B004A,
- 0x19004A, 0x2B804A, 0x13804A, 0x21804A,
- 0x30000A, 0x089144, 0x19A144, 0x2AB144,
- 0x0389E4, 0x0399EC, 0x007502, 0x007D0A,
- 0x03A9E4, 0x000702, 0x00107D, 0x000415,
- 0x018042, 0x08000A, 0x0109E4, 0x000F02,
- 0x002AF5, 0x0019FD, 0x010042, 0x09804A,
- 0x10000A, 0x000934, 0x001674, 0x0029F5,
- 0x010042, 0x10000A, 0x00917C, 0x002075,
- 0x010042, 0x08000A, 0x000904, 0x1ED286,
- 0x0026F5, 0x0027F5, 0x030042, 0x09004A,
- 0x10000A, 0x000A3C, 0x00167C, 0x001A75,
- 0x000BFD, 0x010042, 0x51804A, 0x48000A,
- 0x160007, 0x001075, 0x010042, 0x282C0A,
- 0x281D12, 0x282512, 0x001F32, 0x1E0007,
- 0x0E0007, 0x001975, 0x010042, 0x002DF5,
- 0x0D004A, 0x10000A, 0x009144, 0x1FB286,
- 0x010042, 0x28340A, 0x000E5D, 0x00008D,
- 0x000375, 0x000820, 0x010040, 0x05D2F4,
- 0x54D104, 0x00735C, 0x205386, 0x000007,
- 0x0C0007, 0x080007, 0x0A0007, 0x02040D,
- 0x000810, 0x08043A, 0x332206, 0x000007,
- 0x205A06, 0x000007, 0x080007, 0x002275,
- 0x010042, 0x20000A, 0x002104, 0x212086,
- 0x001E2D, 0x0002F5, 0x010042, 0x08000A,
- 0x000904, 0x209286, 0x000007, 0x002010,
- 0x30043A, 0x00057D, 0x0180C3, 0x08000A,
- 0x028924, 0x280502, 0x280C02, 0x0A810D,
- 0x000820, 0x0002F5, 0x010040, 0x220007,
- 0x0004FD, 0x018042, 0x70000A, 0x030000,
- 0x007020, 0x06FA06, 0x018040, 0x02180D,
- 0x000810, 0x08043A, 0x2B2206, 0x000007,
- 0x0002FD, 0x018042, 0x08000A, 0x000904,
- 0x218A86, 0x000007, 0x01F206, 0x000007,
- 0x000875, 0x0009FD, 0x00010D, 0x220A06,
- 0x000295, 0x000B75, 0x00097D, 0x00000D,
- 0x000515, 0x010042, 0x18000A, 0x001904,
- 0x287886, 0x0006F5, 0x001020, 0x010040,
- 0x0004F5, 0x000820, 0x010040, 0x000775,
- 0x010042, 0x09804A, 0x10000A, 0x001124,
- 0x000904, 0x22BA86, 0x000815, 0x080102,
- 0x101204, 0x22DA06, 0x000575, 0x081204,
- 0x000007, 0x100102, 0x000575, 0x000425,
- 0x021124, 0x100102, 0x000820, 0x031060,
- 0x010040, 0x001924, 0x287886, 0x00008D,
- 0x000464, 0x009D04, 0x278886, 0x180102,
- 0x000575, 0x010042, 0x28040A, 0x00018D,
- 0x000924, 0x280D02, 0x00000D, 0x000924,
- 0x281502, 0x10000D, 0x000820, 0x0002F5,
- 0x010040, 0x200007, 0x001175, 0x0002FD,
- 0x018042, 0x08000A, 0x000904, 0x23C286,
- 0x000007, 0x000100, 0x080B20, 0x130B60,
- 0x1B0B60, 0x030A60, 0x010040, 0x050042,
- 0x3D004A, 0x35004A, 0x2D004A, 0x20000A,
- 0x0006F5, 0x010042, 0x28140A, 0x0004F5,
- 0x010042, 0x08000A, 0x000315, 0x010D04,
- 0x24CA86, 0x004015, 0x000095, 0x010D04,
- 0x24B886, 0x100022, 0x10002A, 0x24E206,
- 0x000007, 0x333104, 0x2AA904, 0x000007,
- 0x032124, 0x280502, 0x001124, 0x000424,
- 0x000424, 0x003224, 0x00292C, 0x00636C,
- 0x25F386, 0x000007, 0x02B164, 0x000464,
- 0x000464, 0x00008D, 0x000A64, 0x280D02,
- 0x10008D, 0x000820, 0x0002F5, 0x010040,
- 0x220007, 0x00008D, 0x38B904, 0x000007,
- 0x03296C, 0x30010A, 0x0002F5, 0x010042,
- 0x08000A, 0x000904, 0x25BA86, 0x000007,
- 0x02312C, 0x28050A, 0x00008D, 0x01096C,
- 0x280D0A, 0x10010D, 0x000820, 0x0002F5,
- 0x010040, 0x220007, 0x001124, 0x000424,
- 0x000424, 0x003224, 0x300102, 0x032944,
- 0x267A86, 0x000007, 0x300002, 0x0004F5,
- 0x010042, 0x08000A, 0x000315, 0x010D04,
- 0x26C086, 0x003124, 0x000464, 0x300102,
- 0x0002F5, 0x010042, 0x08000A, 0x000904,
- 0x26CA86, 0x000007, 0x003124, 0x300502,
- 0x003924, 0x300583, 0x000883, 0x0005F5,
- 0x010042, 0x28040A, 0x00008D, 0x008124,
- 0x280D02, 0x00008D, 0x008124, 0x281502,
- 0x10018D, 0x000820, 0x0002F5, 0x010040,
- 0x220007, 0x001025, 0x000575, 0x030042,
- 0x09004A, 0x10000A, 0x0A0904, 0x121104,
- 0x000007, 0x001020, 0x050860, 0x050040,
- 0x0006FD, 0x018042, 0x09004A, 0x10000A,
- 0x0000A5, 0x0A0904, 0x121104, 0x000007,
- 0x000820, 0x019060, 0x010040, 0x0002F5,
- 0x010042, 0x08000A, 0x000904, 0x284286,
- 0x000007, 0x230A06, 0x000007, 0x000606,
- 0x000007, 0x0002F5, 0x010042, 0x08000A,
- 0x000904, 0x289286, 0x000007, 0x000100,
- 0x080B20, 0x138B60, 0x1B8B60, 0x238B60,
- 0x2B8B60, 0x338B60, 0x3B8B60, 0x438B60,
- 0x4B8B60, 0x538B60, 0x5B8B60, 0x638B60,
- 0x6B8B60, 0x738B60, 0x7B8B60, 0x038F60,
- 0x0B8F60, 0x138F60, 0x1B8F60, 0x238F60,
- 0x2B8F60, 0x338F60, 0x3B8F60, 0x438F60,
- 0x4B8F60, 0x538F60, 0x5B8F60, 0x638F60,
- 0x6B8F60, 0x738F60, 0x7B8F60, 0x038A60,
- 0x000606, 0x018040, 0x00008D, 0x000A64,
- 0x280D02, 0x000A24, 0x00027D, 0x018042,
- 0x10000A, 0x001224, 0x0003FD, 0x018042,
- 0x08000A, 0x000904, 0x2A8286, 0x000007,
- 0x00018D, 0x000A24, 0x000464, 0x000464,
- 0x080102, 0x000924, 0x000424, 0x000424,
- 0x100102, 0x02000D, 0x009144, 0x2AD986,
- 0x000007, 0x0001FD, 0x018042, 0x08000A,
- 0x000A44, 0x2ABB86, 0x018042, 0x0A000D,
- 0x000820, 0x0002FD, 0x018040, 0x200007,
- 0x00027D, 0x001020, 0x000606, 0x018040,
- 0x0002F5, 0x010042, 0x08000A, 0x000904,
- 0x2B2A86, 0x000007, 0x00037D, 0x018042,
- 0x08000A, 0x000904, 0x2B5A86, 0x000007,
- 0x000075, 0x002E7D, 0x010042, 0x0B804A,
- 0x000020, 0x000904, 0x000686, 0x010040,
- 0x31844A, 0x30048B, 0x000883, 0x00008D,
- 0x000810, 0x28143A, 0x00008D, 0x000810,
- 0x280C3A, 0x000675, 0x010042, 0x08000A,
- 0x003815, 0x010924, 0x280502, 0x0B000D,
- 0x000820, 0x0002F5, 0x010040, 0x000606,
- 0x220007, 0x000464, 0x000464, 0x000606,
- 0x000007, 0x000134, 0x007F8D, 0x00093C,
- 0x281D12, 0x282512, 0x001F32, 0x0E0007,
- 0x00010D, 0x00037D, 0x000820, 0x018040,
- 0x05D2F4, 0x000007, 0x080007, 0x00037D,
- 0x018042, 0x08000A, 0x000904, 0x2D0286,
- 0x000007, 0x000606, 0x000007, 0x000007,
- 0x000012, 0x100007, 0x320007, 0x600007,
- 0x100080, 0x48001A, 0x004904, 0x2D6186,
- 0x000007, 0x001210, 0x58003A, 0x000145,
- 0x5C5D04, 0x000007, 0x000080, 0x48001A,
- 0x004904, 0x2DB186, 0x000007, 0x001210,
- 0x50003A, 0x005904, 0x2E0886, 0x000045,
- 0x0000C5, 0x7FFFF5, 0x7FFF7D, 0x07D524,
- 0x004224, 0x500102, 0x200502, 0x000082,
- 0x40001A, 0x004104, 0x2E3986, 0x000007,
- 0x003865, 0x40001A, 0x004020, 0x00104D,
- 0x04C184, 0x301B86, 0x000040, 0x040007,
- 0x000165, 0x000145, 0x004020, 0x000040,
- 0x000765, 0x080080, 0x40001A, 0x004104,
- 0x2EC986, 0x000007, 0x001210, 0x40003A,
- 0x004104, 0x2F2286, 0x00004D, 0x0000CD,
- 0x004810, 0x20043A, 0x000882, 0x40001A,
- 0x004104, 0x2F3186, 0x000007, 0x004820,
- 0x005904, 0x300886, 0x000040, 0x0007E5,
- 0x200480, 0x2816A0, 0x3216E0, 0x3A16E0,
- 0x4216E0, 0x021260, 0x000040, 0x000032,
- 0x400075, 0x00007D, 0x07D574, 0x200512,
- 0x000082, 0x40001A, 0x004104, 0x2FE186,
- 0x000007, 0x037206, 0x640007, 0x060007,
- 0x0000E5, 0x000020, 0x000040, 0x000A65,
- 0x000020, 0x020040, 0x020040, 0x000040,
- 0x000165, 0x000042, 0x70000A, 0x007104,
- 0x30A286, 0x000007, 0x018206, 0x640007,
- 0x050000, 0x007020, 0x000040, 0x037206,
- 0x640007, 0x000007, 0x00306D, 0x028860,
- 0x029060, 0x08000A, 0x028860, 0x008040,
- 0x100012, 0x00100D, 0x009184, 0x314186,
- 0x000E0D, 0x009184, 0x325186, 0x000007,
- 0x300007, 0x001020, 0x003B6D, 0x008040,
- 0x000080, 0x08001A, 0x000904, 0x316186,
- 0x000007, 0x001220, 0x000DED, 0x008040,
- 0x008042, 0x10000A, 0x40000D, 0x109544,
- 0x000007, 0x001020, 0x000DED, 0x008040,
- 0x008042, 0x20040A, 0x000082, 0x08001A,
- 0x000904, 0x31F186, 0x000007, 0x003B6D,
- 0x008042, 0x08000A, 0x000E15, 0x010984,
- 0x329B86, 0x600007, 0x08001A, 0x000C15,
- 0x010984, 0x328386, 0x000020, 0x1A0007,
- 0x0002ED, 0x008040, 0x620007, 0x00306D,
- 0x028042, 0x0A804A, 0x000820, 0x0A804A,
- 0x000606, 0x10804A, 0x000007, 0x282512,
- 0x001F32, 0x05D2F4, 0x54D104, 0x00735C,
- 0x000786, 0x000007, 0x0C0007, 0x0A0007,
- 0x1C0007, 0x003465, 0x020040, 0x004820,
- 0x025060, 0x40000A, 0x024060, 0x000040,
- 0x454944, 0x000007, 0x004020, 0x003AE5,
- 0x000040, 0x0028E5, 0x000042, 0x48000A,
- 0x004904, 0x386886, 0x002C65, 0x000042,
- 0x40000A, 0x0000D5, 0x454104, 0x000007,
- 0x000655, 0x054504, 0x34F286, 0x0001D5,
- 0x054504, 0x34F086, 0x002B65, 0x000042,
- 0x003AE5, 0x50004A, 0x40000A, 0x45C3D4,
- 0x000007, 0x454504, 0x000007, 0x0000CD,
- 0x444944, 0x000007, 0x454504, 0x000007,
- 0x00014D, 0x554944, 0x000007, 0x045144,
- 0x34E986, 0x002C65, 0x000042, 0x48000A,
- 0x4CD104, 0x000007, 0x04C144, 0x34F386,
- 0x000007, 0x160007, 0x002CE5, 0x040042,
- 0x40000A, 0x004020, 0x000040, 0x002965,
- 0x000042, 0x40000A, 0x004104, 0x356086,
- 0x000007, 0x002402, 0x36A206, 0x005C02,
- 0x0025E5, 0x000042, 0x40000A, 0x004274,
- 0x002AE5, 0x000042, 0x40000A, 0x004274,
- 0x500112, 0x0029E5, 0x000042, 0x40000A,
- 0x004234, 0x454104, 0x000007, 0x004020,
- 0x000040, 0x003EE5, 0x000020, 0x000040,
- 0x002DE5, 0x400152, 0x50000A, 0x045144,
- 0x364A86, 0x0000C5, 0x003EE5, 0x004020,
- 0x000040, 0x002BE5, 0x000042, 0x40000A,
- 0x404254, 0x000007, 0x002AE5, 0x004020,
- 0x000040, 0x500132, 0x040134, 0x005674,
- 0x0029E5, 0x020042, 0x42000A, 0x000042,
- 0x50000A, 0x05417C, 0x0028E5, 0x000042,
- 0x48000A, 0x0000C5, 0x4CC144, 0x371086,
- 0x0026E5, 0x0027E5, 0x020042, 0x40004A,
- 0x50000A, 0x00423C, 0x00567C, 0x0028E5,
- 0x004820, 0x000040, 0x281D12, 0x282512,
- 0x001F72, 0x002965, 0x000042, 0x40000A,
- 0x004104, 0x37AA86, 0x0E0007, 0x160007,
- 0x1E0007, 0x003EE5, 0x000042, 0x40000A,
- 0x004104, 0x37E886, 0x002D65, 0x000042,
- 0x28340A, 0x003465, 0x020042, 0x42004A,
- 0x004020, 0x4A004A, 0x50004A, 0x05D2F4,
- 0x54D104, 0x00735C, 0x385186, 0x000007,
- 0x000606, 0x080007, 0x0C0007, 0x080007,
- 0x0A0007, 0x0001E5, 0x020045, 0x004020,
- 0x000060, 0x000365, 0x000040, 0x002E65,
- 0x001A20, 0x0A1A60, 0x000040, 0x003465,
- 0x020042, 0x42004A, 0x004020, 0x4A004A,
- 0x000606, 0x50004A, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000
-};
-
-// --------------------------------------------
-// DS-1E Controller InstructionRAM Code
-// 1999/06/21
-// Buf441 slot is Enabled.
-// --------------------------------------------
-// 04/09 creat
-// 04/12 stop nise fix
-// 06/21 WorkingOff timming
-static u32 CntrlInst1E[YDSXG_CTRLLENGTH / 4] = {
- 0x000007, 0x240007, 0x0C0007, 0x1C0007,
- 0x060007, 0x700002, 0x000020, 0x030040,
- 0x007104, 0x004286, 0x030040, 0x000F0D,
- 0x000810, 0x20043A, 0x000282, 0x00020D,
- 0x000810, 0x20043A, 0x001282, 0x200E82,
- 0x00800D, 0x000810, 0x20043A, 0x001A82,
- 0x03460D, 0x000810, 0x10043A, 0x02EC0D,
- 0x000810, 0x18043A, 0x00010D, 0x020015,
- 0x0000FD, 0x000020, 0x038860, 0x039060,
- 0x038060, 0x038040, 0x038040, 0x038040,
- 0x018040, 0x000A7D, 0x038040, 0x038040,
- 0x018040, 0x200402, 0x000882, 0x08001A,
- 0x000904, 0x017186, 0x000007, 0x260007,
- 0x400007, 0x000007, 0x03258D, 0x000810,
- 0x18043A, 0x260007, 0x284402, 0x00087D,
- 0x018042, 0x00160A, 0x05A206, 0x000007,
- 0x440007, 0x00230D, 0x000810, 0x08043A,
- 0x22FA06, 0x000007, 0x0007FD, 0x018042,
- 0x08000A, 0x000904, 0x02AB86, 0x000195,
- 0x090D04, 0x000007, 0x000820, 0x0000F5,
- 0x000B7D, 0x01F060, 0x0000FD, 0x033A06,
- 0x018040, 0x000A7D, 0x038042, 0x13804A,
- 0x18000A, 0x001820, 0x059060, 0x058860,
- 0x018040, 0x0000FD, 0x018042, 0x70000A,
- 0x000115, 0x071144, 0x033B86, 0x030000,
- 0x007020, 0x036206, 0x018040, 0x00360D,
- 0x000810, 0x08043A, 0x232206, 0x000007,
- 0x02EC0D, 0x000810, 0x18043A, 0x019A06,
- 0x000007, 0x240007, 0x000F8D, 0x000810,
- 0x00163A, 0x002402, 0x005C02, 0x0028FD,
- 0x000020, 0x018040, 0x08000D, 0x000815,
- 0x510984, 0x000007, 0x00004D, 0x000E5D,
- 0x000E02, 0x00430D, 0x000810, 0x08043A,
- 0x2E1206, 0x000007, 0x00008D, 0x000924,
- 0x000F02, 0x00470D, 0x000810, 0x08043A,
- 0x2E1206, 0x000007, 0x480480, 0x001210,
- 0x28043A, 0x00778D, 0x000810, 0x280C3A,
- 0x00068D, 0x000810, 0x28143A, 0x284402,
- 0x03258D, 0x000810, 0x18043A, 0x07FF8D,
- 0x000820, 0x0002FD, 0x018040, 0x260007,
- 0x200007, 0x0002FD, 0x018042, 0x08000A,
- 0x000904, 0x051286, 0x000007, 0x240007,
- 0x02EC0D, 0x000810, 0x18043A, 0x00387D,
- 0x018042, 0x08000A, 0x001015, 0x010984,
- 0x019B86, 0x000007, 0x01B206, 0x000007,
- 0x0008FD, 0x018042, 0x18000A, 0x001904,
- 0x22B886, 0x280007, 0x001810, 0x28043A,
- 0x280C02, 0x00000D, 0x000810, 0x28143A,
- 0x08808D, 0x000820, 0x0002FD, 0x018040,
- 0x200007, 0x00020D, 0x189904, 0x000007,
- 0x00402D, 0x0000BD, 0x0002FD, 0x018042,
- 0x08000A, 0x000904, 0x065A86, 0x000007,
- 0x000100, 0x000A20, 0x00047D, 0x018040,
- 0x018042, 0x20000A, 0x003015, 0x012144,
- 0x036186, 0x000007, 0x002104, 0x036186,
- 0x000007, 0x000F8D, 0x000810, 0x280C3A,
- 0x023944, 0x07C986, 0x000007, 0x001810,
- 0x28043A, 0x08810D, 0x000820, 0x0002FD,
- 0x018040, 0x200007, 0x002810, 0x78003A,
- 0x00788D, 0x000810, 0x08043A, 0x2A1206,
- 0x000007, 0x00400D, 0x001015, 0x189904,
- 0x292904, 0x393904, 0x000007, 0x070206,
- 0x000007, 0x0004F5, 0x00007D, 0x000020,
- 0x00008D, 0x010860, 0x018040, 0x00047D,
- 0x038042, 0x21804A, 0x18000A, 0x021944,
- 0x229086, 0x000007, 0x004075, 0x71F104,
- 0x000007, 0x010042, 0x28000A, 0x002904,
- 0x225886, 0x000007, 0x003C0D, 0x30A904,
- 0x000007, 0x00077D, 0x018042, 0x08000A,
- 0x000904, 0x08DA86, 0x00057D, 0x002820,
- 0x03B060, 0x08F206, 0x018040, 0x003020,
- 0x03A860, 0x018040, 0x0002FD, 0x018042,
- 0x08000A, 0x000904, 0x08FA86, 0x000007,
- 0x00057D, 0x018042, 0x28040A, 0x000E8D,
- 0x000810, 0x280C3A, 0x00000D, 0x000810,
- 0x28143A, 0x09000D, 0x000820, 0x0002FD,
- 0x018040, 0x200007, 0x003DFD, 0x000020,
- 0x018040, 0x00107D, 0x009D8D, 0x000810,
- 0x08043A, 0x2A1206, 0x000007, 0x000815,
- 0x08001A, 0x010984, 0x0A5186, 0x00137D,
- 0x200500, 0x280F20, 0x338F60, 0x3B8F60,
- 0x438F60, 0x4B8F60, 0x538F60, 0x5B8F60,
- 0x038A60, 0x018040, 0x00107D, 0x018042,
- 0x08000A, 0x000215, 0x010984, 0x3A8186,
- 0x000007, 0x007FBD, 0x383DC4, 0x000007,
- 0x001A7D, 0x001375, 0x018042, 0x09004A,
- 0x10000A, 0x0B8D04, 0x139504, 0x000007,
- 0x000820, 0x019060, 0x001104, 0x225886,
- 0x010040, 0x0017FD, 0x018042, 0x08000A,
- 0x000904, 0x225A86, 0x000007, 0x00197D,
- 0x038042, 0x09804A, 0x10000A, 0x000924,
- 0x001664, 0x0011FD, 0x038042, 0x2B804A,
- 0x19804A, 0x00008D, 0x218944, 0x000007,
- 0x002244, 0x0C1986, 0x000007, 0x001A64,
- 0x002A24, 0x00197D, 0x080102, 0x100122,
- 0x000820, 0x039060, 0x018040, 0x003DFD,
- 0x00008D, 0x000820, 0x018040, 0x001375,
- 0x001A7D, 0x010042, 0x09804A, 0x10000A,
- 0x00021D, 0x0189E4, 0x2992E4, 0x309144,
- 0x000007, 0x00060D, 0x000A15, 0x000C1D,
- 0x001025, 0x00A9E4, 0x012BE4, 0x000464,
- 0x01B3E4, 0x0232E4, 0x000464, 0x000464,
- 0x000464, 0x000464, 0x00040D, 0x08B1C4,
- 0x000007, 0x000820, 0x000BF5, 0x030040,
- 0x00197D, 0x038042, 0x09804A, 0x000A24,
- 0x08000A, 0x080E64, 0x000007, 0x100122,
- 0x000820, 0x031060, 0x010040, 0x0064AC,
- 0x00027D, 0x000020, 0x018040, 0x00107D,
- 0x018042, 0x0011FD, 0x3B804A, 0x09804A,
- 0x20000A, 0x000095, 0x1A1144, 0x00A144,
- 0x0E5886, 0x00040D, 0x00B984, 0x0E5986,
- 0x0018FD, 0x018042, 0x0010FD, 0x09804A,
- 0x28000A, 0x000095, 0x010924, 0x002A64,
- 0x0E4986, 0x000007, 0x002904, 0x0E5A86,
- 0x000007, 0x0E6206, 0x080002, 0x00008D,
- 0x00387D, 0x000820, 0x018040, 0x00127D,
- 0x018042, 0x10000A, 0x003904, 0x0F0986,
- 0x00080D, 0x7FFFB5, 0x00B984, 0x0ED986,
- 0x000025, 0x0FB206, 0x00002D, 0x000015,
- 0x00082D, 0x02E00D, 0x000820, 0x0FFA06,
- 0x00000D, 0x7F8035, 0x00B984, 0x0FA986,
- 0x400025, 0x00008D, 0x110944, 0x000007,
- 0x00018D, 0x109504, 0x000007, 0x009164,
- 0x000424, 0x000424, 0x000424, 0x100102,
- 0x280002, 0x02DF0D, 0x000820, 0x0FFA06,
- 0x00018D, 0x00042D, 0x00008D, 0x109504,
- 0x000007, 0x00020D, 0x109184, 0x000007,
- 0x02DF8D, 0x000820, 0x00008D, 0x0038FD,
- 0x018040, 0x003BFD, 0x001020, 0x03A860,
- 0x000815, 0x313184, 0x212184, 0x000007,
- 0x03B060, 0x03A060, 0x018040, 0x0022FD,
- 0x000095, 0x010924, 0x000424, 0x000424,
- 0x001264, 0x100102, 0x000820, 0x039060,
- 0x018040, 0x001924, 0x010F0D, 0x00397D,
- 0x000820, 0x058040, 0x038042, 0x09844A,
- 0x000606, 0x08040A, 0x000424, 0x000424,
- 0x00117D, 0x018042, 0x08000A, 0x000A24,
- 0x280502, 0x280C02, 0x09800D, 0x000820,
- 0x0002FD, 0x018040, 0x200007, 0x0022FD,
- 0x018042, 0x08000A, 0x000095, 0x280DC4,
- 0x011924, 0x00197D, 0x018042, 0x0011FD,
- 0x09804A, 0x10000A, 0x0000B5, 0x113144,
- 0x0A8D04, 0x000007, 0x080A44, 0x129504,
- 0x000007, 0x0023FD, 0x001020, 0x038040,
- 0x101244, 0x000007, 0x000820, 0x039060,
- 0x018040, 0x0002FD, 0x018042, 0x08000A,
- 0x000904, 0x123286, 0x000007, 0x003BFD,
- 0x000100, 0x000A10, 0x0B807A, 0x13804A,
- 0x090984, 0x000007, 0x000095, 0x013D04,
- 0x12B886, 0x10000A, 0x100002, 0x090984,
- 0x000007, 0x038042, 0x11804A, 0x090D04,
- 0x000007, 0x10000A, 0x090D84, 0x000007,
- 0x00257D, 0x000820, 0x018040, 0x00010D,
- 0x000810, 0x28143A, 0x00127D, 0x018042,
- 0x20000A, 0x00197D, 0x018042, 0x00117D,
- 0x31804A, 0x10000A, 0x003124, 0x013B8D,
- 0x00397D, 0x000820, 0x058040, 0x038042,
- 0x09844A, 0x000606, 0x08040A, 0x300102,
- 0x003124, 0x000424, 0x000424, 0x001224,
- 0x280502, 0x001A4C, 0x143986, 0x700002,
- 0x00002D, 0x030000, 0x00387D, 0x018042,
- 0x10000A, 0x146206, 0x002124, 0x0000AD,
- 0x100002, 0x00010D, 0x000924, 0x006B24,
- 0x014A0D, 0x00397D, 0x000820, 0x058040,
- 0x038042, 0x09844A, 0x000606, 0x08040A,
- 0x003264, 0x00008D, 0x000A24, 0x001020,
- 0x00227D, 0x018040, 0x014F8D, 0x000810,
- 0x08043A, 0x2B5A06, 0x000007, 0x002820,
- 0x00207D, 0x018040, 0x00117D, 0x038042,
- 0x13804A, 0x33800A, 0x00387D, 0x018042,
- 0x08000A, 0x000904, 0x177286, 0x000007,
- 0x00008D, 0x030964, 0x015B0D, 0x00397D,
- 0x000820, 0x058040, 0x038042, 0x09844A,
- 0x000606, 0x08040A, 0x380102, 0x000424,
- 0x000424, 0x001224, 0x0002FD, 0x018042,
- 0x08000A, 0x000904, 0x15DA86, 0x000007,
- 0x280502, 0x001A4C, 0x177186, 0x000007,
- 0x032164, 0x00632C, 0x003DFD, 0x018042,
- 0x08000A, 0x000095, 0x090904, 0x000007,
- 0x000820, 0x001A4C, 0x169986, 0x018040,
- 0x030000, 0x16B206, 0x002124, 0x00010D,
- 0x000924, 0x006B24, 0x016F0D, 0x00397D,
- 0x000820, 0x058040, 0x038042, 0x09844A,
- 0x000606, 0x08040A, 0x003A64, 0x000095,
- 0x001224, 0x0002FD, 0x018042, 0x08000A,
- 0x000904, 0x171286, 0x000007, 0x01760D,
- 0x000810, 0x08043A, 0x2B5A06, 0x000007,
- 0x160A06, 0x000007, 0x007020, 0x08010A,
- 0x10012A, 0x0020FD, 0x038860, 0x039060,
- 0x018040, 0x00227D, 0x018042, 0x003DFD,
- 0x08000A, 0x31844A, 0x000904, 0x181086,
- 0x18008B, 0x00008D, 0x189904, 0x00312C,
- 0x18E206, 0x000007, 0x00324C, 0x186B86,
- 0x000007, 0x001904, 0x186886, 0x000007,
- 0x000095, 0x199144, 0x00222C, 0x003124,
- 0x00636C, 0x000E3D, 0x001375, 0x000BFD,
- 0x010042, 0x09804A, 0x10000A, 0x038AEC,
- 0x0393EC, 0x00224C, 0x18E186, 0x000007,
- 0x00008D, 0x189904, 0x00226C, 0x00322C,
- 0x30050A, 0x301DAB, 0x002083, 0x0018FD,
- 0x018042, 0x08000A, 0x018924, 0x300502,
- 0x001083, 0x001875, 0x010042, 0x10000A,
- 0x00008D, 0x010924, 0x001375, 0x330542,
- 0x330CCB, 0x332CCB, 0x3334CB, 0x333CCB,
- 0x3344CB, 0x334CCB, 0x3354CB, 0x305C8B,
- 0x006083, 0x0002F5, 0x010042, 0x08000A,
- 0x000904, 0x19B286, 0x000007, 0x001E2D,
- 0x0005FD, 0x018042, 0x08000A, 0x028924,
- 0x280502, 0x00060D, 0x000810, 0x280C3A,
- 0x00008D, 0x000810, 0x28143A, 0x0A808D,
- 0x000820, 0x0002F5, 0x010040, 0x220007,
- 0x001275, 0x030042, 0x21004A, 0x00008D,
- 0x1A0944, 0x000007, 0x01AB8D, 0x000810,
- 0x08043A, 0x2CAA06, 0x000007, 0x0001F5,
- 0x030042, 0x0D004A, 0x10000A, 0x089144,
- 0x000007, 0x000820, 0x010040, 0x0025F5,
- 0x0A3144, 0x000007, 0x000820, 0x032860,
- 0x030040, 0x00217D, 0x038042, 0x0B804A,
- 0x10000A, 0x000820, 0x031060, 0x030040,
- 0x00008D, 0x000124, 0x00012C, 0x000E64,
- 0x001A64, 0x00636C, 0x08010A, 0x10012A,
- 0x000820, 0x031060, 0x030040, 0x0020FD,
- 0x018042, 0x08000A, 0x00227D, 0x018042,
- 0x10000A, 0x000820, 0x031060, 0x030040,
- 0x00197D, 0x018042, 0x08000A, 0x0022FD,
- 0x038042, 0x10000A, 0x000820, 0x031060,
- 0x030040, 0x090D04, 0x000007, 0x000820,
- 0x030040, 0x038042, 0x0B804A, 0x10000A,
- 0x000820, 0x031060, 0x030040, 0x038042,
- 0x13804A, 0x19804A, 0x110D04, 0x198D04,
- 0x000007, 0x08000A, 0x001020, 0x031860,
- 0x030860, 0x030040, 0x00008D, 0x0B0944,
- 0x000007, 0x000820, 0x010040, 0x0005F5,
- 0x030042, 0x08000A, 0x000820, 0x010040,
- 0x0000F5, 0x010042, 0x08000A, 0x000904,
- 0x1D9886, 0x001E75, 0x030042, 0x01044A,
- 0x000C0A, 0x1DAA06, 0x000007, 0x000402,
- 0x000C02, 0x00177D, 0x001AF5, 0x018042,
- 0x03144A, 0x031C4A, 0x03244A, 0x032C4A,
- 0x03344A, 0x033C4A, 0x03444A, 0x004C0A,
- 0x00043D, 0x0013F5, 0x001AFD, 0x030042,
- 0x0B004A, 0x1B804A, 0x13804A, 0x20000A,
- 0x089144, 0x19A144, 0x0389E4, 0x0399EC,
- 0x005502, 0x005D0A, 0x030042, 0x0B004A,
- 0x1B804A, 0x13804A, 0x20000A, 0x089144,
- 0x19A144, 0x0389E4, 0x0399EC, 0x006502,
- 0x006D0A, 0x030042, 0x0B004A, 0x19004A,
- 0x2B804A, 0x13804A, 0x21804A, 0x30000A,
- 0x089144, 0x19A144, 0x2AB144, 0x0389E4,
- 0x0399EC, 0x007502, 0x007D0A, 0x03A9E4,
- 0x000702, 0x00107D, 0x000415, 0x018042,
- 0x08000A, 0x0109E4, 0x000F02, 0x002AF5,
- 0x0019FD, 0x010042, 0x09804A, 0x10000A,
- 0x000934, 0x001674, 0x0029F5, 0x010042,
- 0x10000A, 0x00917C, 0x002075, 0x010042,
- 0x08000A, 0x000904, 0x200A86, 0x0026F5,
- 0x0027F5, 0x030042, 0x09004A, 0x10000A,
- 0x000A3C, 0x00167C, 0x001A75, 0x000BFD,
- 0x010042, 0x51804A, 0x48000A, 0x160007,
- 0x001075, 0x010042, 0x282C0A, 0x281D12,
- 0x282512, 0x001F32, 0x1E0007, 0x0E0007,
- 0x001975, 0x010042, 0x002DF5, 0x0D004A,
- 0x10000A, 0x009144, 0x20EA86, 0x010042,
- 0x28340A, 0x000E5D, 0x00008D, 0x000375,
- 0x000820, 0x010040, 0x05D2F4, 0x54D104,
- 0x00735C, 0x218B86, 0x000007, 0x0C0007,
- 0x080007, 0x0A0007, 0x02178D, 0x000810,
- 0x08043A, 0x34B206, 0x000007, 0x219206,
- 0x000007, 0x080007, 0x002275, 0x010042,
- 0x20000A, 0x002104, 0x225886, 0x001E2D,
- 0x0002F5, 0x010042, 0x08000A, 0x000904,
- 0x21CA86, 0x000007, 0x002010, 0x30043A,
- 0x00057D, 0x0180C3, 0x08000A, 0x028924,
- 0x280502, 0x280C02, 0x0A810D, 0x000820,
- 0x0002F5, 0x010040, 0x220007, 0x0004FD,
- 0x018042, 0x70000A, 0x030000, 0x007020,
- 0x07FA06, 0x018040, 0x022B8D, 0x000810,
- 0x08043A, 0x2CAA06, 0x000007, 0x0002FD,
- 0x018042, 0x08000A, 0x000904, 0x22C286,
- 0x000007, 0x020206, 0x000007, 0x000875,
- 0x0009FD, 0x00010D, 0x234206, 0x000295,
- 0x000B75, 0x00097D, 0x00000D, 0x000515,
- 0x010042, 0x18000A, 0x001904, 0x2A0086,
- 0x0006F5, 0x001020, 0x010040, 0x0004F5,
- 0x000820, 0x010040, 0x000775, 0x010042,
- 0x09804A, 0x10000A, 0x001124, 0x000904,
- 0x23F286, 0x000815, 0x080102, 0x101204,
- 0x241206, 0x000575, 0x081204, 0x000007,
- 0x100102, 0x000575, 0x000425, 0x021124,
- 0x100102, 0x000820, 0x031060, 0x010040,
- 0x001924, 0x2A0086, 0x00008D, 0x000464,
- 0x009D04, 0x291086, 0x180102, 0x000575,
- 0x010042, 0x28040A, 0x00018D, 0x000924,
- 0x280D02, 0x00000D, 0x000924, 0x281502,
- 0x10000D, 0x000820, 0x0002F5, 0x010040,
- 0x200007, 0x001175, 0x0002FD, 0x018042,
- 0x08000A, 0x000904, 0x24FA86, 0x000007,
- 0x000100, 0x080B20, 0x130B60, 0x1B0B60,
- 0x030A60, 0x010040, 0x050042, 0x3D004A,
- 0x35004A, 0x2D004A, 0x20000A, 0x0006F5,
- 0x010042, 0x28140A, 0x0004F5, 0x010042,
- 0x08000A, 0x000315, 0x010D04, 0x260286,
- 0x004015, 0x000095, 0x010D04, 0x25F086,
- 0x100022, 0x10002A, 0x261A06, 0x000007,
- 0x333104, 0x2AA904, 0x000007, 0x032124,
- 0x280502, 0x284402, 0x001124, 0x400102,
- 0x000424, 0x000424, 0x003224, 0x00292C,
- 0x00636C, 0x277386, 0x000007, 0x02B164,
- 0x000464, 0x000464, 0x00008D, 0x000A64,
- 0x280D02, 0x10008D, 0x000820, 0x0002F5,
- 0x010040, 0x220007, 0x00008D, 0x38B904,
- 0x000007, 0x03296C, 0x30010A, 0x0002F5,
- 0x010042, 0x08000A, 0x000904, 0x270286,
- 0x000007, 0x00212C, 0x28050A, 0x00316C,
- 0x00046C, 0x00046C, 0x28450A, 0x001124,
- 0x006B64, 0x100102, 0x00008D, 0x01096C,
- 0x280D0A, 0x10010D, 0x000820, 0x0002F5,
- 0x010040, 0x220007, 0x004124, 0x000424,
- 0x000424, 0x003224, 0x300102, 0x032944,
- 0x27FA86, 0x000007, 0x300002, 0x0004F5,
- 0x010042, 0x08000A, 0x000315, 0x010D04,
- 0x284086, 0x003124, 0x000464, 0x300102,
- 0x0002F5, 0x010042, 0x08000A, 0x000904,
- 0x284A86, 0x000007, 0x284402, 0x003124,
- 0x300502, 0x003924, 0x300583, 0x000883,
- 0x0005F5, 0x010042, 0x28040A, 0x00008D,
- 0x008124, 0x280D02, 0x00008D, 0x008124,
- 0x281502, 0x10018D, 0x000820, 0x0002F5,
- 0x010040, 0x220007, 0x001025, 0x000575,
- 0x030042, 0x09004A, 0x10000A, 0x0A0904,
- 0x121104, 0x000007, 0x001020, 0x050860,
- 0x050040, 0x0006FD, 0x018042, 0x09004A,
- 0x10000A, 0x0000A5, 0x0A0904, 0x121104,
- 0x000007, 0x000820, 0x019060, 0x010040,
- 0x0002F5, 0x010042, 0x08000A, 0x000904,
- 0x29CA86, 0x000007, 0x244206, 0x000007,
- 0x000606, 0x000007, 0x0002F5, 0x010042,
- 0x08000A, 0x000904, 0x2A1A86, 0x000007,
- 0x000100, 0x080B20, 0x138B60, 0x1B8B60,
- 0x238B60, 0x2B8B60, 0x338B60, 0x3B8B60,
- 0x438B60, 0x4B8B60, 0x538B60, 0x5B8B60,
- 0x638B60, 0x6B8B60, 0x738B60, 0x7B8B60,
- 0x038F60, 0x0B8F60, 0x138F60, 0x1B8F60,
- 0x238F60, 0x2B8F60, 0x338F60, 0x3B8F60,
- 0x438F60, 0x4B8F60, 0x538F60, 0x5B8F60,
- 0x638F60, 0x6B8F60, 0x738F60, 0x7B8F60,
- 0x038A60, 0x000606, 0x018040, 0x00008D,
- 0x000A64, 0x280D02, 0x000A24, 0x00027D,
- 0x018042, 0x10000A, 0x001224, 0x0003FD,
- 0x018042, 0x08000A, 0x000904, 0x2C0A86,
- 0x000007, 0x00018D, 0x000A24, 0x000464,
- 0x000464, 0x080102, 0x000924, 0x000424,
- 0x000424, 0x100102, 0x02000D, 0x009144,
- 0x2C6186, 0x000007, 0x0001FD, 0x018042,
- 0x08000A, 0x000A44, 0x2C4386, 0x018042,
- 0x0A000D, 0x000820, 0x0002FD, 0x018040,
- 0x200007, 0x00027D, 0x001020, 0x000606,
- 0x018040, 0x0002F5, 0x010042, 0x08000A,
- 0x000904, 0x2CB286, 0x000007, 0x00037D,
- 0x018042, 0x08000A, 0x000904, 0x2CE286,
- 0x000007, 0x000075, 0x002E7D, 0x010042,
- 0x0B804A, 0x000020, 0x000904, 0x000686,
- 0x010040, 0x31844A, 0x30048B, 0x000883,
- 0x00008D, 0x000810, 0x28143A, 0x00008D,
- 0x000810, 0x280C3A, 0x000675, 0x010042,
- 0x08000A, 0x003815, 0x010924, 0x280502,
- 0x0B000D, 0x000820, 0x0002F5, 0x010040,
- 0x000606, 0x220007, 0x000464, 0x000464,
- 0x000606, 0x000007, 0x000134, 0x007F8D,
- 0x00093C, 0x281D12, 0x282512, 0x001F32,
- 0x0E0007, 0x00010D, 0x00037D, 0x000820,
- 0x018040, 0x05D2F4, 0x000007, 0x080007,
- 0x00037D, 0x018042, 0x08000A, 0x000904,
- 0x2E8A86, 0x000007, 0x000606, 0x000007,
- 0x000007, 0x000012, 0x100007, 0x320007,
- 0x600007, 0x460007, 0x100080, 0x48001A,
- 0x004904, 0x2EF186, 0x000007, 0x001210,
- 0x58003A, 0x000145, 0x5C5D04, 0x000007,
- 0x000080, 0x48001A, 0x004904, 0x2F4186,
- 0x000007, 0x001210, 0x50003A, 0x005904,
- 0x2F9886, 0x000045, 0x0000C5, 0x7FFFF5,
- 0x7FFF7D, 0x07D524, 0x004224, 0x500102,
- 0x200502, 0x000082, 0x40001A, 0x004104,
- 0x2FC986, 0x000007, 0x003865, 0x40001A,
- 0x004020, 0x00104D, 0x04C184, 0x31AB86,
- 0x000040, 0x040007, 0x000165, 0x000145,
- 0x004020, 0x000040, 0x000765, 0x080080,
- 0x40001A, 0x004104, 0x305986, 0x000007,
- 0x001210, 0x40003A, 0x004104, 0x30B286,
- 0x00004D, 0x0000CD, 0x004810, 0x20043A,
- 0x000882, 0x40001A, 0x004104, 0x30C186,
- 0x000007, 0x004820, 0x005904, 0x319886,
- 0x000040, 0x0007E5, 0x200480, 0x2816A0,
- 0x3216E0, 0x3A16E0, 0x4216E0, 0x021260,
- 0x000040, 0x000032, 0x400075, 0x00007D,
- 0x07D574, 0x200512, 0x000082, 0x40001A,
- 0x004104, 0x317186, 0x000007, 0x038A06,
- 0x640007, 0x0000E5, 0x000020, 0x000040,
- 0x000A65, 0x000020, 0x020040, 0x020040,
- 0x000040, 0x000165, 0x000042, 0x70000A,
- 0x007104, 0x323286, 0x000007, 0x060007,
- 0x019A06, 0x640007, 0x050000, 0x007020,
- 0x000040, 0x038A06, 0x640007, 0x000007,
- 0x00306D, 0x028860, 0x029060, 0x08000A,
- 0x028860, 0x008040, 0x100012, 0x00100D,
- 0x009184, 0x32D186, 0x000E0D, 0x009184,
- 0x33E186, 0x000007, 0x300007, 0x001020,
- 0x003B6D, 0x008040, 0x000080, 0x08001A,
- 0x000904, 0x32F186, 0x000007, 0x001220,
- 0x000DED, 0x008040, 0x008042, 0x10000A,
- 0x40000D, 0x109544, 0x000007, 0x001020,
- 0x000DED, 0x008040, 0x008042, 0x20040A,
- 0x000082, 0x08001A, 0x000904, 0x338186,
- 0x000007, 0x003B6D, 0x008042, 0x08000A,
- 0x000E15, 0x010984, 0x342B86, 0x600007,
- 0x08001A, 0x000C15, 0x010984, 0x341386,
- 0x000020, 0x1A0007, 0x0002ED, 0x008040,
- 0x620007, 0x00306D, 0x028042, 0x0A804A,
- 0x000820, 0x0A804A, 0x000606, 0x10804A,
- 0x000007, 0x282512, 0x001F32, 0x05D2F4,
- 0x54D104, 0x00735C, 0x000786, 0x000007,
- 0x0C0007, 0x0A0007, 0x1C0007, 0x003465,
- 0x020040, 0x004820, 0x025060, 0x40000A,
- 0x024060, 0x000040, 0x454944, 0x000007,
- 0x004020, 0x003AE5, 0x000040, 0x0028E5,
- 0x000042, 0x48000A, 0x004904, 0x39F886,
- 0x002C65, 0x000042, 0x40000A, 0x0000D5,
- 0x454104, 0x000007, 0x000655, 0x054504,
- 0x368286, 0x0001D5, 0x054504, 0x368086,
- 0x002B65, 0x000042, 0x003AE5, 0x50004A,
- 0x40000A, 0x45C3D4, 0x000007, 0x454504,
- 0x000007, 0x0000CD, 0x444944, 0x000007,
- 0x454504, 0x000007, 0x00014D, 0x554944,
- 0x000007, 0x045144, 0x367986, 0x002C65,
- 0x000042, 0x48000A, 0x4CD104, 0x000007,
- 0x04C144, 0x368386, 0x000007, 0x160007,
- 0x002CE5, 0x040042, 0x40000A, 0x004020,
- 0x000040, 0x002965, 0x000042, 0x40000A,
- 0x004104, 0x36F086, 0x000007, 0x002402,
- 0x383206, 0x005C02, 0x0025E5, 0x000042,
- 0x40000A, 0x004274, 0x002AE5, 0x000042,
- 0x40000A, 0x004274, 0x500112, 0x0029E5,
- 0x000042, 0x40000A, 0x004234, 0x454104,
- 0x000007, 0x004020, 0x000040, 0x003EE5,
- 0x000020, 0x000040, 0x002DE5, 0x400152,
- 0x50000A, 0x045144, 0x37DA86, 0x0000C5,
- 0x003EE5, 0x004020, 0x000040, 0x002BE5,
- 0x000042, 0x40000A, 0x404254, 0x000007,
- 0x002AE5, 0x004020, 0x000040, 0x500132,
- 0x040134, 0x005674, 0x0029E5, 0x020042,
- 0x42000A, 0x000042, 0x50000A, 0x05417C,
- 0x0028E5, 0x000042, 0x48000A, 0x0000C5,
- 0x4CC144, 0x38A086, 0x0026E5, 0x0027E5,
- 0x020042, 0x40004A, 0x50000A, 0x00423C,
- 0x00567C, 0x0028E5, 0x004820, 0x000040,
- 0x281D12, 0x282512, 0x001F72, 0x002965,
- 0x000042, 0x40000A, 0x004104, 0x393A86,
- 0x0E0007, 0x160007, 0x1E0007, 0x003EE5,
- 0x000042, 0x40000A, 0x004104, 0x397886,
- 0x002D65, 0x000042, 0x28340A, 0x003465,
- 0x020042, 0x42004A, 0x004020, 0x4A004A,
- 0x50004A, 0x05D2F4, 0x54D104, 0x00735C,
- 0x39E186, 0x000007, 0x000606, 0x080007,
- 0x0C0007, 0x080007, 0x0A0007, 0x0001E5,
- 0x020045, 0x004020, 0x000060, 0x000365,
- 0x000040, 0x002E65, 0x001A20, 0x0A1A60,
- 0x000040, 0x003465, 0x020042, 0x42004A,
- 0x004020, 0x4A004A, 0x000606, 0x50004A,
- 0x0017FD, 0x018042, 0x08000A, 0x000904,
- 0x225A86, 0x000007, 0x00107D, 0x018042,
- 0x0011FD, 0x33804A, 0x19804A, 0x20000A,
- 0x000095, 0x2A1144, 0x01A144, 0x3B9086,
- 0x00040D, 0x00B184, 0x3B9186, 0x0018FD,
- 0x018042, 0x0010FD, 0x09804A, 0x38000A,
- 0x000095, 0x010924, 0x003A64, 0x3B8186,
- 0x000007, 0x003904, 0x3B9286, 0x000007,
- 0x3B9A06, 0x00000D, 0x00008D, 0x000820,
- 0x00387D, 0x018040, 0x700002, 0x00117D,
- 0x018042, 0x00197D, 0x29804A, 0x30000A,
- 0x380002, 0x003124, 0x000424, 0x000424,
- 0x002A24, 0x280502, 0x00068D, 0x000810,
- 0x28143A, 0x00750D, 0x00B124, 0x002264,
- 0x3D0386, 0x284402, 0x000810, 0x280C3A,
- 0x0B800D, 0x000820, 0x0002FD, 0x018040,
- 0x200007, 0x00758D, 0x00B124, 0x100102,
- 0x012144, 0x3E4986, 0x001810, 0x10003A,
- 0x00387D, 0x018042, 0x08000A, 0x000904,
- 0x3E4886, 0x030000, 0x3E4A06, 0x0000BD,
- 0x00008D, 0x023164, 0x000A64, 0x280D02,
- 0x0B808D, 0x000820, 0x0002FD, 0x018040,
- 0x200007, 0x00387D, 0x018042, 0x08000A,
- 0x000904, 0x3E3286, 0x030000, 0x0002FD,
- 0x018042, 0x08000A, 0x000904, 0x3D8286,
- 0x000007, 0x002810, 0x28043A, 0x00750D,
- 0x030924, 0x002264, 0x280D02, 0x02316C,
- 0x28450A, 0x0B810D, 0x000820, 0x0002FD,
- 0x018040, 0x200007, 0x00008D, 0x000A24,
- 0x3E4A06, 0x100102, 0x001810, 0x10003A,
- 0x0000BD, 0x003810, 0x30043A, 0x00187D,
- 0x018042, 0x0018FD, 0x09804A, 0x20000A,
- 0x0000AD, 0x028924, 0x07212C, 0x001010,
- 0x300583, 0x300D8B, 0x3014BB, 0x301C83,
- 0x002083, 0x00137D, 0x038042, 0x33844A,
- 0x33ACCB, 0x33B4CB, 0x33BCCB, 0x33C4CB,
- 0x33CCCB, 0x33D4CB, 0x305C8B, 0x006083,
- 0x001E0D, 0x0005FD, 0x018042, 0x20000A,
- 0x020924, 0x00068D, 0x00A96C, 0x00009D,
- 0x0002FD, 0x018042, 0x08000A, 0x000904,
- 0x3F6A86, 0x000007, 0x280502, 0x280D0A,
- 0x284402, 0x001810, 0x28143A, 0x0C008D,
- 0x000820, 0x0002FD, 0x018040, 0x220007,
- 0x003904, 0x225886, 0x001E0D, 0x00057D,
- 0x018042, 0x20000A, 0x020924, 0x0000A5,
- 0x0002FD, 0x018042, 0x08000A, 0x000904,
- 0x402A86, 0x000007, 0x280502, 0x280C02,
- 0x002010, 0x28143A, 0x0C010D, 0x000820,
- 0x0002FD, 0x018040, 0x225A06, 0x220007,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000,
- 0x000000, 0x000000, 0x000000, 0x000000
-};
-
-#endif //_HWMCODE_
diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c
index 29b3056c5109..90d0d62bd0b4 100644
--- a/sound/pci/ymfpci/ymfpci_main.c
+++ b/sound/pci/ymfpci/ymfpci_main.c
@@ -26,6 +26,7 @@
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
+#include <linux/mutex.h>
#include <sound/core.h>
#include <sound/control.h>
@@ -258,8 +259,10 @@ static int snd_ymfpci_voice_alloc(struct snd_ymfpci *chip,
unsigned long flags;
int result;
- snd_assert(rvoice != NULL, return -EINVAL);
- snd_assert(!pair || type == YMFPCI_PCM, return -EINVAL);
+ if (snd_BUG_ON(!rvoice))
+ return -EINVAL;
+ if (snd_BUG_ON(pair && type != YMFPCI_PCM))
+ return -EINVAL;
spin_lock_irqsave(&chip->voice_lock, flags);
for (;;) {
@@ -277,7 +280,8 @@ static int snd_ymfpci_voice_free(struct snd_ymfpci *chip, struct snd_ymfpci_voic
{
unsigned long flags;
- snd_assert(pvoice != NULL, return -EINVAL);
+ if (snd_BUG_ON(!pvoice))
+ return -EINVAL;
snd_ymfpci_hw_stop(chip);
spin_lock_irqsave(&chip->voice_lock, flags);
if (pvoice->number == chip->src441_used) {
@@ -493,7 +497,8 @@ static void snd_ymfpci_pcm_init_voice(struct snd_ymfpci_pcm *ypcm, unsigned int
u8 use_left, use_right;
unsigned long flags;
- snd_assert(voice != NULL, return);
+ if (snd_BUG_ON(!voice))
+ return;
if (runtime->channels == 1) {
use_left = 1;
use_right = 1;
@@ -1812,7 +1817,8 @@ int __devinit snd_ymfpci_mixer(struct snd_ymfpci *chip, int rear_switch)
}
/* add S/PDIF control */
- snd_assert(chip->pcm_spdif != NULL, return -EIO);
+ if (snd_BUG_ON(!chip->pcm_spdif))
+ return -ENXIO;
if ((err = snd_ctl_add(chip->card, kctl = snd_ctl_new1(&snd_ymfpci_spdif_default, chip))) < 0)
return err;
kctl->id.device = chip->pcm_spdif->device;
@@ -1993,55 +1999,6 @@ static void snd_ymfpci_disable_dsp(struct snd_ymfpci *chip)
}
}
-#ifdef CONFIG_SND_YMFPCI_FIRMWARE_IN_KERNEL
-
-#include "ymfpci_image.h"
-
-static struct firmware snd_ymfpci_dsp_microcode = {
- .size = YDSXG_DSPLENGTH,
- .data = (u8 *)DspInst,
-};
-static struct firmware snd_ymfpci_controller_microcode = {
- .size = YDSXG_CTRLLENGTH,
- .data = (u8 *)CntrlInst,
-};
-static struct firmware snd_ymfpci_controller_1e_microcode = {
- .size = YDSXG_CTRLLENGTH,
- .data = (u8 *)CntrlInst1E,
-};
-#endif
-
-#ifdef CONFIG_SND_YMFPCI_FIRMWARE_IN_KERNEL
-static int snd_ymfpci_request_firmware(struct snd_ymfpci *chip)
-{
- chip->dsp_microcode = &snd_ymfpci_dsp_microcode;
- if (chip->device_id == PCI_DEVICE_ID_YAMAHA_724F ||
- chip->device_id == PCI_DEVICE_ID_YAMAHA_740C ||
- chip->device_id == PCI_DEVICE_ID_YAMAHA_744 ||
- chip->device_id == PCI_DEVICE_ID_YAMAHA_754)
- chip->controller_microcode =
- &snd_ymfpci_controller_1e_microcode;
- else
- chip->controller_microcode =
- &snd_ymfpci_controller_microcode;
- return 0;
-}
-
-#else /* use fw_loader */
-
-#ifdef __LITTLE_ENDIAN
-static inline void snd_ymfpci_convert_from_le(const struct firmware *fw) { }
-#else
-static void snd_ymfpci_convert_from_le(const struct firmware *fw)
-{
- int i;
- u32 *data = (u32 *)fw->data;
-
- for (i = 0; i < fw->size / 4; ++i)
- le32_to_cpus(&data[i]);
-}
-#endif
-
static int snd_ymfpci_request_firmware(struct snd_ymfpci *chip)
{
int err, is_1e;
@@ -2050,9 +2007,7 @@ static int snd_ymfpci_request_firmware(struct snd_ymfpci *chip)
err = request_firmware(&chip->dsp_microcode, "yamaha/ds1_dsp.fw",
&chip->pci->dev);
if (err >= 0) {
- if (chip->dsp_microcode->size == YDSXG_DSPLENGTH)
- snd_ymfpci_convert_from_le(chip->dsp_microcode);
- else {
+ if (chip->dsp_microcode->size != YDSXG_DSPLENGTH) {
snd_printk(KERN_ERR "DSP microcode has wrong size\n");
err = -EINVAL;
}
@@ -2067,9 +2022,7 @@ static int snd_ymfpci_request_firmware(struct snd_ymfpci *chip)
err = request_firmware(&chip->controller_microcode, name,
&chip->pci->dev);
if (err >= 0) {
- if (chip->controller_microcode->size == YDSXG_CTRLLENGTH)
- snd_ymfpci_convert_from_le(chip->controller_microcode);
- else {
+ if (chip->controller_microcode->size != YDSXG_CTRLLENGTH) {
snd_printk(KERN_ERR "controller microcode"
" has wrong size\n");
err = -EINVAL;
@@ -2084,13 +2037,11 @@ MODULE_FIRMWARE("yamaha/ds1_dsp.fw");
MODULE_FIRMWARE("yamaha/ds1_ctrl.fw");
MODULE_FIRMWARE("yamaha/ds1e_ctrl.fw");
-#endif
-
static void snd_ymfpci_download_image(struct snd_ymfpci *chip)
{
int i;
u16 ctrl;
- u32 *inst;
+ const __le32 *inst;
snd_ymfpci_writel(chip, YDSXGR_NATIVEDACOUTVOL, 0x00000000);
snd_ymfpci_disable_dsp(chip);
@@ -2105,14 +2056,16 @@ static void snd_ymfpci_download_image(struct snd_ymfpci *chip)
snd_ymfpci_writew(chip, YDSXGR_GLOBALCTRL, ctrl & ~0x0007);
/* setup DSP instruction code */
- inst = (u32 *)chip->dsp_microcode->data;
+ inst = (const __le32 *)chip->dsp_microcode->data;
for (i = 0; i < YDSXG_DSPLENGTH / 4; i++)
- snd_ymfpci_writel(chip, YDSXGR_DSPINSTRAM + (i << 2), inst[i]);
+ snd_ymfpci_writel(chip, YDSXGR_DSPINSTRAM + (i << 2),
+ le32_to_cpu(inst[i]));
/* setup control instruction code */
- inst = (u32 *)chip->controller_microcode->data;
+ inst = (const __le32 *)chip->controller_microcode->data;
for (i = 0; i < YDSXG_CTRLLENGTH / 4; i++)
- snd_ymfpci_writel(chip, YDSXGR_CTRLINSTRAM + (i << 2), inst[i]);
+ snd_ymfpci_writel(chip, YDSXGR_CTRLINSTRAM + (i << 2),
+ le32_to_cpu(inst[i]));
snd_ymfpci_enable_dsp(chip);
}
@@ -2185,7 +2138,8 @@ static int __devinit snd_ymfpci_memalloc(struct snd_ymfpci *chip)
chip->work_base = ptr;
chip->work_base_addr = ptr_addr;
- snd_assert(ptr + chip->work_size == chip->work_ptr.area + chip->work_ptr.bytes, );
+ snd_BUG_ON(ptr + chip->work_size !=
+ chip->work_ptr.area + chip->work_ptr.bytes);
snd_ymfpci_writel(chip, YDSXGR_PLAYCTRLBASE, chip->bank_base_playback_addr);
snd_ymfpci_writel(chip, YDSXGR_RECCTRLBASE, chip->bank_base_capture_addr);
@@ -2205,6 +2159,7 @@ static int __devinit snd_ymfpci_memalloc(struct snd_ymfpci *chip)
for (reg = 0x80; reg < 0xc0; reg += 4)
snd_ymfpci_writel(chip, reg, 0);
snd_ymfpci_writel(chip, YDSXGR_NATIVEDACOUTVOL, 0x3fff3fff);
+ snd_ymfpci_writel(chip, YDSXGR_BUF441OUTVOL, 0x3fff3fff);
snd_ymfpci_writel(chip, YDSXGR_ZVOUTVOL, 0x3fff3fff);
snd_ymfpci_writel(chip, YDSXGR_SPDIFOUTVOL, 0x3fff3fff);
snd_ymfpci_writel(chip, YDSXGR_NATIVEADCINVOL, 0x3fff3fff);
@@ -2219,7 +2174,8 @@ static int snd_ymfpci_free(struct snd_ymfpci *chip)
{
u16 ctrl;
- snd_assert(chip != NULL, return -EINVAL);
+ if (snd_BUG_ON(!chip))
+ return -EINVAL;
if (chip->res_reg_area) { /* don't touch busy hardware */
snd_ymfpci_writel(chip, YDSXGR_NATIVEDACOUTVOL, 0);
@@ -2264,10 +2220,8 @@ static int snd_ymfpci_free(struct snd_ymfpci *chip)
pci_write_config_word(chip->pci, 0x40, chip->old_legacy_ctrl);
pci_disable_device(chip->pci);
-#ifndef CONFIG_SND_YMFPCI_FIRMWARE_IN_KERNEL
release_firmware(chip->dsp_microcode);
release_firmware(chip->controller_microcode);
-#endif
kfree(chip);
return 0;
}
@@ -2324,6 +2278,7 @@ int snd_ymfpci_suspend(struct pci_dev *pci, pm_message_t state)
chip->saved_regs[i] = snd_ymfpci_readl(chip, saved_regs_index[i]);
chip->saved_ydsxgr_mode = snd_ymfpci_readl(chip, YDSXGR_MODE);
snd_ymfpci_writel(chip, YDSXGR_NATIVEDACOUTVOL, 0);
+ snd_ymfpci_writel(chip, YDSXGR_BUF441OUTVOL, 0);
snd_ymfpci_disable_dsp(chip);
pci_disable_device(pci);
pci_save_state(pci);