aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CREDITS10
-rw-r--r--Documentation/sound/alsa/ALSA-Configuration.txt75
-rw-r--r--Documentation/sound/alsa/Audiophile-Usb.txt242
-rw-r--r--Documentation/sound/alsa/OSS-Emulation.txt15
-rw-r--r--include/linux/i2c-id.h7
-rw-r--r--include/sound/ak4xxx-adda.h1
-rw-r--r--include/sound/cs46xx.h4
-rw-r--r--include/sound/cs46xx_dsp_spos.h2
-rw-r--r--include/sound/emu10k1.h16
-rw-r--r--include/sound/sb.h1
-rw-r--r--include/sound/version.h2
-rw-r--r--include/sound/wavefront_fx.h9
-rw-r--r--sound/Kconfig2
-rw-r--r--sound/Makefile2
-rw-r--r--sound/aoa/codecs/snd-aoa-codec-onyx.c4
-rw-r--r--sound/core/pcm_native.c2
-rw-r--r--sound/core/seq/seq_instr.c6
-rw-r--r--sound/core/timer.c27
-rw-r--r--sound/drivers/dummy.c2
-rw-r--r--sound/drivers/mpu401/mpu401.c2
-rw-r--r--sound/drivers/portman2x4.c2
-rw-r--r--sound/drivers/serial-u16550.c2
-rw-r--r--sound/drivers/virmidi.c2
-rw-r--r--sound/i2c/other/ak4xxx-adda.c24
-rw-r--r--sound/isa/Kconfig32
-rw-r--r--sound/isa/ad1848/ad1848_lib.c4
-rw-r--r--sound/isa/opl3sa2.c2
-rw-r--r--sound/isa/opti9xx/opti92x-ad1848.c3
-rw-r--r--sound/isa/sb/Makefile15
-rw-r--r--sound/isa/sb/sb16_main.c10
-rw-r--r--sound/isa/sb/sb_common.c5
-rw-r--r--sound/isa/sb/sb_mixer.c3
-rw-r--r--sound/isa/sscape.c4
-rw-r--r--sound/isa/wavefront/wavefront_synth.c2
-rw-r--r--sound/pci/Kconfig11
-rw-r--r--sound/pci/Makefile2
-rw-r--r--sound/pci/ali5451/ali5451.c7
-rw-r--r--sound/pci/als300.c7
-rw-r--r--sound/pci/ca0106/ca0106_main.c19
-rw-r--r--sound/pci/cs46xx/cs46xx_lib.c77
-rw-r--r--sound/pci/cs46xx/cs46xx_lib.h3
-rw-r--r--sound/pci/cs46xx/dsp_spos.c170
-rw-r--r--sound/pci/cs5530.c306
-rw-r--r--sound/pci/emu10k1/emu10k1_main.c125
-rw-r--r--sound/pci/emu10k1/emufx.c78
-rw-r--r--sound/pci/emu10k1/emumixer.c16
-rw-r--r--sound/pci/emu10k1/emupcm.c39
-rw-r--r--sound/pci/ens1370.c4
-rw-r--r--sound/pci/hda/hda_intel.c53
-rw-r--r--sound/pci/hda/hda_proc.c6
-rw-r--r--sound/pci/hda/patch_analog.c630
-rw-r--r--sound/pci/hda/patch_atihdmi.c1
-rw-r--r--sound/pci/hda/patch_conexant.c2
-rw-r--r--sound/pci/hda/patch_realtek.c919
-rw-r--r--sound/pci/hda/patch_si3054.c4
-rw-r--r--sound/pci/hda/patch_sigmatel.c266
-rw-r--r--sound/pci/ice1712/revo.c7
-rw-r--r--sound/pci/nm256/nm256.c3
-rw-r--r--sound/pci/rme9652/rme9652.c2
-rw-r--r--sound/pci/via82xx.c4
-rw-r--r--sound/pci/via82xx_modem.c4
-rw-r--r--sound/ppc/Kconfig20
-rw-r--r--sound/ppc/Makefile3
-rw-r--r--sound/ppc/snd_ps3.c1125
-rw-r--r--sound/ppc/snd_ps3.h135
-rw-r--r--sound/ppc/snd_ps3_reg.h891
-rw-r--r--sound/sh/Kconfig14
-rw-r--r--sound/sh/Makefile8
-rw-r--r--sound/sh/aica.c665
-rw-r--r--sound/sh/aica.h81
-rw-r--r--sound/soc/Kconfig1
-rw-r--r--sound/soc/Makefile2
-rw-r--r--sound/soc/s3c24xx/Kconfig27
-rw-r--r--sound/soc/s3c24xx/Makefile9
-rw-r--r--sound/soc/s3c24xx/lm4857.h32
-rw-r--r--sound/soc/s3c24xx/neo1973_wm8753.c670
-rw-r--r--sound/soc/s3c24xx/s3c2443-ac97.c401
-rw-r--r--sound/soc/s3c24xx/s3c24xx-ac97.h25
-rw-r--r--sound/soc/s3c24xx/s3c24xx-i2s.c4
-rw-r--r--sound/soc/s3c24xx/smdk2443_wm9710.c85
-rw-r--r--sound/soc/sh/Kconfig38
-rw-r--r--sound/soc/sh/Makefile14
-rw-r--r--sound/soc/sh/dma-sh7760.c354
-rw-r--r--sound/soc/sh/hac.c322
-rw-r--r--sound/soc/sh/sh7760-ac97.c92
-rw-r--r--sound/soc/sh/ssi.c400
-rw-r--r--sound/usb/usbaudio.c22
-rw-r--r--sound/usb/usbquirks.h72
-rw-r--r--sound/usb/usx2y/usbusx2yaudio.c7
89 files changed, 8426 insertions, 399 deletions
diff --git a/CREDITS b/CREDITS
index 79fd13dbb8e4..10c214dc95e7 100644
--- a/CREDITS
+++ b/CREDITS
@@ -2212,13 +2212,13 @@ S: 2300 Copenhagen S
2212S: Denmark 2212S: Denmark
2213 2213
2214N: Claudio S. Matsuoka 2214N: Claudio S. Matsuoka
2215E: claudio@conectiva.com 2215E: cmatsuoka@gmail.com
2216E: claudio@helllabs.org 2216E: claudio@mandriva.com
2217W: http://helllabs.org/~claudio 2217W: http://helllabs.org/~claudio
2218D: V4L, OV511 driver hacks 2218D: V4L, OV511 and HDA-codec hacks
2219S: Conectiva S.A. 2219S: Conectiva S.A.
2220S: R. Tocantins 89 2220S: Souza Naves 1250
2221S: 80050-430 Curitiba PR 2221S: 80050-040 Curitiba PR
2222S: Brazil 2222S: Brazil
2223 2223
2224N: Heinz Mauelshagen 2224N: Heinz Mauelshagen
diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt
index 355ff0a2bb7c..241e26c4ff92 100644
--- a/Documentation/sound/alsa/ALSA-Configuration.txt
+++ b/Documentation/sound/alsa/ALSA-Configuration.txt
@@ -467,7 +467,12 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
467 above explicitly. 467 above explicitly.
468 468
469 The power-management is supported. 469 The power-management is supported.
470 470
471 Module snd-cs5530
472 _________________
473
474 Module for Cyrix/NatSemi Geode 5530 chip.
475
471 Module snd-cs5535audio 476 Module snd-cs5535audio
472 ---------------------- 477 ----------------------
473 478
@@ -759,6 +764,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
759 764
760 model - force the model name 765 model - force the model name
761 position_fix - Fix DMA pointer (0 = auto, 1 = none, 2 = POSBUF, 3 = FIFO size) 766 position_fix - Fix DMA pointer (0 = auto, 1 = none, 2 = POSBUF, 3 = FIFO size)
767 probe_mask - Bitmask to probe codecs (default = -1, meaning all slots)
762 single_cmd - Use single immediate commands to communicate with 768 single_cmd - Use single immediate commands to communicate with
763 codecs (for debugging only) 769 codecs (for debugging only)
764 enable_msi - Enable Message Signaled Interrupt (MSI) (default = off) 770 enable_msi - Enable Message Signaled Interrupt (MSI) (default = off)
@@ -803,6 +809,8 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
803 hp-3013 HP machines (3013-variant) 809 hp-3013 HP machines (3013-variant)
804 fujitsu Fujitsu S7020 810 fujitsu Fujitsu S7020
805 acer Acer TravelMate 811 acer Acer TravelMate
812 will Will laptops (PB V7900)
813 replacer Replacer 672V
806 basic fixed pin assignment (old default model) 814 basic fixed pin assignment (old default model)
807 auto auto-config reading BIOS (default) 815 auto auto-config reading BIOS (default)
808 816
@@ -811,16 +819,31 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
811 hp-bpc HP xw4400/6400/8400/9400 laptops 819 hp-bpc HP xw4400/6400/8400/9400 laptops
812 hp-bpc-d7000 HP BPC D7000 820 hp-bpc-d7000 HP BPC D7000
813 benq Benq ED8 821 benq Benq ED8
822 benq-t31 Benq T31
814 hippo Hippo (ATI) with jack detection, Sony UX-90s 823 hippo Hippo (ATI) with jack detection, Sony UX-90s
815 hippo_1 Hippo (Benq) with jack detection 824 hippo_1 Hippo (Benq) with jack detection
825 sony-assamd Sony ASSAMD
816 basic fixed pin assignment w/o SPDIF 826 basic fixed pin assignment w/o SPDIF
817 auto auto-config reading BIOS (default) 827 auto auto-config reading BIOS (default)
818 828
829 ALC268
830 3stack 3-stack model
831 auto auto-config reading BIOS (default)
832
833 ALC662
834 3stack-dig 3-stack (2-channel) with SPDIF
835 3stack-6ch 3-stack (6-channel)
836 3stack-6ch-dig 3-stack (6-channel) with SPDIF
837 6stack-dig 6-stack with SPDIF
838 lenovo-101e Lenovo laptop
839 auto auto-config reading BIOS (default)
840
819 ALC882/885 841 ALC882/885
820 3stack-dig 3-jack with SPDIF I/O 842 3stack-dig 3-jack with SPDIF I/O
821 6stack-dig 6-jack digital with SPDIF I/O 843 6stack-dig 6-jack digital with SPDIF I/O
822 arima Arima W820Di1 844 arima Arima W820Di1
823 macpro MacPro support 845 macpro MacPro support
846 imac24 iMac 24'' with jack detection
824 w2jc ASUS W2JC 847 w2jc ASUS W2JC
825 auto auto-config reading BIOS (default) 848 auto auto-config reading BIOS (default)
826 849
@@ -832,9 +855,15 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
832 6stack-dig-demo 6-jack digital for Intel demo board 855 6stack-dig-demo 6-jack digital for Intel demo board
833 acer Acer laptops (Travelmate 3012WTMi, Aspire 5600, etc) 856 acer Acer laptops (Travelmate 3012WTMi, Aspire 5600, etc)
834 medion Medion Laptops 857 medion Medion Laptops
858 medion-md2 Medion MD2
835 targa-dig Targa/MSI 859 targa-dig Targa/MSI
836 targa-2ch-dig Targs/MSI with 2-channel 860 targa-2ch-dig Targs/MSI with 2-channel
837 laptop-eapd 3-jack with SPDIF I/O and EAPD (Clevo M540JE, M550JE) 861 laptop-eapd 3-jack with SPDIF I/O and EAPD (Clevo M540JE, M550JE)
862 lenovo-101e Lenovo 101E
863 lenovo-nb0763 Lenovo NB0763
864 lenovo-ms7195-dig Lenovo MS7195
865 6stack-hp HP machines with 6stack (Nettle boards)
866 3stack-hp HP machines with 3stack (Lucknow, Samba boards)
838 auto auto-config reading BIOS (default) 867 auto auto-config reading BIOS (default)
839 868
840 ALC861/660 869 ALC861/660
@@ -853,7 +882,9 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
853 3stack-dig 3-jack with SPDIF OUT 882 3stack-dig 3-jack with SPDIF OUT
854 6stack-dig 6-jack with SPDIF OUT 883 6stack-dig 6-jack with SPDIF OUT
855 3stack-660 3-jack (for ALC660VD) 884 3stack-660 3-jack (for ALC660VD)
885 3stack-660-digout 3-jack with SPDIF OUT (for ALC660VD)
856 lenovo Lenovo 3000 C200 886 lenovo Lenovo 3000 C200
887 dallas Dallas laptops
857 auto auto-config reading BIOS (default) 888 auto auto-config reading BIOS (default)
858 889
859 CMI9880 890 CMI9880
@@ -864,12 +895,26 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
864 allout 5-jack in back, 2-jack in front, SPDIF out 895 allout 5-jack in back, 2-jack in front, SPDIF out
865 auto auto-config reading BIOS (default) 896 auto auto-config reading BIOS (default)
866 897
898 AD1882
899 3stack 3-stack mode (default)
900 6stack 6-stack mode
901
902 AD1884
903 N/A
904
867 AD1981 905 AD1981
868 basic 3-jack (default) 906 basic 3-jack (default)
869 hp HP nx6320 907 hp HP nx6320
870 thinkpad Lenovo Thinkpad T60/X60/Z60 908 thinkpad Lenovo Thinkpad T60/X60/Z60
871 toshiba Toshiba U205 909 toshiba Toshiba U205
872 910
911 AD1983
912 N/A
913
914 AD1984
915 basic default configuration
916 thinkpad Lenovo Thinkpad T61/X61
917
873 AD1986A 918 AD1986A
874 6stack 6-jack, separate surrounds (default) 919 6stack 6-jack, separate surrounds (default)
875 3stack 3-stack, shared surrounds 920 3stack 3-stack, shared surrounds
@@ -907,11 +952,18 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
907 ref Reference board 952 ref Reference board
908 3stack D945 3stack 953 3stack D945 3stack
909 5stack D945 5stack + SPDIF 954 5stack D945 5stack + SPDIF
910 macmini Intel Mac Mini 955 dell Dell XPS M1210
911 macbook Intel Mac Book 956 intel-mac-v1 Intel Mac Type 1
912 macbook-pro-v1 Intel Mac Book Pro 1st generation 957 intel-mac-v2 Intel Mac Type 2
913 macbook-pro Intel Mac Book Pro 2nd generation 958 intel-mac-v3 Intel Mac Type 3
914 imac-intel Intel iMac 959 intel-mac-v4 Intel Mac Type 4
960 intel-mac-v5 Intel Mac Type 5
961 macmini Intel Mac Mini (equivalent with type 3)
962 macbook Intel Mac Book (eq. type 5)
963 macbook-pro-v1 Intel Mac Book Pro 1st generation (eq. type 3)
964 macbook-pro Intel Mac Book Pro 2nd generation (eq. type 3)
965 imac-intel Intel iMac (eq. type 2)
966 imac-intel-20 Intel iMac (newer version) (eq. type 3)
915 967
916 STAC9202/9250/9251 968 STAC9202/9250/9251
917 ref Reference board, base config 969 ref Reference board, base config
@@ -956,6 +1008,17 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
956 from the irq. Remember this is a last resort, and should be 1008 from the irq. Remember this is a last resort, and should be
957 avoided as much as possible... 1009 avoided as much as possible...
958 1010
1011 MORE NOTES ON "azx_get_response timeout" PROBLEMS:
1012 On some hardwares, you may need to add a proper probe_mask option
1013 to avoid the "azx_get_response timeout" problem above, instead.
1014 This occurs when the access to non-existing or non-working codec slot
1015 (likely a modem one) causes a stall of the communication via HD-audio
1016 bus. You can see which codec slots are probed by enabling
1017 CONFIG_SND_DEBUG_DETECT, or simply from the file name of the codec
1018 proc files. Then limit the slots to probe by probe_mask option.
1019 For example, probe_mask=1 means to probe only the first slot, and
1020 probe_mask=4 means only the third slot.
1021
959 The power-management is supported. 1022 The power-management is supported.
960 1023
961 Module snd-hdsp 1024 Module snd-hdsp
diff --git a/Documentation/sound/alsa/Audiophile-Usb.txt b/Documentation/sound/alsa/Audiophile-Usb.txt
index e40cce83327c..2ad5e6306c44 100644
--- a/Documentation/sound/alsa/Audiophile-Usb.txt
+++ b/Documentation/sound/alsa/Audiophile-Usb.txt
@@ -1,4 +1,4 @@
1 Guide to using M-Audio Audiophile USB with ALSA and Jack v1.3 1 Guide to using M-Audio Audiophile USB with ALSA and Jack v1.5
2 ======================================================== 2 ========================================================
3 3
4 Thibault Le Meur <Thibault.LeMeur@supelec.fr> 4 Thibault Le Meur <Thibault.LeMeur@supelec.fr>
@@ -6,8 +6,19 @@
6This document is a guide to using the M-Audio Audiophile USB (tm) device with 6This document is a guide to using the M-Audio Audiophile USB (tm) device with
7ALSA and JACK. 7ALSA and JACK.
8 8
9History
10=======
11* v1.4 - Thibault Le Meur (2007-07-11)
12 - Added Low Endianness nature of 16bits-modes
13 found by Hakan Lennestal <Hakan.Lennestal@brfsodrahamn.se>
14 - Modifying document structure
15* v1.5 - Thibault Le Meur (2007-07-12)
16 - Added AC3/DTS passthru info
17
18
91 - Audiophile USB Specs and correct usage 191 - Audiophile USB Specs and correct usage
10========================================== 20==========================================
21
11This part is a reminder of important facts about the functions and limitations 22This part is a reminder of important facts about the functions and limitations
12of the device. 23of the device.
13 24
@@ -25,18 +36,18 @@ The device has 4 audio interfaces, and 2 MIDI ports:
25The internal DAC/ADC has the following characteristics: 36The internal DAC/ADC has the following characteristics:
26* sample depth of 16 or 24 bits 37* sample depth of 16 or 24 bits
27* sample rate from 8kHz to 96kHz 38* sample rate from 8kHz to 96kHz
28* Two ports can't use different sample depths at the same time. Moreover, the 39* Two interfaces can't use different sample depths at the same time.
29Audiophile USB documentation gives the following Warning: "Please exit any 40Moreover, the Audiophile USB documentation gives the following Warning:
30audio application running before switching between bit depths" 41"Please exit any audio application running before switching between bit depths"
31 42
32Due to the USB 1.1 bandwidth limitation, a limited number of interfaces can be 43Due to the USB 1.1 bandwidth limitation, a limited number of interfaces can be
33activated at the same time depending on the audio mode selected: 44activated at the same time depending on the audio mode selected:
34 * 16-bit/48kHz ==> 4 channels in/4 channels out 45 * 16-bit/48kHz ==> 4 channels in + 4 channels out
35 - Ai+Ao+Di+Do 46 - Ai+Ao+Di+Do
36 * 24-bit/48kHz ==> 4 channels in/2 channels out, 47 * 24-bit/48kHz ==> 4 channels in + 2 channels out,
37 or 2 channels in/4 channels out 48 or 2 channels in + 4 channels out
38 - Ai+Ao+Do or Ai+Di+Ao or Ai+Di+Do or Di+Ao+Do 49 - Ai+Ao+Do or Ai+Di+Ao or Ai+Di+Do or Di+Ao+Do
39 * 24-bit/96kHz ==> 2 channels in, or 2 channels out (half duplex only) 50 * 24-bit/96kHz ==> 2 channels in _or_ 2 channels out (half duplex only)
40 - Ai or Ao or Di or Do 51 - Ai or Ao or Di or Do
41 52
42Important facts about the Digital interface: 53Important facts about the Digital interface:
@@ -52,44 +63,56 @@ source is connected
52synchronization error (for instance sound played at an odd sample rate) 63synchronization error (for instance sound played at an odd sample rate)
53 64
54 65
552 - Audiophile USB support in ALSA 662 - Audiophile USB MIDI support in ALSA
56================================== 67=======================================
57 68
582.1 - MIDI ports 69The Audiophile USB MIDI ports will be automatically supported once the
59----------------
60The Audiophile USB MIDI ports will be automatically supported once the
61following modules have been loaded: 70following modules have been loaded:
62 * snd-usb-audio 71 * snd-usb-audio
63 * snd-seq-midi 72 * snd-seq-midi
64 73
65No additional setting is required. 74No additional setting is required.
66 75
672.2 - Audio ports 76
68----------------- 773 - Audiophile USB Audio support in ALSA
78========================================
69 79
70Audio functions of the Audiophile USB device are handled by the snd-usb-audio 80Audio functions of the Audiophile USB device are handled by the snd-usb-audio
71module. This module can work in a default mode (without any device-specific 81module. This module can work in a default mode (without any device-specific
72parameter), or in an "advanced" mode with the device-specific parameter called 82parameter), or in an "advanced" mode with the device-specific parameter called
73"device_setup". 83"device_setup".
74 84
752.2.1 - Default Alsa driver mode 853.1 - Default Alsa driver mode
76 86------------------------------
77The default behavior of the snd-usb-audio driver is to parse the device 87
78capabilities at startup and enable all functions inside the device (including 88The default behavior of the snd-usb-audio driver is to list the device
79all ports at any supported sample rates and sample depths). This approach 89capabilities at startup and activate the required mode when required
80has the advantage to let the driver easily switch from sample rates/depths 90by the applications: for instance if the user is recording in a
81automatically according to the need of the application claiming the device. 9124bit-depth-mode and immediately after wants to switch to a 16bit-depth mode,
82 92the snd-usb-audio module will reconfigure the device on the fly.
83In this case the Audiophile ports are mapped to alsa pcm devices in the 93
84following way (I suppose the device's index is 1): 94This approach has the advantage to let the driver automatically switch from sample
95rates/depths automatically according to the user's needs. However, those who
96are using the device under windows know that this is not how the device is meant to
97work: under windows applications must be closed before using the m-audio control
98panel to switch the device working mode. Thus as we'll see in next section, this
99Default Alsa driver mode can lead to device misconfigurations.
100
101Let's get back to the Default Alsa driver mode for now. In this case the
102Audiophile interfaces are mapped to alsa pcm devices in the following
103way (I suppose the device's index is 1):
85 * hw:1,0 is Ao in playback and Di in capture 104 * hw:1,0 is Ao in playback and Di in capture
86 * hw:1,1 is Do in playback and Ai in capture 105 * hw:1,1 is Do in playback and Ai in capture
87 * hw:1,2 is Do in AC3/DTS passthrough mode 106 * hw:1,2 is Do in AC3/DTS passthrough mode
88 107
89You must note as well that the device uses Big Endian byte encoding so that 108In this mode, the device uses Big Endian byte-encoding so that
90supported audio format are S16_BE for 16-bit depth modes and S24_3BE for 109supported audio format are S16_BE for 16-bit depth modes and S24_3BE for
9124-bits depth mode. One exception is the hw:1,2 port which is Little Endian 11024-bits depth mode.
92compliant and thus uses S16_LE. 111
112One exception is the hw:1,2 port which was reported to be Little Endian
113compliant (supposedly supporting S16_LE) but processes in fact only S16_BE streams.
114This has been fixed in kernel 2.6.23 and above and now the hw:1,2 interface
115is reported to be big endian in this default driver mode.
93 116
94Examples: 117Examples:
95 * playing a S24_3BE encoded raw file to the Ao port 118 * playing a S24_3BE encoded raw file to the Ao port
@@ -98,22 +121,26 @@ Examples:
98 % arecord -D hw:1,1 -c2 -t raw -r48000 -fS24_3BE test.raw 121 % arecord -D hw:1,1 -c2 -t raw -r48000 -fS24_3BE test.raw
99 * playing a S16_BE encoded raw file to the Do port 122 * playing a S16_BE encoded raw file to the Do port
100 % aplay -D hw:1,1 -c2 -t raw -r48000 -fS16_BE test.raw 123 % aplay -D hw:1,1 -c2 -t raw -r48000 -fS16_BE test.raw
124 * playing an ac3 sample file to the Do port
125 % aplay -D hw:1,2 --channels=6 ac3_S16_BE_encoded_file.raw
101 126
102If you're happy with the default Alsa driver setup and don't experience any 127If you're happy with the default Alsa driver mode and don't experience any
103issue with this mode, then you can skip the following chapter. 128issue with this mode, then you can skip the following chapter.
104 129
1052.2.2 - Advanced module setup 1303.2 - Advanced module setup
131---------------------------
106 132
107Due to the hardware constraints described above, the device initialization made 133Due to the hardware constraints described above, the device initialization made
108by the Alsa driver in default mode may result in a corrupted state of the 134by the Alsa driver in default mode may result in a corrupted state of the
109device. For instance, a particularly annoying issue is that the sound captured 135device. For instance, a particularly annoying issue is that the sound captured
110from the Ai port sounds distorted (as if boosted with an excessive high volume 136from the Ai interface sounds distorted (as if boosted with an excessive high
111gain). 137volume gain).
112 138
113For people having this problem, the snd-usb-audio module has a new module 139For people having this problem, the snd-usb-audio module has a new module
114parameter called "device_setup". 140parameter called "device_setup" (this parameter was introduced in kernel
141release 2.6.17)
115 142
1162.2.2.1 - Initializing the working mode of the Audiophile USB 1433.2.1 - Initializing the working mode of the Audiophile USB
117 144
118As far as the Audiophile USB device is concerned, this value let the user 145As far as the Audiophile USB device is concerned, this value let the user
119specify: 146specify:
@@ -121,33 +148,57 @@ specify:
121 * the sample rate 148 * the sample rate
122 * whether the Di port is used or not 149 * whether the Di port is used or not
123 150
124Here is a list of supported device_setup values for this device: 151When initialized with "device_setup=0x00", the snd-usb-audio module has
125 * device_setup=0x00 (or omitted) 152the same behaviour as when the parameter is omitted (see paragraph "Default
126 - Alsa driver default mode 153Alsa driver mode" above)
127 - maintains backward compatibility with setups that do not use this 154
128 parameter by not introducing any change 155Others modes are described in the following subsections.
129 - results sometimes in corrupted sound as described earlier 156
1573.2.1.1 - 16-bit modes
158
159The two supported modes are:
160
130 * device_setup=0x01 161 * device_setup=0x01
131 - 16bits 48kHz mode with Di disabled 162 - 16bits 48kHz mode with Di disabled
132 - Ai,Ao,Do can be used at the same time 163 - Ai,Ao,Do can be used at the same time
133 - hw:1,0 is not available in capture mode 164 - hw:1,0 is not available in capture mode
134 - hw:1,2 is not available 165 - hw:1,2 is not available
166
135 * device_setup=0x11 167 * device_setup=0x11
136 - 16bits 48kHz mode with Di enabled 168 - 16bits 48kHz mode with Di enabled
137 - Ai,Ao,Di,Do can be used at the same time 169 - Ai,Ao,Di,Do can be used at the same time
138 - hw:1,0 is available in capture mode 170 - hw:1,0 is available in capture mode
139 - hw:1,2 is not available 171 - hw:1,2 is not available
172
173In this modes the device operates only at 16bits-modes. Before kernel 2.6.23,
174the devices where reported to be Big-Endian when in fact they were Little-Endian
175so that playing a file was a matter of using:
176 % aplay -D hw:1,1 -c2 -t raw -r48000 -fS16_BE test_S16_LE.raw
177where "test_S16_LE.raw" was in fact a little-endian sample file.
178
179Thanks to Hakan Lennestal (who discovered the Little-Endiannes of the device in
180these modes) a fix has been committed (expected in kernel 2.6.23) and
181Alsa now reports Little-Endian interfaces. Thus playing a file now is as simple as
182using:
183 % aplay -D hw:1,1 -c2 -t raw -r48000 -fS16_LE test_S16_LE.raw
184
1853.2.1.2 - 24-bit modes
186
187The three supported modes are:
188
140 * device_setup=0x09 189 * device_setup=0x09
141 - 24bits 48kHz mode with Di disabled 190 - 24bits 48kHz mode with Di disabled
142 - Ai,Ao,Do can be used at the same time 191 - Ai,Ao,Do can be used at the same time
143 - hw:1,0 is not available in capture mode 192 - hw:1,0 is not available in capture mode
144 - hw:1,2 is not available 193 - hw:1,2 is not available
194
145 * device_setup=0x19 195 * device_setup=0x19
146 - 24bits 48kHz mode with Di enabled 196 - 24bits 48kHz mode with Di enabled
147 - 3 ports from {Ai,Ao,Di,Do} can be used at the same time 197 - 3 ports from {Ai,Ao,Di,Do} can be used at the same time
148 - hw:1,0 is available in capture mode and an active digital source must be 198 - hw:1,0 is available in capture mode and an active digital source must be
149 connected to Di 199 connected to Di
150 - hw:1,2 is not available 200 - hw:1,2 is not available
201
151 * device_setup=0x0D or 0x10 202 * device_setup=0x0D or 0x10
152 - 24bits 96kHz mode 203 - 24bits 96kHz mode
153 - Di is enabled by default for this mode but does not need to be connected 204 - Di is enabled by default for this mode but does not need to be connected
@@ -155,34 +206,64 @@ Here is a list of supported device_setup values for this device:
155 - Only 1 port from {Ai,Ao,Di,Do} can be used at the same time 206 - Only 1 port from {Ai,Ao,Di,Do} can be used at the same time
156 - hw:1,0 is available in captured mode 207 - hw:1,0 is available in captured mode
157 - hw:1,2 is not available 208 - hw:1,2 is not available
209
210In these modes the device is only Big-Endian compliant (see "Default Alsa driver
211mode" above for an aplay command example)
212
2133.2.1.3 - AC3 w/ DTS passthru mode
214
215Thanks to Hakan Lennestal, I now have a report saying that this mode works.
216
158 * device_setup=0x03 217 * device_setup=0x03
159 - 16bits 48kHz mode with only the Do port enabled 218 - 16bits 48kHz mode with only the Do port enabled
160 - AC3 with DTS passthru (not tested) 219 - AC3 with DTS passthru
161 - Caution with this setup the Do port is mapped to the pcm device hw:1,0 220 - Caution with this setup the Do port is mapped to the pcm device hw:1,0
162 221
1632.2.2.2 - Setting and switching configurations with the device_setup parameter 222The command line used to playback the AC3/DTS encoded .wav-files in this mode:
223 % aplay -D hw:1,0 --channels=6 ac3_S16_LE_encoded_file.raw
224
2253.2.2 - How to use the device_setup parameter
226----------------------------------------------
164 227
165The parameter can be given: 228The parameter can be given:
229
166 * By manually probing the device (as root): 230 * By manually probing the device (as root):
167 # modprobe -r snd-usb-audio 231 # modprobe -r snd-usb-audio
168 # modprobe snd-usb-audio index=1 device_setup=0x09 232 # modprobe snd-usb-audio index=1 device_setup=0x09
233
169 * Or while configuring the modules options in your modules configuration file 234 * Or while configuring the modules options in your modules configuration file
170 - For Fedora distributions, edit the /etc/modprobe.conf file: 235 - For Fedora distributions, edit the /etc/modprobe.conf file:
171 alias snd-card-1 snd-usb-audio 236 alias snd-card-1 snd-usb-audio
172 options snd-usb-audio index=1 device_setup=0x09 237 options snd-usb-audio index=1 device_setup=0x09
173 238
174IMPORTANT NOTE WHEN SWITCHING CONFIGURATION: 239CAUTION when initializaing the device
175------------------------------------------- 240-------------------------------------
176 * You may need to _first_ initialize the module with the correct device_setup 241
177 parameter and _only_after_ turn on the Audiophile USB device 242 * Correct initialization on the device requires that device_setup is given to
178 * This is especially true when switching the sample depth: 243 the module BEFORE the device is turned on. So, if you use the "manual probing"
244 method described above, take care to power-on the device AFTER this initialization.
245
246 * Failing to respect this will lead in a misconfiguration of the device. In this case
247 turn off the device, unproble the snd-usb-audio module, then probe it again with
248 correct device_setup parameter and then (and only then) turn on the device again.
249
250 * If you've correctly initialized the device in a valid mode and then want to switch
251 to another mode (possibly with another sample-depth), please use also the following
252 procedure:
179 - first turn off the device 253 - first turn off the device
180 - de-register the snd-usb-audio module (modprobe -r) 254 - de-register the snd-usb-audio module (modprobe -r)
181 - change the device_setup parameter by changing the device_setup 255 - change the device_setup parameter by changing the device_setup
182 option in /etc/modprobe.conf 256 option in /etc/modprobe.conf
183 - turn on the device 257 - turn on the device
258 * A workaround for this last issue has been applied to kernel 2.6.23, but it may not
259 be enough to ensure the 'stability' of the device initialization.
184 260
1852.2.2.3 - Audiophile USB's device_setup structure 2613.2.3 - Technical details for hackers
262-------------------------------------
263This section is for hackers, wanting to understand details about the device
264internals and how Alsa supports it.
265
2663.2.3.1 - Audiophile USB's device_setup structure
186 267
187If you want to understand the device_setup magic numbers for the Audiophile 268If you want to understand the device_setup magic numbers for the Audiophile
188USB, you need some very basic understanding of binary computation. However, 269USB, you need some very basic understanding of binary computation. However,
@@ -228,12 +309,12 @@ Caution:
228 - choosing b2 will prepare all interfaces for 24bits/96kHz but you'll 309 - choosing b2 will prepare all interfaces for 24bits/96kHz but you'll
229 only be able to use one at the same time 310 only be able to use one at the same time
230 311
2312.2.3 - USB implementation details for this device 3123.2.3.2 - USB implementation details for this device
232 313
233You may safely skip this section if you're not interested in driver 314You may safely skip this section if you're not interested in driver
234development. 315hacking.
235 316
236This section describes some internal aspects of the device and summarize the 317This section describes some internal aspects of the device and summarizes the
237data I got by usb-snooping the windows and Linux drivers. 318data I got by usb-snooping the windows and Linux drivers.
238 319
239The M-Audio Audiophile USB has 7 USB Interfaces: 320The M-Audio Audiophile USB has 7 USB Interfaces:
@@ -293,43 +374,45 @@ parse_audio_endpoints function uses a quirk called
293"audiophile_skip_setting_quirk" in order to prevent AltSettings not 374"audiophile_skip_setting_quirk" in order to prevent AltSettings not
294corresponding to device_setup from being registered in the driver. 375corresponding to device_setup from being registered in the driver.
295 376
2963 - Audiophile USB and Jack support 3774 - Audiophile USB and Jack support
297=================================== 378===================================
298 379
299This section deals with support of the Audiophile USB device in Jack. 380This section deals with support of the Audiophile USB device in Jack.
300The main issue regarding this support is that the device is Big Endian
301compliant.
302 381
3033.1 - Using the plug alsa plugin 382There are 2 main potential issues when using Jackd with the device:
304-------------------------------- 383* support for Big-Endian devices in 24-bit modes
384* support for 4-in / 4-out channels
385
3864.1 - Direct support in Jackd
387-----------------------------
305 388
306Jack doesn't directly support big endian devices. Thus, one way to have support 389Jack supports big endian devices only in recent versions (thanks to
307for this device with Alsa is to use the Alsa "plug" converter. 390Andreas Steinmetz for his first big-endian patch). I can't remember
391extacly when this support was released into jackd, let's just say that
392with jackd version 0.103.0 it's almost ok (just a small bug is affecting
39316bits Big-Endian devices, but since you've read carefully the above
394paragraphs, you're now using kernel >= 2.6.23 and your 16bits devices
395are now Little Endians ;-) ).
396
397You can run jackd with the following command for playback with Ao and
398record with Ai:
399 % jackd -R -dalsa -Phw:1,0 -r48000 -p128 -n2 -D -Chw:1,1
400
4014.2 - Using Alsa plughw
402-----------------------
403If you don't have a recent Jackd installed, you can downgrade to using
404the Alsa "plug" converter.
308 405
309For instance here is one way to run Jack with 2 playback channels on Ao and 2 406For instance here is one way to run Jack with 2 playback channels on Ao and 2
310capture channels from Ai: 407capture channels from Ai:
311 % jackd -R -dalsa -dplughw:1 -r48000 -p256 -n2 -D -Cplughw:1,1 408 % jackd -R -dalsa -dplughw:1 -r48000 -p256 -n2 -D -Cplughw:1,1
312 409
313
314However you may see the following warning message: 410However you may see the following warning message:
315"You appear to be using the ALSA software "plug" layer, probably a result of 411"You appear to be using the ALSA software "plug" layer, probably a result of
316using the "default" ALSA device. This is less efficient than it could be. 412using the "default" ALSA device. This is less efficient than it could be.
317Consider using a hardware device instead rather than using the plug layer." 413Consider using a hardware device instead rather than using the plug layer."
318 414
3193.2 - Patching alsa to use direct pcm device 4154.3 - Getting 2 input and/or output interfaces in Jack
320--------------------------------------------
321A patch for Jack by Andreas Steinmetz adds support for Big Endian devices.
322However it has not been included in the CVS tree.
323
324You can find it at the following URL:
325http://sourceforge.net/tracker/index.php?func=detail&aid=1289682&group_id=39687&
326atid=425939
327
328After having applied the patch you can run jackd with the following command
329line:
330 % jackd -R -dalsa -Phw:1,0 -r48000 -p128 -n2 -D -Chw:1,1
331
3323.2 - Getting 2 input and/or output interfaces in Jack
333------------------------------------------------------ 416------------------------------------------------------
334 417
335As you can see, starting the Jack server this way will only enable 1 stereo 418As you can see, starting the Jack server this way will only enable 1 stereo
@@ -339,6 +422,7 @@ This is due to the following restrictions:
339* Jack can only open one capture device and one playback device at a time 422* Jack can only open one capture device and one playback device at a time
340* The Audiophile USB is seen as 2 (or three) Alsa devices: hw:1,0, hw:1,1 423* The Audiophile USB is seen as 2 (or three) Alsa devices: hw:1,0, hw:1,1
341 (and optionally hw:1,2) 424 (and optionally hw:1,2)
425
342If you want to get Ai+Di and/or Ao+Do support with Jack, you would need to 426If you want to get Ai+Di and/or Ao+Do support with Jack, you would need to
343combine the Alsa devices into one logical "complex" device. 427combine the Alsa devices into one logical "complex" device.
344 428
@@ -348,13 +432,11 @@ It is related to another device (ice1712) but can be adapted to suit
348the Audiophile USB. 432the Audiophile USB.
349 433
350Enabling multiple Audiophile USB interfaces for Jackd will certainly require: 434Enabling multiple Audiophile USB interfaces for Jackd will certainly require:
351* patching Jack with the previously mentioned "Big Endian" patch 435* Making sure your Jackd version has the MMAP_COMPLEX patch (see the ice1712 page)
352* patching Jackd with the MMAP_COMPLEX patch (see the ice1712 page) 436* (maybe) patching the alsa-lib/src/pcm/pcm_multi.c file (see the ice1712 page)
353* patching the alsa-lib/src/pcm/pcm_multi.c file (see the ice1712 page)
354* define a multi device (combination of hw:1,0 and hw:1,1) in your .asoundrc 437* define a multi device (combination of hw:1,0 and hw:1,1) in your .asoundrc
355 file 438 file
356* start jackd with this device 439* start jackd with this device
357 440
358I had no success in testing this for now, but this may be due to my OS 441I had no success in testing this for now, if you have any success with this kind
359configuration. If you have any success with this kind of setup, please 442of setup, please drop me an email.
360drop me an email.
diff --git a/Documentation/sound/alsa/OSS-Emulation.txt b/Documentation/sound/alsa/OSS-Emulation.txt
index ec2a02541d5b..bfa0c9aacb4b 100644
--- a/Documentation/sound/alsa/OSS-Emulation.txt
+++ b/Documentation/sound/alsa/OSS-Emulation.txt
@@ -278,6 +278,21 @@ current mixer configuration by reading and writing the whole file
278image. 278image.
279 279
280 280
281Duplex Streams
282==============
283
284Note that when attempting to use a single device file for playback and
285capture, the OSS API provides no way to set the format, sample rate or
286number of channels different in each direction. Thus
287 io_handle = open("device", O_RDWR)
288will only function correctly if the values are the same in each direction.
289
290To use different values in the two directions, use both
291 input_handle = open("device", O_RDONLY)
292 output_handle = open("device", O_WRONLY)
293and set the values for the corresponding handle.
294
295
281Unsupported Features 296Unsupported Features
282==================== 297====================
283 298
diff --git a/include/linux/i2c-id.h b/include/linux/i2c-id.h
index aa83d4163096..b69014865714 100644
--- a/include/linux/i2c-id.h
+++ b/include/linux/i2c-id.h
@@ -115,9 +115,10 @@
115#define I2C_DRIVERID_KS0127 86 /* Samsung ks0127 video decoder */ 115#define I2C_DRIVERID_KS0127 86 /* Samsung ks0127 video decoder */
116#define I2C_DRIVERID_TLV320AIC23B 87 /* TI TLV320AIC23B audio codec */ 116#define I2C_DRIVERID_TLV320AIC23B 87 /* TI TLV320AIC23B audio codec */
117#define I2C_DRIVERID_ISL1208 88 /* Intersil ISL1208 RTC */ 117#define I2C_DRIVERID_ISL1208 88 /* Intersil ISL1208 RTC */
118#define I2C_DRIVERID_WM8731 89 /* Wolfson WM8731 audio codec */ 118#define I2C_DRIVERID_WM8731 89 /* Wolfson WM8731 audio codec */
119#define I2C_DRIVERID_WM8750 90 /* Wolfson WM8750 audio codec */ 119#define I2C_DRIVERID_WM8750 90 /* Wolfson WM8750 audio codec */
120#define I2C_DRIVERID_WM8753 91 /* Wolfson WM8753 audio codec */ 120#define I2C_DRIVERID_WM8753 91 /* Wolfson WM8753 audio codec */
121#define I2C_DRIVERID_LM4857 92 /* LM4857 Audio Amplifier */
121 122
122#define I2C_DRIVERID_I2CDEV 900 123#define I2C_DRIVERID_I2CDEV 900
123#define I2C_DRIVERID_ARP 902 /* SMBus ARP Client */ 124#define I2C_DRIVERID_ARP 902 /* SMBus ARP Client */
diff --git a/include/sound/ak4xxx-adda.h b/include/sound/ak4xxx-adda.h
index aa49dda4f410..fd0a6c46f497 100644
--- a/include/sound/ak4xxx-adda.h
+++ b/include/sound/ak4xxx-adda.h
@@ -43,6 +43,7 @@ struct snd_ak4xxx_ops {
43struct snd_akm4xxx_dac_channel { 43struct snd_akm4xxx_dac_channel {
44 char *name; /* mixer volume name */ 44 char *name; /* mixer volume name */
45 unsigned int num_channels; 45 unsigned int num_channels;
46 char *switch_name; /* mixer switch*/
46}; 47};
47 48
48/* ADC labels and channels */ 49/* ADC labels and channels */
diff --git a/include/sound/cs46xx.h b/include/sound/cs46xx.h
index 685928e6f65a..353910ce9755 100644
--- a/include/sound/cs46xx.h
+++ b/include/sound/cs46xx.h
@@ -1723,6 +1723,10 @@ struct snd_cs46xx {
1723 struct snd_cs46xx_pcm *playback_pcm; 1723 struct snd_cs46xx_pcm *playback_pcm;
1724 unsigned int play_ctl; 1724 unsigned int play_ctl;
1725#endif 1725#endif
1726
1727#ifdef CONFIG_PM
1728 u32 *saved_regs;
1729#endif
1726}; 1730};
1727 1731
1728int snd_cs46xx_create(struct snd_card *card, 1732int snd_cs46xx_create(struct snd_card *card,
diff --git a/include/sound/cs46xx_dsp_spos.h b/include/sound/cs46xx_dsp_spos.h
index da934def31e9..d9da9e59cf37 100644
--- a/include/sound/cs46xx_dsp_spos.h
+++ b/include/sound/cs46xx_dsp_spos.h
@@ -107,6 +107,7 @@ struct dsp_scb_descriptor {
107 char scb_name[DSP_MAX_SCB_NAME]; 107 char scb_name[DSP_MAX_SCB_NAME];
108 u32 address; 108 u32 address;
109 int index; 109 int index;
110 u32 *data;
110 111
111 struct dsp_scb_descriptor * sub_list_ptr; 112 struct dsp_scb_descriptor * sub_list_ptr;
112 struct dsp_scb_descriptor * next_scb_ptr; 113 struct dsp_scb_descriptor * next_scb_ptr;
@@ -127,6 +128,7 @@ struct dsp_task_descriptor {
127 int size; 128 int size;
128 u32 address; 129 u32 address;
129 int index; 130 int index;
131 u32 *data;
130}; 132};
131 133
132struct dsp_pcm_channel_descriptor { 134struct dsp_pcm_channel_descriptor {
diff --git a/include/sound/emu10k1.h b/include/sound/emu10k1.h
index 23e45a4cf0e4..529d0a564367 100644
--- a/include/sound/emu10k1.h
+++ b/include/sound/emu10k1.h
@@ -1120,6 +1120,16 @@
1120/************************************************************************************************/ 1120/************************************************************************************************/
1121/* EMU1010m HANA Destinations */ 1121/* EMU1010m HANA Destinations */
1122/************************************************************************************************/ 1122/************************************************************************************************/
1123/* 32-bit destinations of signal in the Hana FPGA. Destinations are either
1124 * physical outputs of Hana, or outputs going to Alice2 (audigy) for capture
1125 * - 16 x EMU_DST_ALICE2_EMU32_X.
1126 */
1127/* EMU32 = 32-bit serial channel between Alice2 (audigy) and Hana (FPGA) */
1128/* EMU_DST_ALICE2_EMU32_X - data channels from Hana to Alice2 used for capture.
1129 * Which data is fed into a EMU_DST_ALICE2_EMU32_X channel in Hana depends on
1130 * setup of mixer control for each destination - see emumixer.c -
1131 * snd_emu1010_output_enum_ctls[], snd_emu1010_input_enum_ctls[]
1132 */
1123#define EMU_DST_ALICE2_EMU32_0 0x000f /* 16 EMU32 channels to Alice2 +0 to +0xf */ 1133#define EMU_DST_ALICE2_EMU32_0 0x000f /* 16 EMU32 channels to Alice2 +0 to +0xf */
1124#define EMU_DST_ALICE2_EMU32_1 0x0000 /* 16 EMU32 channels to Alice2 +0 to +0xf */ 1134#define EMU_DST_ALICE2_EMU32_1 0x0000 /* 16 EMU32 channels to Alice2 +0 to +0xf */
1125#define EMU_DST_ALICE2_EMU32_2 0x0001 /* 16 EMU32 channels to Alice2 +0 to +0xf */ 1135#define EMU_DST_ALICE2_EMU32_2 0x0001 /* 16 EMU32 channels to Alice2 +0 to +0xf */
@@ -1199,6 +1209,12 @@
1199/************************************************************************************************/ 1209/************************************************************************************************/
1200/* EMU1010m HANA Sources */ 1210/* EMU1010m HANA Sources */
1201/************************************************************************************************/ 1211/************************************************************************************************/
1212/* 32-bit sources of signal in the Hana FPGA. The sources are routed to
1213 * destinations using mixer control for each destination - see emumixer.c
1214 * Sources are either physical inputs of FPGA,
1215 * or outputs from Alice (audigy) - 16 x EMU_SRC_ALICE_EMU32A +
1216 * 16 x EMU_SRC_ALICE_EMU32B
1217 */
1202#define EMU_SRC_SILENCE 0x0000 /* Silence */ 1218#define EMU_SRC_SILENCE 0x0000 /* Silence */
1203#define EMU_SRC_DOCK_MIC_A1 0x0100 /* Audio Dock Mic A, 1st or 48kHz only */ 1219#define EMU_SRC_DOCK_MIC_A1 0x0100 /* Audio Dock Mic A, 1st or 48kHz only */
1204#define EMU_SRC_DOCK_MIC_A2 0x0101 /* Audio Dock Mic A, 2nd or 96kHz */ 1220#define EMU_SRC_DOCK_MIC_A2 0x0101 /* Audio Dock Mic A, 2nd or 96kHz */
diff --git a/include/sound/sb.h b/include/sound/sb.h
index 2dd5c8e5b4fe..3ad854b397d2 100644
--- a/include/sound/sb.h
+++ b/include/sound/sb.h
@@ -38,6 +38,7 @@ enum sb_hw_type {
38 SB_HW_ALS100, /* Avance Logic ALS100 chip */ 38 SB_HW_ALS100, /* Avance Logic ALS100 chip */
39 SB_HW_ALS4000, /* Avance Logic ALS4000 chip */ 39 SB_HW_ALS4000, /* Avance Logic ALS4000 chip */
40 SB_HW_DT019X, /* Diamond Tech. DT-019X / Avance Logic ALS-007 */ 40 SB_HW_DT019X, /* Diamond Tech. DT-019X / Avance Logic ALS-007 */
41 SB_HW_CS5530, /* Cyrix/NatSemi 5530 VSA1 */
41}; 42};
42 43
43#define SB_OPEN_PCM 0x01 44#define SB_OPEN_PCM 0x01
diff --git a/include/sound/version.h b/include/sound/version.h
index 8e5b2f0f5946..6bbcfefd2c38 100644
--- a/include/sound/version.h
+++ b/include/sound/version.h
@@ -1,3 +1,3 @@
1/* include/version.h. Generated by alsa/ksync script. */ 1/* include/version.h. Generated by alsa/ksync script. */
2#define CONFIG_SND_VERSION "1.0.14" 2#define CONFIG_SND_VERSION "1.0.14"
3#define CONFIG_SND_DATE " (Thu May 31 09:03:25 2007 UTC)" 3#define CONFIG_SND_DATE " (Fri Jul 20 09:12:58 2007 UTC)"
diff --git a/include/sound/wavefront_fx.h b/include/sound/wavefront_fx.h
deleted file mode 100644
index cec92b141796..000000000000
--- a/include/sound/wavefront_fx.h
+++ /dev/null
@@ -1,9 +0,0 @@
1#ifndef __SOUND_WAVEFRONT_FX_H
2#define __SOUND_WAVEFRONT_FX_H
3
4extern int snd_wavefront_fx_detect (snd_wavefront_t *);
5extern void snd_wavefront_fx_ioctl (snd_synth_t *sdev,
6 unsigned int cmd,
7 unsigned long arg);
8
9#endif __SOUND_WAVEFRONT_FX_H
diff --git a/sound/Kconfig b/sound/Kconfig
index 9ea473823418..e48b9b37d228 100644
--- a/sound/Kconfig
+++ b/sound/Kconfig
@@ -65,6 +65,8 @@ source "sound/arm/Kconfig"
65 65
66source "sound/mips/Kconfig" 66source "sound/mips/Kconfig"
67 67
68source "sound/sh/Kconfig"
69
68# the following will depend on the order of config. 70# the following will depend on the order of config.
69# here assuming USB is defined before ALSA 71# here assuming USB is defined before ALSA
70source "sound/usb/Kconfig" 72source "sound/usb/Kconfig"
diff --git a/sound/Makefile b/sound/Makefile
index b7c7fb7c24c8..3ead922bd9c6 100644
--- a/sound/Makefile
+++ b/sound/Makefile
@@ -5,7 +5,7 @@ obj-$(CONFIG_SOUND) += soundcore.o
5obj-$(CONFIG_SOUND_PRIME) += sound_firmware.o 5obj-$(CONFIG_SOUND_PRIME) += sound_firmware.o
6obj-$(CONFIG_SOUND_PRIME) += oss/ 6obj-$(CONFIG_SOUND_PRIME) += oss/
7obj-$(CONFIG_DMASOUND) += oss/ 7obj-$(CONFIG_DMASOUND) += oss/
8obj-$(CONFIG_SND) += core/ i2c/ drivers/ isa/ pci/ ppc/ arm/ synth/ usb/ sparc/ parisc/ pcmcia/ mips/ soc/ 8obj-$(CONFIG_SND) += core/ i2c/ drivers/ isa/ pci/ ppc/ arm/ sh/ synth/ usb/ sparc/ parisc/ pcmcia/ mips/ soc/
9obj-$(CONFIG_SND_AOA) += aoa/ 9obj-$(CONFIG_SND_AOA) += aoa/
10 10
11# This one must be compilable even if sound is configured out 11# This one must be compilable even if sound is configured out
diff --git a/sound/aoa/codecs/snd-aoa-codec-onyx.c b/sound/aoa/codecs/snd-aoa-codec-onyx.c
index ded516717940..028852374f21 100644
--- a/sound/aoa/codecs/snd-aoa-codec-onyx.c
+++ b/sound/aoa/codecs/snd-aoa-codec-onyx.c
@@ -661,7 +661,7 @@ static struct transfer_info onyx_transfers[] = {
661 .tag = 2, 661 .tag = 2,
662 }, 662 },
663#ifdef SNDRV_PCM_FMTBIT_COMPRESSED_16BE 663#ifdef SNDRV_PCM_FMTBIT_COMPRESSED_16BE
664Once alsa gets supports for this kind of thing we can add it... 664 /* Once alsa gets supports for this kind of thing we can add it... */
665 { 665 {
666 /* digital compressed output */ 666 /* digital compressed output */
667 .formats = SNDRV_PCM_FMTBIT_COMPRESSED_16BE, 667 .formats = SNDRV_PCM_FMTBIT_COMPRESSED_16BE,
@@ -713,7 +713,7 @@ static int onyx_prepare(struct codec_info_item *cii,
713 if (substream->runtime->format == SNDRV_PCM_FMTBIT_COMPRESSED_16BE) { 713 if (substream->runtime->format == SNDRV_PCM_FMTBIT_COMPRESSED_16BE) {
714 /* mute and lock analog output */ 714 /* mute and lock analog output */
715 onyx_read_register(onyx, ONYX_REG_DAC_CONTROL, &v); 715 onyx_read_register(onyx, ONYX_REG_DAC_CONTROL, &v);
716 if (onyx_write_register(onyx 716 if (onyx_write_register(onyx,
717 ONYX_REG_DAC_CONTROL, 717 ONYX_REG_DAC_CONTROL,
718 v | ONYX_MUTE_RIGHT | ONYX_MUTE_LEFT)) 718 v | ONYX_MUTE_RIGHT | ONYX_MUTE_LEFT))
719 goto out_unlock; 719 goto out_unlock;
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index a96733a5beb8..59b29cd482ae 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -1487,7 +1487,7 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream)
1487 1487
1488 snd_pcm_stream_lock_irq(substream); 1488 snd_pcm_stream_lock_irq(substream);
1489 /* resume pause */ 1489 /* resume pause */
1490 if (runtime->status->state == SNDRV_PCM_STATE_PAUSED) 1490 if (substream->runtime->status->state == SNDRV_PCM_STATE_PAUSED)
1491 snd_pcm_pause(substream, 0); 1491 snd_pcm_pause(substream, 0);
1492 1492
1493 /* pre-start/stop - all running streams are changed to DRAINING state */ 1493 /* pre-start/stop - all running streams are changed to DRAINING state */
diff --git a/sound/core/seq/seq_instr.c b/sound/core/seq/seq_instr.c
index f30d171b6d96..5efe6523a589 100644
--- a/sound/core/seq/seq_instr.c
+++ b/sound/core/seq/seq_instr.c
@@ -109,7 +109,7 @@ void snd_seq_instr_list_free(struct snd_seq_kinstr_list **list_ptr)
109 spin_lock_irqsave(&list->lock, flags); 109 spin_lock_irqsave(&list->lock, flags);
110 while (instr->use) { 110 while (instr->use) {
111 spin_unlock_irqrestore(&list->lock, flags); 111 spin_unlock_irqrestore(&list->lock, flags);
112 schedule_timeout_interruptible(1); 112 schedule_timeout(1);
113 spin_lock_irqsave(&list->lock, flags); 113 spin_lock_irqsave(&list->lock, flags);
114 } 114 }
115 spin_unlock_irqrestore(&list->lock, flags); 115 spin_unlock_irqrestore(&list->lock, flags);
@@ -199,7 +199,7 @@ int snd_seq_instr_list_free_cond(struct snd_seq_kinstr_list *list,
199 instr = flist; 199 instr = flist;
200 flist = instr->next; 200 flist = instr->next;
201 while (instr->use) 201 while (instr->use)
202 schedule_timeout_interruptible(1); 202 schedule_timeout(1);
203 if (snd_seq_instr_free(instr, atomic)<0) 203 if (snd_seq_instr_free(instr, atomic)<0)
204 snd_printk(KERN_WARNING "instrument free problem\n"); 204 snd_printk(KERN_WARNING "instrument free problem\n");
205 instr = next; 205 instr = next;
@@ -555,7 +555,7 @@ static int instr_free(struct snd_seq_kinstr_ops *ops,
555 SNDRV_SEQ_INSTR_NOTIFY_REMOVE); 555 SNDRV_SEQ_INSTR_NOTIFY_REMOVE);
556 while (instr->use) { 556 while (instr->use) {
557 spin_unlock_irqrestore(&list->lock, flags); 557 spin_unlock_irqrestore(&list->lock, flags);
558 schedule_timeout_interruptible(1); 558 schedule_timeout(1);
559 spin_lock_irqsave(&list->lock, flags); 559 spin_lock_irqsave(&list->lock, flags);
560 } 560 }
561 spin_unlock_irqrestore(&list->lock, flags); 561 spin_unlock_irqrestore(&list->lock, flags);
diff --git a/sound/core/timer.c b/sound/core/timer.c
index 67520b3c0042..f2bbacedd567 100644
--- a/sound/core/timer.c
+++ b/sound/core/timer.c
@@ -1549,9 +1549,11 @@ static int snd_timer_user_info(struct file *file,
1549 int err = 0; 1549 int err = 0;
1550 1550
1551 tu = file->private_data; 1551 tu = file->private_data;
1552 snd_assert(tu->timeri != NULL, return -ENXIO); 1552 if (!tu->timeri)
1553 return -EBADFD;
1553 t = tu->timeri->timer; 1554 t = tu->timeri->timer;
1554 snd_assert(t != NULL, return -ENXIO); 1555 if (!t)
1556 return -EBADFD;
1555 1557
1556 info = kzalloc(sizeof(*info), GFP_KERNEL); 1558 info = kzalloc(sizeof(*info), GFP_KERNEL);
1557 if (! info) 1559 if (! info)
@@ -1579,9 +1581,11 @@ static int snd_timer_user_params(struct file *file,
1579 int err; 1581 int err;
1580 1582
1581 tu = file->private_data; 1583 tu = file->private_data;
1582 snd_assert(tu->timeri != NULL, return -ENXIO); 1584 if (!tu->timeri)
1585 return -EBADFD;
1583 t = tu->timeri->timer; 1586 t = tu->timeri->timer;
1584 snd_assert(t != NULL, return -ENXIO); 1587 if (!t)
1588 return -EBADFD;
1585 if (copy_from_user(&params, _params, sizeof(params))) 1589 if (copy_from_user(&params, _params, sizeof(params)))
1586 return -EFAULT; 1590 return -EFAULT;
1587 if (!(t->hw.flags & SNDRV_TIMER_HW_SLAVE) && params.ticks < 1) { 1591 if (!(t->hw.flags & SNDRV_TIMER_HW_SLAVE) && params.ticks < 1) {
@@ -1675,7 +1679,8 @@ static int snd_timer_user_status(struct file *file,
1675 struct snd_timer_status status; 1679 struct snd_timer_status status;
1676 1680
1677 tu = file->private_data; 1681 tu = file->private_data;
1678 snd_assert(tu->timeri != NULL, return -ENXIO); 1682 if (!tu->timeri)
1683 return -EBADFD;
1679 memset(&status, 0, sizeof(status)); 1684 memset(&status, 0, sizeof(status));
1680 status.tstamp = tu->tstamp; 1685 status.tstamp = tu->tstamp;
1681 status.resolution = snd_timer_resolution(tu->timeri); 1686 status.resolution = snd_timer_resolution(tu->timeri);
@@ -1695,7 +1700,8 @@ static int snd_timer_user_start(struct file *file)
1695 struct snd_timer_user *tu; 1700 struct snd_timer_user *tu;
1696 1701
1697 tu = file->private_data; 1702 tu = file->private_data;
1698 snd_assert(tu->timeri != NULL, return -ENXIO); 1703 if (!tu->timeri)
1704 return -EBADFD;
1699 snd_timer_stop(tu->timeri); 1705 snd_timer_stop(tu->timeri);
1700 tu->timeri->lost = 0; 1706 tu->timeri->lost = 0;
1701 tu->last_resolution = 0; 1707 tu->last_resolution = 0;
@@ -1708,7 +1714,8 @@ static int snd_timer_user_stop(struct file *file)
1708 struct snd_timer_user *tu; 1714 struct snd_timer_user *tu;
1709 1715
1710 tu = file->private_data; 1716 tu = file->private_data;
1711 snd_assert(tu->timeri != NULL, return -ENXIO); 1717 if (!tu->timeri)
1718 return -EBADFD;
1712 return (err = snd_timer_stop(tu->timeri)) < 0 ? err : 0; 1719 return (err = snd_timer_stop(tu->timeri)) < 0 ? err : 0;
1713} 1720}
1714 1721
@@ -1718,7 +1725,8 @@ static int snd_timer_user_continue(struct file *file)
1718 struct snd_timer_user *tu; 1725 struct snd_timer_user *tu;
1719 1726
1720 tu = file->private_data; 1727 tu = file->private_data;
1721 snd_assert(tu->timeri != NULL, return -ENXIO); 1728 if (!tu->timeri)
1729 return -EBADFD;
1722 tu->timeri->lost = 0; 1730 tu->timeri->lost = 0;
1723 return (err = snd_timer_continue(tu->timeri)) < 0 ? err : 0; 1731 return (err = snd_timer_continue(tu->timeri)) < 0 ? err : 0;
1724} 1732}
@@ -1729,7 +1737,8 @@ static int snd_timer_user_pause(struct file *file)
1729 struct snd_timer_user *tu; 1737 struct snd_timer_user *tu;
1730 1738
1731 tu = file->private_data; 1739 tu = file->private_data;
1732 snd_assert(tu->timeri != NULL, return -ENXIO); 1740 if (!tu->timeri)
1741 return -EBADFD;
1733 return (err = snd_timer_pause(tu->timeri)) < 0 ? err : 0; 1742 return (err = snd_timer_pause(tu->timeri)) < 0 ? err : 0;
1734} 1743}
1735 1744
diff --git a/sound/drivers/dummy.c b/sound/drivers/dummy.c
index a0f28f51fc7e..4360ae9de19c 100644
--- a/sound/drivers/dummy.c
+++ b/sound/drivers/dummy.c
@@ -659,7 +659,7 @@ static struct platform_driver snd_dummy_driver = {
659 }, 659 },
660}; 660};
661 661
662static void __init_or_module snd_dummy_unregister_all(void) 662static void snd_dummy_unregister_all(void)
663{ 663{
664 int i; 664 int i;
665 665
diff --git a/sound/drivers/mpu401/mpu401.c b/sound/drivers/mpu401/mpu401.c
index 1d563e515c17..67c6e9745418 100644
--- a/sound/drivers/mpu401/mpu401.c
+++ b/sound/drivers/mpu401/mpu401.c
@@ -228,7 +228,7 @@ static struct pnp_driver snd_mpu401_pnp_driver = {
228static struct pnp_driver snd_mpu401_pnp_driver; 228static struct pnp_driver snd_mpu401_pnp_driver;
229#endif 229#endif
230 230
231static void __init_or_module snd_mpu401_unregister_all(void) 231static void snd_mpu401_unregister_all(void)
232{ 232{
233 int i; 233 int i;
234 234
diff --git a/sound/drivers/portman2x4.c b/sound/drivers/portman2x4.c
index 497cafb57d9b..0eb9b5cebfcd 100644
--- a/sound/drivers/portman2x4.c
+++ b/sound/drivers/portman2x4.c
@@ -833,7 +833,7 @@ static struct platform_driver snd_portman_driver = {
833/********************************************************************* 833/*********************************************************************
834 * module init stuff 834 * module init stuff
835 *********************************************************************/ 835 *********************************************************************/
836static void __init_or_module snd_portman_unregister_all(void) 836static void snd_portman_unregister_all(void)
837{ 837{
838 int i; 838 int i;
839 839
diff --git a/sound/drivers/serial-u16550.c b/sound/drivers/serial-u16550.c
index 838a4277929d..d3e6a20edd38 100644
--- a/sound/drivers/serial-u16550.c
+++ b/sound/drivers/serial-u16550.c
@@ -998,7 +998,7 @@ static struct platform_driver snd_serial_driver = {
998 }, 998 },
999}; 999};
1000 1000
1001static void __init_or_module snd_serial_unregister_all(void) 1001static void snd_serial_unregister_all(void)
1002{ 1002{
1003 int i; 1003 int i;
1004 1004
diff --git a/sound/drivers/virmidi.c b/sound/drivers/virmidi.c
index 46f3d3486067..915c86773c21 100644
--- a/sound/drivers/virmidi.c
+++ b/sound/drivers/virmidi.c
@@ -145,7 +145,7 @@ static struct platform_driver snd_virmidi_driver = {
145 }, 145 },
146}; 146};
147 147
148static void __init_or_module snd_virmidi_unregister_all(void) 148static void snd_virmidi_unregister_all(void)
149{ 149{
150 int i; 150 int i;
151 151
diff --git a/sound/i2c/other/ak4xxx-adda.c b/sound/i2c/other/ak4xxx-adda.c
index 8805110017a7..fd335159f849 100644
--- a/sound/i2c/other/ak4xxx-adda.c
+++ b/sound/i2c/other/ak4xxx-adda.c
@@ -481,8 +481,8 @@ static int ak4xxx_switch_get(struct snd_kcontrol *kcontrol,
481 int addr = AK_GET_ADDR(kcontrol->private_value); 481 int addr = AK_GET_ADDR(kcontrol->private_value);
482 int shift = AK_GET_SHIFT(kcontrol->private_value); 482 int shift = AK_GET_SHIFT(kcontrol->private_value);
483 int invert = AK_GET_INVERT(kcontrol->private_value); 483 int invert = AK_GET_INVERT(kcontrol->private_value);
484 unsigned char val = snd_akm4xxx_get(ak, chip, addr); 484 /* we observe the (1<<shift) bit only */
485 485 unsigned char val = snd_akm4xxx_get(ak, chip, addr) & (1<<shift);
486 if (invert) 486 if (invert)
487 val = ! val; 487 val = ! val;
488 ucontrol->value.integer.value[0] = (val & (1<<shift)) != 0; 488 ucontrol->value.integer.value[0] = (val & (1<<shift)) != 0;
@@ -585,6 +585,26 @@ static int build_dac_controls(struct snd_akm4xxx *ak)
585 585
586 mixer_ch = 0; 586 mixer_ch = 0;
587 for (idx = 0; idx < ak->num_dacs; ) { 587 for (idx = 0; idx < ak->num_dacs; ) {
588 /* mute control for Revolution 7.1 - AK4381 */
589 if (ak->type == SND_AK4381
590 && ak->dac_info[mixer_ch].switch_name) {
591 memset(&knew, 0, sizeof(knew));
592 knew.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
593 knew.count = 1;
594 knew.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
595 knew.name = ak->dac_info[mixer_ch].switch_name;
596 knew.info = ak4xxx_switch_info;
597 knew.get = ak4xxx_switch_get;
598 knew.put = ak4xxx_switch_put;
599 knew.access = 0;
600 /* register 1, bit 0 (SMUTE): 0 = normal operation,
601 1 = mute */
602 knew.private_value =
603 AK_COMPOSE(idx/2, 1, 0, 0) | AK_INVERT;
604 err = snd_ctl_add(ak->card, snd_ctl_new1(&knew, ak));
605 if (err < 0)
606 return err;
607 }
588 memset(&knew, 0, sizeof(knew)); 608 memset(&knew, 0, sizeof(knew));
589 if (! ak->dac_info || ! ak->dac_info[mixer_ch].name) { 609 if (! ak->dac_info || ! ak->dac_info[mixer_ch].name) {
590 knew.name = "DAC Volume"; 610 knew.name = "DAC Volume";
diff --git a/sound/isa/Kconfig b/sound/isa/Kconfig
index cf3803cd579c..ea5084abe60f 100644
--- a/sound/isa/Kconfig
+++ b/sound/isa/Kconfig
@@ -1,8 +1,5 @@
1# ALSA ISA drivers 1# ALSA ISA drivers
2 2
3menu "ISA devices"
4 depends on SND!=n && ISA && ISA_DMA_API
5
6config SND_AD1848_LIB 3config SND_AD1848_LIB
7 tristate 4 tristate
8 select SND_PCM 5 select SND_PCM
@@ -11,6 +8,22 @@ config SND_CS4231_LIB
11 tristate 8 tristate
12 select SND_PCM 9 select SND_PCM
13 10
11config SND_SB_COMMON
12 tristate
13
14config SND_SB8_DSP
15 tristate
16 select SND_PCM
17 select SND_SB_COMMON
18
19config SND_SB16_DSP
20 tristate
21 select SND_PCM
22 select SND_SB_COMMON
23
24menu "ISA devices"
25 depends on SND!=n && ISA && ISA_DMA_API
26
14config SND_ADLIB 27config SND_ADLIB
15 tristate "AdLib FM card" 28 tristate "AdLib FM card"
16 depends on SND 29 depends on SND
@@ -55,7 +68,7 @@ config SND_ALS100
55 select ISAPNP 68 select ISAPNP
56 select SND_OPL3_LIB 69 select SND_OPL3_LIB
57 select SND_MPU401_UART 70 select SND_MPU401_UART
58 select SND_PCM 71 select SND_SB16_DSP
59 help 72 help
60 Say Y here to include support for soundcards based on Avance 73 Say Y here to include support for soundcards based on Avance
61 Logic ALS100, ALS110, ALS120 and ALS200 chips. 74 Logic ALS100, ALS110, ALS120 and ALS200 chips.
@@ -81,6 +94,7 @@ config SND_CMI8330
81 tristate "C-Media CMI8330" 94 tristate "C-Media CMI8330"
82 depends on SND 95 depends on SND
83 select SND_AD1848_LIB 96 select SND_AD1848_LIB
97 select SND_SB16_DSP
84 help 98 help
85 Say Y here to include support for soundcards based on the 99 Say Y here to include support for soundcards based on the
86 C-Media CMI8330 chip. 100 C-Media CMI8330 chip.
@@ -132,7 +146,7 @@ config SND_DT019X
132 select ISAPNP 146 select ISAPNP
133 select SND_OPL3_LIB 147 select SND_OPL3_LIB
134 select SND_MPU401_UART 148 select SND_MPU401_UART
135 select SND_PCM 149 select SND_SB16_DSP
136 help 150 help
137 Say Y here to include support for soundcards based on the 151 Say Y here to include support for soundcards based on the
138 Diamond Technologies DT-019X or Avance Logic ALS-007 chips. 152 Diamond Technologies DT-019X or Avance Logic ALS-007 chips.
@@ -145,7 +159,7 @@ config SND_ES968
145 depends on SND && PNP && ISA 159 depends on SND && PNP && ISA
146 select ISAPNP 160 select ISAPNP
147 select SND_MPU401_UART 161 select SND_MPU401_UART
148 select SND_PCM 162 select SND_SB8_DSP
149 help 163 help
150 Say Y here to include support for ESS AudioDrive ES968 chips. 164 Say Y here to include support for ESS AudioDrive ES968 chips.
151 165
@@ -321,7 +335,7 @@ config SND_SB8
321 depends on SND 335 depends on SND
322 select SND_OPL3_LIB 336 select SND_OPL3_LIB
323 select SND_RAWMIDI 337 select SND_RAWMIDI
324 select SND_PCM 338 select SND_SB8_DSP
325 help 339 help
326 Say Y here to include support for Creative Sound Blaster 1.0/ 340 Say Y here to include support for Creative Sound Blaster 1.0/
327 2.0/Pro (8-bit) or 100% compatible soundcards. 341 2.0/Pro (8-bit) or 100% compatible soundcards.
@@ -334,7 +348,7 @@ config SND_SB16
334 depends on SND 348 depends on SND
335 select SND_OPL3_LIB 349 select SND_OPL3_LIB
336 select SND_MPU401_UART 350 select SND_MPU401_UART
337 select SND_PCM 351 select SND_SB16_DSP
338 help 352 help
339 Say Y here to include support for Sound Blaster 16 soundcards 353 Say Y here to include support for Sound Blaster 16 soundcards
340 (including the Plug and Play version). 354 (including the Plug and Play version).
@@ -347,7 +361,7 @@ config SND_SBAWE
347 depends on SND 361 depends on SND
348 select SND_OPL3_LIB 362 select SND_OPL3_LIB
349 select SND_MPU401_UART 363 select SND_MPU401_UART
350 select SND_PCM 364 select SND_SB16_DSP
351 help 365 help
352 Say Y here to include support for Sound Blaster AWE soundcards 366 Say Y here to include support for Sound Blaster AWE soundcards
353 (including the Plug and Play version). 367 (including the Plug and Play version).
diff --git a/sound/isa/ad1848/ad1848_lib.c b/sound/isa/ad1848/ad1848_lib.c
index 8094282c2ae1..1bc2e3fd5721 100644
--- a/sound/isa/ad1848/ad1848_lib.c
+++ b/sound/isa/ad1848/ad1848_lib.c
@@ -245,7 +245,7 @@ static void snd_ad1848_mce_down(struct snd_ad1848 *chip)
245 snd_printk(KERN_ERR "mce_down - auto calibration time out (2)\n"); 245 snd_printk(KERN_ERR "mce_down - auto calibration time out (2)\n");
246 return; 246 return;
247 } 247 }
248 time = schedule_timeout_interruptible(time); 248 time = schedule_timeout(time);
249 spin_lock_irqsave(&chip->reg_lock, flags); 249 spin_lock_irqsave(&chip->reg_lock, flags);
250 } 250 }
251#if 0 251#if 0
@@ -258,7 +258,7 @@ static void snd_ad1848_mce_down(struct snd_ad1848 *chip)
258 snd_printk(KERN_ERR "mce_down - auto calibration time out (3)\n"); 258 snd_printk(KERN_ERR "mce_down - auto calibration time out (3)\n");
259 return; 259 return;
260 } 260 }
261 time = schedule_timeout_interruptible(time); 261 time = schedule_timeout(time);
262 spin_lock_irqsave(&chip->reg_lock, flags); 262 spin_lock_irqsave(&chip->reg_lock, flags);
263 } 263 }
264 spin_unlock_irqrestore(&chip->reg_lock, flags); 264 spin_unlock_irqrestore(&chip->reg_lock, flags);
diff --git a/sound/isa/opl3sa2.c b/sound/isa/opl3sa2.c
index 4f6800b43b0e..e70db32991d9 100644
--- a/sound/isa/opl3sa2.c
+++ b/sound/isa/opl3sa2.c
@@ -164,6 +164,8 @@ static struct pnp_card_device_id snd_opl3sa2_pnpids[] = {
164 { .id = "YMH0801", .devs = { { "YMH0021" } } }, 164 { .id = "YMH0801", .devs = { { "YMH0021" } } },
165 /* NeoMagic MagicWave 3DX */ 165 /* NeoMagic MagicWave 3DX */
166 { .id = "NMX2200", .devs = { { "YMH2210" } } }, 166 { .id = "NMX2200", .devs = { { "YMH2210" } } },
167 /* NeoMagic MagicWave 3D */
168 { .id = "NMX2200", .devs = { { "NMX2210" } } },
167 /* --- */ 169 /* --- */
168 { .id = "" } /* end */ 170 { .id = "" } /* end */
169}; 171};
diff --git a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c
index 60c120ffb9de..049d479ce2b3 100644
--- a/sound/isa/opti9xx/opti92x-ad1848.c
+++ b/sound/isa/opti9xx/opti92x-ad1848.c
@@ -1927,10 +1927,12 @@ static struct snd_card *snd_opti9xx_card_new(void)
1927static int __devinit snd_opti9xx_isa_match(struct device *devptr, 1927static int __devinit snd_opti9xx_isa_match(struct device *devptr,
1928 unsigned int dev) 1928 unsigned int dev)
1929{ 1929{
1930#ifdef CONFIG_PNP
1930 if (snd_opti9xx_pnp_is_probed) 1931 if (snd_opti9xx_pnp_is_probed)
1931 return 0; 1932 return 0;
1932 if (isapnp) 1933 if (isapnp)
1933 return 0; 1934 return 0;
1935#endif
1934 return 1; 1936 return 1;
1935} 1937}
1936 1938
@@ -2096,6 +2098,7 @@ static int __init alsa_card_opti9xx_init(void)
2096 pnp_register_card_driver(&opti9xx_pnpc_driver); 2098 pnp_register_card_driver(&opti9xx_pnpc_driver);
2097 if (snd_opti9xx_pnp_is_probed) 2099 if (snd_opti9xx_pnp_is_probed)
2098 return 0; 2100 return 0;
2101 pnp_unregister_card_driver(&opti9xx_pnpc_driver);
2099#endif 2102#endif
2100 return isa_register_driver(&snd_opti9xx_driver, 1); 2103 return isa_register_driver(&snd_opti9xx_driver, 1);
2101} 2104}
diff --git a/sound/isa/sb/Makefile b/sound/isa/sb/Makefile
index fd9d9c5726fc..556e66928029 100644
--- a/sound/isa/sb/Makefile
+++ b/sound/isa/sb/Makefile
@@ -22,14 +22,13 @@ snd-es968-objs := es968.o
22sequencer = $(if $(subst y,,$(CONFIG_SND_SEQUENCER)),$(if $(1),m),$(if $(CONFIG_SND_SEQUENCER),$(1))) 22sequencer = $(if $(subst y,,$(CONFIG_SND_SEQUENCER)),$(if $(1),m),$(if $(CONFIG_SND_SEQUENCER),$(1)))
23 23
24# Toplevel Module Dependency 24# Toplevel Module Dependency
25obj-$(CONFIG_SND_ALS100) += snd-sb16-dsp.o snd-sb-common.o 25obj-$(CONFIG_SND_SB_COMMON) += snd-sb-common.o
26obj-$(CONFIG_SND_CMI8330) += snd-sb16-dsp.o snd-sb-common.o 26obj-$(CONFIG_SND_SB16_DSP) += snd-sb16-dsp.o
27obj-$(CONFIG_SND_DT019X) += snd-sb16-dsp.o snd-sb-common.o 27obj-$(CONFIG_SND_SB8_DSP) += snd-sb8-dsp.o
28obj-$(CONFIG_SND_SB8) += snd-sb8.o snd-sb8-dsp.o snd-sb-common.o 28obj-$(CONFIG_SND_SB8) += snd-sb8.o
29obj-$(CONFIG_SND_SB16) += snd-sb16.o snd-sb16-dsp.o snd-sb-common.o 29obj-$(CONFIG_SND_SB16) += snd-sb16.o
30obj-$(CONFIG_SND_SBAWE) += snd-sbawe.o snd-sb16-dsp.o snd-sb-common.o 30obj-$(CONFIG_SND_SBAWE) += snd-sbawe.o
31obj-$(CONFIG_SND_ES968) += snd-es968.o snd-sb8-dsp.o snd-sb-common.o 31obj-$(CONFIG_SND_ES968) += snd-es968.o
32obj-$(CONFIG_SND_ALS4000) += snd-sb-common.o
33ifeq ($(CONFIG_SND_SB16_CSP),y) 32ifeq ($(CONFIG_SND_SB16_CSP),y)
34 obj-$(CONFIG_SND_SB16) += snd-sb16-csp.o 33 obj-$(CONFIG_SND_SB16) += snd-sb16-csp.o
35 obj-$(CONFIG_SND_SBAWE) += snd-sb16-csp.o 34 obj-$(CONFIG_SND_SBAWE) += snd-sb16-csp.o
diff --git a/sound/isa/sb/sb16_main.c b/sound/isa/sb/sb16_main.c
index 383911b9e74d..5d4d3aafe2d5 100644
--- a/sound/isa/sb/sb16_main.c
+++ b/sound/isa/sb/sb16_main.c
@@ -563,6 +563,11 @@ static int snd_sb16_playback_open(struct snd_pcm_substream *substream)
563 __open_ok: 563 __open_ok:
564 if (chip->hardware == SB_HW_ALS100) 564 if (chip->hardware == SB_HW_ALS100)
565 runtime->hw.rate_max = 48000; 565 runtime->hw.rate_max = 48000;
566 if (chip->hardware == SB_HW_CS5530) {
567 runtime->hw.buffer_bytes_max = 32 * 1024;
568 runtime->hw.periods_min = 2;
569 runtime->hw.rate_min = 44100;
570 }
566 if (chip->mode & SB_RATE_LOCK) 571 if (chip->mode & SB_RATE_LOCK)
567 runtime->hw.rate_min = runtime->hw.rate_max = chip->locked_rate; 572 runtime->hw.rate_min = runtime->hw.rate_max = chip->locked_rate;
568 chip->playback_substream = substream; 573 chip->playback_substream = substream;
@@ -633,6 +638,11 @@ static int snd_sb16_capture_open(struct snd_pcm_substream *substream)
633 __open_ok: 638 __open_ok:
634 if (chip->hardware == SB_HW_ALS100) 639 if (chip->hardware == SB_HW_ALS100)
635 runtime->hw.rate_max = 48000; 640 runtime->hw.rate_max = 48000;
641 if (chip->hardware == SB_HW_CS5530) {
642 runtime->hw.buffer_bytes_max = 32 * 1024;
643 runtime->hw.periods_min = 2;
644 runtime->hw.rate_min = 44100;
645 }
636 if (chip->mode & SB_RATE_LOCK) 646 if (chip->mode & SB_RATE_LOCK)
637 runtime->hw.rate_min = runtime->hw.rate_max = chip->locked_rate; 647 runtime->hw.rate_min = runtime->hw.rate_max = chip->locked_rate;
638 chip->capture_substream = substream; 648 chip->capture_substream = substream;
diff --git a/sound/isa/sb/sb_common.c b/sound/isa/sb/sb_common.c
index 3094f3852167..efa9d5c2558a 100644
--- a/sound/isa/sb/sb_common.c
+++ b/sound/isa/sb/sb_common.c
@@ -128,7 +128,7 @@ static int snd_sbdsp_probe(struct snd_sb * chip)
128 minor = version & 0xff; 128 minor = version & 0xff;
129 snd_printdd("SB [0x%lx]: DSP chip found, version = %i.%i\n", 129 snd_printdd("SB [0x%lx]: DSP chip found, version = %i.%i\n",
130 chip->port, major, minor); 130 chip->port, major, minor);
131 131
132 switch (chip->hardware) { 132 switch (chip->hardware) {
133 case SB_HW_AUTO: 133 case SB_HW_AUTO:
134 switch (major) { 134 switch (major) {
@@ -168,6 +168,9 @@ static int snd_sbdsp_probe(struct snd_sb * chip)
168 case SB_HW_DT019X: 168 case SB_HW_DT019X:
169 str = "(DT019X/ALS007)"; 169 str = "(DT019X/ALS007)";
170 break; 170 break;
171 case SB_HW_CS5530:
172 str = "16 (CS5530)";
173 break;
171 default: 174 default:
172 return -ENODEV; 175 return -ENODEV;
173 } 176 }
diff --git a/sound/isa/sb/sb_mixer.c b/sound/isa/sb/sb_mixer.c
index 490b1ca5cf58..3d4befcff28e 100644
--- a/sound/isa/sb/sb_mixer.c
+++ b/sound/isa/sb/sb_mixer.c
@@ -821,6 +821,7 @@ int snd_sbmixer_new(struct snd_sb *chip)
821 break; 821 break;
822 case SB_HW_16: 822 case SB_HW_16:
823 case SB_HW_ALS100: 823 case SB_HW_ALS100:
824 case SB_HW_CS5530:
824 if ((err = snd_sbmixer_init(chip, 825 if ((err = snd_sbmixer_init(chip,
825 snd_sb16_controls, 826 snd_sb16_controls,
826 ARRAY_SIZE(snd_sb16_controls), 827 ARRAY_SIZE(snd_sb16_controls),
@@ -950,6 +951,7 @@ void snd_sbmixer_suspend(struct snd_sb *chip)
950 break; 951 break;
951 case SB_HW_16: 952 case SB_HW_16:
952 case SB_HW_ALS100: 953 case SB_HW_ALS100:
954 case SB_HW_CS5530:
953 save_mixer(chip, sb16_saved_regs, ARRAY_SIZE(sb16_saved_regs)); 955 save_mixer(chip, sb16_saved_regs, ARRAY_SIZE(sb16_saved_regs));
954 break; 956 break;
955 case SB_HW_ALS4000: 957 case SB_HW_ALS4000:
@@ -975,6 +977,7 @@ void snd_sbmixer_resume(struct snd_sb *chip)
975 break; 977 break;
976 case SB_HW_16: 978 case SB_HW_16:
977 case SB_HW_ALS100: 979 case SB_HW_ALS100:
980 case SB_HW_CS5530:
978 restore_mixer(chip, sb16_saved_regs, ARRAY_SIZE(sb16_saved_regs)); 981 restore_mixer(chip, sb16_saved_regs, ARRAY_SIZE(sb16_saved_regs));
979 break; 982 break;
980 case SB_HW_ALS4000: 983 case SB_HW_ALS4000:
diff --git a/sound/isa/sscape.c b/sound/isa/sscape.c
index 9ea417bcf3e5..cbad2a51cbaa 100644
--- a/sound/isa/sscape.c
+++ b/sound/isa/sscape.c
@@ -382,7 +382,7 @@ static int obp_startup_ack(struct soundscape *s, unsigned timeout)
382 unsigned long flags; 382 unsigned long flags;
383 unsigned char x; 383 unsigned char x;
384 384
385 schedule_timeout_interruptible(1); 385 schedule_timeout(1);
386 386
387 spin_lock_irqsave(&s->lock, flags); 387 spin_lock_irqsave(&s->lock, flags);
388 x = inb(HOST_DATA_IO(s->io_base)); 388 x = inb(HOST_DATA_IO(s->io_base));
@@ -409,7 +409,7 @@ static int host_startup_ack(struct soundscape *s, unsigned timeout)
409 unsigned long flags; 409 unsigned long flags;
410 unsigned char x; 410 unsigned char x;
411 411
412 schedule_timeout_interruptible(1); 412 schedule_timeout(1);
413 413
414 spin_lock_irqsave(&s->lock, flags); 414 spin_lock_irqsave(&s->lock, flags);
415 x = inb(HOST_DATA_IO(s->io_base)); 415 x = inb(HOST_DATA_IO(s->io_base));
diff --git a/sound/isa/wavefront/wavefront_synth.c b/sound/isa/wavefront/wavefront_synth.c
index 78020d832e04..bacc51c86587 100644
--- a/sound/isa/wavefront/wavefront_synth.c
+++ b/sound/isa/wavefront/wavefront_synth.c
@@ -1780,7 +1780,7 @@ wavefront_should_cause_interrupt (snd_wavefront_t *dev,
1780 outb (val,port); 1780 outb (val,port);
1781 spin_unlock_irq(&dev->irq_lock); 1781 spin_unlock_irq(&dev->irq_lock);
1782 while (1) { 1782 while (1) {
1783 if ((timeout = schedule_timeout_interruptible(timeout)) == 0) 1783 if ((timeout = schedule_timeout(timeout)) == 0)
1784 return; 1784 return;
1785 if (dev->irq_ok) 1785 if (dev->irq_ok)
1786 return; 1786 return;
diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig
index 61e35ecc57b8..c6b44102aa5b 100644
--- a/sound/pci/Kconfig
+++ b/sound/pci/Kconfig
@@ -33,6 +33,7 @@ config SND_ALS4000
33 select SND_OPL3_LIB 33 select SND_OPL3_LIB
34 select SND_MPU401_UART 34 select SND_MPU401_UART
35 select SND_PCM 35 select SND_PCM
36 select SND_SB_COMMON
36 help 37 help
37 Say Y here to include support for soundcards based on Avance Logic 38 Say Y here to include support for soundcards based on Avance Logic
38 ALS4000 chips. 39 ALS4000 chips.
@@ -215,6 +216,16 @@ config SND_CS46XX_NEW_DSP
215 216
216 This works better than the old code, so say Y. 217 This works better than the old code, so say Y.
217 218
219config SND_CS5530
220 tristate "CS5530 Audio"
221 depends on SND && ISA_DMA_API
222 select SND_SB16_DSP
223 help
224 Say Y here to include support for audio on Cyrix/NatSemi CS5530 chips.
225
226 To compile this driver as a module, choose M here: the module
227 will be called snd-cs5530.
228
218config SND_CS5535AUDIO 229config SND_CS5535AUDIO
219 tristate "CS5535/CS5536 Audio" 230 tristate "CS5535/CS5536 Audio"
220 depends on SND && X86 && !X86_64 231 depends on SND && X86 && !X86_64
diff --git a/sound/pci/Makefile b/sound/pci/Makefile
index e06736da9ef1..cd76e0293d06 100644
--- a/sound/pci/Makefile
+++ b/sound/pci/Makefile
@@ -12,6 +12,7 @@ snd-azt3328-objs := azt3328.o
12snd-bt87x-objs := bt87x.o 12snd-bt87x-objs := bt87x.o
13snd-cmipci-objs := cmipci.o 13snd-cmipci-objs := cmipci.o
14snd-cs4281-objs := cs4281.o 14snd-cs4281-objs := cs4281.o
15snd-cs5530-objs := cs5530.o
15snd-ens1370-objs := ens1370.o 16snd-ens1370-objs := ens1370.o
16snd-ens1371-objs := ens1371.o 17snd-ens1371-objs := ens1371.o
17snd-es1938-objs := es1938.o 18snd-es1938-objs := es1938.o
@@ -36,6 +37,7 @@ obj-$(CONFIG_SND_AZT3328) += snd-azt3328.o
36obj-$(CONFIG_SND_BT87X) += snd-bt87x.o 37obj-$(CONFIG_SND_BT87X) += snd-bt87x.o
37obj-$(CONFIG_SND_CMIPCI) += snd-cmipci.o 38obj-$(CONFIG_SND_CMIPCI) += snd-cmipci.o
38obj-$(CONFIG_SND_CS4281) += snd-cs4281.o 39obj-$(CONFIG_SND_CS4281) += snd-cs4281.o
40obj-$(CONFIG_SND_CS5530) += snd-cs5530.o
39obj-$(CONFIG_SND_ENS1370) += snd-ens1370.o 41obj-$(CONFIG_SND_ENS1370) += snd-ens1370.o
40obj-$(CONFIG_SND_ENS1371) += snd-ens1371.o 42obj-$(CONFIG_SND_ENS1371) += snd-ens1371.o
41obj-$(CONFIG_SND_ES1938) += snd-es1938.o 43obj-$(CONFIG_SND_ES1938) += snd-es1938.o
diff --git a/sound/pci/ali5451/ali5451.c b/sound/pci/ali5451/ali5451.c
index 41543a4933e7..05b4c8696941 100644
--- a/sound/pci/ali5451/ali5451.c
+++ b/sound/pci/ali5451/ali5451.c
@@ -239,7 +239,7 @@ struct snd_ali_image {
239 239
240 240
241struct snd_ali { 241struct snd_ali {
242 unsigned long irq; 242 int irq;
243 unsigned long port; 243 unsigned long port;
244 unsigned char revision; 244 unsigned char revision;
245 245
@@ -731,8 +731,7 @@ static void snd_ali_detect_spdif_rate(struct snd_ali *codec)
731 return; 731 return;
732 } 732 }
733 733
734 count = 0; 734 for (count = 0; count <= 50000; count++) {
735 while (count++ <= 50000) {
736 snd_ali_delay(codec, 6); 735 snd_ali_delay(codec, 6);
737 bval = inb(ALI_REG(codec,ALI_SPDIF_CTRL + 1)); 736 bval = inb(ALI_REG(codec,ALI_SPDIF_CTRL + 1));
738 R2 = bval & 0x1F; 737 R2 = bval & 0x1F;
@@ -2343,7 +2342,7 @@ static int __devinit snd_ali_probe(struct pci_dev *pci,
2343 strcpy(card->driver, "ALI5451"); 2342 strcpy(card->driver, "ALI5451");
2344 strcpy(card->shortname, "ALI 5451"); 2343 strcpy(card->shortname, "ALI 5451");
2345 2344
2346 sprintf(card->longname, "%s at 0x%lx, irq %li", 2345 sprintf(card->longname, "%s at 0x%lx, irq %i",
2347 card->shortname, codec->port, codec->irq); 2346 card->shortname, codec->port, codec->irq);
2348 2347
2349 snd_ali_printk("register card.\n"); 2348 snd_ali_printk("register card.\n");
diff --git a/sound/pci/als300.c b/sound/pci/als300.c
index 8afcb98ca7bb..48cc39b771d9 100644
--- a/sound/pci/als300.c
+++ b/sound/pci/als300.c
@@ -88,8 +88,8 @@
88#define PLAYBACK_BLOCK_COUNTER 0x9A 88#define PLAYBACK_BLOCK_COUNTER 0x9A
89#define RECORD_BLOCK_COUNTER 0x9B 89#define RECORD_BLOCK_COUNTER 0x9B
90 90
91#define DEBUG_CALLS 1 91#define DEBUG_CALLS 0
92#define DEBUG_PLAY_REC 1 92#define DEBUG_PLAY_REC 0
93 93
94#if DEBUG_CALLS 94#if DEBUG_CALLS
95#define snd_als300_dbgcalls(format, args...) printk(format, ##args) 95#define snd_als300_dbgcalls(format, args...) printk(format, ##args)
@@ -733,7 +733,8 @@ static int __devinit snd_als300_create(struct snd_card *card,
733 733
734 snd_als300_init(chip); 734 snd_als300_init(chip);
735 735
736 if (snd_als300_ac97(chip) < 0) { 736 err = snd_als300_ac97(chip);
737 if (err < 0) {
737 snd_printk(KERN_WARNING "Could not create ac97\n"); 738 snd_printk(KERN_WARNING "Could not create ac97\n");
738 snd_als300_free(chip); 739 snd_als300_free(chip);
739 return err; 740 return err;
diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c
index 9fd7b8a5b75e..fcab8fb97e38 100644
--- a/sound/pci/ca0106/ca0106_main.c
+++ b/sound/pci/ca0106/ca0106_main.c
@@ -168,6 +168,25 @@ MODULE_PARM_DESC(subsystem, "Force card subsystem model.");
168#include "ca0106.h" 168#include "ca0106.h"
169 169
170static struct snd_ca0106_details ca0106_chip_details[] = { 170static struct snd_ca0106_details ca0106_chip_details[] = {
171 /* Sound Blaster X-Fi Extreme Audio. This does not have an AC97. 53SB079000000 */
172 /* It is really just a normal SB Live 24bit. */
173 /*
174 * CTRL:CA0111-WTLF
175 * ADC: WM8775SEDS
176 * DAC: CS4382-KQZ
177 */
178 /* Tested:
179 * Playback on front, rear, center/lfe speakers
180 * Capture from Mic in.
181 * Not-Tested:
182 * Capture from Line in.
183 * Playback to digital out.
184 */
185 { .serial = 0x10121102,
186 .name = "X-Fi Extreme Audio [SB0790]",
187 .gpio_type = 1,
188 .i2c_adc = 1 } ,
189 /* New Dell Sound Blaster Live! 7.1 24bit. This does not have an AC97. */
171 /* AudigyLS[SB0310] */ 190 /* AudigyLS[SB0310] */
172 { .serial = 0x10021102, 191 { .serial = 0x10021102,
173 .name = "AudigyLS [SB0310]", 192 .name = "AudigyLS [SB0310]",
diff --git a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c
index bef1f6d1859c..71d7aab9d869 100644
--- a/sound/pci/cs46xx/cs46xx_lib.c
+++ b/sound/pci/cs46xx/cs46xx_lib.c
@@ -2897,6 +2897,10 @@ static int snd_cs46xx_free(struct snd_cs46xx *chip)
2897 } 2897 }
2898#endif 2898#endif
2899 2899
2900#ifdef CONFIG_PM
2901 kfree(chip->saved_regs);
2902#endif
2903
2900 pci_disable_device(chip->pci); 2904 pci_disable_device(chip->pci);
2901 kfree(chip); 2905 kfree(chip);
2902 return 0; 2906 return 0;
@@ -3140,6 +3144,23 @@ static int snd_cs46xx_chip_init(struct snd_cs46xx *chip)
3140/* 3144/*
3141 * start and load DSP 3145 * start and load DSP
3142 */ 3146 */
3147
3148static void cs46xx_enable_stream_irqs(struct snd_cs46xx *chip)
3149{
3150 unsigned int tmp;
3151
3152 snd_cs46xx_pokeBA0(chip, BA0_HICR, HICR_IEV | HICR_CHGM);
3153
3154 tmp = snd_cs46xx_peek(chip, BA1_PFIE);
3155 tmp &= ~0x0000f03f;
3156 snd_cs46xx_poke(chip, BA1_PFIE, tmp); /* playback interrupt enable */
3157
3158 tmp = snd_cs46xx_peek(chip, BA1_CIE);
3159 tmp &= ~0x0000003f;
3160 tmp |= 0x00000001;
3161 snd_cs46xx_poke(chip, BA1_CIE, tmp); /* capture interrupt enable */
3162}
3163
3143int __devinit snd_cs46xx_start_dsp(struct snd_cs46xx *chip) 3164int __devinit snd_cs46xx_start_dsp(struct snd_cs46xx *chip)
3144{ 3165{
3145 unsigned int tmp; 3166 unsigned int tmp;
@@ -3214,19 +3235,7 @@ int __devinit snd_cs46xx_start_dsp(struct snd_cs46xx *chip)
3214 3235
3215 snd_cs46xx_proc_start(chip); 3236 snd_cs46xx_proc_start(chip);
3216 3237
3217 /* 3238 cs46xx_enable_stream_irqs(chip);
3218 * Enable interrupts on the part.
3219 */
3220 snd_cs46xx_pokeBA0(chip, BA0_HICR, HICR_IEV | HICR_CHGM);
3221
3222 tmp = snd_cs46xx_peek(chip, BA1_PFIE);
3223 tmp &= ~0x0000f03f;
3224 snd_cs46xx_poke(chip, BA1_PFIE, tmp); /* playback interrupt enable */
3225
3226 tmp = snd_cs46xx_peek(chip, BA1_CIE);
3227 tmp &= ~0x0000003f;
3228 tmp |= 0x00000001;
3229 snd_cs46xx_poke(chip, BA1_CIE, tmp); /* capture interrupt enable */
3230 3239
3231#ifndef CONFIG_SND_CS46XX_NEW_DSP 3240#ifndef CONFIG_SND_CS46XX_NEW_DSP
3232 /* set the attenuation to 0dB */ 3241 /* set the attenuation to 0dB */
@@ -3665,11 +3674,19 @@ static struct cs_card_type __devinitdata cards[] = {
3665 * APM support 3674 * APM support
3666 */ 3675 */
3667#ifdef CONFIG_PM 3676#ifdef CONFIG_PM
3677static unsigned int saved_regs[] = {
3678 BA0_ACOSV,
3679 BA0_ASER_FADDR,
3680 BA0_ASER_MASTER,
3681 BA1_PVOL,
3682 BA1_CVOL,
3683};
3684
3668int snd_cs46xx_suspend(struct pci_dev *pci, pm_message_t state) 3685int snd_cs46xx_suspend(struct pci_dev *pci, pm_message_t state)
3669{ 3686{
3670 struct snd_card *card = pci_get_drvdata(pci); 3687 struct snd_card *card = pci_get_drvdata(pci);
3671 struct snd_cs46xx *chip = card->private_data; 3688 struct snd_cs46xx *chip = card->private_data;
3672 int amp_saved; 3689 int i, amp_saved;
3673 3690
3674 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); 3691 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
3675 chip->in_suspend = 1; 3692 chip->in_suspend = 1;
@@ -3680,6 +3697,10 @@ int snd_cs46xx_suspend(struct pci_dev *pci, pm_message_t state)
3680 snd_ac97_suspend(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]); 3697 snd_ac97_suspend(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]);
3681 snd_ac97_suspend(chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]); 3698 snd_ac97_suspend(chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]);
3682 3699
3700 /* save some registers */
3701 for (i = 0; i < ARRAY_SIZE(saved_regs); i++)
3702 chip->saved_regs[i] = snd_cs46xx_peekBA0(chip, saved_regs[i]);
3703
3683 amp_saved = chip->amplifier; 3704 amp_saved = chip->amplifier;
3684 /* turn off amp */ 3705 /* turn off amp */
3685 chip->amplifier_ctrl(chip, -chip->amplifier); 3706 chip->amplifier_ctrl(chip, -chip->amplifier);
@@ -3698,7 +3719,7 @@ int snd_cs46xx_resume(struct pci_dev *pci)
3698{ 3719{
3699 struct snd_card *card = pci_get_drvdata(pci); 3720 struct snd_card *card = pci_get_drvdata(pci);
3700 struct snd_cs46xx *chip = card->private_data; 3721 struct snd_cs46xx *chip = card->private_data;
3701 int amp_saved; 3722 int i, amp_saved;
3702 3723
3703 pci_set_power_state(pci, PCI_D0); 3724 pci_set_power_state(pci, PCI_D0);
3704 pci_restore_state(pci); 3725 pci_restore_state(pci);
@@ -3716,6 +3737,16 @@ int snd_cs46xx_resume(struct pci_dev *pci)
3716 3737
3717 snd_cs46xx_chip_init(chip); 3738 snd_cs46xx_chip_init(chip);
3718 3739
3740 snd_cs46xx_reset(chip);
3741#ifdef CONFIG_SND_CS46XX_NEW_DSP
3742 cs46xx_dsp_resume(chip);
3743 /* restore some registers */
3744 for (i = 0; i < ARRAY_SIZE(saved_regs); i++)
3745 snd_cs46xx_pokeBA0(chip, saved_regs[i], chip->saved_regs[i]);
3746#else
3747 snd_cs46xx_download_image(chip);
3748#endif
3749
3719#if 0 3750#if 0
3720 snd_cs46xx_codec_write(chip, BA0_AC97_GENERAL_PURPOSE, 3751 snd_cs46xx_codec_write(chip, BA0_AC97_GENERAL_PURPOSE,
3721 chip->ac97_general_purpose); 3752 chip->ac97_general_purpose);
@@ -3730,6 +3761,13 @@ int snd_cs46xx_resume(struct pci_dev *pci)
3730 snd_ac97_resume(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]); 3761 snd_ac97_resume(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]);
3731 snd_ac97_resume(chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]); 3762 snd_ac97_resume(chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]);
3732 3763
3764 /* reset playback/capture */
3765 snd_cs46xx_set_play_sample_rate(chip, 8000);
3766 snd_cs46xx_set_capture_sample_rate(chip, 8000);
3767 snd_cs46xx_proc_start(chip);
3768
3769 cs46xx_enable_stream_irqs(chip);
3770
3733 if (amp_saved) 3771 if (amp_saved)
3734 chip->amplifier_ctrl(chip, 1); /* turn amp on */ 3772 chip->amplifier_ctrl(chip, 1); /* turn amp on */
3735 else 3773 else
@@ -3896,6 +3934,15 @@ int __devinit snd_cs46xx_create(struct snd_card *card,
3896 3934
3897 snd_cs46xx_proc_init(card, chip); 3935 snd_cs46xx_proc_init(card, chip);
3898 3936
3937#ifdef CONFIG_PM
3938 chip->saved_regs = kmalloc(sizeof(*chip->saved_regs) *
3939 ARRAY_SIZE(saved_regs), GFP_KERNEL);
3940 if (!chip->saved_regs) {
3941 snd_cs46xx_free(chip);
3942 return -ENOMEM;
3943 }
3944#endif
3945
3899 chip->active_ctrl(chip, -1); /* disable CLKRUN */ 3946 chip->active_ctrl(chip, -1); /* disable CLKRUN */
3900 3947
3901 snd_card_set_dev(card, &pci->dev); 3948 snd_card_set_dev(card, &pci->dev);
diff --git a/sound/pci/cs46xx/cs46xx_lib.h b/sound/pci/cs46xx/cs46xx_lib.h
index f75750c2bd24..20dcd72f06c1 100644
--- a/sound/pci/cs46xx/cs46xx_lib.h
+++ b/sound/pci/cs46xx/cs46xx_lib.h
@@ -86,6 +86,9 @@ static inline unsigned int snd_cs46xx_peekBA0(struct snd_cs46xx *chip, unsigned
86struct dsp_spos_instance *cs46xx_dsp_spos_create (struct snd_cs46xx * chip); 86struct dsp_spos_instance *cs46xx_dsp_spos_create (struct snd_cs46xx * chip);
87void cs46xx_dsp_spos_destroy (struct snd_cs46xx * chip); 87void cs46xx_dsp_spos_destroy (struct snd_cs46xx * chip);
88int cs46xx_dsp_load_module (struct snd_cs46xx * chip, struct dsp_module_desc * module); 88int cs46xx_dsp_load_module (struct snd_cs46xx * chip, struct dsp_module_desc * module);
89#ifdef CONFIG_PM
90int cs46xx_dsp_resume(struct snd_cs46xx * chip);
91#endif
89struct dsp_symbol_entry *cs46xx_dsp_lookup_symbol (struct snd_cs46xx * chip, char * symbol_name, 92struct dsp_symbol_entry *cs46xx_dsp_lookup_symbol (struct snd_cs46xx * chip, char * symbol_name,
90 int symbol_type); 93 int symbol_type);
91#ifdef CONFIG_PROC_FS 94#ifdef CONFIG_PROC_FS
diff --git a/sound/pci/cs46xx/dsp_spos.c b/sound/pci/cs46xx/dsp_spos.c
index 336e77e2600c..590b35d91df2 100644
--- a/sound/pci/cs46xx/dsp_spos.c
+++ b/sound/pci/cs46xx/dsp_spos.c
@@ -306,13 +306,59 @@ void cs46xx_dsp_spos_destroy (struct snd_cs46xx * chip)
306 mutex_unlock(&chip->spos_mutex); 306 mutex_unlock(&chip->spos_mutex);
307} 307}
308 308
309static int dsp_load_parameter(struct snd_cs46xx *chip,
310 struct dsp_segment_desc *parameter)
311{
312 u32 doffset, dsize;
313
314 if (!parameter) {
315 snd_printdd("dsp_spos: module got no parameter segment\n");
316 return 0;
317 }
318
319 doffset = (parameter->offset * 4 + DSP_PARAMETER_BYTE_OFFSET);
320 dsize = parameter->size * 4;
321
322 snd_printdd("dsp_spos: "
323 "downloading parameter data to chip (%08x-%08x)\n",
324 doffset,doffset + dsize);
325 if (snd_cs46xx_download (chip, parameter->data, doffset, dsize)) {
326 snd_printk(KERN_ERR "dsp_spos: "
327 "failed to download parameter data to DSP\n");
328 return -EINVAL;
329 }
330 return 0;
331}
332
333static int dsp_load_sample(struct snd_cs46xx *chip,
334 struct dsp_segment_desc *sample)
335{
336 u32 doffset, dsize;
337
338 if (!sample) {
339 snd_printdd("dsp_spos: module got no sample segment\n");
340 return 0;
341 }
342
343 doffset = (sample->offset * 4 + DSP_SAMPLE_BYTE_OFFSET);
344 dsize = sample->size * 4;
345
346 snd_printdd("dsp_spos: downloading sample data to chip (%08x-%08x)\n",
347 doffset,doffset + dsize);
348
349 if (snd_cs46xx_download (chip,sample->data,doffset,dsize)) {
350 snd_printk(KERN_ERR "dsp_spos: failed to sample data to DSP\n");
351 return -EINVAL;
352 }
353 return 0;
354}
355
309int cs46xx_dsp_load_module (struct snd_cs46xx * chip, struct dsp_module_desc * module) 356int cs46xx_dsp_load_module (struct snd_cs46xx * chip, struct dsp_module_desc * module)
310{ 357{
311 struct dsp_spos_instance * ins = chip->dsp_spos_instance; 358 struct dsp_spos_instance * ins = chip->dsp_spos_instance;
312 struct dsp_segment_desc * code = get_segment_desc (module,SEGTYPE_SP_PROGRAM); 359 struct dsp_segment_desc * code = get_segment_desc (module,SEGTYPE_SP_PROGRAM);
313 struct dsp_segment_desc * parameter = get_segment_desc (module,SEGTYPE_SP_PARAMETER);
314 struct dsp_segment_desc * sample = get_segment_desc (module,SEGTYPE_SP_SAMPLE);
315 u32 doffset, dsize; 360 u32 doffset, dsize;
361 int err;
316 362
317 if (ins->nmodules == DSP_MAX_MODULES - 1) { 363 if (ins->nmodules == DSP_MAX_MODULES - 1) {
318 snd_printk(KERN_ERR "dsp_spos: to many modules loaded into DSP\n"); 364 snd_printk(KERN_ERR "dsp_spos: to many modules loaded into DSP\n");
@@ -326,49 +372,20 @@ int cs46xx_dsp_load_module (struct snd_cs46xx * chip, struct dsp_module_desc * m
326 snd_cs46xx_clear_BA1(chip, DSP_PARAMETER_BYTE_OFFSET, DSP_PARAMETER_BYTE_SIZE); 372 snd_cs46xx_clear_BA1(chip, DSP_PARAMETER_BYTE_OFFSET, DSP_PARAMETER_BYTE_SIZE);
327 } 373 }
328 374
329 if (parameter == NULL) { 375 err = dsp_load_parameter(chip, get_segment_desc(module,
330 snd_printdd("dsp_spos: module got no parameter segment\n"); 376 SEGTYPE_SP_PARAMETER));
331 } else { 377 if (err < 0)
332 if (ins->nmodules > 0) { 378 return err;
333 snd_printk(KERN_WARNING "dsp_spos: WARNING current parameter data may be overwriten!\n");
334 }
335
336 doffset = (parameter->offset * 4 + DSP_PARAMETER_BYTE_OFFSET);
337 dsize = parameter->size * 4;
338
339 snd_printdd("dsp_spos: downloading parameter data to chip (%08x-%08x)\n",
340 doffset,doffset + dsize);
341
342 if (snd_cs46xx_download (chip, parameter->data, doffset, dsize)) {
343 snd_printk(KERN_ERR "dsp_spos: failed to download parameter data to DSP\n");
344 return -EINVAL;
345 }
346 }
347 379
348 if (ins->nmodules == 0) { 380 if (ins->nmodules == 0) {
349 snd_printdd("dsp_spos: clearing sample area\n"); 381 snd_printdd("dsp_spos: clearing sample area\n");
350 snd_cs46xx_clear_BA1(chip, DSP_SAMPLE_BYTE_OFFSET, DSP_SAMPLE_BYTE_SIZE); 382 snd_cs46xx_clear_BA1(chip, DSP_SAMPLE_BYTE_OFFSET, DSP_SAMPLE_BYTE_SIZE);
351 } 383 }
352 384
353 if (sample == NULL) { 385 err = dsp_load_sample(chip, get_segment_desc(module,
354 snd_printdd("dsp_spos: module got no sample segment\n"); 386 SEGTYPE_SP_SAMPLE));
355 } else { 387 if (err < 0)
356 if (ins->nmodules > 0) { 388 return err;
357 snd_printk(KERN_WARNING "dsp_spos: WARNING current sample data may be overwriten\n");
358 }
359
360 doffset = (sample->offset * 4 + DSP_SAMPLE_BYTE_OFFSET);
361 dsize = sample->size * 4;
362
363 snd_printdd("dsp_spos: downloading sample data to chip (%08x-%08x)\n",
364 doffset,doffset + dsize);
365
366 if (snd_cs46xx_download (chip,sample->data,doffset,dsize)) {
367 snd_printk(KERN_ERR "dsp_spos: failed to sample data to DSP\n");
368 return -EINVAL;
369 }
370 }
371
372 389
373 if (ins->nmodules == 0) { 390 if (ins->nmodules == 0) {
374 snd_printdd("dsp_spos: clearing code area\n"); 391 snd_printdd("dsp_spos: clearing code area\n");
@@ -986,7 +1003,10 @@ _map_task_tree (struct snd_cs46xx *chip, char * name, u32 dest, u32 size)
986 return NULL; 1003 return NULL;
987 } 1004 }
988 1005
989 strcpy(ins->tasks[ins->ntask].task_name,name); 1006 if (name)
1007 strcpy(ins->tasks[ins->ntask].task_name, name);
1008 else
1009 strcpy(ins->tasks[ins->ntask].task_name, "(NULL)");
990 ins->tasks[ins->ntask].address = dest; 1010 ins->tasks[ins->ntask].address = dest;
991 ins->tasks[ins->ntask].size = size; 1011 ins->tasks[ins->ntask].size = size;
992 1012
@@ -995,7 +1015,8 @@ _map_task_tree (struct snd_cs46xx *chip, char * name, u32 dest, u32 size)
995 desc = (ins->tasks + ins->ntask); 1015 desc = (ins->tasks + ins->ntask);
996 ins->ntask++; 1016 ins->ntask++;
997 1017
998 add_symbol (chip,name,dest,SYMBOL_PARAMETER); 1018 if (name)
1019 add_symbol (chip,name,dest,SYMBOL_PARAMETER);
999 return desc; 1020 return desc;
1000} 1021}
1001 1022
@@ -1006,6 +1027,7 @@ cs46xx_dsp_create_scb (struct snd_cs46xx *chip, char * name, u32 * scb_data, u32
1006 1027
1007 desc = _map_scb (chip,name,dest); 1028 desc = _map_scb (chip,name,dest);
1008 if (desc) { 1029 if (desc) {
1030 desc->data = scb_data;
1009 _dsp_create_scb(chip,scb_data,dest); 1031 _dsp_create_scb(chip,scb_data,dest);
1010 } else { 1032 } else {
1011 snd_printk(KERN_ERR "dsp_spos: failed to map SCB\n"); 1033 snd_printk(KERN_ERR "dsp_spos: failed to map SCB\n");
@@ -1023,6 +1045,7 @@ cs46xx_dsp_create_task_tree (struct snd_cs46xx *chip, char * name, u32 * task_da
1023 1045
1024 desc = _map_task_tree (chip,name,dest,size); 1046 desc = _map_task_tree (chip,name,dest,size);
1025 if (desc) { 1047 if (desc) {
1048 desc->data = task_data;
1026 _dsp_create_task_tree(chip,task_data,dest,size); 1049 _dsp_create_task_tree(chip,task_data,dest,size);
1027 } else { 1050 } else {
1028 snd_printk(KERN_ERR "dsp_spos: failed to map TASK\n"); 1051 snd_printk(KERN_ERR "dsp_spos: failed to map TASK\n");
@@ -1320,8 +1343,10 @@ int cs46xx_dsp_scb_and_task_init (struct snd_cs46xx *chip)
1320 0x0000ffff 1343 0x0000ffff
1321 }; 1344 };
1322 1345
1323 /* dirty hack ... */ 1346 if (!cs46xx_dsp_create_task_tree(chip, NULL,
1324 _dsp_create_task_tree (chip,(u32 *)&mix2_ostream_spb,WRITE_BACK_SPB,2); 1347 (u32 *)&mix2_ostream_spb,
1348 WRITE_BACK_SPB, 2))
1349 goto _fail_end;
1325 } 1350 }
1326 1351
1327 /* input sample converter */ 1352 /* input sample converter */
@@ -1622,7 +1647,6 @@ static int cs46xx_dsp_async_init (struct snd_cs46xx *chip,
1622 return 0; 1647 return 0;
1623} 1648}
1624 1649
1625
1626static void cs46xx_dsp_disable_spdif_hw (struct snd_cs46xx *chip) 1650static void cs46xx_dsp_disable_spdif_hw (struct snd_cs46xx *chip)
1627{ 1651{
1628 struct dsp_spos_instance * ins = chip->dsp_spos_instance; 1652 struct dsp_spos_instance * ins = chip->dsp_spos_instance;
@@ -1894,3 +1918,61 @@ int cs46xx_dsp_set_iec958_volume (struct snd_cs46xx * chip, u16 left, u16 right)
1894 1918
1895 return 0; 1919 return 0;
1896} 1920}
1921
1922#ifdef CONFIG_PM
1923int cs46xx_dsp_resume(struct snd_cs46xx * chip)
1924{
1925 struct dsp_spos_instance * ins = chip->dsp_spos_instance;
1926 int i, err;
1927
1928 /* clear parameter, sample and code areas */
1929 snd_cs46xx_clear_BA1(chip, DSP_PARAMETER_BYTE_OFFSET,
1930 DSP_PARAMETER_BYTE_SIZE);
1931 snd_cs46xx_clear_BA1(chip, DSP_SAMPLE_BYTE_OFFSET,
1932 DSP_SAMPLE_BYTE_SIZE);
1933 snd_cs46xx_clear_BA1(chip, DSP_CODE_BYTE_OFFSET, DSP_CODE_BYTE_SIZE);
1934
1935 for (i = 0; i < ins->nmodules; i++) {
1936 struct dsp_module_desc *module = &ins->modules[i];
1937 struct dsp_segment_desc *seg;
1938 u32 doffset, dsize;
1939
1940 seg = get_segment_desc(module, SEGTYPE_SP_PARAMETER);
1941 err = dsp_load_parameter(chip, seg);
1942 if (err < 0)
1943 return err;
1944
1945 seg = get_segment_desc(module, SEGTYPE_SP_SAMPLE);
1946 err = dsp_load_sample(chip, seg);
1947 if (err < 0)
1948 return err;
1949
1950 seg = get_segment_desc(module, SEGTYPE_SP_PROGRAM);
1951 if (!seg)
1952 continue;
1953
1954 doffset = seg->offset * 4 + module->load_address * 4
1955 + DSP_CODE_BYTE_OFFSET;
1956 dsize = seg->size * 4;
1957 err = snd_cs46xx_download(chip,
1958 ins->code.data + module->load_address,
1959 doffset, dsize);
1960 if (err < 0)
1961 return err;
1962 }
1963
1964 for (i = 0; i < ins->ntask; i++) {
1965 struct dsp_task_descriptor *t = &ins->tasks[i];
1966 _dsp_create_task_tree(chip, t->data, t->address, t->size);
1967 }
1968
1969 for (i = 0; i < ins->nscb; i++) {
1970 struct dsp_scb_descriptor *s = &ins->scbs[i];
1971 if (s->deleted)
1972 continue;
1973 _dsp_create_scb(chip, s->data, s->address);
1974 }
1975
1976 return 0;
1977}
1978#endif
diff --git a/sound/pci/cs5530.c b/sound/pci/cs5530.c
new file mode 100644
index 000000000000..240a0a462209
--- /dev/null
+++ b/sound/pci/cs5530.c
@@ -0,0 +1,306 @@
1/*
2 * cs5530.c - Initialisation code for Cyrix/NatSemi VSA1 softaudio
3 *
4 * (C) Copyright 2007 Ash Willis <ashwillis@programmer.net>
5 * (C) Copyright 2003 Red Hat Inc <alan@redhat.com>
6 *
7 * This driver was ported (shamelessly ripped ;) from oss/kahlua.c but I did
8 * mess with it a bit. The chip seems to have to have trouble with full duplex
9 * mode. If we're recording in 8bit 8000kHz, say, and we then attempt to
10 * simultaneously play back audio at 16bit 44100kHz, the device actually plays
11 * back in the same format in which it is capturing. By forcing the chip to
12 * always play/capture in 16/44100, we can let alsa-lib convert the samples and
13 * that way we can hack up some full duplex audio.
14 *
15 * XpressAudio(tm) is used on the Cyrix MediaGX (now NatSemi Geode) systems.
16 * The older version (VSA1) provides fairly good soundblaster emulation
17 * although there are a couple of bugs: large DMA buffers break record,
18 * and the MPU event handling seems suspect. VSA2 allows the native driver
19 * to control the AC97 audio engine directly and requires a different driver.
20 *
21 * Thanks to National Semiconductor for providing the needed information
22 * on the XpressAudio(tm) internals.
23 *
24 * This program is free software; you can redistribute it and/or modify it
25 * under the terms of the GNU General Public License as published by the
26 * Free Software Foundation; either version 2, or (at your option) any
27 * later version.
28 *
29 * This program is distributed in the hope that it will be useful, but
30 * WITHOUT ANY WARRANTY; without even the implied warranty of
31 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
32 * General Public License for more details.
33 *
34 * TO DO:
35 * Investigate whether we can portably support Cognac (5520) in the
36 * same manner.
37 */
38
39#include <sound/driver.h>
40#include <linux/delay.h>
41#include <linux/moduleparam.h>
42#include <linux/pci.h>
43#include <sound/core.h>
44#include <sound/sb.h>
45#include <sound/initval.h>
46
47MODULE_AUTHOR("Ash Willis");
48MODULE_DESCRIPTION("CS5530 Audio");
49MODULE_LICENSE("GPL");
50
51static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
52static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
53static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
54
55struct snd_cs5530 {
56 struct snd_card *card;
57 struct pci_dev *pci;
58 struct snd_sb *sb;
59 unsigned long pci_base;
60};
61
62static struct pci_device_id snd_cs5530_ids[] = {
63 {PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_AUDIO, PCI_ANY_ID,
64 PCI_ANY_ID, 0, 0},
65 {0,}
66};
67
68MODULE_DEVICE_TABLE(pci, snd_cs5530_ids);
69
70static int snd_cs5530_free(struct snd_cs5530 *chip)
71{
72 pci_release_regions(chip->pci);
73 pci_disable_device(chip->pci);
74 kfree(chip);
75 return 0;
76}
77
78static int snd_cs5530_dev_free(struct snd_device *device)
79{
80 struct snd_cs5530 *chip = device->device_data;
81 return snd_cs5530_free(chip);
82}
83
84static void __devexit snd_cs5530_remove(struct pci_dev *pci)
85{
86 snd_card_free(pci_get_drvdata(pci));
87 pci_set_drvdata(pci, NULL);
88}
89
90static u8 __devinit snd_cs5530_mixer_read(unsigned long io, u8 reg)
91{
92 outb(reg, io + 4);
93 udelay(20);
94 reg = inb(io + 5);
95 udelay(20);
96 return reg;
97}
98
99static int __devinit snd_cs5530_create(struct snd_card *card,
100 struct pci_dev *pci,
101 struct snd_cs5530 **rchip)
102{
103 struct snd_cs5530 *chip;
104 unsigned long sb_base;
105 u8 irq, dma8, dma16 = 0;
106 u16 map;
107 void __iomem *mem;
108 int err;
109
110 static struct snd_device_ops ops = {
111 .dev_free = snd_cs5530_dev_free,
112 };
113 *rchip = NULL;
114
115 err = pci_enable_device(pci);
116 if (err < 0)
117 return err;
118
119 chip = kzalloc(sizeof(*chip), GFP_KERNEL);
120 if (chip == NULL) {
121 pci_disable_device(pci);
122 return -ENOMEM;
123 }
124
125 chip->card = card;
126 chip->pci = pci;
127
128 err = pci_request_regions(pci, "CS5530");
129 if (err < 0) {
130 kfree(chip);
131 pci_disable_device(pci);
132 return err;
133 }
134 chip->pci_base = pci_resource_start(pci, 0);
135
136 mem = ioremap_nocache(chip->pci_base, pci_resource_len(pci, 0));
137 if (mem == NULL) {
138 kfree(chip);
139 pci_disable_device(pci);
140 return -EBUSY;
141 }
142
143 map = readw(mem + 0x18);
144 iounmap(mem);
145
146 /* Map bits
147 0:1 * 0x20 + 0x200 = sb base
148 2 sb enable
149 3 adlib enable
150 5 MPU enable 0x330
151 6 MPU enable 0x300
152
153 The other bits may be used internally so must be masked */
154
155 sb_base = 0x220 + 0x20 * (map & 3);
156
157 if (map & (1<<2))
158 printk(KERN_INFO "CS5530: XpressAudio at 0x%lx\n", sb_base);
159 else {
160 printk(KERN_ERR "Could not find XpressAudio!\n");
161 snd_cs5530_free(chip);
162 return -ENODEV;
163 }
164
165 if (map & (1<<5))
166 printk(KERN_INFO "CS5530: MPU at 0x300\n");
167 else if (map & (1<<6))
168 printk(KERN_INFO "CS5530: MPU at 0x330\n");
169
170 irq = snd_cs5530_mixer_read(sb_base, 0x80) & 0x0F;
171 dma8 = snd_cs5530_mixer_read(sb_base, 0x81);
172
173 if (dma8 & 0x20)
174 dma16 = 5;
175 else if (dma8 & 0x40)
176 dma16 = 6;
177 else if (dma8 & 0x80)
178 dma16 = 7;
179 else {
180 printk(KERN_ERR "CS5530: No 16bit DMA enabled\n");
181 snd_cs5530_free(chip);
182 return -ENODEV;
183 }
184
185 if (dma8 & 0x01)
186 dma8 = 0;
187 else if (dma8 & 02)
188 dma8 = 1;
189 else if (dma8 & 0x08)
190 dma8 = 3;
191 else {
192 printk(KERN_ERR "CS5530: No 8bit DMA enabled\n");
193 snd_cs5530_free(chip);
194 return -ENODEV;
195 }
196
197 if (irq & 1)
198 irq = 9;
199 else if (irq & 2)
200 irq = 5;
201 else if (irq & 4)
202 irq = 7;
203 else if (irq & 8)
204 irq = 10;
205 else {
206 printk(KERN_ERR "CS5530: SoundBlaster IRQ not set\n");
207 snd_cs5530_free(chip);
208 return -ENODEV;
209 }
210
211 printk(KERN_INFO "CS5530: IRQ: %d DMA8: %d DMA16: %d\n", irq, dma8,
212 dma16);
213
214 err = snd_sbdsp_create(card, sb_base, irq, snd_sb16dsp_interrupt, dma8,
215 dma16, SB_HW_CS5530, &chip->sb);
216 if (err < 0) {
217 printk(KERN_ERR "CS5530: Could not create SoundBlaster\n");
218 snd_cs5530_free(chip);
219 return err;
220 }
221
222 err = snd_sb16dsp_pcm(chip->sb, 0, &chip->sb->pcm);
223 if (err < 0) {
224 printk(KERN_ERR "CS5530: Could not create PCM\n");
225 snd_cs5530_free(chip);
226 return err;
227 }
228
229 err = snd_sbmixer_new(chip->sb);
230 if (err < 0) {
231 printk(KERN_ERR "CS5530: Could not create Mixer\n");
232 snd_cs5530_free(chip);
233 return err;
234 }
235
236 err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
237 if (err < 0) {
238 snd_cs5530_free(chip);
239 return err;
240 }
241
242 snd_card_set_dev(card, &pci->dev);
243 *rchip = chip;
244 return 0;
245}
246
247static int __devinit snd_cs5530_probe(struct pci_dev *pci,
248 const struct pci_device_id *pci_id)
249{
250 static int dev;
251 struct snd_card *card;
252 struct snd_cs5530 *chip = NULL;
253 int err;
254
255 if (dev >= SNDRV_CARDS)
256 return -ENODEV;
257 if (!enable[dev]) {
258 dev++;
259 return -ENOENT;
260 }
261
262 card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
263
264 if (card == NULL)
265 return -ENOMEM;
266
267 err = snd_cs5530_create(card, pci, &chip);
268 if (err < 0) {
269 snd_card_free(card);
270 return err;
271 }
272
273 strcpy(card->driver, "CS5530");
274 strcpy(card->shortname, "CS5530 Audio");
275 sprintf(card->longname, "%s at 0x%lx", card->shortname, chip->pci_base);
276
277 err = snd_card_register(card);
278 if (err < 0) {
279 snd_card_free(card);
280 return err;
281 }
282 pci_set_drvdata(pci, card);
283 dev++;
284 return 0;
285}
286
287static struct pci_driver driver = {
288 .name = "CS5530_Audio",
289 .id_table = snd_cs5530_ids,
290 .probe = snd_cs5530_probe,
291 .remove = __devexit_p(snd_cs5530_remove),
292};
293
294static int __init alsa_card_cs5530_init(void)
295{
296 return pci_register_driver(&driver);
297}
298
299static void __exit alsa_card_cs5530_exit(void)
300{
301 pci_unregister_driver(&driver);
302}
303
304module_init(alsa_card_cs5530_init)
305module_exit(alsa_card_cs5530_exit)
306
diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c
index 4a9b59ad8ab1..404ae1be0a4b 100644
--- a/sound/pci/emu10k1/emu10k1_main.c
+++ b/sound/pci/emu10k1/emu10k1_main.c
@@ -51,9 +51,15 @@
51 51
52#define HANA_FILENAME "emu/hana.fw" 52#define HANA_FILENAME "emu/hana.fw"
53#define DOCK_FILENAME "emu/audio_dock.fw" 53#define DOCK_FILENAME "emu/audio_dock.fw"
54#define EMU1010B_FILENAME "emu/emu1010b.fw"
55#define MICRO_DOCK_FILENAME "emu/micro_dock.fw"
56#define EMU1010_NOTEBOOK_FILENAME "emu/emu1010_notebook.fw"
54 57
55MODULE_FIRMWARE(HANA_FILENAME); 58MODULE_FIRMWARE(HANA_FILENAME);
56MODULE_FIRMWARE(DOCK_FILENAME); 59MODULE_FIRMWARE(DOCK_FILENAME);
60MODULE_FIRMWARE(EMU1010B_FILENAME);
61MODULE_FIRMWARE(MICRO_DOCK_FILENAME);
62MODULE_FIRMWARE(EMU1010_NOTEBOOK_FILENAME);
57 63
58 64
59/************************************************************************* 65/*************************************************************************
@@ -660,10 +666,12 @@ static int snd_emu1010_load_firmware(struct snd_emu10k1 * emu, const char * file
660 return err; 666 return err;
661 } 667 }
662 snd_printk(KERN_INFO "firmware size=0x%zx\n", fw_entry->size); 668 snd_printk(KERN_INFO "firmware size=0x%zx\n", fw_entry->size);
669#if 0
663 if (fw_entry->size != 0x133a4) { 670 if (fw_entry->size != 0x133a4) {
664 snd_printk(KERN_ERR "firmware: %s wrong size.\n",filename); 671 snd_printk(KERN_ERR "firmware: %s wrong size.\n",filename);
665 return -EINVAL; 672 return -EINVAL;
666 } 673 }
674#endif
667 675
668 /* The FPGA is a Xilinx Spartan IIE XC2S50E */ 676 /* The FPGA is a Xilinx Spartan IIE XC2S50E */
669 /* GPIO7 -> FPGA PGMN 677 /* GPIO7 -> FPGA PGMN
@@ -694,6 +702,37 @@ static int snd_emu1010_load_firmware(struct snd_emu10k1 * emu, const char * file
694 return 0; 702 return 0;
695} 703}
696 704
705/*
706 * EMU-1010 - details found out from this driver, official MS Win drivers,
707 * testing the card:
708 *
709 * Audigy2 (aka Alice2):
710 * ---------------------
711 * * communication over PCI
712 * * conversion of 32-bit data coming over EMU32 links from HANA FPGA
713 * to 2 x 16-bit, using internal DSP instructions
714 * * slave mode, clock supplied by HANA
715 * * linked to HANA using:
716 * 32 x 32-bit serial EMU32 output channels
717 * 16 x EMU32 input channels
718 * (?) x I2S I/O channels (?)
719 *
720 * FPGA (aka HANA):
721 * ---------------
722 * * provides all (?) physical inputs and outputs of the card
723 * (ADC, DAC, SPDIF I/O, ADAT I/O, etc.)
724 * * provides clock signal for the card and Alice2
725 * * two crystals - for 44.1kHz and 48kHz multiples
726 * * provides internal routing of signal sources to signal destinations
727 * * inputs/outputs to Alice2 - see above
728 *
729 * Current status of the driver:
730 * ----------------------------
731 * * only 44.1/48kHz supported (the MS Win driver supports up to 192 kHz)
732 * * PCM device nb. 2:
733 * 16 x 16-bit playback - snd_emu10k1_fx8010_playback_ops
734 * 16 x 32-bit capture - snd_emu10k1_capture_efx_ops
735 */
697static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu) 736static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu)
698{ 737{
699 unsigned int i; 738 unsigned int i;
@@ -727,7 +766,7 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu)
727 /* ID, should read & 0x7f = 0x55. (Bit 7 is the IRQ bit) */ 766 /* ID, should read & 0x7f = 0x55. (Bit 7 is the IRQ bit) */
728 snd_emu1010_fpga_read(emu, EMU_HANA_ID, &reg ); 767 snd_emu1010_fpga_read(emu, EMU_HANA_ID, &reg );
729 snd_printdd("reg1=0x%x\n",reg); 768 snd_printdd("reg1=0x%x\n",reg);
730 if (reg == 0x55) { 769 if ((reg & 0x3f) == 0x15) {
731 /* FPGA netlist already present so clear it */ 770 /* FPGA netlist already present so clear it */
732 /* Return to programming mode */ 771 /* Return to programming mode */
733 772
@@ -735,19 +774,32 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu)
735 } 774 }
736 snd_emu1010_fpga_read(emu, EMU_HANA_ID, &reg ); 775 snd_emu1010_fpga_read(emu, EMU_HANA_ID, &reg );
737 snd_printdd("reg2=0x%x\n",reg); 776 snd_printdd("reg2=0x%x\n",reg);
738 if (reg == 0x55) { 777 if ((reg & 0x3f) == 0x15) {
739 /* FPGA failed to return to programming mode */ 778 /* FPGA failed to return to programming mode */
779 snd_printk(KERN_INFO "emu1010: FPGA failed to return to programming mode\n");
740 return -ENODEV; 780 return -ENODEV;
741 } 781 }
742 snd_printk(KERN_INFO "emu1010: EMU_HANA_ID=0x%x\n",reg); 782 snd_printk(KERN_INFO "emu1010: EMU_HANA_ID=0x%x\n",reg);
743 if ((err = snd_emu1010_load_firmware(emu, HANA_FILENAME)) != 0) { 783 if (emu->card_capabilities->emu1010 == 1) {
744 snd_printk(KERN_INFO "emu1010: Loading Hana Firmware file %s failed\n", HANA_FILENAME); 784 if ((err = snd_emu1010_load_firmware(emu, HANA_FILENAME)) != 0) {
745 return err; 785 snd_printk(KERN_INFO "emu1010: Loading Hana Firmware file %s failed\n", HANA_FILENAME);
786 return err;
787 }
788 } else if (emu->card_capabilities->emu1010 == 2) {
789 if ((err = snd_emu1010_load_firmware(emu, EMU1010B_FILENAME)) != 0) {
790 snd_printk(KERN_INFO "emu1010: Loading Firmware file %s failed\n", EMU1010B_FILENAME);
791 return err;
792 }
793 } else if (emu->card_capabilities->emu1010 == 3) {
794 if ((err = snd_emu1010_load_firmware(emu, EMU1010_NOTEBOOK_FILENAME)) != 0) {
795 snd_printk(KERN_INFO "emu1010: Loading Firmware file %s failed\n", EMU1010_NOTEBOOK_FILENAME);
796 return err;
797 }
746 } 798 }
747 799
748 /* ID, should read & 0x7f = 0x55 when FPGA programmed. */ 800 /* ID, should read & 0x7f = 0x55 when FPGA programmed. */
749 snd_emu1010_fpga_read(emu, EMU_HANA_ID, &reg ); 801 snd_emu1010_fpga_read(emu, EMU_HANA_ID, &reg );
750 if (reg != 0x55) { 802 if ((reg & 0x3f) != 0x15) {
751 /* FPGA failed to be programmed */ 803 /* FPGA failed to be programmed */
752 snd_printk(KERN_INFO "emu1010: Loading Hana Firmware file failed, reg=0x%x\n", reg); 804 snd_printk(KERN_INFO "emu1010: Loading Hana Firmware file failed, reg=0x%x\n", reg);
753 return -ENODEV; 805 return -ENODEV;
@@ -850,6 +902,27 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu)
850 EMU_DST_ALICE2_EMU32_6, EMU_SRC_DOCK_ADC2_LEFT1); 902 EMU_DST_ALICE2_EMU32_6, EMU_SRC_DOCK_ADC2_LEFT1);
851 snd_emu1010_fpga_link_dst_src_write(emu, 903 snd_emu1010_fpga_link_dst_src_write(emu,
852 EMU_DST_ALICE2_EMU32_7, EMU_SRC_DOCK_ADC2_RIGHT1); 904 EMU_DST_ALICE2_EMU32_7, EMU_SRC_DOCK_ADC2_RIGHT1);
905 /* Pavel Hofman - setting defaults for 8 more capture channels
906 * Defaults only, users will set their own values anyways, let's
907 * just copy/paste.
908 */
909
910 snd_emu1010_fpga_link_dst_src_write(emu,
911 EMU_DST_ALICE2_EMU32_8, EMU_SRC_DOCK_MIC_A1);
912 snd_emu1010_fpga_link_dst_src_write(emu,
913 EMU_DST_ALICE2_EMU32_9, EMU_SRC_DOCK_MIC_B1);
914 snd_emu1010_fpga_link_dst_src_write(emu,
915 EMU_DST_ALICE2_EMU32_A, EMU_SRC_HAMOA_ADC_LEFT2);
916 snd_emu1010_fpga_link_dst_src_write(emu,
917 EMU_DST_ALICE2_EMU32_B, EMU_SRC_HAMOA_ADC_LEFT2);
918 snd_emu1010_fpga_link_dst_src_write(emu,
919 EMU_DST_ALICE2_EMU32_C, EMU_SRC_DOCK_ADC1_LEFT1);
920 snd_emu1010_fpga_link_dst_src_write(emu,
921 EMU_DST_ALICE2_EMU32_D, EMU_SRC_DOCK_ADC1_RIGHT1);
922 snd_emu1010_fpga_link_dst_src_write(emu,
923 EMU_DST_ALICE2_EMU32_E, EMU_SRC_DOCK_ADC2_LEFT1);
924 snd_emu1010_fpga_link_dst_src_write(emu,
925 EMU_DST_ALICE2_EMU32_F, EMU_SRC_DOCK_ADC2_RIGHT1);
853#endif 926#endif
854#if 0 927#if 0
855 /* Original */ 928 /* Original */
@@ -943,16 +1016,27 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu)
943 /* Return to Audio Dock programming mode */ 1016 /* Return to Audio Dock programming mode */
944 snd_printk(KERN_INFO "emu1010: Loading Audio Dock Firmware\n"); 1017 snd_printk(KERN_INFO "emu1010: Loading Audio Dock Firmware\n");
945 snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, EMU_HANA_FPGA_CONFIG_AUDIODOCK ); 1018 snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, EMU_HANA_FPGA_CONFIG_AUDIODOCK );
946 if ((err = snd_emu1010_load_firmware(emu, DOCK_FILENAME)) != 0) { 1019 if (emu->card_capabilities->emu1010 == 1) {
947 return err; 1020 if ((err = snd_emu1010_load_firmware(emu, DOCK_FILENAME)) != 0) {
1021 return err;
1022 }
1023 } else if (emu->card_capabilities->emu1010 == 2) {
1024 if ((err = snd_emu1010_load_firmware(emu, MICRO_DOCK_FILENAME)) != 0) {
1025 return err;
1026 }
1027 } else if (emu->card_capabilities->emu1010 == 3) {
1028 if ((err = snd_emu1010_load_firmware(emu, MICRO_DOCK_FILENAME)) != 0) {
1029 return err;
1030 }
948 } 1031 }
1032
949 snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, 0 ); 1033 snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, 0 );
950 snd_emu1010_fpga_read(emu, EMU_HANA_IRQ_STATUS, &reg ); 1034 snd_emu1010_fpga_read(emu, EMU_HANA_IRQ_STATUS, &reg );
951 snd_printk(KERN_INFO "emu1010: EMU_HANA+DOCK_IRQ_STATUS=0x%x\n",reg); 1035 snd_printk(KERN_INFO "emu1010: EMU_HANA+DOCK_IRQ_STATUS=0x%x\n",reg);
952 /* ID, should read & 0x7f = 0x55 when FPGA programmed. */ 1036 /* ID, should read & 0x7f = 0x55 when FPGA programmed. */
953 snd_emu1010_fpga_read(emu, EMU_HANA_ID, &reg ); 1037 snd_emu1010_fpga_read(emu, EMU_HANA_ID, &reg );
954 snd_printk(KERN_INFO "emu1010: EMU_HANA+DOCK_ID=0x%x\n",reg); 1038 snd_printk(KERN_INFO "emu1010: EMU_HANA+DOCK_ID=0x%x\n",reg);
955 if (reg != 0x55) { 1039 if ((reg & 0x3f) != 0x15) {
956 /* FPGA failed to be programmed */ 1040 /* FPGA failed to be programmed */
957 snd_printk(KERN_INFO "emu1010: Loading Audio Dock Firmware file failed, reg=0x%x\n", reg); 1041 snd_printk(KERN_INFO "emu1010: Loading Audio Dock Firmware file failed, reg=0x%x\n", reg);
958 return 0; 1042 return 0;
@@ -1227,9 +1311,15 @@ static struct snd_emu_chip_details emu_chip_details[] = {
1227 .emu10k2_chip = 1, 1311 .emu10k2_chip = 1,
1228 .ca0108_chip = 1, 1312 .ca0108_chip = 1,
1229 .ca_cardbus_chip = 1, 1313 .ca_cardbus_chip = 1,
1230 .spi_dac = 1, 1314 .spk71 = 1 ,
1231 .i2c_adc = 1, 1315 .emu1010 = 3} ,
1232 .spk71 = 1} , 1316 {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x40041102,
1317 .driver = "Audigy2", .name = "E-mu 1010b PCI [MAEM????]",
1318 .id = "EMU1010",
1319 .emu10k2_chip = 1,
1320 .ca0108_chip = 1,
1321 .spk71 = 1 ,
1322 .emu1010 = 2} ,
1233 {.vendor = 0x1102, .device = 0x0008, 1323 {.vendor = 0x1102, .device = 0x0008,
1234 .driver = "Audigy2", .name = "Audigy 2 Value [Unknown]", 1324 .driver = "Audigy2", .name = "Audigy 2 Value [Unknown]",
1235 .id = "Audigy2", 1325 .id = "Audigy2",
@@ -1663,12 +1753,13 @@ int __devinit snd_emu10k1_create(struct snd_card *card,
1663 emu->fx8010.extout_mask = extout_mask; 1753 emu->fx8010.extout_mask = extout_mask;
1664 emu->enable_ir = enable_ir; 1754 emu->enable_ir = enable_ir;
1665 1755
1756 if (emu->card_capabilities->ca_cardbus_chip) {
1757 if ((err = snd_emu10k1_cardbus_init(emu)) < 0)
1758 goto error;
1759 }
1666 if (emu->card_capabilities->ecard) { 1760 if (emu->card_capabilities->ecard) {
1667 if ((err = snd_emu10k1_ecard_init(emu)) < 0) 1761 if ((err = snd_emu10k1_ecard_init(emu)) < 0)
1668 goto error; 1762 goto error;
1669 } else if (emu->card_capabilities->ca_cardbus_chip) {
1670 if ((err = snd_emu10k1_cardbus_init(emu)) < 0)
1671 goto error;
1672 } else if (emu->card_capabilities->emu1010) { 1763 } else if (emu->card_capabilities->emu1010) {
1673 if ((err = snd_emu10k1_emu1010_init(emu)) < 0) { 1764 if ((err = snd_emu10k1_emu1010_init(emu)) < 0) {
1674 snd_emu10k1_free(emu); 1765 snd_emu10k1_free(emu);
@@ -1814,10 +1905,10 @@ void snd_emu10k1_suspend_regs(struct snd_emu10k1 *emu)
1814 1905
1815void snd_emu10k1_resume_init(struct snd_emu10k1 *emu) 1906void snd_emu10k1_resume_init(struct snd_emu10k1 *emu)
1816{ 1907{
1908 if (emu->card_capabilities->ca_cardbus_chip)
1909 snd_emu10k1_cardbus_init(emu);
1817 if (emu->card_capabilities->ecard) 1910 if (emu->card_capabilities->ecard)
1818 snd_emu10k1_ecard_init(emu); 1911 snd_emu10k1_ecard_init(emu);
1819 else if (emu->card_capabilities->ca_cardbus_chip)
1820 snd_emu10k1_cardbus_init(emu);
1821 else if (emu->card_capabilities->emu1010) 1912 else if (emu->card_capabilities->emu1010)
1822 snd_emu10k1_emu1010_init(emu); 1913 snd_emu10k1_emu1010_init(emu);
1823 else 1914 else
diff --git a/sound/pci/emu10k1/emufx.c b/sound/pci/emu10k1/emufx.c
index c02012cccd8e..7206c0fa06f2 100644
--- a/sound/pci/emu10k1/emufx.c
+++ b/sound/pci/emu10k1/emufx.c
@@ -1123,6 +1123,11 @@ snd_emu10k1_init_stereo_onoff_control(struct snd_emu10k1_fx8010_control_gpr *ctl
1123 ctl->translation = EMU10K1_GPR_TRANSLATION_ONOFF; 1123 ctl->translation = EMU10K1_GPR_TRANSLATION_ONOFF;
1124} 1124}
1125 1125
1126/*
1127 * Used for emu1010 - conversion from 32-bit capture inputs from HANA
1128 * to 2 x 16-bit registers in audigy - their values are read via DMA.
1129 * Conversion is performed by Audigy DSP instructions of FX8010.
1130 */
1126static int snd_emu10k1_audigy_dsp_convert_32_to_2x16( 1131static int snd_emu10k1_audigy_dsp_convert_32_to_2x16(
1127 struct snd_emu10k1_fx8010_code *icode, 1132 struct snd_emu10k1_fx8010_code *icode,
1128 u32 *ptr, int tmp, int bit_shifter16, 1133 u32 *ptr, int tmp, int bit_shifter16,
@@ -1193,7 +1198,11 @@ static int __devinit _snd_emu10k1_audigy_init_efx(struct snd_emu10k1 *emu)
1193 snd_emu10k1_ptr_write(emu, A_DBG, 0, (emu->fx8010.dbg = 0) | A_DBG_SINGLE_STEP); 1198 snd_emu10k1_ptr_write(emu, A_DBG, 0, (emu->fx8010.dbg = 0) | A_DBG_SINGLE_STEP);
1194 1199
1195#if 1 1200#if 1
1196 /* PCM front Playback Volume (independent from stereo mix) */ 1201 /* PCM front Playback Volume (independent from stereo mix)
1202 * playback = 0 + ( gpr * FXBUS_PCM_LEFT_FRONT >> 31)
1203 * where gpr contains attenuation from corresponding mixer control
1204 * (snd_emu10k1_init_stereo_control)
1205 */
1197 A_OP(icode, &ptr, iMAC0, A_GPR(playback), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_FRONT)); 1206 A_OP(icode, &ptr, iMAC0, A_GPR(playback), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_FRONT));
1198 A_OP(icode, &ptr, iMAC0, A_GPR(playback+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_FRONT)); 1207 A_OP(icode, &ptr, iMAC0, A_GPR(playback+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_FRONT));
1199 snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Front Playback Volume", gpr, 100); 1208 snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Front Playback Volume", gpr, 100);
@@ -1549,7 +1558,7 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input))
1549 1558
1550 if (emu->card_capabilities->emu1010) { 1559 if (emu->card_capabilities->emu1010) {
1551 snd_printk("EMU inputs on\n"); 1560 snd_printk("EMU inputs on\n");
1552 /* Capture 8 channels of S32_LE sound */ 1561 /* Capture 16 (originally 8) channels of S32_LE sound */
1553 1562
1554 /* printk("emufx.c: gpr=0x%x, tmp=0x%x\n",gpr, tmp); */ 1563 /* printk("emufx.c: gpr=0x%x, tmp=0x%x\n",gpr, tmp); */
1555 /* For the EMU1010: How to get 32bit values from the DSP. High 16bits into L, low 16bits into R. */ 1564 /* For the EMU1010: How to get 32bit values from the DSP. High 16bits into L, low 16bits into R. */
@@ -1560,6 +1569,11 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input))
1560 snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_P16VIN(0x0), A_FXBUS2(0) ); 1569 snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_P16VIN(0x0), A_FXBUS2(0) );
1561 /* Right ADC in 1 of 2 */ 1570 /* Right ADC in 1 of 2 */
1562 gpr_map[gpr++] = 0x00000000; 1571 gpr_map[gpr++] = 0x00000000;
1572 /* Delaying by one sample: instead of copying the input
1573 * value A_P16VIN to output A_FXBUS2 as in the first channel,
1574 * we use an auxiliary register, delaying the value by one
1575 * sample
1576 */
1563 snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(2) ); 1577 snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(2) );
1564 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x1), A_C_00000000, A_C_00000000); 1578 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x1), A_C_00000000, A_C_00000000);
1565 gpr_map[gpr++] = 0x00000000; 1579 gpr_map[gpr++] = 0x00000000;
@@ -1583,6 +1597,66 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input))
1583 gpr_map[gpr++] = 0x00000000; 1597 gpr_map[gpr++] = 0x00000000;
1584 snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(0xe) ); 1598 snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(0xe) );
1585 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x7), A_C_00000000, A_C_00000000); 1599 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x7), A_C_00000000, A_C_00000000);
1600 /* Pavel Hofman - we still have voices, A_FXBUS2s, and
1601 * A_P16VINs available -
1602 * let's add 8 more capture channels - total of 16
1603 */
1604 gpr_map[gpr++] = 0x00000000;
1605 snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
1606 bit_shifter16,
1607 A_GPR(gpr - 1),
1608 A_FXBUS2(0x10));
1609 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x8),
1610 A_C_00000000, A_C_00000000);
1611 gpr_map[gpr++] = 0x00000000;
1612 snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
1613 bit_shifter16,
1614 A_GPR(gpr - 1),
1615 A_FXBUS2(0x12));
1616 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x9),
1617 A_C_00000000, A_C_00000000);
1618 gpr_map[gpr++] = 0x00000000;
1619 snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
1620 bit_shifter16,
1621 A_GPR(gpr - 1),
1622 A_FXBUS2(0x14));
1623 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xa),
1624 A_C_00000000, A_C_00000000);
1625 gpr_map[gpr++] = 0x00000000;
1626 snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
1627 bit_shifter16,
1628 A_GPR(gpr - 1),
1629 A_FXBUS2(0x16));
1630 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xb),
1631 A_C_00000000, A_C_00000000);
1632 gpr_map[gpr++] = 0x00000000;
1633 snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
1634 bit_shifter16,
1635 A_GPR(gpr - 1),
1636 A_FXBUS2(0x18));
1637 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xc),
1638 A_C_00000000, A_C_00000000);
1639 gpr_map[gpr++] = 0x00000000;
1640 snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
1641 bit_shifter16,
1642 A_GPR(gpr - 1),
1643 A_FXBUS2(0x1a));
1644 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xd),
1645 A_C_00000000, A_C_00000000);
1646 gpr_map[gpr++] = 0x00000000;
1647 snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
1648 bit_shifter16,
1649 A_GPR(gpr - 1),
1650 A_FXBUS2(0x1c));
1651 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xe),
1652 A_C_00000000, A_C_00000000);
1653 gpr_map[gpr++] = 0x00000000;
1654 snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
1655 bit_shifter16,
1656 A_GPR(gpr - 1),
1657 A_FXBUS2(0x1e));
1658 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xf),
1659 A_C_00000000, A_C_00000000);
1586 1660
1587#if 0 1661#if 0
1588 for (z = 4; z < 8; z++) { 1662 for (z = 4; z < 8; z++) {
diff --git a/sound/pci/emu10k1/emumixer.c b/sound/pci/emu10k1/emumixer.c
index 4db6e1ca1665..7b2c1dcc5337 100644
--- a/sound/pci/emu10k1/emumixer.c
+++ b/sound/pci/emu10k1/emumixer.c
@@ -77,6 +77,10 @@ static int snd_emu10k1_spdif_get_mask(struct snd_kcontrol *kcontrol,
77 return 0; 77 return 0;
78} 78}
79 79
80/*
81 * Items labels in enum mixer controls assigning source data to
82 * each destination
83 */
80static char *emu1010_src_texts[] = { 84static char *emu1010_src_texts[] = {
81 "Silence", 85 "Silence",
82 "Dock Mic A", 86 "Dock Mic A",
@@ -133,6 +137,9 @@ static char *emu1010_src_texts[] = {
133 "DSP 31", 137 "DSP 31",
134}; 138};
135 139
140/*
141 * List of data sources available for each destination
142 */
136static unsigned int emu1010_src_regs[] = { 143static unsigned int emu1010_src_regs[] = {
137 EMU_SRC_SILENCE,/* 0 */ 144 EMU_SRC_SILENCE,/* 0 */
138 EMU_SRC_DOCK_MIC_A1, /* 1 */ 145 EMU_SRC_DOCK_MIC_A1, /* 1 */
@@ -189,6 +196,10 @@ static unsigned int emu1010_src_regs[] = {
189 EMU_SRC_ALICE_EMU32B+0xf, /* 52 */ 196 EMU_SRC_ALICE_EMU32B+0xf, /* 52 */
190}; 197};
191 198
199/*
200 * Data destinations - physical EMU outputs.
201 * Each destination has an enum mixer control to choose a data source
202 */
192static unsigned int emu1010_output_dst[] = { 203static unsigned int emu1010_output_dst[] = {
193 EMU_DST_DOCK_DAC1_LEFT1, /* 0 */ 204 EMU_DST_DOCK_DAC1_LEFT1, /* 0 */
194 EMU_DST_DOCK_DAC1_RIGHT1, /* 1 */ 205 EMU_DST_DOCK_DAC1_RIGHT1, /* 1 */
@@ -216,6 +227,11 @@ static unsigned int emu1010_output_dst[] = {
216 EMU_DST_HANA_ADAT+7, /* 23 */ 227 EMU_DST_HANA_ADAT+7, /* 23 */
217}; 228};
218 229
230/*
231 * Data destinations - HANA outputs going to Alice2 (audigy) for
232 * capture (EMU32 + I2S links)
233 * Each destination has an enum mixer control to choose a data source
234 */
219static unsigned int emu1010_input_dst[] = { 235static unsigned int emu1010_input_dst[] = {
220 EMU_DST_ALICE2_EMU32_0, 236 EMU_DST_ALICE2_EMU32_0,
221 EMU_DST_ALICE2_EMU32_1, 237 EMU_DST_ALICE2_EMU32_1,
diff --git a/sound/pci/emu10k1/emupcm.c b/sound/pci/emu10k1/emupcm.c
index ab4f5df5241b..eda5cb373ded 100644
--- a/sound/pci/emu10k1/emupcm.c
+++ b/sound/pci/emu10k1/emupcm.c
@@ -1233,24 +1233,26 @@ static int snd_emu10k1_capture_efx_open(struct snd_pcm_substream *substream)
1233 runtime->hw.rate_min = runtime->hw.rate_max = 48000; 1233 runtime->hw.rate_min = runtime->hw.rate_max = 48000;
1234 spin_lock_irq(&emu->reg_lock); 1234 spin_lock_irq(&emu->reg_lock);
1235 if (emu->card_capabilities->emu1010) { 1235 if (emu->card_capabilities->emu1010) {
1236 /* TODO 1236 /* Nb. of channels has been increased to 16 */
1237 /* TODO
1237 * SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE 1238 * SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE
1238 * SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | 1239 * SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
1239 * SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | 1240 * SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 |
1240 * SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000 1241 * SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000
1241 * rate_min = 44100, 1242 * rate_min = 44100,
1242 * rate_max = 192000, 1243 * rate_max = 192000,
1243 * channels_min = 8, 1244 * channels_min = 16,
1244 * channels_max = 8, 1245 * channels_max = 16,
1245 * Need to add mixer control to fix sample rate 1246 * Need to add mixer control to fix sample rate
1246 * 1247 *
1247 * There are 16 mono channels of 16bits each. 1248 * There are 32 mono channels of 16bits each.
1248 * 24bit Audio uses 2x channels over 16bit 1249 * 24bit Audio uses 2x channels over 16bit
1249 * 96kHz uses 2x channels over 48kHz 1250 * 96kHz uses 2x channels over 48kHz
1250 * 192kHz uses 4x channels over 48kHz 1251 * 192kHz uses 4x channels over 48kHz
1251 * So, for 48kHz 24bit, one has 8 channels 1252 * So, for 48kHz 24bit, one has 16 channels
1252 * for 96kHz 24bit, one has 4 channels 1253 * for 96kHz 24bit, one has 8 channels
1253 * for 192kHz 24bit, one has 2 channels 1254 * for 192kHz 24bit, one has 4 channels
1255 *
1254 */ 1256 */
1255#if 1 1257#if 1
1256 switch (emu->emu1010.internal_clock) { 1258 switch (emu->emu1010.internal_clock) {
@@ -1258,13 +1260,15 @@ static int snd_emu10k1_capture_efx_open(struct snd_pcm_substream *substream)
1258 /* For 44.1kHz */ 1260 /* For 44.1kHz */
1259 runtime->hw.rates = SNDRV_PCM_RATE_44100; 1261 runtime->hw.rates = SNDRV_PCM_RATE_44100;
1260 runtime->hw.rate_min = runtime->hw.rate_max = 44100; 1262 runtime->hw.rate_min = runtime->hw.rate_max = 44100;
1261 runtime->hw.channels_min = runtime->hw.channels_max = 8; 1263 runtime->hw.channels_min =
1264 runtime->hw.channels_max = 16;
1262 break; 1265 break;
1263 case 1: 1266 case 1:
1264 /* For 48kHz */ 1267 /* For 48kHz */
1265 runtime->hw.rates = SNDRV_PCM_RATE_48000; 1268 runtime->hw.rates = SNDRV_PCM_RATE_48000;
1266 runtime->hw.rate_min = runtime->hw.rate_max = 48000; 1269 runtime->hw.rate_min = runtime->hw.rate_max = 48000;
1267 runtime->hw.channels_min = runtime->hw.channels_max = 8; 1270 runtime->hw.channels_min =
1271 runtime->hw.channels_max = 16;
1268 break; 1272 break;
1269 }; 1273 };
1270#endif 1274#endif
@@ -1282,7 +1286,7 @@ static int snd_emu10k1_capture_efx_open(struct snd_pcm_substream *substream)
1282#endif 1286#endif
1283 runtime->hw.formats = SNDRV_PCM_FMTBIT_S32_LE; 1287 runtime->hw.formats = SNDRV_PCM_FMTBIT_S32_LE;
1284 /* efx_voices_mask[0] is expected to be zero 1288 /* efx_voices_mask[0] is expected to be zero
1285 * efx_voices_mask[1] is expected to have 16bits set 1289 * efx_voices_mask[1] is expected to have 32bits set
1286 */ 1290 */
1287 } else { 1291 } else {
1288 runtime->hw.channels_min = runtime->hw.channels_max = 0; 1292 runtime->hw.channels_min = runtime->hw.channels_max = 0;
@@ -1787,11 +1791,24 @@ int __devinit snd_emu10k1_pcm_efx(struct snd_emu10k1 * emu, int device, struct s
1787 /* emu->efx_voices_mask[0] = FXWC_DEFAULTROUTE_C | FXWC_DEFAULTROUTE_A; */ 1791 /* emu->efx_voices_mask[0] = FXWC_DEFAULTROUTE_C | FXWC_DEFAULTROUTE_A; */
1788 if (emu->audigy) { 1792 if (emu->audigy) {
1789 emu->efx_voices_mask[0] = 0; 1793 emu->efx_voices_mask[0] = 0;
1790 emu->efx_voices_mask[1] = 0xffff; 1794 if (emu->card_capabilities->emu1010)
1795 /* Pavel Hofman - 32 voices will be used for
1796 * capture (write mode) -
1797 * each bit = corresponding voice
1798 */
1799 emu->efx_voices_mask[1] = 0xffffffff;
1800 else
1801 emu->efx_voices_mask[1] = 0xffff;
1791 } else { 1802 } else {
1792 emu->efx_voices_mask[0] = 0xffff0000; 1803 emu->efx_voices_mask[0] = 0xffff0000;
1793 emu->efx_voices_mask[1] = 0; 1804 emu->efx_voices_mask[1] = 0;
1794 } 1805 }
1806 /* For emu1010, the control has to set 32 upper bits (voices)
1807 * out of the 64 bits (voices) to true for the 16-channels capture
1808 * to work correctly. Correct A_FXWC2 initial value (0xffffffff)
1809 * is already defined but the snd_emu10k1_pcm_efx_voices_mask
1810 * control can override this register's value.
1811 */
1795 kctl = snd_ctl_new1(&snd_emu10k1_pcm_efx_voices_mask, emu); 1812 kctl = snd_ctl_new1(&snd_emu10k1_pcm_efx_voices_mask, emu);
1796 if (!kctl) 1813 if (!kctl)
1797 return -ENOMEM; 1814 return -ENOMEM;
diff --git a/sound/pci/ens1370.c b/sound/pci/ens1370.c
index 7c403965153b..21cb4268a59b 100644
--- a/sound/pci/ens1370.c
+++ b/sound/pci/ens1370.c
@@ -1607,8 +1607,8 @@ struct es1371_quirk {
1607 unsigned char rev; /* revision */ 1607 unsigned char rev; /* revision */
1608}; 1608};
1609 1609
1610static int __devinit es1371_quirk_lookup(struct ensoniq *ensoniq, 1610static int es1371_quirk_lookup(struct ensoniq *ensoniq,
1611 struct es1371_quirk *list) 1611 struct es1371_quirk *list)
1612{ 1612{
1613 while (list->vid != (unsigned short)PCI_ANY_ID) { 1613 while (list->vid != (unsigned short)PCI_ANY_ID) {
1614 if (ensoniq->pci->vendor == list->vid && 1614 if (ensoniq->pci->vendor == list->vid &&
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 2fa281cbef91..92bc8b3fa2a0 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -341,6 +341,9 @@ struct azx {
341 unsigned int single_cmd :1; 341 unsigned int single_cmd :1;
342 unsigned int polling_mode :1; 342 unsigned int polling_mode :1;
343 unsigned int msi :1; 343 unsigned int msi :1;
344
345 /* for debugging */
346 unsigned int last_cmd; /* last issued command (to sync) */
344}; 347};
345 348
346/* driver types */ 349/* driver types */
@@ -466,18 +469,10 @@ static void azx_free_cmd_io(struct azx *chip)
466} 469}
467 470
468/* send a command */ 471/* send a command */
469static int azx_corb_send_cmd(struct hda_codec *codec, hda_nid_t nid, int direct, 472static int azx_corb_send_cmd(struct hda_codec *codec, u32 val)
470 unsigned int verb, unsigned int para)
471{ 473{
472 struct azx *chip = codec->bus->private_data; 474 struct azx *chip = codec->bus->private_data;
473 unsigned int wp; 475 unsigned int wp;
474 u32 val;
475
476 val = (u32)(codec->addr & 0x0f) << 28;
477 val |= (u32)direct << 27;
478 val |= (u32)nid << 20;
479 val |= verb << 8;
480 val |= para;
481 476
482 /* add command to corb */ 477 /* add command to corb */
483 wp = azx_readb(chip, CORBWP); 478 wp = azx_readb(chip, CORBWP);
@@ -538,12 +533,12 @@ static unsigned int azx_rirb_get_response(struct hda_codec *codec)
538 } 533 }
539 if (! chip->rirb.cmds) 534 if (! chip->rirb.cmds)
540 return chip->rirb.res; /* the last value */ 535 return chip->rirb.res; /* the last value */
541 schedule_timeout_interruptible(1); 536 schedule_timeout(1);
542 } while (time_after_eq(timeout, jiffies)); 537 } while (time_after_eq(timeout, jiffies));
543 538
544 if (chip->msi) { 539 if (chip->msi) {
545 snd_printk(KERN_WARNING "hda_intel: No response from codec, " 540 snd_printk(KERN_WARNING "hda_intel: No response from codec, "
546 "disabling MSI...\n"); 541 "disabling MSI: last cmd=0x%08x\n", chip->last_cmd);
547 free_irq(chip->irq, chip); 542 free_irq(chip->irq, chip);
548 chip->irq = -1; 543 chip->irq = -1;
549 pci_disable_msi(chip->pci); 544 pci_disable_msi(chip->pci);
@@ -555,13 +550,15 @@ static unsigned int azx_rirb_get_response(struct hda_codec *codec)
555 550
556 if (!chip->polling_mode) { 551 if (!chip->polling_mode) {
557 snd_printk(KERN_WARNING "hda_intel: azx_get_response timeout, " 552 snd_printk(KERN_WARNING "hda_intel: azx_get_response timeout, "
558 "switching to polling mode...\n"); 553 "switching to polling mode: last cmd=0x%08x\n",
554 chip->last_cmd);
559 chip->polling_mode = 1; 555 chip->polling_mode = 1;
560 goto again; 556 goto again;
561 } 557 }
562 558
563 snd_printk(KERN_ERR "hda_intel: azx_get_response timeout, " 559 snd_printk(KERN_ERR "hda_intel: azx_get_response timeout, "
564 "switching to single_cmd mode...\n"); 560 "switching to single_cmd mode: last cmd=0x%08x\n",
561 chip->last_cmd);
565 chip->rirb.rp = azx_readb(chip, RIRBWP); 562 chip->rirb.rp = azx_readb(chip, RIRBWP);
566 chip->rirb.cmds = 0; 563 chip->rirb.cmds = 0;
567 /* switch to single_cmd mode */ 564 /* switch to single_cmd mode */
@@ -581,20 +578,11 @@ static unsigned int azx_rirb_get_response(struct hda_codec *codec)
581 */ 578 */
582 579
583/* send a command */ 580/* send a command */
584static int azx_single_send_cmd(struct hda_codec *codec, hda_nid_t nid, 581static int azx_single_send_cmd(struct hda_codec *codec, u32 val)
585 int direct, unsigned int verb,
586 unsigned int para)
587{ 582{
588 struct azx *chip = codec->bus->private_data; 583 struct azx *chip = codec->bus->private_data;
589 u32 val;
590 int timeout = 50; 584 int timeout = 50;
591 585
592 val = (u32)(codec->addr & 0x0f) << 28;
593 val |= (u32)direct << 27;
594 val |= (u32)nid << 20;
595 val |= verb << 8;
596 val |= para;
597
598 while (timeout--) { 586 while (timeout--) {
599 /* check ICB busy bit */ 587 /* check ICB busy bit */
600 if (! (azx_readw(chip, IRS) & ICH6_IRS_BUSY)) { 588 if (! (azx_readw(chip, IRS) & ICH6_IRS_BUSY)) {
@@ -639,10 +627,19 @@ static int azx_send_cmd(struct hda_codec *codec, hda_nid_t nid,
639 unsigned int para) 627 unsigned int para)
640{ 628{
641 struct azx *chip = codec->bus->private_data; 629 struct azx *chip = codec->bus->private_data;
630 u32 val;
631
632 val = (u32)(codec->addr & 0x0f) << 28;
633 val |= (u32)direct << 27;
634 val |= (u32)nid << 20;
635 val |= verb << 8;
636 val |= para;
637 chip->last_cmd = val;
638
642 if (chip->single_cmd) 639 if (chip->single_cmd)
643 return azx_single_send_cmd(codec, nid, direct, verb, para); 640 return azx_single_send_cmd(codec, val);
644 else 641 else
645 return azx_corb_send_cmd(codec, nid, direct, verb, para); 642 return azx_corb_send_cmd(codec, val);
646} 643}
647 644
648/* get a response */ 645/* get a response */
@@ -1788,6 +1785,12 @@ static struct pci_device_id azx_ids[] = {
1788 { 0x10de, 0x044b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA MCP65 */ 1785 { 0x10de, 0x044b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA MCP65 */
1789 { 0x10de, 0x055c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA MCP67 */ 1786 { 0x10de, 0x055c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA MCP67 */
1790 { 0x10de, 0x055d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA MCP67 */ 1787 { 0x10de, 0x055d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA MCP67 */
1788 { 0x10de, 0x07fc, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA MCP73 */
1789 { 0x10de, 0x07fd, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA MCP73 */
1790 { 0x10de, 0x0774, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA MCP77 */
1791 { 0x10de, 0x0775, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA MCP77 */
1792 { 0x10de, 0x0776, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA MCP77 */
1793 { 0x10de, 0x0777, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA MCP77 */
1791 { 0, } 1794 { 0, }
1792}; 1795};
1793MODULE_DEVICE_TABLE(pci, azx_ids); 1796MODULE_DEVICE_TABLE(pci, azx_ids);
diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c
index e313e685f161..ac15066fd300 100644
--- a/sound/pci/hda/hda_proc.c
+++ b/sound/pci/hda/hda_proc.c
@@ -250,6 +250,12 @@ static void print_codec_info(struct snd_info_entry *entry, struct snd_info_buffe
250 snd_iprintf(buffer, "Vendor Id: 0x%x\n", codec->vendor_id); 250 snd_iprintf(buffer, "Vendor Id: 0x%x\n", codec->vendor_id);
251 snd_iprintf(buffer, "Subsystem Id: 0x%x\n", codec->subsystem_id); 251 snd_iprintf(buffer, "Subsystem Id: 0x%x\n", codec->subsystem_id);
252 snd_iprintf(buffer, "Revision Id: 0x%x\n", codec->revision_id); 252 snd_iprintf(buffer, "Revision Id: 0x%x\n", codec->revision_id);
253
254 if (codec->mfg)
255 snd_iprintf(buffer, "Modem Function Group: 0x%x\n", codec->mfg);
256 else
257 snd_iprintf(buffer, "No Modem Function Group found\n");
258
253 if (! codec->afg) 259 if (! codec->afg)
254 return; 260 return;
255 snd_iprintf(buffer, "Default PCM:\n"); 261 snd_iprintf(buffer, "Default PCM:\n");
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index 0e1a879663fa..4d7f8d11ad75 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -1,7 +1,8 @@
1/* 1/*
2 * HD audio interface patch for AD1981HD, AD1983, AD1986A, AD1988 2 * HD audio interface patch for AD1882, AD1884, AD1981HD, AD1983, AD1984,
3 * AD1986A, AD1988
3 * 4 *
4 * Copyright (c) 2005 Takashi Iwai <tiwai@suse.de> 5 * Copyright (c) 2005-2007 Takashi Iwai <tiwai@suse.de>
5 * 6 *
6 * This driver is free software; you can redistribute it and/or modify 7 * This driver is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by 8 * it under the terms of the GNU General Public License as published by
@@ -61,7 +62,7 @@ struct ad198x_spec {
61 int num_channel_mode; 62 int num_channel_mode;
62 63
63 /* PCM information */ 64 /* PCM information */
64 struct hda_pcm pcm_rec[2]; /* used in alc_build_pcms() */ 65 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
65 66
66 struct mutex amp_mutex; /* PCM volume/mute control mutex */ 67 struct mutex amp_mutex; /* PCM volume/mute control mutex */
67 unsigned int spdif_route; 68 unsigned int spdif_route;
@@ -2775,11 +2776,634 @@ static int patch_ad1988(struct hda_codec *codec)
2775 2776
2776 2777
2777/* 2778/*
2779 * AD1884 / AD1984
2780 *
2781 * port-B - front line/mic-in
2782 * port-E - aux in/out
2783 * port-F - aux in/out
2784 * port-C - rear line/mic-in
2785 * port-D - rear line/hp-out
2786 * port-A - front line/hp-out
2787 *
2788 * AD1984 = AD1884 + two digital mic-ins
2789 *
2790 * FIXME:
2791 * For simplicity, we share the single DAC for both HP and line-outs
2792 * right now. The inidividual playbacks could be easily implemented,
2793 * but no build-up framework is given, so far.
2794 */
2795
2796static hda_nid_t ad1884_dac_nids[1] = {
2797 0x04,
2798};
2799
2800static hda_nid_t ad1884_adc_nids[2] = {
2801 0x08, 0x09,
2802};
2803
2804static hda_nid_t ad1884_capsrc_nids[2] = {
2805 0x0c, 0x0d,
2806};
2807
2808#define AD1884_SPDIF_OUT 0x02
2809
2810static struct hda_input_mux ad1884_capture_source = {
2811 .num_items = 4,
2812 .items = {
2813 { "Front Mic", 0x0 },
2814 { "Mic", 0x1 },
2815 { "CD", 0x2 },
2816 { "Mix", 0x3 },
2817 },
2818};
2819
2820static struct snd_kcontrol_new ad1884_base_mixers[] = {
2821 HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT),
2822 /* HDA_CODEC_VOLUME_IDX("PCM Playback Volume", 1, 0x03, 0x0, HDA_OUTPUT), */
2823 HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT),
2824 HDA_CODEC_MUTE("Front Playback Switch", 0x12, 0x0, HDA_OUTPUT),
2825 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT),
2826 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT),
2827 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
2828 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
2829 HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x01, HDA_INPUT),
2830 HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
2831 HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x02, HDA_INPUT),
2832 HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x02, HDA_INPUT),
2833 /*
2834 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x20, 0x03, HDA_INPUT),
2835 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x20, 0x03, HDA_INPUT),
2836 HDA_CODEC_VOLUME("Digital Beep Playback Volume", 0x10, 0x0, HDA_OUTPUT),
2837 HDA_CODEC_MUTE("Digital Beep Playback Switch", 0x10, 0x0, HDA_OUTPUT),
2838 */
2839 HDA_CODEC_VOLUME("Mic Boost", 0x15, 0x0, HDA_INPUT),
2840 HDA_CODEC_VOLUME("Front Mic Boost", 0x14, 0x0, HDA_INPUT),
2841 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
2842 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
2843 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
2844 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
2845 {
2846 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2847 /* The multiple "Capture Source" controls confuse alsamixer
2848 * So call somewhat different..
2849 * FIXME: the controls appear in the "playback" view!
2850 */
2851 /* .name = "Capture Source", */
2852 .name = "Input Source",
2853 .count = 2,
2854 .info = ad198x_mux_enum_info,
2855 .get = ad198x_mux_enum_get,
2856 .put = ad198x_mux_enum_put,
2857 },
2858 /* SPDIF controls */
2859 HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
2860 {
2861 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2862 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
2863 /* identical with ad1983 */
2864 .info = ad1983_spdif_route_info,
2865 .get = ad1983_spdif_route_get,
2866 .put = ad1983_spdif_route_put,
2867 },
2868 { } /* end */
2869};
2870
2871static struct snd_kcontrol_new ad1984_dmic_mixers[] = {
2872 HDA_CODEC_VOLUME("Digital Mic Capture Volume", 0x05, 0x0, HDA_INPUT),
2873 HDA_CODEC_MUTE("Digital Mic Capture Switch", 0x05, 0x0, HDA_INPUT),
2874 HDA_CODEC_VOLUME_IDX("Digital Mic Capture Volume", 1, 0x06, 0x0,
2875 HDA_INPUT),
2876 HDA_CODEC_MUTE_IDX("Digital Mic Capture Switch", 1, 0x06, 0x0,
2877 HDA_INPUT),
2878 { } /* end */
2879};
2880
2881/*
2882 * initialization verbs
2883 */
2884static struct hda_verb ad1884_init_verbs[] = {
2885 /* DACs; mute as default */
2886 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2887 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2888 /* Port-A (HP) mixer */
2889 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2890 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2891 /* Port-A pin */
2892 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2893 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2894 /* HP selector - select DAC2 */
2895 {0x22, AC_VERB_SET_CONNECT_SEL, 0x1},
2896 /* Port-D (Line-out) mixer */
2897 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2898 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2899 /* Port-D pin */
2900 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2901 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2902 /* Mono-out mixer */
2903 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2904 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2905 /* Mono-out pin */
2906 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2907 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2908 /* Mono selector */
2909 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x1},
2910 /* Port-B (front mic) pin */
2911 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2912 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2913 /* Port-C (rear mic) pin */
2914 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2915 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2916 /* Analog mixer; mute as default */
2917 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2918 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2919 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2920 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2921 /* Analog Mix output amp */
2922 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */
2923 /* SPDIF output selector */
2924 {0x02, AC_VERB_SET_CONNECT_SEL, 0x0}, /* PCM */
2925 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
2926 { } /* end */
2927};
2928
2929static int patch_ad1884(struct hda_codec *codec)
2930{
2931 struct ad198x_spec *spec;
2932
2933 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
2934 if (spec == NULL)
2935 return -ENOMEM;
2936
2937 mutex_init(&spec->amp_mutex);
2938 codec->spec = spec;
2939
2940 spec->multiout.max_channels = 2;
2941 spec->multiout.num_dacs = ARRAY_SIZE(ad1884_dac_nids);
2942 spec->multiout.dac_nids = ad1884_dac_nids;
2943 spec->multiout.dig_out_nid = AD1884_SPDIF_OUT;
2944 spec->num_adc_nids = ARRAY_SIZE(ad1884_adc_nids);
2945 spec->adc_nids = ad1884_adc_nids;
2946 spec->capsrc_nids = ad1884_capsrc_nids;
2947 spec->input_mux = &ad1884_capture_source;
2948 spec->num_mixers = 1;
2949 spec->mixers[0] = ad1884_base_mixers;
2950 spec->num_init_verbs = 1;
2951 spec->init_verbs[0] = ad1884_init_verbs;
2952 spec->spdif_route = 0;
2953
2954 codec->patch_ops = ad198x_patch_ops;
2955
2956 return 0;
2957}
2958
2959/*
2960 * Lenovo Thinkpad T61/X61
2961 */
2962static struct hda_input_mux ad1984_thinkpad_capture_source = {
2963 .num_items = 3,
2964 .items = {
2965 { "Mic", 0x0 },
2966 { "Internal Mic", 0x1 },
2967 { "Mix", 0x3 },
2968 },
2969};
2970
2971static struct snd_kcontrol_new ad1984_thinkpad_mixers[] = {
2972 HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT),
2973 /* HDA_CODEC_VOLUME_IDX("PCM Playback Volume", 1, 0x03, 0x0, HDA_OUTPUT), */
2974 HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT),
2975 HDA_CODEC_MUTE("Speaker Playback Switch", 0x12, 0x0, HDA_OUTPUT),
2976 HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
2977 HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
2978 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x20, 0x01, HDA_INPUT),
2979 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
2980 HDA_CODEC_VOLUME("Docking Mic Playback Volume", 0x20, 0x04, HDA_INPUT),
2981 HDA_CODEC_MUTE("Docking Mic Playback Switch", 0x20, 0x04, HDA_INPUT),
2982 HDA_CODEC_VOLUME("Mic Boost", 0x14, 0x0, HDA_INPUT),
2983 HDA_CODEC_VOLUME("Internal Mic Boost", 0x15, 0x0, HDA_INPUT),
2984 HDA_CODEC_VOLUME("Docking Mic Boost", 0x25, 0x0, HDA_OUTPUT),
2985 HDA_CODEC_VOLUME("Beep Playback Volume", 0x20, 0x03, HDA_INPUT),
2986 HDA_CODEC_MUTE("Beep Playback Switch", 0x20, 0x03, HDA_INPUT),
2987 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
2988 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
2989 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
2990 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
2991 {
2992 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2993 /* The multiple "Capture Source" controls confuse alsamixer
2994 * So call somewhat different..
2995 * FIXME: the controls appear in the "playback" view!
2996 */
2997 /* .name = "Capture Source", */
2998 .name = "Input Source",
2999 .count = 2,
3000 .info = ad198x_mux_enum_info,
3001 .get = ad198x_mux_enum_get,
3002 .put = ad198x_mux_enum_put,
3003 },
3004 { } /* end */
3005};
3006
3007/* additional verbs */
3008static struct hda_verb ad1984_thinkpad_init_verbs[] = {
3009 /* Port-E (docking station mic) pin */
3010 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3011 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3012 /* docking mic boost */
3013 {0x25, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3014 /* Analog mixer - docking mic; mute as default */
3015 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3016 /* enable EAPD bit */
3017 {0x12, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
3018 { } /* end */
3019};
3020
3021/* Digial MIC ADC NID 0x05 + 0x06 */
3022static int ad1984_pcm_dmic_prepare(struct hda_pcm_stream *hinfo,
3023 struct hda_codec *codec,
3024 unsigned int stream_tag,
3025 unsigned int format,
3026 struct snd_pcm_substream *substream)
3027{
3028 snd_hda_codec_setup_stream(codec, 0x05 + substream->number,
3029 stream_tag, 0, format);
3030 return 0;
3031}
3032
3033static int ad1984_pcm_dmic_cleanup(struct hda_pcm_stream *hinfo,
3034 struct hda_codec *codec,
3035 struct snd_pcm_substream *substream)
3036{
3037 snd_hda_codec_setup_stream(codec, 0x05 + substream->number,
3038 0, 0, 0);
3039 return 0;
3040}
3041
3042static struct hda_pcm_stream ad1984_pcm_dmic_capture = {
3043 .substreams = 2,
3044 .channels_min = 2,
3045 .channels_max = 2,
3046 .nid = 0x05,
3047 .ops = {
3048 .prepare = ad1984_pcm_dmic_prepare,
3049 .cleanup = ad1984_pcm_dmic_cleanup
3050 },
3051};
3052
3053static int ad1984_build_pcms(struct hda_codec *codec)
3054{
3055 struct ad198x_spec *spec = codec->spec;
3056 struct hda_pcm *info;
3057 int err;
3058
3059 err = ad198x_build_pcms(codec);
3060 if (err < 0)
3061 return err;
3062
3063 info = spec->pcm_rec + codec->num_pcms;
3064 codec->num_pcms++;
3065 info->name = "AD1984 Digital Mic";
3066 info->stream[SNDRV_PCM_STREAM_CAPTURE] = ad1984_pcm_dmic_capture;
3067 return 0;
3068}
3069
3070/* models */
3071enum {
3072 AD1984_BASIC,
3073 AD1984_THINKPAD,
3074 AD1984_MODELS
3075};
3076
3077static const char *ad1984_models[AD1984_MODELS] = {
3078 [AD1984_BASIC] = "basic",
3079 [AD1984_THINKPAD] = "thinkpad",
3080};
3081
3082static struct snd_pci_quirk ad1984_cfg_tbl[] = {
3083 /* Lenovo Thinkpad T61/X61 */
3084 SND_PCI_QUIRK(0x17aa, 0, "Lenovo Thinkpad", AD1984_THINKPAD),
3085 {}
3086};
3087
3088static int patch_ad1984(struct hda_codec *codec)
3089{
3090 struct ad198x_spec *spec;
3091 int board_config, err;
3092
3093 err = patch_ad1884(codec);
3094 if (err < 0)
3095 return err;
3096 spec = codec->spec;
3097 board_config = snd_hda_check_board_config(codec, AD1984_MODELS,
3098 ad1984_models, ad1984_cfg_tbl);
3099 switch (board_config) {
3100 case AD1984_BASIC:
3101 /* additional digital mics */
3102 spec->mixers[spec->num_mixers++] = ad1984_dmic_mixers;
3103 codec->patch_ops.build_pcms = ad1984_build_pcms;
3104 break;
3105 case AD1984_THINKPAD:
3106 spec->multiout.dig_out_nid = 0;
3107 spec->input_mux = &ad1984_thinkpad_capture_source;
3108 spec->mixers[0] = ad1984_thinkpad_mixers;
3109 spec->init_verbs[spec->num_init_verbs++] = ad1984_thinkpad_init_verbs;
3110 break;
3111 }
3112 return 0;
3113}
3114
3115
3116/*
3117 * AD1882
3118 *
3119 * port-A - front hp-out
3120 * port-B - front mic-in
3121 * port-C - rear line-in, shared surr-out (3stack)
3122 * port-D - rear line-out
3123 * port-E - rear mic-in, shared clfe-out (3stack)
3124 * port-F - rear surr-out (6stack)
3125 * port-G - rear clfe-out (6stack)
3126 */
3127
3128static hda_nid_t ad1882_dac_nids[3] = {
3129 0x04, 0x03, 0x05
3130};
3131
3132static hda_nid_t ad1882_adc_nids[2] = {
3133 0x08, 0x09,
3134};
3135
3136static hda_nid_t ad1882_capsrc_nids[2] = {
3137 0x0c, 0x0d,
3138};
3139
3140#define AD1882_SPDIF_OUT 0x02
3141
3142/* list: 0x11, 0x39, 0x3a, 0x18, 0x3c, 0x3b, 0x12, 0x20 */
3143static struct hda_input_mux ad1882_capture_source = {
3144 .num_items = 5,
3145 .items = {
3146 { "Front Mic", 0x1 },
3147 { "Mic", 0x4 },
3148 { "Line", 0x2 },
3149 { "CD", 0x3 },
3150 { "Mix", 0x7 },
3151 },
3152};
3153
3154static struct snd_kcontrol_new ad1882_base_mixers[] = {
3155 HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
3156 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
3157 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT),
3158 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x05, 2, 0x0, HDA_OUTPUT),
3159 HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT),
3160 HDA_CODEC_MUTE("Front Playback Switch", 0x12, 0x0, HDA_OUTPUT),
3161 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT),
3162 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT),
3163 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
3164 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
3165 HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x01, HDA_INPUT),
3166 HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
3167 HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x04, HDA_INPUT),
3168 HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x04, HDA_INPUT),
3169 HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x06, HDA_INPUT),
3170 HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x06, HDA_INPUT),
3171 HDA_CODEC_VOLUME("Beep Playback Volume", 0x20, 0x07, HDA_INPUT),
3172 HDA_CODEC_MUTE("Beep Playback Switch", 0x20, 0x07, HDA_INPUT),
3173 HDA_CODEC_VOLUME("Mic Boost", 0x3c, 0x0, HDA_OUTPUT),
3174 HDA_CODEC_VOLUME("Front Mic Boost", 0x39, 0x0, HDA_OUTPUT),
3175 HDA_CODEC_VOLUME("Line-In Boost", 0x3a, 0x0, HDA_OUTPUT),
3176 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
3177 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
3178 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
3179 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
3180 {
3181 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3182 /* The multiple "Capture Source" controls confuse alsamixer
3183 * So call somewhat different..
3184 * FIXME: the controls appear in the "playback" view!
3185 */
3186 /* .name = "Capture Source", */
3187 .name = "Input Source",
3188 .count = 2,
3189 .info = ad198x_mux_enum_info,
3190 .get = ad198x_mux_enum_get,
3191 .put = ad198x_mux_enum_put,
3192 },
3193 /* SPDIF controls */
3194 HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
3195 {
3196 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3197 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
3198 /* identical with ad1983 */
3199 .info = ad1983_spdif_route_info,
3200 .get = ad1983_spdif_route_get,
3201 .put = ad1983_spdif_route_put,
3202 },
3203 { } /* end */
3204};
3205
3206static struct snd_kcontrol_new ad1882_3stack_mixers[] = {
3207 HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT),
3208 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x17, 1, 0x0, HDA_OUTPUT),
3209 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x17, 2, 0x0, HDA_OUTPUT),
3210 {
3211 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3212 .name = "Channel Mode",
3213 .info = ad198x_ch_mode_info,
3214 .get = ad198x_ch_mode_get,
3215 .put = ad198x_ch_mode_put,
3216 },
3217 { } /* end */
3218};
3219
3220static struct snd_kcontrol_new ad1882_6stack_mixers[] = {
3221 HDA_CODEC_MUTE("Surround Playback Switch", 0x16, 0x0, HDA_OUTPUT),
3222 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x24, 1, 0x0, HDA_OUTPUT),
3223 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x24, 2, 0x0, HDA_OUTPUT),
3224 { } /* end */
3225};
3226
3227static struct hda_verb ad1882_ch2_init[] = {
3228 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3229 {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3230 {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3231 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3232 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3233 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3234 { } /* end */
3235};
3236
3237static struct hda_verb ad1882_ch4_init[] = {
3238 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3239 {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3240 {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3241 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3242 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3243 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3244 { } /* end */
3245};
3246
3247static struct hda_verb ad1882_ch6_init[] = {
3248 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3249 {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3250 {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3251 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3252 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3253 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3254 { } /* end */
3255};
3256
3257static struct hda_channel_mode ad1882_modes[3] = {
3258 { 2, ad1882_ch2_init },
3259 { 4, ad1882_ch4_init },
3260 { 6, ad1882_ch6_init },
3261};
3262
3263/*
3264 * initialization verbs
3265 */
3266static struct hda_verb ad1882_init_verbs[] = {
3267 /* DACs; mute as default */
3268 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3269 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3270 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3271 /* Port-A (HP) mixer */
3272 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3273 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3274 /* Port-A pin */
3275 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3276 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3277 /* HP selector - select DAC2 */
3278 {0x37, AC_VERB_SET_CONNECT_SEL, 0x1},
3279 /* Port-D (Line-out) mixer */
3280 {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3281 {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3282 /* Port-D pin */
3283 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3284 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3285 /* Mono-out mixer */
3286 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3287 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3288 /* Mono-out pin */
3289 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3290 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3291 /* Port-B (front mic) pin */
3292 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3293 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3294 {0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, /* boost */
3295 /* Port-C (line-in) pin */
3296 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3297 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3298 {0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, /* boost */
3299 /* Port-C mixer - mute as input */
3300 {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3301 {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3302 /* Port-E (mic-in) pin */
3303 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3304 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3305 {0x3c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, /* boost */
3306 /* Port-E mixer - mute as input */
3307 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3308 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3309 /* Port-F (surround) */
3310 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3311 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3312 /* Port-G (CLFE) */
3313 {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3314 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3315 /* Analog mixer; mute as default */
3316 /* list: 0x39, 0x3a, 0x11, 0x12, 0x3c, 0x3b, 0x18, 0x1a */
3317 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3318 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3319 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3320 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3321 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3322 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
3323 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3324 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
3325 /* Analog Mix output amp */
3326 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */
3327 /* SPDIF output selector */
3328 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
3329 {0x02, AC_VERB_SET_CONNECT_SEL, 0x0}, /* PCM */
3330 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
3331 { } /* end */
3332};
3333
3334/* models */
3335enum {
3336 AD1882_3STACK,
3337 AD1882_6STACK,
3338 AD1882_MODELS
3339};
3340
3341static const char *ad1882_models[AD1986A_MODELS] = {
3342 [AD1882_3STACK] = "3stack",
3343 [AD1882_6STACK] = "6stack",
3344};
3345
3346
3347static int patch_ad1882(struct hda_codec *codec)
3348{
3349 struct ad198x_spec *spec;
3350 int board_config;
3351
3352 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3353 if (spec == NULL)
3354 return -ENOMEM;
3355
3356 mutex_init(&spec->amp_mutex);
3357 codec->spec = spec;
3358
3359 spec->multiout.max_channels = 6;
3360 spec->multiout.num_dacs = 3;
3361 spec->multiout.dac_nids = ad1882_dac_nids;
3362 spec->multiout.dig_out_nid = AD1882_SPDIF_OUT;
3363 spec->num_adc_nids = ARRAY_SIZE(ad1882_adc_nids);
3364 spec->adc_nids = ad1882_adc_nids;
3365 spec->capsrc_nids = ad1882_capsrc_nids;
3366 spec->input_mux = &ad1882_capture_source;
3367 spec->num_mixers = 1;
3368 spec->mixers[0] = ad1882_base_mixers;
3369 spec->num_init_verbs = 1;
3370 spec->init_verbs[0] = ad1882_init_verbs;
3371 spec->spdif_route = 0;
3372
3373 codec->patch_ops = ad198x_patch_ops;
3374
3375 /* override some parameters */
3376 board_config = snd_hda_check_board_config(codec, AD1882_MODELS,
3377 ad1882_models, NULL);
3378 switch (board_config) {
3379 default:
3380 case AD1882_3STACK:
3381 spec->num_mixers = 2;
3382 spec->mixers[1] = ad1882_3stack_mixers;
3383 spec->channel_mode = ad1882_modes;
3384 spec->num_channel_mode = ARRAY_SIZE(ad1882_modes);
3385 spec->need_dac_fix = 1;
3386 spec->multiout.max_channels = 2;
3387 spec->multiout.num_dacs = 1;
3388 break;
3389 case AD1882_6STACK:
3390 spec->num_mixers = 2;
3391 spec->mixers[1] = ad1882_6stack_mixers;
3392 break;
3393 }
3394 return 0;
3395}
3396
3397
3398/*
2778 * patch entries 3399 * patch entries
2779 */ 3400 */
2780struct hda_codec_preset snd_hda_preset_analog[] = { 3401struct hda_codec_preset snd_hda_preset_analog[] = {
3402 { .id = 0x11d41882, .name = "AD1882", .patch = patch_ad1882 },
3403 { .id = 0x11d41884, .name = "AD1884", .patch = patch_ad1884 },
2781 { .id = 0x11d41981, .name = "AD1981", .patch = patch_ad1981 }, 3404 { .id = 0x11d41981, .name = "AD1981", .patch = patch_ad1981 },
2782 { .id = 0x11d41983, .name = "AD1983", .patch = patch_ad1983 }, 3405 { .id = 0x11d41983, .name = "AD1983", .patch = patch_ad1983 },
3406 { .id = 0x11d41984, .name = "AD1984", .patch = patch_ad1984 },
2783 { .id = 0x11d41986, .name = "AD1986A", .patch = patch_ad1986a }, 3407 { .id = 0x11d41986, .name = "AD1986A", .patch = patch_ad1986a },
2784 { .id = 0x11d41988, .name = "AD1988", .patch = patch_ad1988 }, 3408 { .id = 0x11d41988, .name = "AD1988", .patch = patch_ad1988 },
2785 { .id = 0x11d4198b, .name = "AD1988B", .patch = patch_ad1988 }, 3409 { .id = 0x11d4198b, .name = "AD1988B", .patch = patch_ad1988 },
diff --git a/sound/pci/hda/patch_atihdmi.c b/sound/pci/hda/patch_atihdmi.c
index f8eb4c90f801..72d3ab9751ac 100644
--- a/sound/pci/hda/patch_atihdmi.c
+++ b/sound/pci/hda/patch_atihdmi.c
@@ -172,6 +172,7 @@ static int patch_atihdmi(struct hda_codec *codec)
172 */ 172 */
173struct hda_codec_preset snd_hda_preset_atihdmi[] = { 173struct hda_codec_preset snd_hda_preset_atihdmi[] = {
174 { .id = 0x1002793c, .name = "ATI RS600 HDMI", .patch = patch_atihdmi }, 174 { .id = 0x1002793c, .name = "ATI RS600 HDMI", .patch = patch_atihdmi },
175 { .id = 0x10027919, .name = "ATI RS600 HDMI", .patch = patch_atihdmi },
175 { .id = 0x1002791a, .name = "ATI RS690/780 HDMI", .patch = patch_atihdmi }, 176 { .id = 0x1002791a, .name = "ATI RS690/780 HDMI", .patch = patch_atihdmi },
176 { .id = 0x1002aa01, .name = "ATI R600 HDMI", .patch = patch_atihdmi }, 177 { .id = 0x1002aa01, .name = "ATI R600 HDMI", .patch = patch_atihdmi },
177 {} /* terminator */ 178 {} /* terminator */
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index bef214bcdddf..4d8e8af5c819 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -801,7 +801,9 @@ static struct snd_pci_quirk cxt5045_cfg_tbl[] = {
801 SND_PCI_QUIRK(0x103c, 0x30b2, "HP DV Series", CXT5045_LAPTOP), 801 SND_PCI_QUIRK(0x103c, 0x30b2, "HP DV Series", CXT5045_LAPTOP),
802 SND_PCI_QUIRK(0x103c, 0x30b5, "HP DV2120", CXT5045_LAPTOP), 802 SND_PCI_QUIRK(0x103c, 0x30b5, "HP DV2120", CXT5045_LAPTOP),
803 SND_PCI_QUIRK(0x103c, 0x30cd, "HP DV Series", CXT5045_LAPTOP), 803 SND_PCI_QUIRK(0x103c, 0x30cd, "HP DV Series", CXT5045_LAPTOP),
804 SND_PCI_QUIRK(0x103c, 0x30d9, "HP Spartan", CXT5045_LAPTOP),
804 SND_PCI_QUIRK(0x1734, 0x10ad, "Fujitsu Si1520", CXT5045_FUJITSU), 805 SND_PCI_QUIRK(0x1734, 0x10ad, "Fujitsu Si1520", CXT5045_FUJITSU),
806 SND_PCI_QUIRK(0x1734, 0x10cb, "Fujitsu Si3515", CXT5045_LAPTOP),
805 SND_PCI_QUIRK(0x8086, 0x2111, "Conexant Reference board", CXT5045_LAPTOP), 807 SND_PCI_QUIRK(0x8086, 0x2111, "Conexant Reference board", CXT5045_LAPTOP),
806 {} 808 {}
807}; 809};
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 4776de93928b..9a47eec5a27b 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -94,10 +94,18 @@ enum {
94 ALC262_HP_BPC_D7000_WF, 94 ALC262_HP_BPC_D7000_WF,
95 ALC262_BENQ_ED8, 95 ALC262_BENQ_ED8,
96 ALC262_SONY_ASSAMD, 96 ALC262_SONY_ASSAMD,
97 ALC262_BENQ_T31,
97 ALC262_AUTO, 98 ALC262_AUTO,
98 ALC262_MODEL_LAST /* last tag */ 99 ALC262_MODEL_LAST /* last tag */
99}; 100};
100 101
102/* ALC268 models */
103enum {
104 ALC268_3ST,
105 ALC268_AUTO,
106 ALC268_MODEL_LAST /* last tag */
107};
108
101/* ALC861 models */ 109/* ALC861 models */
102enum { 110enum {
103 ALC861_3ST, 111 ALC861_3ST,
@@ -115,6 +123,7 @@ enum {
115/* ALC861-VD models */ 123/* ALC861-VD models */
116enum { 124enum {
117 ALC660VD_3ST, 125 ALC660VD_3ST,
126 ALC660VD_3ST_DIG,
118 ALC861VD_3ST, 127 ALC861VD_3ST,
119 ALC861VD_3ST_DIG, 128 ALC861VD_3ST_DIG,
120 ALC861VD_6ST_DIG, 129 ALC861VD_6ST_DIG,
@@ -144,6 +153,7 @@ enum {
144 ALC882_TARGA, 153 ALC882_TARGA,
145 ALC882_ASUS_A7J, 154 ALC882_ASUS_A7J,
146 ALC885_MACPRO, 155 ALC885_MACPRO,
156 ALC885_IMAC24,
147 ALC882_AUTO, 157 ALC882_AUTO,
148 ALC882_MODEL_LAST, 158 ALC882_MODEL_LAST,
149}; 159};
@@ -163,6 +173,8 @@ enum {
163 ALC883_LENOVO_101E_2ch, 173 ALC883_LENOVO_101E_2ch,
164 ALC883_LENOVO_NB0763, 174 ALC883_LENOVO_NB0763,
165 ALC888_LENOVO_MS7195_DIG, 175 ALC888_LENOVO_MS7195_DIG,
176 ALC888_6ST_HP,
177 ALC888_3ST_HP,
166 ALC883_AUTO, 178 ALC883_AUTO,
167 ALC883_MODEL_LAST, 179 ALC883_MODEL_LAST,
168}; 180};
@@ -713,6 +725,38 @@ static void alc_subsystem_id(struct hda_codec *codec,
713} 725}
714 726
715/* 727/*
728 * Fix-up pin default configurations
729 */
730
731struct alc_pincfg {
732 hda_nid_t nid;
733 u32 val;
734};
735
736static void alc_fix_pincfg(struct hda_codec *codec,
737 const struct snd_pci_quirk *quirk,
738 const struct alc_pincfg **pinfix)
739{
740 const struct alc_pincfg *cfg;
741
742 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
743 if (!quirk)
744 return;
745
746 cfg = pinfix[quirk->value];
747 for (; cfg->nid; cfg++) {
748 int i;
749 u32 val = cfg->val;
750 for (i = 0; i < 4; i++) {
751 snd_hda_codec_write(codec, cfg->nid, 0,
752 AC_VERB_SET_CONFIG_DEFAULT_BYTES_0 + i,
753 val & 0xff);
754 val >>= 8;
755 }
756 }
757}
758
759/*
716 * ALC880 3-stack model 760 * ALC880 3-stack model
717 * 761 *
718 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e) 762 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
@@ -1878,31 +1922,53 @@ static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res)
1878 * Pin assignment: 1922 * Pin assignment:
1879 * Speaker-out: 0x14 1923 * Speaker-out: 0x14
1880 * Mic-In: 0x18 1924 * Mic-In: 0x18
1881 * Built-in Mic-In: 0x19 (?) 1925 * Built-in Mic-In: 0x19
1882 * HP-Out: 0x1b 1926 * Line-In: 0x1b
1927 * HP-Out: 0x1a
1883 * SPDIF-Out: 0x1e 1928 * SPDIF-Out: 0x1e
1884 */ 1929 */
1885 1930
1886/* seems analog CD is not working */
1887static struct hda_input_mux alc880_lg_lw_capture_source = { 1931static struct hda_input_mux alc880_lg_lw_capture_source = {
1888 .num_items = 2, 1932 .num_items = 3,
1889 .items = { 1933 .items = {
1890 { "Mic", 0x0 }, 1934 { "Mic", 0x0 },
1891 { "Internal Mic", 0x1 }, 1935 { "Internal Mic", 0x1 },
1936 { "Line In", 0x2 },
1892 }, 1937 },
1893}; 1938};
1894 1939
1940#define alc880_lg_lw_modes alc880_threestack_modes
1941
1895static struct snd_kcontrol_new alc880_lg_lw_mixer[] = { 1942static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
1896 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 1943 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1897 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT), 1944 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1945 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1946 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
1947 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1948 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1949 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1950 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1951 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1952 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1898 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 1953 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1899 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 1954 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1900 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 1955 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
1901 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 1956 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
1957 {
1958 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1959 .name = "Channel Mode",
1960 .info = alc_ch_mode_info,
1961 .get = alc_ch_mode_get,
1962 .put = alc_ch_mode_put,
1963 },
1902 { } /* end */ 1964 { } /* end */
1903}; 1965};
1904 1966
1905static struct hda_verb alc880_lg_lw_init_verbs[] = { 1967static struct hda_verb alc880_lg_lw_init_verbs[] = {
1968 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1969 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
1970 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
1971
1906 /* set capture source to mic-in */ 1972 /* set capture source to mic-in */
1907 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 1973 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1908 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 1974 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
@@ -1912,7 +1978,6 @@ static struct hda_verb alc880_lg_lw_init_verbs[] = {
1912 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1978 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1913 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1979 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1914 /* HP-out */ 1980 /* HP-out */
1915 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
1916 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1981 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1917 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1982 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1918 /* mic-in to input */ 1983 /* mic-in to input */
@@ -2856,11 +2921,11 @@ static struct alc_config_preset alc880_presets[] = {
2856 .mixers = { alc880_lg_lw_mixer }, 2921 .mixers = { alc880_lg_lw_mixer },
2857 .init_verbs = { alc880_volume_init_verbs, 2922 .init_verbs = { alc880_volume_init_verbs,
2858 alc880_lg_lw_init_verbs }, 2923 alc880_lg_lw_init_verbs },
2859 .num_dacs = 1, 2924 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2860 .dac_nids = alc880_dac_nids, 2925 .dac_nids = alc880_dac_nids,
2861 .dig_out_nid = ALC880_DIGOUT_NID, 2926 .dig_out_nid = ALC880_DIGOUT_NID,
2862 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), 2927 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
2863 .channel_mode = alc880_2_jack_modes, 2928 .channel_mode = alc880_lg_lw_modes,
2864 .input_mux = &alc880_lg_lw_capture_source, 2929 .input_mux = &alc880_lg_lw_capture_source,
2865 .unsol_event = alc880_lg_lw_unsol_event, 2930 .unsol_event = alc880_lg_lw_unsol_event,
2866 .init_hook = alc880_lg_lw_automute, 2931 .init_hook = alc880_lg_lw_automute,
@@ -5054,6 +5119,60 @@ static struct hda_verb alc882_macpro_init_verbs[] = {
5054 { } 5119 { }
5055}; 5120};
5056 5121
5122/* iMac 24 mixer. */
5123static struct snd_kcontrol_new alc885_imac24_mixer[] = {
5124 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
5125 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
5126 { } /* end */
5127};
5128
5129/* iMac 24 init verbs. */
5130static struct hda_verb alc885_imac24_init_verbs[] = {
5131 /* Internal speakers: output 0 (0x0c) */
5132 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5133 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5134 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
5135 /* Internal speakers: output 0 (0x0c) */
5136 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5137 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5138 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
5139 /* Headphone: output 0 (0x0c) */
5140 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5141 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5142 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5143 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5144 /* Front Mic: input vref at 80% */
5145 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5146 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5147 { }
5148};
5149
5150/* Toggle speaker-output according to the hp-jack state */
5151static void alc885_imac24_automute(struct hda_codec *codec)
5152{
5153 unsigned int present;
5154
5155 present = snd_hda_codec_read(codec, 0x14, 0,
5156 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5157 snd_hda_codec_amp_update(codec, 0x18, 0, HDA_OUTPUT, 0,
5158 0x80, present ? 0x80 : 0);
5159 snd_hda_codec_amp_update(codec, 0x18, 1, HDA_OUTPUT, 0,
5160 0x80, present ? 0x80 : 0);
5161 snd_hda_codec_amp_update(codec, 0x1a, 0, HDA_OUTPUT, 0,
5162 0x80, present ? 0x80 : 0);
5163 snd_hda_codec_amp_update(codec, 0x1a, 1, HDA_OUTPUT, 0,
5164 0x80, present ? 0x80 : 0);
5165}
5166
5167/* Processes unsolicited events. */
5168static void alc885_imac24_unsol_event(struct hda_codec *codec,
5169 unsigned int res)
5170{
5171 /* Headphone insertion or removal. */
5172 if ((res >> 26) == ALC880_HP_EVENT)
5173 alc885_imac24_automute(codec);
5174}
5175
5057static struct hda_verb alc882_targa_verbs[] = { 5176static struct hda_verb alc882_targa_verbs[] = {
5058 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5177 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5059 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 5178 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
@@ -5274,6 +5393,7 @@ static const char *alc882_models[ALC882_MODEL_LAST] = {
5274 [ALC882_ARIMA] = "arima", 5393 [ALC882_ARIMA] = "arima",
5275 [ALC882_W2JC] = "w2jc", 5394 [ALC882_W2JC] = "w2jc",
5276 [ALC885_MACPRO] = "macpro", 5395 [ALC885_MACPRO] = "macpro",
5396 [ALC885_IMAC24] = "imac24",
5277 [ALC882_AUTO] = "auto", 5397 [ALC882_AUTO] = "auto",
5278}; 5398};
5279 5399
@@ -5284,6 +5404,7 @@ static struct snd_pci_quirk alc882_cfg_tbl[] = {
5284 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */ 5404 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
5285 SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), 5405 SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA),
5286 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J), 5406 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
5407 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
5287 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG), 5408 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
5288 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC), 5409 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
5289 {} 5410 {}
@@ -5345,6 +5466,19 @@ static struct alc_config_preset alc882_presets[] = {
5345 .channel_mode = alc882_ch_modes, 5466 .channel_mode = alc882_ch_modes,
5346 .input_mux = &alc882_capture_source, 5467 .input_mux = &alc882_capture_source,
5347 }, 5468 },
5469 [ALC885_IMAC24] = {
5470 .mixers = { alc885_imac24_mixer },
5471 .init_verbs = { alc885_imac24_init_verbs },
5472 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5473 .dac_nids = alc882_dac_nids,
5474 .dig_out_nid = ALC882_DIGOUT_NID,
5475 .dig_in_nid = ALC882_DIGIN_NID,
5476 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
5477 .channel_mode = alc882_ch_modes,
5478 .input_mux = &alc882_capture_source,
5479 .unsol_event = alc885_imac24_unsol_event,
5480 .init_hook = alc885_imac24_automute,
5481 },
5348 [ALC882_TARGA] = { 5482 [ALC882_TARGA] = {
5349 .mixers = { alc882_targa_mixer, alc882_chmode_mixer, 5483 .mixers = { alc882_targa_mixer, alc882_chmode_mixer,
5350 alc882_capture_mixer }, 5484 alc882_capture_mixer },
@@ -5379,6 +5513,29 @@ static struct alc_config_preset alc882_presets[] = {
5379 5513
5380 5514
5381/* 5515/*
5516 * Pin config fixes
5517 */
5518enum {
5519 PINFIX_ABIT_AW9D_MAX
5520};
5521
5522static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
5523 { 0x15, 0x01080104 }, /* side */
5524 { 0x16, 0x01011012 }, /* rear */
5525 { 0x17, 0x01016011 }, /* clfe */
5526 { }
5527};
5528
5529static const struct alc_pincfg *alc882_pin_fixes[] = {
5530 [PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix,
5531};
5532
5533static struct snd_pci_quirk alc882_pinfix_tbl[] = {
5534 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
5535 {}
5536};
5537
5538/*
5382 * BIOS auto configuration 5539 * BIOS auto configuration
5383 */ 5540 */
5384static void alc882_auto_set_output_and_unmute(struct hda_codec *codec, 5541static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
@@ -5494,6 +5651,9 @@ static int patch_alc882(struct hda_codec *codec)
5494 case 0x106b0c00: /* Mac Pro */ 5651 case 0x106b0c00: /* Mac Pro */
5495 board_config = ALC885_MACPRO; 5652 board_config = ALC885_MACPRO;
5496 break; 5653 break;
5654 case 0x106b1000: /* iMac 24 */
5655 board_config = ALC885_IMAC24;
5656 break;
5497 default: 5657 default:
5498 printk(KERN_INFO "hda_codec: Unknown model for ALC882, " 5658 printk(KERN_INFO "hda_codec: Unknown model for ALC882, "
5499 "trying auto-probe from BIOS...\n"); 5659 "trying auto-probe from BIOS...\n");
@@ -5501,6 +5661,8 @@ static int patch_alc882(struct hda_codec *codec)
5501 } 5661 }
5502 } 5662 }
5503 5663
5664 alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes);
5665
5504 if (board_config == ALC882_AUTO) { 5666 if (board_config == ALC882_AUTO) {
5505 /* automatic parse from the BIOS config */ 5667 /* automatic parse from the BIOS config */
5506 err = alc882_parse_auto_config(codec); 5668 err = alc882_parse_auto_config(codec);
@@ -5518,7 +5680,7 @@ static int patch_alc882(struct hda_codec *codec)
5518 if (board_config != ALC882_AUTO) 5680 if (board_config != ALC882_AUTO)
5519 setup_preset(spec, &alc882_presets[board_config]); 5681 setup_preset(spec, &alc882_presets[board_config]);
5520 5682
5521 if (board_config == ALC885_MACPRO) { 5683 if (board_config == ALC885_MACPRO || board_config == ALC885_IMAC24) {
5522 alc882_gpio_mute(codec, 0, 0); 5684 alc882_gpio_mute(codec, 0, 0);
5523 alc882_gpio_mute(codec, 1, 0); 5685 alc882_gpio_mute(codec, 1, 0);
5524 } 5686 }
@@ -5995,6 +6157,84 @@ static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
5995 { } /* end */ 6157 { } /* end */
5996}; 6158};
5997 6159
6160static struct snd_kcontrol_new alc888_6st_hp_mixer[] = {
6161 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6162 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6163 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
6164 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
6165 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
6166 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
6167 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
6168 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
6169 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
6170 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
6171 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6172 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6173 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6174 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6175 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6176 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6177 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6178 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6179 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6180 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6181 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6182 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6183 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6184 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6185 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6186 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6187 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6188 {
6189 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6190 /* .name = "Capture Source", */
6191 .name = "Input Source",
6192 .count = 2,
6193 .info = alc883_mux_enum_info,
6194 .get = alc883_mux_enum_get,
6195 .put = alc883_mux_enum_put,
6196 },
6197 { } /* end */
6198};
6199
6200static struct snd_kcontrol_new alc888_3st_hp_mixer[] = {
6201 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6202 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6203 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
6204 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
6205 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
6206 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
6207 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
6208 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
6209 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6210 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6211 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6212 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6213 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6214 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6215 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6216 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6217 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6218 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6219 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6220 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6221 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6222 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6223 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6224 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6225 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6226 {
6227 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6228 /* .name = "Capture Source", */
6229 .name = "Input Source",
6230 .count = 2,
6231 .info = alc883_mux_enum_info,
6232 .get = alc883_mux_enum_get,
6233 .put = alc883_mux_enum_put,
6234 },
6235 { } /* end */
6236};
6237
5998static struct snd_kcontrol_new alc883_chmode_mixer[] = { 6238static struct snd_kcontrol_new alc883_chmode_mixer[] = {
5999 { 6239 {
6000 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 6240 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -6126,6 +6366,42 @@ static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
6126 { } /* end */ 6366 { } /* end */
6127}; 6367};
6128 6368
6369static struct hda_verb alc888_6st_hp_verbs[] = {
6370 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
6371 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Rear : output 2 (0x0e) */
6372 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* CLFE : output 1 (0x0d) */
6373 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, /* Side : output 3 (0x0f) */
6374 { }
6375};
6376
6377static struct hda_verb alc888_3st_hp_verbs[] = {
6378 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
6379 {0x18, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
6380 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
6381 { }
6382};
6383
6384static struct hda_verb alc888_3st_hp_2ch_init[] = {
6385 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6386 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6387 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6388 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6389 { }
6390};
6391
6392static struct hda_verb alc888_3st_hp_6ch_init[] = {
6393 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6394 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6395 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6396 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6397 { }
6398};
6399
6400static struct hda_channel_mode alc888_3st_hp_modes[2] = {
6401 { 2, alc888_3st_hp_2ch_init },
6402 { 6, alc888_3st_hp_6ch_init },
6403};
6404
6129/* toggle front-jack and RCA according to the hp-jack state */ 6405/* toggle front-jack and RCA according to the hp-jack state */
6130static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec) 6406static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
6131{ 6407{
@@ -6368,11 +6644,14 @@ static const char *alc883_models[ALC883_MODEL_LAST] = {
6368 [ALC883_LENOVO_101E_2ch] = "lenovo-101e", 6644 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
6369 [ALC883_LENOVO_NB0763] = "lenovo-nb0763", 6645 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
6370 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig", 6646 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
6647 [ALC888_6ST_HP] = "6stack-hp",
6648 [ALC888_3ST_HP] = "3stack-hp",
6371 [ALC883_AUTO] = "auto", 6649 [ALC883_AUTO] = "auto",
6372}; 6650};
6373 6651
6374static struct snd_pci_quirk alc883_cfg_tbl[] = { 6652static struct snd_pci_quirk alc883_cfg_tbl[] = {
6375 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG), 6653 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG),
6654 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
6376 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch), 6655 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
6377 SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD), 6656 SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD),
6378 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG), 6657 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG),
@@ -6381,6 +6660,8 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = {
6381 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG), 6660 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
6382 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG), 6661 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
6383 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG), 6662 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
6663 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
6664 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
6384 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG), 6665 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
6385 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG), 6666 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
6386 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG), 6667 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
@@ -6400,6 +6681,9 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = {
6400 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch), 6681 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
6401 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763), 6682 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
6402 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763), 6683 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
6684 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC888_6ST_HP),
6685 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
6686 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
6403 SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2), 6687 SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
6404 {} 6688 {}
6405}; 6689};
@@ -6584,6 +6868,31 @@ static struct alc_config_preset alc883_presets[] = {
6584 .unsol_event = alc883_lenovo_ms7195_unsol_event, 6868 .unsol_event = alc883_lenovo_ms7195_unsol_event,
6585 .init_hook = alc888_lenovo_ms7195_front_automute, 6869 .init_hook = alc888_lenovo_ms7195_front_automute,
6586 }, 6870 },
6871 [ALC888_6ST_HP] = {
6872 .mixers = { alc888_6st_hp_mixer, alc883_chmode_mixer },
6873 .init_verbs = { alc883_init_verbs, alc888_6st_hp_verbs },
6874 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6875 .dac_nids = alc883_dac_nids,
6876 .dig_out_nid = ALC883_DIGOUT_NID,
6877 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6878 .adc_nids = alc883_adc_nids,
6879 .dig_in_nid = ALC883_DIGIN_NID,
6880 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
6881 .channel_mode = alc883_sixstack_modes,
6882 .input_mux = &alc883_capture_source,
6883 },
6884 [ALC888_3ST_HP] = {
6885 .mixers = { alc888_3st_hp_mixer, alc883_chmode_mixer },
6886 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
6887 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
6888 .dac_nids = alc883_dac_nids,
6889 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6890 .adc_nids = alc883_adc_nids,
6891 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
6892 .channel_mode = alc888_3st_hp_modes,
6893 .need_dac_fix = 1,
6894 .input_mux = &alc883_capture_source,
6895 },
6587}; 6896};
6588 6897
6589 6898
@@ -6857,7 +7166,16 @@ static struct snd_kcontrol_new alc262_sony_mixer[] = {
6857 { } /* end */ 7166 { } /* end */
6858}; 7167};
6859 7168
6860 7169static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
7170 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7171 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7172 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7173 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7174 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7175 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7176 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7177 { } /* end */
7178};
6861 7179
6862#define alc262_capture_mixer alc882_capture_mixer 7180#define alc262_capture_mixer alc882_capture_mixer
6863#define alc262_capture_alt_mixer alc882_capture_alt_mixer 7181#define alc262_capture_alt_mixer alc882_capture_alt_mixer
@@ -7189,6 +7507,15 @@ static struct hda_verb alc262_EAPD_verbs[] = {
7189 {} 7507 {}
7190}; 7508};
7191 7509
7510static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
7511 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7512 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
7513
7514 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7515 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
7516 {}
7517};
7518
7192/* add playback controls from the parsed DAC table */ 7519/* add playback controls from the parsed DAC table */
7193static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec, 7520static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
7194 const struct auto_pin_cfg *cfg) 7521 const struct auto_pin_cfg *cfg)
@@ -7584,7 +7911,8 @@ static const char *alc262_models[ALC262_MODEL_LAST] = {
7584 [ALC262_HP_BPC] = "hp-bpc", 7911 [ALC262_HP_BPC] = "hp-bpc",
7585 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000", 7912 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
7586 [ALC262_BENQ_ED8] = "benq", 7913 [ALC262_BENQ_ED8] = "benq",
7587 [ALC262_BENQ_ED8] = "sony-assamd", 7914 [ALC262_BENQ_T31] = "benq-t31",
7915 [ALC262_SONY_ASSAMD] = "sony-assamd",
7588 [ALC262_AUTO] = "auto", 7916 [ALC262_AUTO] = "auto",
7589}; 7917};
7590 7918
@@ -7592,8 +7920,12 @@ static struct snd_pci_quirk alc262_cfg_tbl[] = {
7592 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO), 7920 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
7593 SND_PCI_QUIRK(0x103c, 0x12fe, "HP xw9400", ALC262_HP_BPC), 7921 SND_PCI_QUIRK(0x103c, 0x12fe, "HP xw9400", ALC262_HP_BPC),
7594 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC), 7922 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
7923 SND_PCI_QUIRK(0x103c, 0x12ff, "HP xw4550", ALC262_HP_BPC),
7924 SND_PCI_QUIRK(0x103c, 0x1308, "HP xw4600", ALC262_HP_BPC),
7595 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC), 7925 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
7926 SND_PCI_QUIRK(0x103c, 0x1307, "HP xw6600", ALC262_HP_BPC),
7596 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC), 7927 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
7928 SND_PCI_QUIRK(0x103c, 0x1306, "HP xw8600", ALC262_HP_BPC),
7597 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL), 7929 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
7598 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL), 7930 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
7599 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL), 7931 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
@@ -7606,6 +7938,7 @@ static struct snd_pci_quirk alc262_cfg_tbl[] = {
7606 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU), 7938 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
7607 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1), 7939 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
7608 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8), 7940 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
7941 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
7609 SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD), 7942 SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD),
7610 SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD), 7943 SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD),
7611 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD), 7944 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
@@ -7710,6 +8043,17 @@ static struct alc_config_preset alc262_presets[] = {
7710 .channel_mode = alc262_modes, 8043 .channel_mode = alc262_modes,
7711 .input_mux = &alc262_capture_source, 8044 .input_mux = &alc262_capture_source,
7712 .unsol_event = alc262_hippo_unsol_event, 8045 .unsol_event = alc262_hippo_unsol_event,
8046 },
8047 [ALC262_BENQ_T31] = {
8048 .mixers = { alc262_benq_t31_mixer },
8049 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs },
8050 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8051 .dac_nids = alc262_dac_nids,
8052 .hp_nid = 0x03,
8053 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8054 .channel_mode = alc262_modes,
8055 .input_mux = &alc262_capture_source,
8056 .unsol_event = alc262_hippo_unsol_event,
7713 }, 8057 },
7714}; 8058};
7715 8059
@@ -7800,6 +8144,515 @@ static int patch_alc262(struct hda_codec *codec)
7800} 8144}
7801 8145
7802/* 8146/*
8147 * ALC268 channel source setting (2 channel)
8148 */
8149#define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
8150#define alc268_modes alc260_modes
8151
8152static hda_nid_t alc268_dac_nids[2] = {
8153 /* front, hp */
8154 0x02, 0x03
8155};
8156
8157static hda_nid_t alc268_adc_nids[2] = {
8158 /* ADC0-1 */
8159 0x08, 0x07
8160};
8161
8162static hda_nid_t alc268_adc_nids_alt[1] = {
8163 /* ADC0 */
8164 0x08
8165};
8166
8167static struct snd_kcontrol_new alc268_base_mixer[] = {
8168 /* output mixer control */
8169 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
8170 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8171 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
8172 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8173 { }
8174};
8175
8176/*
8177 * generic initialization of ADC, input mixers and output mixers
8178 */
8179static struct hda_verb alc268_base_init_verbs[] = {
8180 /* Unmute DAC0-1 and set vol = 0 */
8181 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8182 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8183 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8184 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8185 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8186 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8187
8188 /*
8189 * Set up output mixers (0x0c - 0x0e)
8190 */
8191 /* set vol=0 to output mixers */
8192 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8193 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8194 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8195 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
8196
8197 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8198 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8199
8200 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
8201 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
8202 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
8203 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8204 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8205 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8206 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8207 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8208
8209 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8210 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8211 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8212 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8213 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8214 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8215 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8216 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8217
8218 /* FIXME: use matrix-type input source selection */
8219 /* Mixer elements: 0x18, 19, 1a, 1c, 14, 15, 0b */
8220 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8221 /* Input mixer2 */
8222 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8223 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8224 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8225 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8226
8227 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8228 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8229 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8230 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8231 { }
8232};
8233
8234/*
8235 * generic initialization of ADC, input mixers and output mixers
8236 */
8237static struct hda_verb alc268_volume_init_verbs[] = {
8238 /* set output DAC */
8239 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8240 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8241 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8242 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8243
8244 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8245 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8246 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8247 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8248 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8249
8250 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8251 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8252 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8253 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8254 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8255
8256 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8257 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8258 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8259 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8260
8261 /* set PCBEEP vol = 0 */
8262 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, (0xb000 | (0x00 << 8))},
8263
8264 { }
8265};
8266
8267#define alc268_mux_enum_info alc_mux_enum_info
8268#define alc268_mux_enum_get alc_mux_enum_get
8269
8270static int alc268_mux_enum_put(struct snd_kcontrol *kcontrol,
8271 struct snd_ctl_elem_value *ucontrol)
8272{
8273 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8274 struct alc_spec *spec = codec->spec;
8275 const struct hda_input_mux *imux = spec->input_mux;
8276 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
8277 static hda_nid_t capture_mixers[3] = { 0x23, 0x24 };
8278 hda_nid_t nid = capture_mixers[adc_idx];
8279 unsigned int *cur_val = &spec->cur_mux[adc_idx];
8280 unsigned int i, idx;
8281
8282 idx = ucontrol->value.enumerated.item[0];
8283 if (idx >= imux->num_items)
8284 idx = imux->num_items - 1;
8285 if (*cur_val == idx && !codec->in_resume)
8286 return 0;
8287 for (i = 0; i < imux->num_items; i++) {
8288 unsigned int v = (i == idx) ? 0x7000 : 0x7080;
8289 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
8290 v | (imux->items[i].index << 8));
8291 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL,
8292 idx );
8293 }
8294 *cur_val = idx;
8295 return 1;
8296}
8297
8298static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
8299 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
8300 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
8301 {
8302 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8303 /* The multiple "Capture Source" controls confuse alsamixer
8304 * So call somewhat different..
8305 * FIXME: the controls appear in the "playback" view!
8306 */
8307 /* .name = "Capture Source", */
8308 .name = "Input Source",
8309 .count = 1,
8310 .info = alc268_mux_enum_info,
8311 .get = alc268_mux_enum_get,
8312 .put = alc268_mux_enum_put,
8313 },
8314 { } /* end */
8315};
8316
8317static struct snd_kcontrol_new alc268_capture_mixer[] = {
8318 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
8319 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
8320 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
8321 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
8322 {
8323 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8324 /* The multiple "Capture Source" controls confuse alsamixer
8325 * So call somewhat different..
8326 * FIXME: the controls appear in the "playback" view!
8327 */
8328 /* .name = "Capture Source", */
8329 .name = "Input Source",
8330 .count = 2,
8331 .info = alc268_mux_enum_info,
8332 .get = alc268_mux_enum_get,
8333 .put = alc268_mux_enum_put,
8334 },
8335 { } /* end */
8336};
8337
8338static struct hda_input_mux alc268_capture_source = {
8339 .num_items = 4,
8340 .items = {
8341 { "Mic", 0x0 },
8342 { "Front Mic", 0x1 },
8343 { "Line", 0x2 },
8344 { "CD", 0x3 },
8345 },
8346};
8347
8348/* create input playback/capture controls for the given pin */
8349static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
8350 const char *ctlname, int idx)
8351{
8352 char name[32];
8353 int err;
8354
8355 sprintf(name, "%s Playback Volume", ctlname);
8356 if (nid == 0x14) {
8357 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
8358 HDA_COMPOSE_AMP_VAL(0x02, 3, idx,
8359 HDA_OUTPUT));
8360 if (err < 0)
8361 return err;
8362 } else if (nid == 0x15) {
8363 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
8364 HDA_COMPOSE_AMP_VAL(0x03, 3, idx,
8365 HDA_OUTPUT));
8366 if (err < 0)
8367 return err;
8368 } else
8369 return -1;
8370 sprintf(name, "%s Playback Switch", ctlname);
8371 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
8372 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
8373 if (err < 0)
8374 return err;
8375 return 0;
8376}
8377
8378/* add playback controls from the parsed DAC table */
8379static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
8380 const struct auto_pin_cfg *cfg)
8381{
8382 hda_nid_t nid;
8383 int err;
8384
8385 spec->multiout.num_dacs = 2; /* only use one dac */
8386 spec->multiout.dac_nids = spec->private_dac_nids;
8387 spec->multiout.dac_nids[0] = 2;
8388 spec->multiout.dac_nids[1] = 3;
8389
8390 nid = cfg->line_out_pins[0];
8391 if (nid)
8392 alc268_new_analog_output(spec, nid, "Front", 0);
8393
8394 nid = cfg->speaker_pins[0];
8395 if (nid == 0x1d) {
8396 err = add_control(spec, ALC_CTL_WIDGET_VOL,
8397 "Speaker Playback Volume",
8398 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
8399 if (err < 0)
8400 return err;
8401 }
8402 nid = cfg->hp_pins[0];
8403 if (nid)
8404 alc268_new_analog_output(spec, nid, "Headphone", 0);
8405
8406 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
8407 if (nid == 0x16) {
8408 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8409 "Mono Playback Switch",
8410 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT));
8411 if (err < 0)
8412 return err;
8413 }
8414 return 0;
8415}
8416
8417/* create playback/capture controls for input pins */
8418static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec,
8419 const struct auto_pin_cfg *cfg)
8420{
8421 struct hda_input_mux *imux = &spec->private_imux;
8422 int i, idx1;
8423
8424 for (i = 0; i < AUTO_PIN_LAST; i++) {
8425 switch(cfg->input_pins[i]) {
8426 case 0x18:
8427 idx1 = 0; /* Mic 1 */
8428 break;
8429 case 0x19:
8430 idx1 = 1; /* Mic 2 */
8431 break;
8432 case 0x1a:
8433 idx1 = 2; /* Line In */
8434 break;
8435 case 0x1c:
8436 idx1 = 3; /* CD */
8437 break;
8438 default:
8439 continue;
8440 }
8441 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
8442 imux->items[imux->num_items].index = idx1;
8443 imux->num_items++;
8444 }
8445 return 0;
8446}
8447
8448static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
8449{
8450 struct alc_spec *spec = codec->spec;
8451 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
8452 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
8453 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
8454 unsigned int dac_vol1, dac_vol2;
8455
8456 if (speaker_nid) {
8457 snd_hda_codec_write(codec, speaker_nid, 0,
8458 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
8459 snd_hda_codec_write(codec, 0x0f, 0,
8460 AC_VERB_SET_AMP_GAIN_MUTE,
8461 AMP_IN_UNMUTE(1));
8462 snd_hda_codec_write(codec, 0x10, 0,
8463 AC_VERB_SET_AMP_GAIN_MUTE,
8464 AMP_IN_UNMUTE(1));
8465 } else {
8466 snd_hda_codec_write(codec, 0x0f, 0,
8467 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
8468 snd_hda_codec_write(codec, 0x10, 0,
8469 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
8470 }
8471
8472 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
8473 if (line_nid == 0x14)
8474 dac_vol2 = AMP_OUT_ZERO;
8475 else if (line_nid == 0x15)
8476 dac_vol1 = AMP_OUT_ZERO;
8477 if (hp_nid == 0x14)
8478 dac_vol2 = AMP_OUT_ZERO;
8479 else if (hp_nid == 0x15)
8480 dac_vol1 = AMP_OUT_ZERO;
8481 if (line_nid != 0x16 || hp_nid != 0x16 ||
8482 spec->autocfg.line_out_pins[1] != 0x16 ||
8483 spec->autocfg.line_out_pins[2] != 0x16)
8484 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
8485
8486 snd_hda_codec_write(codec, 0x02, 0,
8487 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
8488 snd_hda_codec_write(codec, 0x03, 0,
8489 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
8490}
8491
8492/* pcm configuration: identiacal with ALC880 */
8493#define alc268_pcm_analog_playback alc880_pcm_analog_playback
8494#define alc268_pcm_analog_capture alc880_pcm_analog_capture
8495#define alc268_pcm_digital_playback alc880_pcm_digital_playback
8496
8497/*
8498 * BIOS auto configuration
8499 */
8500static int alc268_parse_auto_config(struct hda_codec *codec)
8501{
8502 struct alc_spec *spec = codec->spec;
8503 int err;
8504 static hda_nid_t alc268_ignore[] = { 0 };
8505
8506 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
8507 alc268_ignore);
8508 if (err < 0)
8509 return err;
8510 if (!spec->autocfg.line_outs)
8511 return 0; /* can't find valid BIOS pin config */
8512
8513 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
8514 if (err < 0)
8515 return err;
8516 err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg);
8517 if (err < 0)
8518 return err;
8519
8520 spec->multiout.max_channels = 2;
8521
8522 /* digital only support output */
8523 if (spec->autocfg.dig_out_pin)
8524 spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
8525
8526 if (spec->kctl_alloc)
8527 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
8528
8529 spec->init_verbs[spec->num_init_verbs++] = alc268_volume_init_verbs;
8530 spec->num_mux_defs = 1;
8531 spec->input_mux = &spec->private_imux;
8532
8533 return 1;
8534}
8535
8536#define alc268_auto_init_multi_out alc882_auto_init_multi_out
8537#define alc268_auto_init_hp_out alc882_auto_init_hp_out
8538#define alc268_auto_init_analog_input alc882_auto_init_analog_input
8539
8540/* init callback for auto-configuration model -- overriding the default init */
8541static void alc268_auto_init(struct hda_codec *codec)
8542{
8543 alc268_auto_init_multi_out(codec);
8544 alc268_auto_init_hp_out(codec);
8545 alc268_auto_init_mono_speaker_out(codec);
8546 alc268_auto_init_analog_input(codec);
8547}
8548
8549/*
8550 * configuration and preset
8551 */
8552static const char *alc268_models[ALC268_MODEL_LAST] = {
8553 [ALC268_3ST] = "3stack",
8554 [ALC268_AUTO] = "auto",
8555};
8556
8557static struct snd_pci_quirk alc268_cfg_tbl[] = {
8558 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
8559 {}
8560};
8561
8562static struct alc_config_preset alc268_presets[] = {
8563 [ALC268_3ST] = {
8564 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer },
8565 .init_verbs = { alc268_base_init_verbs },
8566 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
8567 .dac_nids = alc268_dac_nids,
8568 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
8569 .adc_nids = alc268_adc_nids_alt,
8570 .hp_nid = 0x03,
8571 .dig_out_nid = ALC268_DIGOUT_NID,
8572 .num_channel_mode = ARRAY_SIZE(alc268_modes),
8573 .channel_mode = alc268_modes,
8574 .input_mux = &alc268_capture_source,
8575 },
8576};
8577
8578static int patch_alc268(struct hda_codec *codec)
8579{
8580 struct alc_spec *spec;
8581 int board_config;
8582 int err;
8583
8584 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
8585 if (spec == NULL)
8586 return -ENOMEM;
8587
8588 codec->spec = spec;
8589
8590 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
8591 alc268_models,
8592 alc268_cfg_tbl);
8593
8594 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
8595 printk(KERN_INFO "hda_codec: Unknown model for ALC268, "
8596 "trying auto-probe from BIOS...\n");
8597 board_config = ALC268_AUTO;
8598 }
8599
8600 if (board_config == ALC268_AUTO) {
8601 /* automatic parse from the BIOS config */
8602 err = alc268_parse_auto_config(codec);
8603 if (err < 0) {
8604 alc_free(codec);
8605 return err;
8606 } else if (!err) {
8607 printk(KERN_INFO
8608 "hda_codec: Cannot set up configuration "
8609 "from BIOS. Using base mode...\n");
8610 board_config = ALC268_3ST;
8611 }
8612 }
8613
8614 if (board_config != ALC268_AUTO)
8615 setup_preset(spec, &alc268_presets[board_config]);
8616
8617 spec->stream_name_analog = "ALC268 Analog";
8618 spec->stream_analog_playback = &alc268_pcm_analog_playback;
8619 spec->stream_analog_capture = &alc268_pcm_analog_capture;
8620
8621 spec->stream_name_digital = "ALC268 Digital";
8622 spec->stream_digital_playback = &alc268_pcm_digital_playback;
8623
8624 if (board_config == ALC268_AUTO) {
8625 if (!spec->adc_nids && spec->input_mux) {
8626 /* check whether NID 0x07 is valid */
8627 unsigned int wcap = get_wcaps(codec, 0x07);
8628
8629 /* get type */
8630 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
8631 if (wcap != AC_WID_AUD_IN) {
8632 spec->adc_nids = alc268_adc_nids_alt;
8633 spec->num_adc_nids =
8634 ARRAY_SIZE(alc268_adc_nids_alt);
8635 spec->mixers[spec->num_mixers] =
8636 alc268_capture_alt_mixer;
8637 spec->num_mixers++;
8638 } else {
8639 spec->adc_nids = alc268_adc_nids;
8640 spec->num_adc_nids =
8641 ARRAY_SIZE(alc268_adc_nids);
8642 spec->mixers[spec->num_mixers] =
8643 alc268_capture_mixer;
8644 spec->num_mixers++;
8645 }
8646 }
8647 }
8648 codec->patch_ops = alc_patch_ops;
8649 if (board_config == ALC268_AUTO)
8650 spec->init_hook = alc268_auto_init;
8651
8652 return 0;
8653}
8654
8655/*
7803 * ALC861 channel source setting (2/6 channel selection for 3-stack) 8656 * ALC861 channel source setting (2/6 channel selection for 3-stack)
7804 */ 8657 */
7805 8658
@@ -8767,13 +9620,21 @@ static struct snd_pci_quirk alc861_cfg_tbl[] = {
8767 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP), 9620 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
8768 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP), 9621 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
8769 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP), 9622 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
9623 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
8770 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS), 9624 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
9625 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
8771 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA), 9626 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
8772 SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), 9627 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
9628 * Any other models that need this preset?
9629 */
9630 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
8773 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31), 9631 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
9632 SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31),
8774 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31), 9633 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
8775 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST), 9634 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
8776 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST), 9635 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
9636 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
9637 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
8777 {} 9638 {}
8778}; 9639};
8779 9640
@@ -9464,6 +10325,7 @@ static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int re
9464 */ 10325 */
9465static const char *alc861vd_models[ALC861VD_MODEL_LAST] = { 10326static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
9466 [ALC660VD_3ST] = "3stack-660", 10327 [ALC660VD_3ST] = "3stack-660",
10328 [ALC660VD_3ST_DIG]= "3stack-660-digout",
9467 [ALC861VD_3ST] = "3stack", 10329 [ALC861VD_3ST] = "3stack",
9468 [ALC861VD_3ST_DIG] = "3stack-digout", 10330 [ALC861VD_3ST_DIG] = "3stack-digout",
9469 [ALC861VD_6ST_DIG] = "6stack-digout", 10331 [ALC861VD_6ST_DIG] = "6stack-digout",
@@ -9475,7 +10337,7 @@ static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
9475static struct snd_pci_quirk alc861vd_cfg_tbl[] = { 10337static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
9476 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST), 10338 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
9477 SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST), 10339 SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
9478 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST), 10340 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
9479 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST), 10341 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
9480 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST), 10342 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
9481 10343
@@ -9483,6 +10345,7 @@ static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
9483 SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS), 10345 SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS),
9484 SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO), 10346 SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO),
9485 SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO), 10347 SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO),
10348 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
9486 {} 10349 {}
9487}; 10350};
9488 10351
@@ -9499,6 +10362,19 @@ static struct alc_config_preset alc861vd_presets[] = {
9499 .channel_mode = alc861vd_3stack_2ch_modes, 10362 .channel_mode = alc861vd_3stack_2ch_modes,
9500 .input_mux = &alc861vd_capture_source, 10363 .input_mux = &alc861vd_capture_source,
9501 }, 10364 },
10365 [ALC660VD_3ST_DIG] = {
10366 .mixers = { alc861vd_3st_mixer },
10367 .init_verbs = { alc861vd_volume_init_verbs,
10368 alc861vd_3stack_init_verbs },
10369 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
10370 .dac_nids = alc660vd_dac_nids,
10371 .dig_out_nid = ALC861VD_DIGOUT_NID,
10372 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
10373 .adc_nids = alc861vd_adc_nids,
10374 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
10375 .channel_mode = alc861vd_3stack_2ch_modes,
10376 .input_mux = &alc861vd_capture_source,
10377 },
9502 [ALC861VD_3ST] = { 10378 [ALC861VD_3ST] = {
9503 .mixers = { alc861vd_3st_mixer }, 10379 .mixers = { alc861vd_3st_mixer },
9504 .init_verbs = { alc861vd_volume_init_verbs, 10380 .init_verbs = { alc861vd_volume_init_verbs,
@@ -10420,7 +11296,7 @@ static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
10420 for (i = 0; i < cfg->line_outs; i++) { 11296 for (i = 0; i < cfg->line_outs; i++) {
10421 if (!spec->multiout.dac_nids[i]) 11297 if (!spec->multiout.dac_nids[i])
10422 continue; 11298 continue;
10423 nid = alc880_idx_to_dac(i); 11299 nid = alc880_idx_to_mixer(i);
10424 if (i == 2) { 11300 if (i == 2) {
10425 /* Center/LFE */ 11301 /* Center/LFE */
10426 err = add_control(spec, ALC_CTL_WIDGET_VOL, 11302 err = add_control(spec, ALC_CTL_WIDGET_VOL,
@@ -10643,14 +11519,10 @@ static int alc662_parse_auto_config(struct hda_codec *codec)
10643 spec->num_mux_defs = 1; 11519 spec->num_mux_defs = 1;
10644 spec->input_mux = &spec->private_imux; 11520 spec->input_mux = &spec->private_imux;
10645 11521
10646 if (err < 0) 11522 spec->init_verbs[spec->num_init_verbs++] = alc662_auto_init_verbs;
10647 return err;
10648 else if (err > 0)
10649 /* hack - override the init verbs */
10650 spec->init_verbs[0] = alc662_auto_init_verbs;
10651 spec->mixers[spec->num_mixers] = alc662_capture_mixer; 11523 spec->mixers[spec->num_mixers] = alc662_capture_mixer;
10652 spec->num_mixers++; 11524 spec->num_mixers++;
10653 return err; 11525 return 1;
10654} 11526}
10655 11527
10656/* additional initialization for auto-configuration model */ 11528/* additional initialization for auto-configuration model */
@@ -10687,7 +11559,7 @@ static int patch_alc662(struct hda_codec *codec)
10687 if (err < 0) { 11559 if (err < 0) {
10688 alc_free(codec); 11560 alc_free(codec);
10689 return err; 11561 return err;
10690 } else if (err) { 11562 } else if (!err) {
10691 printk(KERN_INFO 11563 printk(KERN_INFO
10692 "hda_codec: Cannot set up configuration " 11564 "hda_codec: Cannot set up configuration "
10693 "from BIOS. Using base mode...\n"); 11565 "from BIOS. Using base mode...\n");
@@ -10724,6 +11596,7 @@ static int patch_alc662(struct hda_codec *codec)
10724struct hda_codec_preset snd_hda_preset_realtek[] = { 11596struct hda_codec_preset snd_hda_preset_realtek[] = {
10725 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 }, 11597 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
10726 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 }, 11598 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
11599 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
10727 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660", 11600 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
10728 .patch = patch_alc861 }, 11601 .patch = patch_alc861 },
10729 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd }, 11602 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
diff --git a/sound/pci/hda/patch_si3054.c b/sound/pci/hda/patch_si3054.c
index 43f537ef40bf..6d2ecc38905c 100644
--- a/sound/pci/hda/patch_si3054.c
+++ b/sound/pci/hda/patch_si3054.c
@@ -304,8 +304,12 @@ struct hda_codec_preset snd_hda_preset_si3054[] = {
304 { .id = 0x10573055, .name = "Si3054", .patch = patch_si3054 }, 304 { .id = 0x10573055, .name = "Si3054", .patch = patch_si3054 },
305 { .id = 0x10573057, .name = "Si3054", .patch = patch_si3054 }, 305 { .id = 0x10573057, .name = "Si3054", .patch = patch_si3054 },
306 { .id = 0x10573155, .name = "Si3054", .patch = patch_si3054 }, 306 { .id = 0x10573155, .name = "Si3054", .patch = patch_si3054 },
307 /* VIA HDA on Clevo m540 */
308 { .id = 0x11063288, .name = "Si3054", .patch = patch_si3054 },
307 /* Asus A8J Modem (SM56) */ 309 /* Asus A8J Modem (SM56) */
308 { .id = 0x15433155, .name = "Si3054", .patch = patch_si3054 }, 310 { .id = 0x15433155, .name = "Si3054", .patch = patch_si3054 },
311 /* LG LW20 modem */
312 { .id = 0x18540018, .name = "Si3054", .patch = patch_si3054 },
309 {} 313 {}
310}; 314};
311 315
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index e3964fc4c405..3f25de72966b 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -44,6 +44,7 @@ enum {
44 44
45enum { 45enum {
46 STAC_9205_REF, 46 STAC_9205_REF,
47 STAC_M43xx,
47 STAC_9205_MODELS 48 STAC_9205_MODELS
48}; 49};
49 50
@@ -59,11 +60,19 @@ enum {
59 STAC_D945_REF, 60 STAC_D945_REF,
60 STAC_D945GTP3, 61 STAC_D945GTP3,
61 STAC_D945GTP5, 62 STAC_D945GTP5,
63 STAC_922X_DELL,
64 STAC_INTEL_MAC_V1,
65 STAC_INTEL_MAC_V2,
66 STAC_INTEL_MAC_V3,
67 STAC_INTEL_MAC_V4,
68 STAC_INTEL_MAC_V5,
69 /* for backward compitability */
62 STAC_MACMINI, 70 STAC_MACMINI,
63 STAC_MACBOOK, 71 STAC_MACBOOK,
64 STAC_MACBOOK_PRO_V1, 72 STAC_MACBOOK_PRO_V1,
65 STAC_MACBOOK_PRO_V2, 73 STAC_MACBOOK_PRO_V2,
66 STAC_IMAC_INTEL, 74 STAC_IMAC_INTEL,
75 STAC_IMAC_INTEL_20,
67 STAC_922X_MODELS 76 STAC_922X_MODELS
68}; 77};
69 78
@@ -210,7 +219,6 @@ static hda_nid_t stac9205_pin_nids[12] = {
210 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 219 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
211 0x0f, 0x14, 0x16, 0x17, 0x18, 220 0x0f, 0x14, 0x16, 0x17, 0x18,
212 0x21, 0x22, 221 0x21, 0x22,
213
214}; 222};
215 223
216static int stac92xx_dmux_enum_info(struct snd_kcontrol *kcontrol, 224static int stac92xx_dmux_enum_info(struct snd_kcontrol *kcontrol,
@@ -326,8 +334,6 @@ static struct snd_kcontrol_new stac9200_mixer[] = {
326}; 334};
327 335
328static struct snd_kcontrol_new stac925x_mixer[] = { 336static struct snd_kcontrol_new stac925x_mixer[] = {
329 HDA_CODEC_VOLUME("Master Playback Volume", 0xe, 0, HDA_OUTPUT),
330 HDA_CODEC_MUTE("Master Playback Switch", 0xe, 0, HDA_OUTPUT),
331 { 337 {
332 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 338 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
333 .name = "Input Source", 339 .name = "Input Source",
@@ -549,44 +555,78 @@ static unsigned int d945gtp5_pin_configs[10] = {
549 0x02a19320, 0x40000100, 555 0x02a19320, 0x40000100,
550}; 556};
551 557
552static unsigned int macbook_pro_v1_pin_configs[10] = { 558static unsigned int intel_mac_v1_pin_configs[10] = {
553 0x0321e230, 0x03a1e020, 0x9017e110, 0x01014010, 559 0x0121e21f, 0x400000ff, 0x9017e110, 0x400000fd,
554 0x01a19021, 0x0381e021, 0x1345e240, 0x13c5e22e, 560 0x400000fe, 0x0181e020, 0x1145e030, 0x11c5e240,
555 0x02a19320, 0x400000fb 561 0x400000fc, 0x400000fb,
562};
563
564static unsigned int intel_mac_v2_pin_configs[10] = {
565 0x0121e21f, 0x90a7012e, 0x9017e110, 0x400000fd,
566 0x400000fe, 0x0181e020, 0x1145e230, 0x500000fa,
567 0x400000fc, 0x400000fb,
568};
569
570static unsigned int intel_mac_v3_pin_configs[10] = {
571 0x0121e21f, 0x90a7012e, 0x9017e110, 0x400000fd,
572 0x400000fe, 0x0181e020, 0x1145e230, 0x11c5e240,
573 0x400000fc, 0x400000fb,
556}; 574};
557 575
558static unsigned int macbook_pro_v2_pin_configs[10] = { 576static unsigned int intel_mac_v4_pin_configs[10] = {
559 0x0221401f, 0x90a70120, 0x01813024, 0x01014010, 577 0x0321e21f, 0x03a1e02e, 0x9017e110, 0x9017e11f,
560 0x400000fd, 0x01016011, 0x1345e240, 0x13c5e22e, 578 0x400000fe, 0x0381e020, 0x1345e230, 0x13c5e240,
561 0x400000fc, 0x400000fb, 579 0x400000fc, 0x400000fb,
562}; 580};
563 581
564static unsigned int imac_intel_pin_configs[10] = { 582static unsigned int intel_mac_v5_pin_configs[10] = {
565 0x0121e230, 0x90a70120, 0x9017e110, 0x400000fe, 583 0x0321e21f, 0x03a1e02e, 0x9017e110, 0x9017e11f,
566 0x400000fd, 0x0181e021, 0x1145e040, 0x400000fa, 584 0x400000fe, 0x0381e020, 0x1345e230, 0x13c5e240,
567 0x400000fc, 0x400000fb, 585 0x400000fc, 0x400000fb,
568}; 586};
569 587
588static unsigned int stac922x_dell_pin_configs[10] = {
589 0x0221121e, 0x408103ff, 0x02a1123e, 0x90100310,
590 0x408003f1, 0x0221122f, 0x03451340, 0x40c003f2,
591 0x50a003f3, 0x405003f4
592};
593
570static unsigned int *stac922x_brd_tbl[STAC_922X_MODELS] = { 594static unsigned int *stac922x_brd_tbl[STAC_922X_MODELS] = {
571 [STAC_D945_REF] = ref922x_pin_configs, 595 [STAC_D945_REF] = ref922x_pin_configs,
572 [STAC_D945GTP3] = d945gtp3_pin_configs, 596 [STAC_D945GTP3] = d945gtp3_pin_configs,
573 [STAC_D945GTP5] = d945gtp5_pin_configs, 597 [STAC_D945GTP5] = d945gtp5_pin_configs,
574 [STAC_MACMINI] = macbook_pro_v1_pin_configs, 598 [STAC_922X_DELL] = stac922x_dell_pin_configs,
575 [STAC_MACBOOK] = macbook_pro_v1_pin_configs, 599 [STAC_INTEL_MAC_V1] = intel_mac_v1_pin_configs,
576 [STAC_MACBOOK_PRO_V1] = macbook_pro_v1_pin_configs, 600 [STAC_INTEL_MAC_V2] = intel_mac_v2_pin_configs,
577 [STAC_MACBOOK_PRO_V2] = macbook_pro_v2_pin_configs, 601 [STAC_INTEL_MAC_V3] = intel_mac_v3_pin_configs,
578 [STAC_IMAC_INTEL] = imac_intel_pin_configs, 602 [STAC_INTEL_MAC_V4] = intel_mac_v4_pin_configs,
603 [STAC_INTEL_MAC_V5] = intel_mac_v5_pin_configs,
604 /* for backward compitability */
605 [STAC_MACMINI] = intel_mac_v3_pin_configs,
606 [STAC_MACBOOK] = intel_mac_v5_pin_configs,
607 [STAC_MACBOOK_PRO_V1] = intel_mac_v3_pin_configs,
608 [STAC_MACBOOK_PRO_V2] = intel_mac_v3_pin_configs,
609 [STAC_IMAC_INTEL] = intel_mac_v2_pin_configs,
610 [STAC_IMAC_INTEL_20] = intel_mac_v3_pin_configs,
579}; 611};
580 612
581static const char *stac922x_models[STAC_922X_MODELS] = { 613static const char *stac922x_models[STAC_922X_MODELS] = {
582 [STAC_D945_REF] = "ref", 614 [STAC_D945_REF] = "ref",
583 [STAC_D945GTP5] = "5stack", 615 [STAC_D945GTP5] = "5stack",
584 [STAC_D945GTP3] = "3stack", 616 [STAC_D945GTP3] = "3stack",
617 [STAC_922X_DELL] = "dell",
618 [STAC_INTEL_MAC_V1] = "intel-mac-v1",
619 [STAC_INTEL_MAC_V2] = "intel-mac-v2",
620 [STAC_INTEL_MAC_V3] = "intel-mac-v3",
621 [STAC_INTEL_MAC_V4] = "intel-mac-v4",
622 [STAC_INTEL_MAC_V5] = "intel-mac-v5",
623 /* for backward compitability */
585 [STAC_MACMINI] = "macmini", 624 [STAC_MACMINI] = "macmini",
586 [STAC_MACBOOK] = "macbook", 625 [STAC_MACBOOK] = "macbook",
587 [STAC_MACBOOK_PRO_V1] = "macbook-pro-v1", 626 [STAC_MACBOOK_PRO_V1] = "macbook-pro-v1",
588 [STAC_MACBOOK_PRO_V2] = "macbook-pro", 627 [STAC_MACBOOK_PRO_V2] = "macbook-pro",
589 [STAC_IMAC_INTEL] = "imac-intel", 628 [STAC_IMAC_INTEL] = "imac-intel",
629 [STAC_IMAC_INTEL_20] = "imac-intel-20",
590}; 630};
591 631
592static struct snd_pci_quirk stac922x_cfg_tbl[] = { 632static struct snd_pci_quirk stac922x_cfg_tbl[] = {
@@ -649,7 +689,10 @@ static struct snd_pci_quirk stac922x_cfg_tbl[] = {
649 /* other systems */ 689 /* other systems */
650 /* Apple Mac Mini (early 2006) */ 690 /* Apple Mac Mini (early 2006) */
651 SND_PCI_QUIRK(0x8384, 0x7680, 691 SND_PCI_QUIRK(0x8384, 0x7680,
652 "Mac Mini", STAC_MACMINI), 692 "Mac Mini", STAC_INTEL_MAC_V3),
693 /* Dell */
694 SND_PCI_QUIRK(0x1028, 0x01d7, "Dell XPS M1210", STAC_922X_DELL),
695
653 {} /* terminator */ 696 {} /* terminator */
654}; 697};
655 698
@@ -730,7 +773,8 @@ static unsigned int ref9205_pin_configs[12] = {
730}; 773};
731 774
732static unsigned int *stac9205_brd_tbl[STAC_9205_MODELS] = { 775static unsigned int *stac9205_brd_tbl[STAC_9205_MODELS] = {
733 ref9205_pin_configs, 776 [STAC_REF] = ref9205_pin_configs,
777 [STAC_M43xx] = NULL,
734}; 778};
735 779
736static const char *stac9205_models[STAC_9205_MODELS] = { 780static const char *stac9205_models[STAC_9205_MODELS] = {
@@ -741,6 +785,10 @@ static struct snd_pci_quirk stac9205_cfg_tbl[] = {
741 /* SigmaTel reference board */ 785 /* SigmaTel reference board */
742 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, 786 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
743 "DFI LanParty", STAC_9205_REF), 787 "DFI LanParty", STAC_9205_REF),
788 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x01f8,
789 "Dell Precision", STAC_M43xx),
790 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x01ff,
791 "Dell Precision", STAC_M43xx),
744 {} /* terminator */ 792 {} /* terminator */
745}; 793};
746 794
@@ -770,33 +818,56 @@ static int stac92xx_save_bios_config_regs(struct hda_codec *codec)
770 return 0; 818 return 0;
771} 819}
772 820
821static void stac92xx_set_config_reg(struct hda_codec *codec,
822 hda_nid_t pin_nid, unsigned int pin_config)
823{
824 int i;
825 snd_hda_codec_write(codec, pin_nid, 0,
826 AC_VERB_SET_CONFIG_DEFAULT_BYTES_0,
827 pin_config & 0x000000ff);
828 snd_hda_codec_write(codec, pin_nid, 0,
829 AC_VERB_SET_CONFIG_DEFAULT_BYTES_1,
830 (pin_config & 0x0000ff00) >> 8);
831 snd_hda_codec_write(codec, pin_nid, 0,
832 AC_VERB_SET_CONFIG_DEFAULT_BYTES_2,
833 (pin_config & 0x00ff0000) >> 16);
834 snd_hda_codec_write(codec, pin_nid, 0,
835 AC_VERB_SET_CONFIG_DEFAULT_BYTES_3,
836 pin_config >> 24);
837 i = snd_hda_codec_read(codec, pin_nid, 0,
838 AC_VERB_GET_CONFIG_DEFAULT,
839 0x00);
840 snd_printdd(KERN_INFO "hda_codec: pin nid %2.2x pin config %8.8x\n",
841 pin_nid, i);
842}
843
773static void stac92xx_set_config_regs(struct hda_codec *codec) 844static void stac92xx_set_config_regs(struct hda_codec *codec)
774{ 845{
775 int i; 846 int i;
776 struct sigmatel_spec *spec = codec->spec; 847 struct sigmatel_spec *spec = codec->spec;
777 unsigned int pin_cfg;
778 848
779 if (! spec->pin_nids || ! spec->pin_configs) 849 if (!spec->pin_configs)
780 return; 850 return;
781 851
782 for (i = 0; i < spec->num_pins; i++) { 852 for (i = 0; i < spec->num_pins; i++)
783 snd_hda_codec_write(codec, spec->pin_nids[i], 0, 853 stac92xx_set_config_reg(codec, spec->pin_nids[i],
784 AC_VERB_SET_CONFIG_DEFAULT_BYTES_0, 854 spec->pin_configs[i]);
785 spec->pin_configs[i] & 0x000000ff); 855}
786 snd_hda_codec_write(codec, spec->pin_nids[i], 0, 856
787 AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 857static void stac92xx_enable_gpio_mask(struct hda_codec *codec,
788 (spec->pin_configs[i] & 0x0000ff00) >> 8); 858 int gpio_mask, int gpio_data)
789 snd_hda_codec_write(codec, spec->pin_nids[i], 0, 859{
790 AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 860 /* Configure GPIOx as output */
791 (spec->pin_configs[i] & 0x00ff0000) >> 16); 861 snd_hda_codec_write(codec, codec->afg, 0,
792 snd_hda_codec_write(codec, spec->pin_nids[i], 0, 862 AC_VERB_SET_GPIO_DIRECTION, gpio_mask);
793 AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 863 /* Configure GPIOx as CMOS */
794 spec->pin_configs[i] >> 24); 864 snd_hda_codec_write(codec, codec->afg, 0, 0x7e7, 0x00000000);
795 pin_cfg = snd_hda_codec_read(codec, spec->pin_nids[i], 0, 865 /* Assert GPIOx */
796 AC_VERB_GET_CONFIG_DEFAULT, 866 snd_hda_codec_write(codec, codec->afg, 0,
797 0x00); 867 AC_VERB_SET_GPIO_DATA, gpio_data);
798 snd_printdd(KERN_INFO "hda_codec: pin nid %2.2x pin config %8.8x\n", spec->pin_nids[i], pin_cfg); 868 /* Enable GPIOx */
799 } 869 snd_hda_codec_write(codec, codec->afg, 0,
870 AC_VERB_SET_GPIO_MASK, gpio_mask);
800} 871}
801 872
802/* 873/*
@@ -1168,7 +1239,7 @@ static int is_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid)
1168 * and 9202/925x. For those, dac_nids[] must be hard-coded. 1239 * and 9202/925x. For those, dac_nids[] must be hard-coded.
1169 */ 1240 */
1170static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec, 1241static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec,
1171 const struct auto_pin_cfg *cfg) 1242 struct auto_pin_cfg *cfg)
1172{ 1243{
1173 struct sigmatel_spec *spec = codec->spec; 1244 struct sigmatel_spec *spec = codec->spec;
1174 int i, j, conn_len = 0; 1245 int i, j, conn_len = 0;
@@ -1193,6 +1264,13 @@ static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec,
1193 } 1264 }
1194 1265
1195 if (j == conn_len) { 1266 if (j == conn_len) {
1267 if (spec->multiout.num_dacs > 0) {
1268 /* we have already working output pins,
1269 * so let's drop the broken ones again
1270 */
1271 cfg->line_outs = spec->multiout.num_dacs;
1272 break;
1273 }
1196 /* error out, no available DAC found */ 1274 /* error out, no available DAC found */
1197 snd_printk(KERN_ERR 1275 snd_printk(KERN_ERR
1198 "%s: No available DAC for pin 0x%x\n", 1276 "%s: No available DAC for pin 0x%x\n",
@@ -1334,7 +1412,15 @@ static int stac92xx_auto_create_hp_ctls(struct hda_codec *codec,
1334 continue; 1412 continue;
1335 add_spec_dacs(spec, nid); 1413 add_spec_dacs(spec, nid);
1336 } 1414 }
1337 1415 for (i = 0; i < cfg->line_outs; i++) {
1416 nid = snd_hda_codec_read(codec, cfg->line_out_pins[i], 0,
1417 AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
1418 if (check_in_dac_nids(spec, nid))
1419 nid = 0;
1420 if (! nid)
1421 continue;
1422 add_spec_dacs(spec, nid);
1423 }
1338 for (i = old_num_dacs; i < spec->multiout.num_dacs; i++) { 1424 for (i = old_num_dacs; i < spec->multiout.num_dacs; i++) {
1339 static const char *pfxs[] = { 1425 static const char *pfxs[] = {
1340 "Speaker", "External Speaker", "Speaker2", 1426 "Speaker", "External Speaker", "Speaker2",
@@ -1891,7 +1977,7 @@ static int patch_stac9200(struct hda_codec *codec)
1891 return -ENOMEM; 1977 return -ENOMEM;
1892 1978
1893 codec->spec = spec; 1979 codec->spec = spec;
1894 spec->num_pins = 8; 1980 spec->num_pins = ARRAY_SIZE(stac9200_pin_nids);
1895 spec->pin_nids = stac9200_pin_nids; 1981 spec->pin_nids = stac9200_pin_nids;
1896 spec->board_config = snd_hda_check_board_config(codec, STAC_9200_MODELS, 1982 spec->board_config = snd_hda_check_board_config(codec, STAC_9200_MODELS,
1897 stac9200_models, 1983 stac9200_models,
@@ -1941,7 +2027,7 @@ static int patch_stac925x(struct hda_codec *codec)
1941 return -ENOMEM; 2027 return -ENOMEM;
1942 2028
1943 codec->spec = spec; 2029 codec->spec = spec;
1944 spec->num_pins = 8; 2030 spec->num_pins = ARRAY_SIZE(stac925x_pin_nids);
1945 spec->pin_nids = stac925x_pin_nids; 2031 spec->pin_nids = stac925x_pin_nids;
1946 spec->board_config = snd_hda_check_board_config(codec, STAC_925x_MODELS, 2032 spec->board_config = snd_hda_check_board_config(codec, STAC_925x_MODELS,
1947 stac925x_models, 2033 stac925x_models,
@@ -2013,29 +2099,41 @@ static int patch_stac922x(struct hda_codec *codec)
2013 return -ENOMEM; 2099 return -ENOMEM;
2014 2100
2015 codec->spec = spec; 2101 codec->spec = spec;
2016 spec->num_pins = 10; 2102 spec->num_pins = ARRAY_SIZE(stac922x_pin_nids);
2017 spec->pin_nids = stac922x_pin_nids; 2103 spec->pin_nids = stac922x_pin_nids;
2018 spec->board_config = snd_hda_check_board_config(codec, STAC_922X_MODELS, 2104 spec->board_config = snd_hda_check_board_config(codec, STAC_922X_MODELS,
2019 stac922x_models, 2105 stac922x_models,
2020 stac922x_cfg_tbl); 2106 stac922x_cfg_tbl);
2021 if (spec->board_config == STAC_MACMINI) { 2107 if (spec->board_config == STAC_INTEL_MAC_V3) {
2022 spec->gpio_mute = 1; 2108 spec->gpio_mute = 1;
2023 /* Intel Macs have all same PCI SSID, so we need to check 2109 /* Intel Macs have all same PCI SSID, so we need to check
2024 * codec SSID to distinguish the exact models 2110 * codec SSID to distinguish the exact models
2025 */ 2111 */
2026 printk(KERN_INFO "hda_codec: STAC922x, Apple subsys_id=%x\n", codec->subsystem_id); 2112 printk(KERN_INFO "hda_codec: STAC922x, Apple subsys_id=%x\n", codec->subsystem_id);
2027 switch (codec->subsystem_id) { 2113 switch (codec->subsystem_id) {
2028 case 0x106b0a00: /* MacBook First generatoin */ 2114
2029 spec->board_config = STAC_MACBOOK; 2115 case 0x106b0800:
2116 spec->board_config = STAC_INTEL_MAC_V1;
2117 break;
2118 case 0x106b0600:
2119 case 0x106b0700:
2120 spec->board_config = STAC_INTEL_MAC_V2;
2030 break; 2121 break;
2031 case 0x106b0200: /* MacBook Pro first generation */ 2122 case 0x106b0e00:
2032 spec->board_config = STAC_MACBOOK_PRO_V1; 2123 case 0x106b0f00:
2124 case 0x106b1600:
2125 case 0x106b1700:
2126 case 0x106b0200:
2127 case 0x106b1e00:
2128 spec->board_config = STAC_INTEL_MAC_V3;
2033 break; 2129 break;
2034 case 0x106b1e00: /* MacBook Pro second generation */ 2130 case 0x106b1a00:
2035 spec->board_config = STAC_MACBOOK_PRO_V2; 2131 case 0x00000100:
2132 spec->board_config = STAC_INTEL_MAC_V4;
2036 break; 2133 break;
2037 case 0x106b0700: /* Intel-based iMac */ 2134 case 0x106b0a00:
2038 spec->board_config = STAC_IMAC_INTEL; 2135 case 0x106b2200:
2136 spec->board_config = STAC_INTEL_MAC_V5;
2039 break; 2137 break;
2040 } 2138 }
2041 } 2139 }
@@ -2082,6 +2180,13 @@ static int patch_stac922x(struct hda_codec *codec)
2082 2180
2083 codec->patch_ops = stac92xx_patch_ops; 2181 codec->patch_ops = stac92xx_patch_ops;
2084 2182
2183 /* Fix Mux capture level; max to 2 */
2184 snd_hda_override_amp_caps(codec, 0x12, HDA_OUTPUT,
2185 (0 << AC_AMPCAP_OFFSET_SHIFT) |
2186 (2 << AC_AMPCAP_NUM_STEPS_SHIFT) |
2187 (0x27 << AC_AMPCAP_STEP_SIZE_SHIFT) |
2188 (0 << AC_AMPCAP_MUTE_SHIFT));
2189
2085 return 0; 2190 return 0;
2086} 2191}
2087 2192
@@ -2095,7 +2200,7 @@ static int patch_stac927x(struct hda_codec *codec)
2095 return -ENOMEM; 2200 return -ENOMEM;
2096 2201
2097 codec->spec = spec; 2202 codec->spec = spec;
2098 spec->num_pins = 14; 2203 spec->num_pins = ARRAY_SIZE(stac927x_pin_nids);
2099 spec->pin_nids = stac927x_pin_nids; 2204 spec->pin_nids = stac927x_pin_nids;
2100 spec->board_config = snd_hda_check_board_config(codec, STAC_927X_MODELS, 2205 spec->board_config = snd_hda_check_board_config(codec, STAC_927X_MODELS,
2101 stac927x_models, 2206 stac927x_models,
@@ -2141,7 +2246,9 @@ static int patch_stac927x(struct hda_codec *codec)
2141 } 2246 }
2142 2247
2143 spec->multiout.dac_nids = spec->dac_nids; 2248 spec->multiout.dac_nids = spec->dac_nids;
2144 2249 /* GPIO0 High = Enable EAPD */
2250 stac92xx_enable_gpio_mask(codec, 0x00000001, 0x00000001);
2251
2145 err = stac92xx_parse_auto_config(codec, 0x1e, 0x20); 2252 err = stac92xx_parse_auto_config(codec, 0x1e, 0x20);
2146 if (!err) { 2253 if (!err) {
2147 if (spec->board_config < 0) { 2254 if (spec->board_config < 0) {
@@ -2159,27 +2266,20 @@ static int patch_stac927x(struct hda_codec *codec)
2159 2266
2160 codec->patch_ops = stac92xx_patch_ops; 2267 codec->patch_ops = stac92xx_patch_ops;
2161 2268
2162 /* Fix Mux capture level; max to 2 */
2163 snd_hda_override_amp_caps(codec, 0x12, HDA_OUTPUT,
2164 (0 << AC_AMPCAP_OFFSET_SHIFT) |
2165 (2 << AC_AMPCAP_NUM_STEPS_SHIFT) |
2166 (0x27 << AC_AMPCAP_STEP_SIZE_SHIFT) |
2167 (0 << AC_AMPCAP_MUTE_SHIFT));
2168
2169 return 0; 2269 return 0;
2170} 2270}
2171 2271
2172static int patch_stac9205(struct hda_codec *codec) 2272static int patch_stac9205(struct hda_codec *codec)
2173{ 2273{
2174 struct sigmatel_spec *spec; 2274 struct sigmatel_spec *spec;
2175 int err; 2275 int err, gpio_mask, gpio_data;
2176 2276
2177 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 2277 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
2178 if (spec == NULL) 2278 if (spec == NULL)
2179 return -ENOMEM; 2279 return -ENOMEM;
2180 2280
2181 codec->spec = spec; 2281 codec->spec = spec;
2182 spec->num_pins = 14; 2282 spec->num_pins = ARRAY_SIZE(stac9205_pin_nids);
2183 spec->pin_nids = stac9205_pin_nids; 2283 spec->pin_nids = stac9205_pin_nids;
2184 spec->board_config = snd_hda_check_board_config(codec, STAC_9205_MODELS, 2284 spec->board_config = snd_hda_check_board_config(codec, STAC_9205_MODELS,
2185 stac9205_models, 2285 stac9205_models,
@@ -2209,19 +2309,21 @@ static int patch_stac9205(struct hda_codec *codec)
2209 spec->mixer = stac9205_mixer; 2309 spec->mixer = stac9205_mixer;
2210 2310
2211 spec->multiout.dac_nids = spec->dac_nids; 2311 spec->multiout.dac_nids = spec->dac_nids;
2312
2313 if (spec->board_config == STAC_M43xx) {
2314 /* Enable SPDIF in/out */
2315 stac92xx_set_config_reg(codec, 0x1f, 0x01441030);
2316 stac92xx_set_config_reg(codec, 0x20, 0x1c410030);
2317
2318 gpio_mask = 0x00000007; /* GPIO0-2 */
2319 /* GPIO0 High = EAPD, GPIO1 Low = DRM,
2320 * GPIO2 High = Headphone Mute
2321 */
2322 gpio_data = 0x00000005;
2323 } else
2324 gpio_mask = gpio_data = 0x00000001; /* GPIO0 High = EAPD */
2212 2325
2213 /* Configure GPIO0 as EAPD output */ 2326 stac92xx_enable_gpio_mask(codec, gpio_mask, gpio_data);
2214 snd_hda_codec_write(codec, codec->afg, 0,
2215 AC_VERB_SET_GPIO_DIRECTION, 0x00000001);
2216 /* Configure GPIO0 as CMOS */
2217 snd_hda_codec_write(codec, codec->afg, 0, 0x7e7, 0x00000000);
2218 /* Assert GPIO0 high */
2219 snd_hda_codec_write(codec, codec->afg, 0,
2220 AC_VERB_SET_GPIO_DATA, 0x00000001);
2221 /* Enable GPIO0 */
2222 snd_hda_codec_write(codec, codec->afg, 0,
2223 AC_VERB_SET_GPIO_MASK, 0x00000001);
2224
2225 err = stac92xx_parse_auto_config(codec, 0x1f, 0x20); 2327 err = stac92xx_parse_auto_config(codec, 0x1f, 0x20);
2226 if (!err) { 2328 if (!err) {
2227 if (spec->board_config < 0) { 2329 if (spec->board_config < 0) {
@@ -2256,8 +2358,8 @@ static struct hda_input_mux vaio_mux = {
2256 .num_items = 2, 2358 .num_items = 2,
2257 .items = { 2359 .items = {
2258 /* { "HP", 0x0 }, */ 2360 /* { "HP", 0x0 }, */
2259 { "Line", 0x1 }, 2361 { "Mic Jack", 0x1 },
2260 { "Mic", 0x2 }, 2362 { "Internal Mic", 0x2 },
2261 { "PCM", 0x3 }, 2363 { "PCM", 0x3 },
2262 } 2364 }
2263}; 2365};
@@ -2268,7 +2370,7 @@ static struct hda_verb vaio_init[] = {
2268 {0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? (<- 0x2) */ 2370 {0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? (<- 0x2) */
2269 {0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD */ 2371 {0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD */
2270 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? */ 2372 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? */
2271 {0x15, AC_VERB_SET_CONNECT_SEL, 0x2}, /* mic-sel: 0a,0d,14,02 */ 2373 {0x15, AC_VERB_SET_CONNECT_SEL, 0x1}, /* mic-sel: 0a,0d,14,02 */
2272 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* HP */ 2374 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* HP */
2273 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Speaker */ 2375 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Speaker */
2274 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* capture sw/vol -> 0x8 */ 2376 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* capture sw/vol -> 0x8 */
@@ -2284,7 +2386,7 @@ static struct hda_verb vaio_ar_init[] = {
2284 {0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD */ 2386 {0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD */
2285/* {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },*/ /* Optical Out */ 2387/* {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },*/ /* Optical Out */
2286 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? */ 2388 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? */
2287 {0x15, AC_VERB_SET_CONNECT_SEL, 0x2}, /* mic-sel: 0a,0d,14,02 */ 2389 {0x15, AC_VERB_SET_CONNECT_SEL, 0x1}, /* mic-sel: 0a,0d,14,02 */
2288 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* HP */ 2390 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* HP */
2289 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Speaker */ 2391 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Speaker */
2290/* {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},*/ /* Optical Out */ 2392/* {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},*/ /* Optical Out */
diff --git a/sound/pci/ice1712/revo.c b/sound/pci/ice1712/revo.c
index 690ceb340644..d18a31e188a9 100644
--- a/sound/pci/ice1712/revo.c
+++ b/sound/pci/ice1712/revo.c
@@ -186,7 +186,12 @@ static int revo51_i2c_init(struct snd_ice1712 *ice,
186#define AK_DAC(xname,xch) { .name = xname, .num_channels = xch } 186#define AK_DAC(xname,xch) { .name = xname, .num_channels = xch }
187 187
188static const struct snd_akm4xxx_dac_channel revo71_front[] = { 188static const struct snd_akm4xxx_dac_channel revo71_front[] = {
189 AK_DAC("PCM Playback Volume", 2) 189 {
190 .name = "PCM Playback Volume",
191 .num_channels = 2,
192 /* front channels DAC supports muting */
193 .switch_name = "PCM Playback Switch",
194 },
190}; 195};
191 196
192static const struct snd_akm4xxx_dac_channel revo71_surround[] = { 197static const struct snd_akm4xxx_dac_channel revo71_surround[] = {
diff --git a/sound/pci/nm256/nm256.c b/sound/pci/nm256/nm256.c
index 03b3a4792f73..c7621bd770a6 100644
--- a/sound/pci/nm256/nm256.c
+++ b/sound/pci/nm256/nm256.c
@@ -1533,7 +1533,8 @@ snd_nm256_create(struct snd_card *card, struct pci_dev *pci,
1533 printk(KERN_ERR " force the driver to load by " 1533 printk(KERN_ERR " force the driver to load by "
1534 "passing in the module parameter\n"); 1534 "passing in the module parameter\n");
1535 printk(KERN_ERR " force_ac97=1\n"); 1535 printk(KERN_ERR " force_ac97=1\n");
1536 printk(KERN_ERR " or try sb16 or cs423x drivers instead.\n"); 1536 printk(KERN_ERR " or try sb16, opl3sa2, or "
1537 "cs423x drivers instead.\n");
1537 err = -ENXIO; 1538 err = -ENXIO;
1538 goto __error; 1539 goto __error;
1539 } 1540 }
diff --git a/sound/pci/rme9652/rme9652.c b/sound/pci/rme9652/rme9652.c
index bd7dbd267ed1..2de27405a0bd 100644
--- a/sound/pci/rme9652/rme9652.c
+++ b/sound/pci/rme9652/rme9652.c
@@ -406,7 +406,7 @@ static snd_pcm_uframes_t rme9652_hw_pointer(struct snd_rme9652 *rme9652)
406 } else if (!frag) 406 } else if (!frag)
407 return 0; 407 return 0;
408 offset -= rme9652->max_jitter; 408 offset -= rme9652->max_jitter;
409 if (offset < 0) 409 if ((int)offset < 0)
410 offset += period_size * 2; 410 offset += period_size * 2;
411 } else { 411 } else {
412 if (offset > period_size + rme9652->max_jitter) { 412 if (offset > period_size + rme9652->max_jitter) {
diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c
index 50c9f92cfd1b..6ea09df0c73a 100644
--- a/sound/pci/via82xx.c
+++ b/sound/pci/via82xx.c
@@ -2098,7 +2098,7 @@ static int snd_via82xx_chip_init(struct via82xx *chip)
2098 pci_read_config_byte(chip->pci, VIA_ACLINK_STAT, &pval); 2098 pci_read_config_byte(chip->pci, VIA_ACLINK_STAT, &pval);
2099 if (pval & VIA_ACLINK_C00_READY) /* primary codec ready */ 2099 if (pval & VIA_ACLINK_C00_READY) /* primary codec ready */
2100 break; 2100 break;
2101 schedule_timeout_uninterruptible(1); 2101 schedule_timeout(1);
2102 } while (time_before(jiffies, end_time)); 2102 } while (time_before(jiffies, end_time));
2103 2103
2104 if ((val = snd_via82xx_codec_xread(chip)) & VIA_REG_AC97_BUSY) 2104 if ((val = snd_via82xx_codec_xread(chip)) & VIA_REG_AC97_BUSY)
@@ -2117,7 +2117,7 @@ static int snd_via82xx_chip_init(struct via82xx *chip)
2117 chip->ac97_secondary = 1; 2117 chip->ac97_secondary = 1;
2118 goto __ac97_ok2; 2118 goto __ac97_ok2;
2119 } 2119 }
2120 schedule_timeout_interruptible(1); 2120 schedule_timeout(1);
2121 } while (time_before(jiffies, end_time)); 2121 } while (time_before(jiffies, end_time));
2122 /* This is ok, the most of motherboards have only one codec */ 2122 /* This is ok, the most of motherboards have only one codec */
2123 2123
diff --git a/sound/pci/via82xx_modem.c b/sound/pci/via82xx_modem.c
index 8cbf8eba4ae9..72425e73abae 100644
--- a/sound/pci/via82xx_modem.c
+++ b/sound/pci/via82xx_modem.c
@@ -983,7 +983,7 @@ static int snd_via82xx_chip_init(struct via82xx_modem *chip)
983 pci_read_config_byte(chip->pci, VIA_ACLINK_STAT, &pval); 983 pci_read_config_byte(chip->pci, VIA_ACLINK_STAT, &pval);
984 if (pval & VIA_ACLINK_C00_READY) /* primary codec ready */ 984 if (pval & VIA_ACLINK_C00_READY) /* primary codec ready */
985 break; 985 break;
986 schedule_timeout_uninterruptible(1); 986 schedule_timeout(1);
987 } while (time_before(jiffies, end_time)); 987 } while (time_before(jiffies, end_time));
988 988
989 if ((val = snd_via82xx_codec_xread(chip)) & VIA_REG_AC97_BUSY) 989 if ((val = snd_via82xx_codec_xread(chip)) & VIA_REG_AC97_BUSY)
@@ -1001,7 +1001,7 @@ static int snd_via82xx_chip_init(struct via82xx_modem *chip)
1001 chip->ac97_secondary = 1; 1001 chip->ac97_secondary = 1;
1002 goto __ac97_ok2; 1002 goto __ac97_ok2;
1003 } 1003 }
1004 schedule_timeout_interruptible(1); 1004 schedule_timeout(1);
1005 } while (time_before(jiffies, end_time)); 1005 } while (time_before(jiffies, end_time));
1006 /* This is ok, the most of motherboards have only one codec */ 1006 /* This is ok, the most of motherboards have only one codec */
1007 1007
diff --git a/sound/ppc/Kconfig b/sound/ppc/Kconfig
index a3fb1496e4dc..cacb0b136883 100644
--- a/sound/ppc/Kconfig
+++ b/sound/ppc/Kconfig
@@ -33,3 +33,23 @@ config SND_POWERMAC_AUTO_DRC
33 option. 33 option.
34 34
35endmenu 35endmenu
36
37menu "ALSA PowerPC devices"
38 depends on SND!=n && ( PPC64 || PPC32 )
39
40config SND_PS3
41 tristate "PS3 Audio support"
42 depends on SND && PS3_PS3AV
43 select SND_PCM
44 default m
45 help
46 Say Y here to include support for audio on the PS3
47
48 To compile this driver as a module, choose M here: the module
49 will be called snd_ps3.
50
51config SND_PS3_DEFAULT_START_DELAY
52 int "Startup delay time in ms"
53 depends on SND_PS3
54 default "2000"
55endmenu
diff --git a/sound/ppc/Makefile b/sound/ppc/Makefile
index 4d95c652c8ca..eacee2d0675c 100644
--- a/sound/ppc/Makefile
+++ b/sound/ppc/Makefile
@@ -6,4 +6,5 @@
6snd-powermac-objs := powermac.o pmac.o awacs.o burgundy.o daca.o tumbler.o keywest.o beep.o 6snd-powermac-objs := powermac.o pmac.o awacs.o burgundy.o daca.o tumbler.o keywest.o beep.o
7 7
8# Toplevel Module Dependency 8# Toplevel Module Dependency
9obj-$(CONFIG_SND_POWERMAC) += snd-powermac.o 9obj-$(CONFIG_SND_POWERMAC) += snd-powermac.o
10obj-$(CONFIG_SND_PS3) += snd_ps3.o
diff --git a/sound/ppc/snd_ps3.c b/sound/ppc/snd_ps3.c
new file mode 100644
index 000000000000..1aa0b467599f
--- /dev/null
+++ b/sound/ppc/snd_ps3.c
@@ -0,0 +1,1125 @@
1/*
2 * Audio support for PS3
3 * Copyright (C) 2007 Sony Computer Entertainment Inc.
4 * All rights reserved.
5 * Copyright 2006, 2007 Sony Corporation
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; version 2 of the Licence.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include <linux/init.h>
22#include <linux/slab.h>
23#include <linux/io.h>
24#include <linux/interrupt.h>
25#include <sound/driver.h>
26#include <sound/core.h>
27#include <sound/initval.h>
28#include <sound/pcm.h>
29#include <sound/asound.h>
30#include <sound/memalloc.h>
31#include <sound/pcm_params.h>
32#include <sound/control.h>
33#include <linux/dmapool.h>
34#include <linux/dma-mapping.h>
35#include <asm/firmware.h>
36#include <linux/io.h>
37#include <asm/dma.h>
38#include <asm/lv1call.h>
39#include <asm/ps3.h>
40#include <asm/ps3av.h>
41
42#include "snd_ps3_reg.h"
43#include "snd_ps3.h"
44
45MODULE_LICENSE("GPL v2");
46MODULE_DESCRIPTION("PS3 sound driver");
47MODULE_AUTHOR("Sony Computer Entertainment Inc.");
48
49/* module entries */
50static int __init snd_ps3_init(void);
51static void __exit snd_ps3_exit(void);
52
53/* ALSA snd driver ops */
54static int snd_ps3_pcm_open(struct snd_pcm_substream *substream);
55static int snd_ps3_pcm_close(struct snd_pcm_substream *substream);
56static int snd_ps3_pcm_prepare(struct snd_pcm_substream *substream);
57static int snd_ps3_pcm_trigger(struct snd_pcm_substream *substream,
58 int cmd);
59static snd_pcm_uframes_t snd_ps3_pcm_pointer(struct snd_pcm_substream
60 *substream);
61static int snd_ps3_pcm_hw_params(struct snd_pcm_substream *substream,
62 struct snd_pcm_hw_params *hw_params);
63static int snd_ps3_pcm_hw_free(struct snd_pcm_substream *substream);
64
65
66/* ps3_system_bus_driver entries */
67static int __init snd_ps3_driver_probe(struct ps3_system_bus_device *dev);
68static int snd_ps3_driver_remove(struct ps3_system_bus_device *dev);
69
70/* address setup */
71static int snd_ps3_map_mmio(void);
72static void snd_ps3_unmap_mmio(void);
73static int snd_ps3_allocate_irq(void);
74static void snd_ps3_free_irq(void);
75static void snd_ps3_audio_set_base_addr(uint64_t ioaddr_start);
76
77/* interrupt handler */
78static irqreturn_t snd_ps3_interrupt(int irq, void *dev_id);
79
80
81/* set sampling rate/format */
82static int snd_ps3_set_avsetting(struct snd_pcm_substream *substream);
83/* take effect parameter change */
84static int snd_ps3_change_avsetting(struct snd_ps3_card_info *card);
85/* initialize avsetting and take it effect */
86static int snd_ps3_init_avsetting(struct snd_ps3_card_info *card);
87/* setup dma */
88static int snd_ps3_program_dma(struct snd_ps3_card_info *card,
89 enum snd_ps3_dma_filltype filltype);
90static void snd_ps3_wait_for_dma_stop(struct snd_ps3_card_info *card);
91
92static dma_addr_t v_to_bus(struct snd_ps3_card_info *, void *vaddr, int ch);
93
94
95module_init(snd_ps3_init);
96module_exit(snd_ps3_exit);
97
98/*
99 * global
100 */
101static struct snd_ps3_card_info the_card;
102
103static int snd_ps3_start_delay = CONFIG_SND_PS3_DEFAULT_START_DELAY;
104
105module_param_named(start_delay, snd_ps3_start_delay, uint, 0644);
106MODULE_PARM_DESC(start_delay, "time to insert silent data in milisec");
107
108static int index = SNDRV_DEFAULT_IDX1;
109static char *id = SNDRV_DEFAULT_STR1;
110
111module_param(index, int, 0444);
112MODULE_PARM_DESC(index, "Index value for PS3 soundchip.");
113module_param(id, charp, 0444);
114MODULE_PARM_DESC(id, "ID string for PS3 soundchip.");
115
116
117/*
118 * PS3 audio register access
119 */
120static inline u32 read_reg(unsigned int reg)
121{
122 return in_be32(the_card.mapped_mmio_vaddr + reg);
123}
124static inline void write_reg(unsigned int reg, u32 val)
125{
126 out_be32(the_card.mapped_mmio_vaddr + reg, val);
127}
128static inline void update_reg(unsigned int reg, u32 or_val)
129{
130 u32 newval = read_reg(reg) | or_val;
131 write_reg(reg, newval);
132}
133static inline void update_mask_reg(unsigned int reg, u32 mask, u32 or_val)
134{
135 u32 newval = (read_reg(reg) & mask) | or_val;
136 write_reg(reg, newval);
137}
138
139/*
140 * ALSA defs
141 */
142const static struct snd_pcm_hardware snd_ps3_pcm_hw = {
143 .info = (SNDRV_PCM_INFO_MMAP |
144 SNDRV_PCM_INFO_NONINTERLEAVED |
145 SNDRV_PCM_INFO_MMAP_VALID),
146 .formats = (SNDRV_PCM_FMTBIT_S16_BE |
147 SNDRV_PCM_FMTBIT_S24_BE),
148 .rates = (SNDRV_PCM_RATE_44100 |
149 SNDRV_PCM_RATE_48000 |
150 SNDRV_PCM_RATE_88200 |
151 SNDRV_PCM_RATE_96000),
152 .rate_min = 44100,
153 .rate_max = 96000,
154
155 .channels_min = 2, /* stereo only */
156 .channels_max = 2,
157
158 .buffer_bytes_max = PS3_AUDIO_FIFO_SIZE * 64,
159
160 /* interrupt by four stages */
161 .period_bytes_min = PS3_AUDIO_FIFO_STAGE_SIZE * 4,
162 .period_bytes_max = PS3_AUDIO_FIFO_STAGE_SIZE * 4,
163
164 .periods_min = 16,
165 .periods_max = 32, /* buffer_size_max/ period_bytes_max */
166
167 .fifo_size = PS3_AUDIO_FIFO_SIZE
168};
169
170static struct snd_pcm_ops snd_ps3_pcm_spdif_ops =
171{
172 .open = snd_ps3_pcm_open,
173 .close = snd_ps3_pcm_close,
174 .prepare = snd_ps3_pcm_prepare,
175 .ioctl = snd_pcm_lib_ioctl,
176 .trigger = snd_ps3_pcm_trigger,
177 .pointer = snd_ps3_pcm_pointer,
178 .hw_params = snd_ps3_pcm_hw_params,
179 .hw_free = snd_ps3_pcm_hw_free
180};
181
182static int snd_ps3_verify_dma_stop(struct snd_ps3_card_info *card,
183 int count, int force_stop)
184{
185 int dma_ch, done, retries, stop_forced = 0;
186 uint32_t status;
187
188 for (dma_ch = 0; dma_ch < 8; dma_ch ++) {
189 retries = count;
190 do {
191 status = read_reg(PS3_AUDIO_KICK(dma_ch)) &
192 PS3_AUDIO_KICK_STATUS_MASK;
193 switch (status) {
194 case PS3_AUDIO_KICK_STATUS_DONE:
195 case PS3_AUDIO_KICK_STATUS_NOTIFY:
196 case PS3_AUDIO_KICK_STATUS_CLEAR:
197 case PS3_AUDIO_KICK_STATUS_ERROR:
198 done = 1;
199 break;
200 default:
201 done = 0;
202 udelay(10);
203 }
204 } while (!done && --retries);
205 if (!retries && force_stop) {
206 pr_info("%s: DMA ch %d is not stopped.",
207 __func__, dma_ch);
208 /* last resort. force to stop dma.
209 * NOTE: this cause DMA done interrupts
210 */
211 update_reg(PS3_AUDIO_CONFIG, PS3_AUDIO_CONFIG_CLEAR);
212 stop_forced = 1;
213 }
214 }
215 return stop_forced;
216}
217
218/*
219 * wait for all dma is done.
220 * NOTE: caller should reset card->running before call.
221 * If not, the interrupt handler will re-start DMA,
222 * then DMA is never stopped.
223 */
224static void snd_ps3_wait_for_dma_stop(struct snd_ps3_card_info *card)
225{
226 int stop_forced;
227 /*
228 * wait for the last dma is done
229 */
230
231 /*
232 * expected maximum DMA done time is 5.7ms + something (DMA itself).
233 * 5.7ms is from 16bit/sample 2ch 44.1Khz; the time next
234 * DMA kick event would occur.
235 */
236 stop_forced = snd_ps3_verify_dma_stop(card, 700, 1);
237
238 /*
239 * clear outstanding interrupts.
240 */
241 update_reg(PS3_AUDIO_INTR_0, 0);
242 update_reg(PS3_AUDIO_AX_IS, 0);
243
244 /*
245 *revert CLEAR bit since it will not reset automatically after DMA stop
246 */
247 if (stop_forced)
248 update_mask_reg(PS3_AUDIO_CONFIG, ~PS3_AUDIO_CONFIG_CLEAR, 0);
249 /* ensure the hardware sees changes */
250 wmb();
251}
252
253static void snd_ps3_kick_dma(struct snd_ps3_card_info *card)
254{
255
256 update_reg(PS3_AUDIO_KICK(0), PS3_AUDIO_KICK_REQUEST);
257 /* ensure the hardware sees the change */
258 wmb();
259}
260
261/*
262 * convert virtual addr to ioif bus addr.
263 */
264static dma_addr_t v_to_bus(struct snd_ps3_card_info *card,
265 void * paddr,
266 int ch)
267{
268 return card->dma_start_bus_addr[ch] +
269 (paddr - card->dma_start_vaddr[ch]);
270};
271
272
273/*
274 * increment ring buffer pointer.
275 * NOTE: caller must hold write spinlock
276 */
277static void snd_ps3_bump_buffer(struct snd_ps3_card_info *card,
278 enum snd_ps3_ch ch, size_t byte_count,
279 int stage)
280{
281 if (!stage)
282 card->dma_last_transfer_vaddr[ch] =
283 card->dma_next_transfer_vaddr[ch];
284 card->dma_next_transfer_vaddr[ch] += byte_count;
285 if ((card->dma_start_vaddr[ch] + (card->dma_buffer_size / 2)) <=
286 card->dma_next_transfer_vaddr[ch]) {
287 card->dma_next_transfer_vaddr[ch] = card->dma_start_vaddr[ch];
288 }
289}
290/*
291 * setup dmac to send data to audio and attenuate samples on the ring buffer
292 */
293static int snd_ps3_program_dma(struct snd_ps3_card_info *card,
294 enum snd_ps3_dma_filltype filltype)
295{
296 /* this dmac does not support over 4G */
297 uint32_t dma_addr;
298 int fill_stages, dma_ch, stage;
299 enum snd_ps3_ch ch;
300 uint32_t ch0_kick_event = 0; /* initialize to mute gcc */
301 void *start_vaddr;
302 unsigned long irqsave;
303 int silent = 0;
304
305 switch (filltype) {
306 case SND_PS3_DMA_FILLTYPE_SILENT_FIRSTFILL:
307 silent = 1;
308 /* intentionally fall thru */
309 case SND_PS3_DMA_FILLTYPE_FIRSTFILL:
310 ch0_kick_event = PS3_AUDIO_KICK_EVENT_ALWAYS;
311 break;
312
313 case SND_PS3_DMA_FILLTYPE_SILENT_RUNNING:
314 silent = 1;
315 /* intentionally fall thru */
316 case SND_PS3_DMA_FILLTYPE_RUNNING:
317 ch0_kick_event = PS3_AUDIO_KICK_EVENT_SERIALOUT0_EMPTY;
318 break;
319 }
320
321 snd_ps3_verify_dma_stop(card, 700, 0);
322 fill_stages = 4;
323 spin_lock_irqsave(&card->dma_lock, irqsave);
324 for (ch = 0; ch < 2; ch++) {
325 start_vaddr = card->dma_next_transfer_vaddr[0];
326 for (stage = 0; stage < fill_stages; stage ++) {
327 dma_ch = stage * 2 + ch;
328 if (silent)
329 dma_addr = card->null_buffer_start_dma_addr;
330 else
331 dma_addr =
332 v_to_bus(card,
333 card->dma_next_transfer_vaddr[ch],
334 ch);
335
336 write_reg(PS3_AUDIO_SOURCE(dma_ch),
337 (PS3_AUDIO_SOURCE_TARGET_SYSTEM_MEMORY |
338 dma_addr));
339
340 /* dst: fixed to 3wire#0 */
341 if (ch == 0)
342 write_reg(PS3_AUDIO_DEST(dma_ch),
343 (PS3_AUDIO_DEST_TARGET_AUDIOFIFO |
344 PS3_AUDIO_AO_3W_LDATA(0)));
345 else
346 write_reg(PS3_AUDIO_DEST(dma_ch),
347 (PS3_AUDIO_DEST_TARGET_AUDIOFIFO |
348 PS3_AUDIO_AO_3W_RDATA(0)));
349
350 /* count always 1 DMA block (1/2 stage = 128 bytes) */
351 write_reg(PS3_AUDIO_DMASIZE(dma_ch), 0);
352 /* bump pointer if needed */
353 if (!silent)
354 snd_ps3_bump_buffer(card, ch,
355 PS3_AUDIO_DMAC_BLOCK_SIZE,
356 stage);
357
358 /* kick event */
359 if (dma_ch == 0)
360 write_reg(PS3_AUDIO_KICK(dma_ch),
361 ch0_kick_event);
362 else
363 write_reg(PS3_AUDIO_KICK(dma_ch),
364 PS3_AUDIO_KICK_EVENT_AUDIO_DMA(dma_ch
365 - 1) |
366 PS3_AUDIO_KICK_REQUEST);
367 }
368 }
369 /* ensure the hardware sees the change */
370 wmb();
371 spin_unlock_irqrestore(&card->dma_lock, irqsave);
372
373 return 0;
374}
375
376/*
377 * audio mute on/off
378 * mute_on : 0 output enabled
379 * 1 mute
380 */
381static int snd_ps3_mute(int mute_on)
382{
383 return ps3av_audio_mute(mute_on);
384}
385
386/*
387 * PCM operators
388 */
389static int snd_ps3_pcm_open(struct snd_pcm_substream *substream)
390{
391 struct snd_pcm_runtime *runtime = substream->runtime;
392 struct snd_ps3_card_info *card = snd_pcm_substream_chip(substream);
393 int pcm_index;
394
395 pcm_index = substream->pcm->device;
396 /* to retrieve substream/runtime in interrupt handler */
397 card->substream = substream;
398
399 runtime->hw = snd_ps3_pcm_hw;
400
401 card->start_delay = snd_ps3_start_delay;
402
403 /* mute off */
404 snd_ps3_mute(0); /* this function sleep */
405
406 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
407 PS3_AUDIO_FIFO_STAGE_SIZE * 4 * 2);
408 return 0;
409};
410
411static int snd_ps3_pcm_hw_params(struct snd_pcm_substream *substream,
412 struct snd_pcm_hw_params *hw_params)
413{
414 size_t size;
415
416 /* alloc transport buffer */
417 size = params_buffer_bytes(hw_params);
418 snd_pcm_lib_malloc_pages(substream, size);
419 return 0;
420};
421
422static int snd_ps3_delay_to_bytes(struct snd_pcm_substream *substream,
423 unsigned int delay_ms)
424{
425 int ret;
426 int rate ;
427
428 rate = substream->runtime->rate;
429 ret = snd_pcm_format_size(substream->runtime->format,
430 rate * delay_ms / 1000)
431 * substream->runtime->channels;
432
433 pr_debug(KERN_ERR "%s: time=%d rate=%d bytes=%ld, frames=%d, ret=%d\n",
434 __func__,
435 delay_ms,
436 rate,
437 snd_pcm_format_size(substream->runtime->format, rate),
438 rate * delay_ms / 1000,
439 ret);
440
441 return ret;
442};
443
444static int snd_ps3_pcm_prepare(struct snd_pcm_substream *substream)
445{
446 struct snd_pcm_runtime *runtime = substream->runtime;
447 struct snd_ps3_card_info *card = snd_pcm_substream_chip(substream);
448 unsigned long irqsave;
449
450 if (!snd_ps3_set_avsetting(substream)) {
451 /* some parameter changed */
452 write_reg(PS3_AUDIO_AX_IE,
453 PS3_AUDIO_AX_IE_ASOBEIE(0) |
454 PS3_AUDIO_AX_IE_ASOBUIE(0));
455 /*
456 * let SPDIF device re-lock with SPDIF signal,
457 * start with some silence
458 */
459 card->silent = snd_ps3_delay_to_bytes(substream,
460 card->start_delay) /
461 (PS3_AUDIO_FIFO_STAGE_SIZE * 4); /* every 4 times */
462 }
463
464 /* restart ring buffer pointer */
465 spin_lock_irqsave(&card->dma_lock, irqsave);
466 {
467 card->dma_buffer_size = runtime->dma_bytes;
468
469 card->dma_last_transfer_vaddr[SND_PS3_CH_L] =
470 card->dma_next_transfer_vaddr[SND_PS3_CH_L] =
471 card->dma_start_vaddr[SND_PS3_CH_L] =
472 runtime->dma_area;
473 card->dma_start_bus_addr[SND_PS3_CH_L] = runtime->dma_addr;
474
475 card->dma_last_transfer_vaddr[SND_PS3_CH_R] =
476 card->dma_next_transfer_vaddr[SND_PS3_CH_R] =
477 card->dma_start_vaddr[SND_PS3_CH_R] =
478 runtime->dma_area + (runtime->dma_bytes / 2);
479 card->dma_start_bus_addr[SND_PS3_CH_R] =
480 runtime->dma_addr + (runtime->dma_bytes / 2);
481
482 pr_debug("%s: vaddr=%p bus=%#lx\n", __func__,
483 card->dma_start_vaddr[SND_PS3_CH_L],
484 card->dma_start_bus_addr[SND_PS3_CH_L]);
485
486 }
487 spin_unlock_irqrestore(&card->dma_lock, irqsave);
488
489 /* ensure the hardware sees the change */
490 mb();
491
492 return 0;
493};
494
495static int snd_ps3_pcm_trigger(struct snd_pcm_substream *substream,
496 int cmd)
497{
498 struct snd_ps3_card_info *card = snd_pcm_substream_chip(substream);
499 int ret = 0;
500
501 switch (cmd) {
502 case SNDRV_PCM_TRIGGER_START:
503 /* clear outstanding interrupts */
504 update_reg(PS3_AUDIO_AX_IS, 0);
505
506 spin_lock(&card->dma_lock);
507 {
508 card->running = 1;
509 }
510 spin_unlock(&card->dma_lock);
511
512 snd_ps3_program_dma(card,
513 SND_PS3_DMA_FILLTYPE_SILENT_FIRSTFILL);
514 snd_ps3_kick_dma(card);
515 while (read_reg(PS3_AUDIO_KICK(7)) &
516 PS3_AUDIO_KICK_STATUS_MASK) {
517 udelay(1);
518 }
519 snd_ps3_program_dma(card, SND_PS3_DMA_FILLTYPE_SILENT_RUNNING);
520 snd_ps3_kick_dma(card);
521 break;
522
523 case SNDRV_PCM_TRIGGER_STOP:
524 spin_lock(&card->dma_lock);
525 {
526 card->running = 0;
527 }
528 spin_unlock(&card->dma_lock);
529 snd_ps3_wait_for_dma_stop(card);
530 break;
531 default:
532 break;
533
534 }
535
536 return ret;
537};
538
539/*
540 * report current pointer
541 */
542static snd_pcm_uframes_t snd_ps3_pcm_pointer(
543 struct snd_pcm_substream *substream)
544{
545 struct snd_ps3_card_info *card = snd_pcm_substream_chip(substream);
546 size_t bytes;
547 snd_pcm_uframes_t ret;
548
549 spin_lock(&card->dma_lock);
550 {
551 bytes = (size_t)(card->dma_last_transfer_vaddr[SND_PS3_CH_L] -
552 card->dma_start_vaddr[SND_PS3_CH_L]);
553 }
554 spin_unlock(&card->dma_lock);
555
556 ret = bytes_to_frames(substream->runtime, bytes * 2);
557
558 return ret;
559};
560
561static int snd_ps3_pcm_hw_free(struct snd_pcm_substream *substream)
562{
563 int ret;
564 ret = snd_pcm_lib_free_pages(substream);
565 return ret;
566};
567
568static int snd_ps3_pcm_close(struct snd_pcm_substream *substream)
569{
570 /* mute on */
571 snd_ps3_mute(1);
572 return 0;
573};
574
575static void snd_ps3_audio_fixup(struct snd_ps3_card_info *card)
576{
577 /*
578 * avsetting driver seems to never change the followings
579 * so, init them here once
580 */
581
582 /* no dma interrupt needed */
583 write_reg(PS3_AUDIO_INTR_EN_0, 0);
584
585 /* use every 4 buffer empty interrupt */
586 update_mask_reg(PS3_AUDIO_AX_IC,
587 PS3_AUDIO_AX_IC_AASOIMD_MASK,
588 PS3_AUDIO_AX_IC_AASOIMD_EVERY4);
589
590 /* enable 3wire clocks */
591 update_mask_reg(PS3_AUDIO_AO_3WMCTRL,
592 ~(PS3_AUDIO_AO_3WMCTRL_ASOBCLKD_DISABLED |
593 PS3_AUDIO_AO_3WMCTRL_ASOLRCKD_DISABLED),
594 0);
595 update_reg(PS3_AUDIO_AO_3WMCTRL,
596 PS3_AUDIO_AO_3WMCTRL_ASOPLRCK_DEFAULT);
597}
598
599/*
600 * av setting
601 * NOTE: calling this function may generate audio interrupt.
602 */
603static int snd_ps3_change_avsetting(struct snd_ps3_card_info *card)
604{
605 int ret, retries, i;
606 pr_debug("%s: start\n", __func__);
607
608 ret = ps3av_set_audio_mode(card->avs.avs_audio_ch,
609 card->avs.avs_audio_rate,
610 card->avs.avs_audio_width,
611 card->avs.avs_audio_format,
612 card->avs.avs_audio_source);
613 /*
614 * Reset the following unwanted settings:
615 */
616
617 /* disable all 3wire buffers */
618 update_mask_reg(PS3_AUDIO_AO_3WMCTRL,
619 ~(PS3_AUDIO_AO_3WMCTRL_ASOEN(0) |
620 PS3_AUDIO_AO_3WMCTRL_ASOEN(1) |
621 PS3_AUDIO_AO_3WMCTRL_ASOEN(2) |
622 PS3_AUDIO_AO_3WMCTRL_ASOEN(3)),
623 0);
624 wmb(); /* ensure the hardware sees the change */
625 /* wait for actually stopped */
626 retries = 1000;
627 while ((read_reg(PS3_AUDIO_AO_3WMCTRL) &
628 (PS3_AUDIO_AO_3WMCTRL_ASORUN(0) |
629 PS3_AUDIO_AO_3WMCTRL_ASORUN(1) |
630 PS3_AUDIO_AO_3WMCTRL_ASORUN(2) |
631 PS3_AUDIO_AO_3WMCTRL_ASORUN(3))) &&
632 --retries) {
633 udelay(1);
634 }
635
636 /* reset buffer pointer */
637 for (i = 0; i < 4; i++) {
638 update_reg(PS3_AUDIO_AO_3WCTRL(i),
639 PS3_AUDIO_AO_3WCTRL_ASOBRST_RESET);
640 udelay(10);
641 }
642 wmb(); /* ensure the hardware actually start resetting */
643
644 /* enable 3wire#0 buffer */
645 update_reg(PS3_AUDIO_AO_3WMCTRL, PS3_AUDIO_AO_3WMCTRL_ASOEN(0));
646
647
648 /* In 24bit mode,ALSA inserts a zero byte at first byte of per sample */
649 update_mask_reg(PS3_AUDIO_AO_3WCTRL(0),
650 ~PS3_AUDIO_AO_3WCTRL_ASODF,
651 PS3_AUDIO_AO_3WCTRL_ASODF_LSB);
652 update_mask_reg(PS3_AUDIO_AO_SPDCTRL(0),
653 ~PS3_AUDIO_AO_SPDCTRL_SPODF,
654 PS3_AUDIO_AO_SPDCTRL_SPODF_LSB);
655 /* ensure all the setting above is written back to register */
656 wmb();
657 /* avsetting driver altered AX_IE, caller must reset it if you want */
658 pr_debug("%s: end\n", __func__);
659 return ret;
660}
661
662static int snd_ps3_init_avsetting(struct snd_ps3_card_info *card)
663{
664 int ret;
665 pr_debug("%s: start\n", __func__);
666 card->avs.avs_audio_ch = PS3AV_CMD_AUDIO_NUM_OF_CH_2;
667 card->avs.avs_audio_rate = PS3AV_CMD_AUDIO_FS_48K;
668 card->avs.avs_audio_width = PS3AV_CMD_AUDIO_WORD_BITS_16;
669 card->avs.avs_audio_format = PS3AV_CMD_AUDIO_FORMAT_PCM;
670 card->avs.avs_audio_source = PS3AV_CMD_AUDIO_SOURCE_SERIAL;
671
672 ret = snd_ps3_change_avsetting(card);
673
674 snd_ps3_audio_fixup(card);
675
676 /* to start to generate SPDIF signal, fill data */
677 snd_ps3_program_dma(card, SND_PS3_DMA_FILLTYPE_SILENT_FIRSTFILL);
678 snd_ps3_kick_dma(card);
679 pr_debug("%s: end\n", __func__);
680 return ret;
681}
682
683/*
684 * set sampling rate according to the substream
685 */
686static int snd_ps3_set_avsetting(struct snd_pcm_substream *substream)
687{
688 struct snd_ps3_card_info *card = snd_pcm_substream_chip(substream);
689 struct snd_ps3_avsetting_info avs;
690
691 avs = card->avs;
692
693 pr_debug("%s: called freq=%d width=%d\n", __func__,
694 substream->runtime->rate,
695 snd_pcm_format_width(substream->runtime->format));
696
697 pr_debug("%s: before freq=%d width=%d\n", __func__,
698 card->avs.avs_audio_rate, card->avs.avs_audio_width);
699
700 /* sample rate */
701 switch (substream->runtime->rate) {
702 case 44100:
703 avs.avs_audio_rate = PS3AV_CMD_AUDIO_FS_44K;
704 break;
705 case 48000:
706 avs.avs_audio_rate = PS3AV_CMD_AUDIO_FS_48K;
707 break;
708 case 88200:
709 avs.avs_audio_rate = PS3AV_CMD_AUDIO_FS_88K;
710 break;
711 case 96000:
712 avs.avs_audio_rate = PS3AV_CMD_AUDIO_FS_96K;
713 break;
714 default:
715 pr_info("%s: invalid rate %d\n", __func__,
716 substream->runtime->rate);
717 return 1;
718 }
719
720 /* width */
721 switch (snd_pcm_format_width(substream->runtime->format)) {
722 case 16:
723 avs.avs_audio_width = PS3AV_CMD_AUDIO_WORD_BITS_16;
724 break;
725 case 24:
726 avs.avs_audio_width = PS3AV_CMD_AUDIO_WORD_BITS_24;
727 break;
728 default:
729 pr_info("%s: invalid width %d\n", __func__,
730 snd_pcm_format_width(substream->runtime->format));
731 return 1;
732 }
733
734 if ((card->avs.avs_audio_width != avs.avs_audio_width) ||
735 (card->avs.avs_audio_rate != avs.avs_audio_rate)) {
736 card->avs = avs;
737 snd_ps3_change_avsetting(card);
738
739 pr_debug("%s: after freq=%d width=%d\n", __func__,
740 card->avs.avs_audio_rate, card->avs.avs_audio_width);
741
742 return 0;
743 } else
744 return 1;
745}
746
747
748
749static int snd_ps3_map_mmio(void)
750{
751 the_card.mapped_mmio_vaddr =
752 ioremap(the_card.ps3_dev->m_region->bus_addr,
753 the_card.ps3_dev->m_region->len);
754
755 if (!the_card.mapped_mmio_vaddr) {
756 pr_info("%s: ioremap 0 failed p=%#lx l=%#lx \n",
757 __func__, the_card.ps3_dev->m_region->lpar_addr,
758 the_card.ps3_dev->m_region->len);
759 return -ENXIO;
760 }
761
762 return 0;
763};
764
765static void snd_ps3_unmap_mmio(void)
766{
767 iounmap(the_card.mapped_mmio_vaddr);
768 the_card.mapped_mmio_vaddr = NULL;
769}
770
771static int snd_ps3_allocate_irq(void)
772{
773 int ret;
774 u64 lpar_addr, lpar_size;
775 u64 __iomem *mapped;
776
777 /* FIXME: move this to device_init (H/W probe) */
778
779 /* get irq outlet */
780 ret = lv1_gpu_device_map(1, &lpar_addr, &lpar_size);
781 if (ret) {
782 pr_info("%s: device map 1 failed %d\n", __func__,
783 ret);
784 return -ENXIO;
785 }
786
787 mapped = ioremap(lpar_addr, lpar_size);
788 if (!mapped) {
789 pr_info("%s: ioremap 1 failed \n", __func__);
790 return -ENXIO;
791 }
792
793 the_card.audio_irq_outlet = in_be64(mapped);
794
795 iounmap(mapped);
796 ret = lv1_gpu_device_unmap(1);
797 if (ret)
798 pr_info("%s: unmap 1 failed\n", __func__);
799
800 /* irq */
801 ret = ps3_irq_plug_setup(PS3_BINDING_CPU_ANY,
802 the_card.audio_irq_outlet,
803 &the_card.irq_no);
804 if (ret) {
805 pr_info("%s:ps3_alloc_irq failed (%d)\n", __func__, ret);
806 return ret;
807 }
808
809 ret = request_irq(the_card.irq_no, snd_ps3_interrupt, IRQF_DISABLED,
810 SND_PS3_DRIVER_NAME, &the_card);
811 if (ret) {
812 pr_info("%s: request_irq failed (%d)\n", __func__, ret);
813 goto cleanup_irq;
814 }
815
816 return 0;
817
818 cleanup_irq:
819 ps3_irq_plug_destroy(the_card.irq_no);
820 return ret;
821};
822
823static void snd_ps3_free_irq(void)
824{
825 free_irq(the_card.irq_no, &the_card);
826 ps3_irq_plug_destroy(the_card.irq_no);
827}
828
829static void snd_ps3_audio_set_base_addr(uint64_t ioaddr_start)
830{
831 uint64_t val;
832 int ret;
833
834 val = (ioaddr_start & (0x0fUL << 32)) >> (32 - 20) |
835 (0x03UL << 24) |
836 (0x0fUL << 12) |
837 (PS3_AUDIO_IOID);
838
839 ret = lv1_gpu_attribute(0x100, 0x007, val, 0, 0);
840 if (ret)
841 pr_info("%s: gpu_attribute failed %d\n", __func__,
842 ret);
843}
844
845static int __init snd_ps3_driver_probe(struct ps3_system_bus_device *dev)
846{
847 int ret;
848 u64 lpar_addr, lpar_size;
849
850 BUG_ON(!firmware_has_feature(FW_FEATURE_PS3_LV1));
851 BUG_ON(dev->match_id != PS3_MATCH_ID_SOUND);
852
853 the_card.ps3_dev = dev;
854
855 ret = ps3_open_hv_device(dev);
856
857 if (ret)
858 return -ENXIO;
859
860 /* setup MMIO */
861 ret = lv1_gpu_device_map(2, &lpar_addr, &lpar_size);
862 if (ret) {
863 pr_info("%s: device map 2 failed %d\n", __func__, ret);
864 goto clean_open;
865 }
866 ps3_mmio_region_init(dev, dev->m_region, lpar_addr, lpar_size,
867 PAGE_SHIFT);
868
869 ret = snd_ps3_map_mmio();
870 if (ret)
871 goto clean_dev_map;
872
873 /* setup DMA area */
874 ps3_dma_region_init(dev, dev->d_region,
875 PAGE_SHIFT, /* use system page size */
876 0, /* dma type; not used */
877 NULL,
878 _ALIGN_UP(SND_PS3_DMA_REGION_SIZE, PAGE_SIZE));
879 dev->d_region->ioid = PS3_AUDIO_IOID;
880
881 ret = ps3_dma_region_create(dev->d_region);
882 if (ret) {
883 pr_info("%s: region_create\n", __func__);
884 goto clean_mmio;
885 }
886
887 snd_ps3_audio_set_base_addr(dev->d_region->bus_addr);
888
889 /* CONFIG_SND_PS3_DEFAULT_START_DELAY */
890 the_card.start_delay = snd_ps3_start_delay;
891
892 /* irq */
893 if (snd_ps3_allocate_irq()) {
894 ret = -ENXIO;
895 goto clean_dma_region;
896 }
897
898 /* create card instance */
899 the_card.card = snd_card_new(index, id, THIS_MODULE, 0);
900 if (!the_card.card) {
901 ret = -ENXIO;
902 goto clean_irq;
903 }
904
905 strcpy(the_card.card->driver, "PS3");
906 strcpy(the_card.card->shortname, "PS3");
907 strcpy(the_card.card->longname, "PS3 sound");
908 /* create PCM devices instance */
909 /* NOTE:this driver works assuming pcm:substream = 1:1 */
910 ret = snd_pcm_new(the_card.card,
911 "SPDIF",
912 0, /* instance index, will be stored pcm.device*/
913 1, /* output substream */
914 0, /* input substream */
915 &(the_card.pcm));
916 if (ret)
917 goto clean_card;
918
919 the_card.pcm->private_data = &the_card;
920 strcpy(the_card.pcm->name, "SPDIF");
921
922 /* set pcm ops */
923 snd_pcm_set_ops(the_card.pcm, SNDRV_PCM_STREAM_PLAYBACK,
924 &snd_ps3_pcm_spdif_ops);
925
926 the_card.pcm->info_flags = SNDRV_PCM_INFO_NONINTERLEAVED;
927 /* pre-alloc PCM DMA buffer*/
928 ret = snd_pcm_lib_preallocate_pages_for_all(the_card.pcm,
929 SNDRV_DMA_TYPE_DEV,
930 &dev->core,
931 SND_PS3_PCM_PREALLOC_SIZE,
932 SND_PS3_PCM_PREALLOC_SIZE);
933 if (ret < 0) {
934 pr_info("%s: prealloc failed\n", __func__);
935 goto clean_card;
936 }
937
938 /*
939 * allocate null buffer
940 * its size should be lager than PS3_AUDIO_FIFO_STAGE_SIZE * 2
941 * PAGE_SIZE is enogh
942 */
943 if (!(the_card.null_buffer_start_vaddr =
944 dma_alloc_coherent(&the_card.ps3_dev->core,
945 PAGE_SIZE,
946 &the_card.null_buffer_start_dma_addr,
947 GFP_KERNEL))) {
948 pr_info("%s: nullbuffer alloc failed\n", __func__);
949 goto clean_preallocate;
950 }
951 pr_debug("%s: null vaddr=%p dma=%#lx\n", __func__,
952 the_card.null_buffer_start_vaddr,
953 the_card.null_buffer_start_dma_addr);
954 /* set default sample rate/word width */
955 snd_ps3_init_avsetting(&the_card);
956
957 /* register the card */
958 ret = snd_card_register(the_card.card);
959 if (ret < 0)
960 goto clean_dma_map;
961
962 pr_info("%s started. start_delay=%dms\n",
963 the_card.card->longname, the_card.start_delay);
964 return 0;
965
966clean_dma_map:
967 dma_free_coherent(&the_card.ps3_dev->core,
968 PAGE_SIZE,
969 the_card.null_buffer_start_vaddr,
970 the_card.null_buffer_start_dma_addr);
971clean_preallocate:
972 snd_pcm_lib_preallocate_free_for_all(the_card.pcm);
973clean_card:
974 snd_card_free(the_card.card);
975clean_irq:
976 snd_ps3_free_irq();
977clean_dma_region:
978 ps3_dma_region_free(dev->d_region);
979clean_mmio:
980 snd_ps3_unmap_mmio();
981clean_dev_map:
982 lv1_gpu_device_unmap(2);
983clean_open:
984 ps3_close_hv_device(dev);
985 /*
986 * there is no destructor function to pcm.
987 * midlayer automatically releases if the card removed
988 */
989 return ret;
990}; /* snd_ps3_probe */
991
992/* called when module removal */
993static int snd_ps3_driver_remove(struct ps3_system_bus_device *dev)
994{
995 int ret;
996 pr_info("%s:start id=%d\n", __func__, dev->match_id);
997 if (dev->match_id != PS3_MATCH_ID_SOUND)
998 return -ENXIO;
999
1000 /*
1001 * ctl and preallocate buffer will be freed in
1002 * snd_card_free
1003 */
1004 ret = snd_card_free(the_card.card);
1005 if (ret)
1006 pr_info("%s: ctl freecard=%d\n", __func__, ret);
1007
1008 dma_free_coherent(&dev->core,
1009 PAGE_SIZE,
1010 the_card.null_buffer_start_vaddr,
1011 the_card.null_buffer_start_dma_addr);
1012
1013 ps3_dma_region_free(dev->d_region);
1014
1015 snd_ps3_free_irq();
1016 snd_ps3_unmap_mmio();
1017
1018 lv1_gpu_device_unmap(2);
1019 ps3_close_hv_device(dev);
1020 pr_info("%s:end id=%d\n", __func__, dev->match_id);
1021 return 0;
1022} /* snd_ps3_remove */
1023
1024static struct ps3_system_bus_driver snd_ps3_bus_driver_info = {
1025 .match_id = PS3_MATCH_ID_SOUND,
1026 .probe = snd_ps3_driver_probe,
1027 .remove = snd_ps3_driver_remove,
1028 .shutdown = snd_ps3_driver_remove,
1029 .core = {
1030 .name = SND_PS3_DRIVER_NAME,
1031 .owner = THIS_MODULE,
1032 },
1033};
1034
1035
1036/*
1037 * Interrupt handler
1038 */
1039static irqreturn_t snd_ps3_interrupt(int irq, void *dev_id)
1040{
1041
1042 uint32_t port_intr;
1043 int underflow_occured = 0;
1044 struct snd_ps3_card_info *card = dev_id;
1045
1046 if (!card->running) {
1047 update_reg(PS3_AUDIO_AX_IS, 0);
1048 update_reg(PS3_AUDIO_INTR_0, 0);
1049 return IRQ_HANDLED;
1050 }
1051
1052 port_intr = read_reg(PS3_AUDIO_AX_IS);
1053 /*
1054 *serial buffer empty detected (every 4 times),
1055 *program next dma and kick it
1056 */
1057 if (port_intr & PS3_AUDIO_AX_IE_ASOBEIE(0)) {
1058 write_reg(PS3_AUDIO_AX_IS, PS3_AUDIO_AX_IE_ASOBEIE(0));
1059 if (port_intr & PS3_AUDIO_AX_IE_ASOBUIE(0)) {
1060 write_reg(PS3_AUDIO_AX_IS, port_intr);
1061 underflow_occured = 1;
1062 }
1063 if (card->silent) {
1064 /* we are still in silent time */
1065 snd_ps3_program_dma(card,
1066 (underflow_occured) ?
1067 SND_PS3_DMA_FILLTYPE_SILENT_FIRSTFILL :
1068 SND_PS3_DMA_FILLTYPE_SILENT_RUNNING);
1069 snd_ps3_kick_dma(card);
1070 card->silent --;
1071 } else {
1072 snd_ps3_program_dma(card,
1073 (underflow_occured) ?
1074 SND_PS3_DMA_FILLTYPE_FIRSTFILL :
1075 SND_PS3_DMA_FILLTYPE_RUNNING);
1076 snd_ps3_kick_dma(card);
1077 snd_pcm_period_elapsed(card->substream);
1078 }
1079 } else if (port_intr & PS3_AUDIO_AX_IE_ASOBUIE(0)) {
1080 write_reg(PS3_AUDIO_AX_IS, PS3_AUDIO_AX_IE_ASOBUIE(0));
1081 /*
1082 * serial out underflow, but buffer empty not detected.
1083 * in this case, fill fifo with 0 to recover. After
1084 * filling dummy data, serial automatically start to
1085 * consume them and then will generate normal buffer
1086 * empty interrupts.
1087 * If both buffer underflow and buffer empty are occured,
1088 * it is better to do nomal data transfer than empty one
1089 */
1090 snd_ps3_program_dma(card,
1091 SND_PS3_DMA_FILLTYPE_SILENT_FIRSTFILL);
1092 snd_ps3_kick_dma(card);
1093 snd_ps3_program_dma(card,
1094 SND_PS3_DMA_FILLTYPE_SILENT_FIRSTFILL);
1095 snd_ps3_kick_dma(card);
1096 }
1097 /* clear interrupt cause */
1098 return IRQ_HANDLED;
1099};
1100
1101/*
1102 * module/subsystem initialize/terminate
1103 */
1104static int __init snd_ps3_init(void)
1105{
1106 int ret;
1107
1108 if (!firmware_has_feature(FW_FEATURE_PS3_LV1))
1109 return -ENXIO;
1110
1111 memset(&the_card, 0, sizeof(the_card));
1112 spin_lock_init(&the_card.dma_lock);
1113
1114 /* register systembus DRIVER, this calls our probe() func */
1115 ret = ps3_system_bus_driver_register(&snd_ps3_bus_driver_info);
1116
1117 return ret;
1118}
1119
1120static void __exit snd_ps3_exit(void)
1121{
1122 ps3_system_bus_driver_unregister(&snd_ps3_bus_driver_info);
1123}
1124
1125MODULE_ALIAS(PS3_MODULE_ALIAS_SOUND);
diff --git a/sound/ppc/snd_ps3.h b/sound/ppc/snd_ps3.h
new file mode 100644
index 000000000000..4b7e6fbbe500
--- /dev/null
+++ b/sound/ppc/snd_ps3.h
@@ -0,0 +1,135 @@
1/*
2 * Audio support for PS3
3 * Copyright (C) 2007 Sony Computer Entertainment Inc.
4 * All rights reserved.
5 * Copyright 2006, 2007 Sony Corporation
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; version 2 of the Licence.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#if !defined(_SND_PS3_H_)
22#define _SND_PS3_H_
23
24#include <linux/irqreturn.h>
25
26#define SND_PS3_DRIVER_NAME "snd_ps3"
27
28enum snd_ps3_out_channel {
29 SND_PS3_OUT_SPDIF_0,
30 SND_PS3_OUT_SPDIF_1,
31 SND_PS3_OUT_SERIAL_0,
32 SND_PS3_OUT_DEVS
33};
34
35enum snd_ps3_dma_filltype {
36 SND_PS3_DMA_FILLTYPE_FIRSTFILL,
37 SND_PS3_DMA_FILLTYPE_RUNNING,
38 SND_PS3_DMA_FILLTYPE_SILENT_FIRSTFILL,
39 SND_PS3_DMA_FILLTYPE_SILENT_RUNNING
40};
41
42enum snd_ps3_ch {
43 SND_PS3_CH_L = 0,
44 SND_PS3_CH_R = 1,
45 SND_PS3_CH_MAX = 2
46};
47
48struct snd_ps3_avsetting_info {
49 uint32_t avs_audio_ch; /* fixed */
50 uint32_t avs_audio_rate;
51 uint32_t avs_audio_width;
52 uint32_t avs_audio_format; /* fixed */
53 uint32_t avs_audio_source; /* fixed */
54};
55/*
56 * PS3 audio 'card' instance
57 * there should be only ONE hardware.
58 */
59struct snd_ps3_card_info {
60 struct ps3_system_bus_device *ps3_dev;
61 struct snd_card *card;
62
63 struct snd_pcm *pcm;
64 struct snd_pcm_substream *substream;
65
66 /* hvc info */
67 u64 audio_lpar_addr;
68 u64 audio_lpar_size;
69
70 /* registers */
71 void __iomem *mapped_mmio_vaddr;
72
73 /* irq */
74 u64 audio_irq_outlet;
75 unsigned int irq_no;
76
77 /* remember avsetting */
78 struct snd_ps3_avsetting_info avs;
79
80 /* dma buffer management */
81 spinlock_t dma_lock;
82 /* dma_lock start */
83 void * dma_start_vaddr[2]; /* 0 for L, 1 for R */
84 dma_addr_t dma_start_bus_addr[2];
85 size_t dma_buffer_size;
86 void * dma_last_transfer_vaddr[2];
87 void * dma_next_transfer_vaddr[2];
88 int silent;
89 /* dma_lock end */
90
91 int running;
92
93 /* null buffer */
94 void *null_buffer_start_vaddr;
95 dma_addr_t null_buffer_start_dma_addr;
96
97 /* start delay */
98 unsigned int start_delay;
99
100};
101
102
103/* PS3 audio DMAC block size in bytes */
104#define PS3_AUDIO_DMAC_BLOCK_SIZE (128)
105/* one stage (stereo) of audio FIFO in bytes */
106#define PS3_AUDIO_FIFO_STAGE_SIZE (256)
107/* how many stages the fifo have */
108#define PS3_AUDIO_FIFO_STAGE_COUNT (8)
109/* fifo size 128 bytes * 8 stages * stereo (2ch) */
110#define PS3_AUDIO_FIFO_SIZE \
111 (PS3_AUDIO_FIFO_STAGE_SIZE * PS3_AUDIO_FIFO_STAGE_COUNT)
112
113/* PS3 audio DMAC max block count in one dma shot = 128 (0x80) blocks*/
114#define PS3_AUDIO_DMAC_MAX_BLOCKS (PS3_AUDIO_DMASIZE_BLOCKS_MASK + 1)
115
116#define PS3_AUDIO_NORMAL_DMA_START_CH (0)
117#define PS3_AUDIO_NORMAL_DMA_COUNT (8)
118#define PS3_AUDIO_NULL_DMA_START_CH \
119 (PS3_AUDIO_NORMAL_DMA_START_CH + PS3_AUDIO_NORMAL_DMA_COUNT)
120#define PS3_AUDIO_NULL_DMA_COUNT (2)
121
122#define SND_PS3_MAX_VOL (0x0F)
123#define SND_PS3_MIN_VOL (0x00)
124#define SND_PS3_MIN_ATT SND_PS3_MIN_VOL
125#define SND_PS3_MAX_ATT SND_PS3_MAX_VOL
126
127#define SND_PS3_PCM_PREALLOC_SIZE \
128 (PS3_AUDIO_DMAC_BLOCK_SIZE * PS3_AUDIO_DMAC_MAX_BLOCKS * 4)
129
130#define SND_PS3_DMA_REGION_SIZE \
131 (SND_PS3_PCM_PREALLOC_SIZE + PAGE_SIZE)
132
133#define PS3_AUDIO_IOID (1UL)
134
135#endif /* _SND_PS3_H_ */
diff --git a/sound/ppc/snd_ps3_reg.h b/sound/ppc/snd_ps3_reg.h
new file mode 100644
index 000000000000..03fdee4aaaf2
--- /dev/null
+++ b/sound/ppc/snd_ps3_reg.h
@@ -0,0 +1,891 @@
1/*
2 * Audio support for PS3
3 * Copyright (C) 2007 Sony Computer Entertainment Inc.
4 * Copyright 2006, 2007 Sony Corporation
5 * All rights reserved.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; version 2 of the License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21/*
22 * interrupt / configure registers
23 */
24
25#define PS3_AUDIO_INTR_0 (0x00000100)
26#define PS3_AUDIO_INTR_EN_0 (0x00000140)
27#define PS3_AUDIO_CONFIG (0x00000200)
28
29/*
30 * DMAC registers
31 * n:0..9
32 */
33#define PS3_AUDIO_DMAC_REGBASE(x) (0x0000210 + 0x20 * (x))
34
35#define PS3_AUDIO_KICK(n) (PS3_AUDIO_DMAC_REGBASE(n) + 0x00)
36#define PS3_AUDIO_SOURCE(n) (PS3_AUDIO_DMAC_REGBASE(n) + 0x04)
37#define PS3_AUDIO_DEST(n) (PS3_AUDIO_DMAC_REGBASE(n) + 0x08)
38#define PS3_AUDIO_DMASIZE(n) (PS3_AUDIO_DMAC_REGBASE(n) + 0x0C)
39
40/*
41 * mute control
42 */
43#define PS3_AUDIO_AX_MCTRL (0x00004000)
44#define PS3_AUDIO_AX_ISBP (0x00004004)
45#define PS3_AUDIO_AX_AOBP (0x00004008)
46#define PS3_AUDIO_AX_IC (0x00004010)
47#define PS3_AUDIO_AX_IE (0x00004014)
48#define PS3_AUDIO_AX_IS (0x00004018)
49
50/*
51 * three wire serial
52 * n:0..3
53 */
54#define PS3_AUDIO_AO_MCTRL (0x00006000)
55#define PS3_AUDIO_AO_3WMCTRL (0x00006004)
56
57#define PS3_AUDIO_AO_3WCTRL(n) (0x00006200 + 0x200 * (n))
58
59/*
60 * S/PDIF
61 * n:0..1
62 * x:0..11
63 * y:0..5
64 */
65#define PS3_AUDIO_AO_SPD_REGBASE(n) (0x00007200 + 0x200 * (n))
66
67#define PS3_AUDIO_AO_SPDCTRL(n) \
68 (PS3_AUDIO_AO_SPD_REGBASE(n) + 0x00)
69#define PS3_AUDIO_AO_SPDUB(n, x) \
70 (PS3_AUDIO_AO_SPD_REGBASE(n) + 0x04 + 0x04 * (x))
71#define PS3_AUDIO_AO_SPDCS(n, y) \
72 (PS3_AUDIO_AO_SPD_REGBASE(n) + 0x34 + 0x04 * (y))
73
74
75/*
76 PS3_AUDIO_INTR_0 register tells an interrupt handler which audio
77 DMA channel triggered the interrupt. The interrupt status for a channel
78 can be cleared by writing a '1' to the corresponding bit. A new interrupt
79 cannot be generated until the previous interrupt has been cleared.
80
81 Note that the status reported by PS3_AUDIO_INTR_0 is independent of the
82 value of PS3_AUDIO_INTR_EN_0.
83
84 31 24 23 16 15 8 7 0
85 +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
86 |0 0 0 0 0 0 0 0 0 0 0 0 0|C|0|C|0|C|0|C|0|C|0|C|0|C|0|C|0|C|0|C| INTR_0
87 +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
88*/
89#define PS3_AUDIO_INTR_0_CHAN(n) (1 << ((n) * 2))
90#define PS3_AUDIO_INTR_0_CHAN9 PS3_AUDIO_INTR_0_CHAN(9)
91#define PS3_AUDIO_INTR_0_CHAN8 PS3_AUDIO_INTR_0_CHAN(8)
92#define PS3_AUDIO_INTR_0_CHAN7 PS3_AUDIO_INTR_0_CHAN(7)
93#define PS3_AUDIO_INTR_0_CHAN6 PS3_AUDIO_INTR_0_CHAN(6)
94#define PS3_AUDIO_INTR_0_CHAN5 PS3_AUDIO_INTR_0_CHAN(5)
95#define PS3_AUDIO_INTR_0_CHAN4 PS3_AUDIO_INTR_0_CHAN(4)
96#define PS3_AUDIO_INTR_0_CHAN3 PS3_AUDIO_INTR_0_CHAN(3)
97#define PS3_AUDIO_INTR_0_CHAN2 PS3_AUDIO_INTR_0_CHAN(2)
98#define PS3_AUDIO_INTR_0_CHAN1 PS3_AUDIO_INTR_0_CHAN(1)
99#define PS3_AUDIO_INTR_0_CHAN0 PS3_AUDIO_INTR_0_CHAN(0)
100
101/*
102 The PS3_AUDIO_INTR_EN_0 register specifies which DMA channels can generate
103 an interrupt to the PU. Each bit of PS3_AUDIO_INTR_EN_0 is ANDed with the
104 corresponding bit in PS3_AUDIO_INTR_0. The resulting bits are OR'd together
105 to generate the Audio interrupt.
106
107 31 24 23 16 15 8 7 0
108 +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
109 |0 0 0 0 0 0 0 0 0 0 0 0 0|C|0|C|0|C|0|C|0|C|0|C|0|C|0|C|0|C|0|C| INTR_EN_0
110 +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
111
112 Bit assignments are same as PS3_AUDIO_INTR_0
113*/
114
115/*
116 PS3_AUDIO_CONFIG
117 31 24 23 16 15 8 7 0
118 +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
119 |0 0 0 0 0 0 0 0|0 0 0 0 0 0 0 0|0 0 0 0 0 0 0 C|0 0 0 0 0 0 0 0| CONFIG
120 +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
121
122*/
123
124/* The CLEAR field cancels all pending transfers, and stops any running DMA
125 transfers. Any interrupts associated with the canceled transfers
126 will occur as if the transfer had finished.
127 Since this bit is designed to recover from DMA related issues
128 which are caused by unpredictable situations, it is prefered to wait
129 for normal DMA transfer end without using this bit.
130*/
131#define PS3_AUDIO_CONFIG_CLEAR (1 << 8) /* RWIVF */
132
133/*
134 PS3_AUDIO_AX_MCTRL: Audio Port Mute Control Register
135
136 31 24 23 16 15 8 7 0
137 +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
138 |0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0|A|A|A|0 0 0 0 0 0 0|S|S|A|A|A|A| AX_MCTRL
139 +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
140*/
141
142/* 3 Wire Audio Serial Output Channel Mutes (0..3) */
143#define PS3_AUDIO_AX_MCTRL_ASOMT(n) (1 << (3 - (n))) /* RWIVF */
144#define PS3_AUDIO_AX_MCTRL_ASO3MT (1 << 0) /* RWIVF */
145#define PS3_AUDIO_AX_MCTRL_ASO2MT (1 << 1) /* RWIVF */
146#define PS3_AUDIO_AX_MCTRL_ASO1MT (1 << 2) /* RWIVF */
147#define PS3_AUDIO_AX_MCTRL_ASO0MT (1 << 3) /* RWIVF */
148
149/* S/PDIF mutes (0,1)*/
150#define PS3_AUDIO_AX_MCTRL_SPOMT(n) (1 << (5 - (n))) /* RWIVF */
151#define PS3_AUDIO_AX_MCTRL_SPO1MT (1 << 4) /* RWIVF */
152#define PS3_AUDIO_AX_MCTRL_SPO0MT (1 << 5) /* RWIVF */
153
154/* All 3 Wire Serial Outputs Mute */
155#define PS3_AUDIO_AX_MCTRL_AASOMT (1 << 13) /* RWIVF */
156
157/* All S/PDIF Mute */
158#define PS3_AUDIO_AX_MCTRL_ASPOMT (1 << 14) /* RWIVF */
159
160/* All Audio Outputs Mute */
161#define PS3_AUDIO_AX_MCTRL_AAOMT (1 << 15) /* RWIVF */
162
163/*
164 S/PDIF Outputs Buffer Read/Write Pointer Register
165
166 31 24 23 16 15 8 7 0
167 +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
168 |0 0 0 0 0 0 0 0|0|SPO0B|0|SPO1B|0 0 0 0 0 0 0 0|0|SPO0B|0|SPO1B| AX_ISBP
169 +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
170
171*/
172/*
173 S/PDIF Output Channel Read Buffer Numbers
174 Buffer number is value of field.
175 Indicates current read access buffer ID from Audio Data
176 Transfer controller of S/PDIF Output
177*/
178
179#define PS3_AUDIO_AX_ISBP_SPOBRN_MASK(n) (0x7 << 4 * (1 - (n))) /* R-IUF */
180#define PS3_AUDIO_AX_ISBP_SPO1BRN_MASK (0x7 << 0) /* R-IUF */
181#define PS3_AUDIO_AX_ISBP_SPO0BRN_MASK (0x7 << 4) /* R-IUF */
182
183/*
184S/PDIF Output Channel Buffer Write Numbers
185Indicates current write access buffer ID from bus master.
186*/
187#define PS3_AUDIO_AX_ISBP_SPOBWN_MASK(n) (0x7 << 4 * (5 - (n))) /* R-IUF */
188#define PS3_AUDIO_AX_ISBP_SPO1BWN_MASK (0x7 << 16) /* R-IUF */
189#define PS3_AUDIO_AX_ISBP_SPO0BWN_MASK (0x7 << 20) /* R-IUF */
190
191/*
192 3 Wire Audio Serial Outputs Buffer Read/Write
193 Pointer Register
194 Buffer number is value of field
195
196 31 24 23 16 15 8 7 0
197 +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
198 |0|ASO0B|0|ASO1B|0|ASO2B|0|ASO3B|0|ASO0B|0|ASO1B|0|ASO2B|0|ASO3B| AX_AOBP
199 +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
200*/
201
202/*
2033 Wire Audio Serial Output Channel Buffer Read Numbers
204Indicates current read access buffer Id from Audio Data Transfer
205Controller of 3 Wire Audio Serial Output Channels
206*/
207#define PS3_AUDIO_AX_AOBP_ASOBRN_MASK(n) (0x7 << 4 * (3 - (n))) /* R-IUF */
208
209#define PS3_AUDIO_AX_AOBP_ASO3BRN_MASK (0x7 << 0) /* R-IUF */
210#define PS3_AUDIO_AX_AOBP_ASO2BRN_MASK (0x7 << 4) /* R-IUF */
211#define PS3_AUDIO_AX_AOBP_ASO1BRN_MASK (0x7 << 8) /* R-IUF */
212#define PS3_AUDIO_AX_AOBP_ASO0BRN_MASK (0x7 << 12) /* R-IUF */
213
214/*
2153 Wire Audio Serial Output Channel Buffer Write Numbers
216Indicates current write access buffer ID from bus master.
217*/
218#define PS3_AUDIO_AX_AOBP_ASOBWN_MASK(n) (0x7 << 4 * (7 - (n))) /* R-IUF */
219
220#define PS3_AUDIO_AX_AOBP_ASO3BWN_MASK (0x7 << 16) /* R-IUF */
221#define PS3_AUDIO_AX_AOBP_ASO2BWN_MASK (0x7 << 20) /* R-IUF */
222#define PS3_AUDIO_AX_AOBP_ASO1BWN_MASK (0x7 << 24) /* R-IUF */
223#define PS3_AUDIO_AX_AOBP_ASO0BWN_MASK (0x7 << 28) /* R-IUF */
224
225
226
227/*
228Audio Port Interrupt Condition Register
229For the fields in this register, the following values apply:
2300 = Interrupt is generated every interrupt event.
2311 = Interrupt is generated every 2 interrupt events.
2322 = Interrupt is generated every 4 interrupt events.
2333 = Reserved
234
235
236 31 24 23 16 15 8 7 0
237 +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
238 |0 0 0 0 0 0 0 0|0 0|SPO|0 0|SPO|0 0|AAS|0 0 0 0 0 0 0 0 0 0 0 0| AX_IC
239 +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
240*/
241/*
242All 3-Wire Audio Serial Outputs Interrupt Mode
243Configures the Interrupt and Signal Notification
244condition of all 3-wire Audio Serial Outputs.
245*/
246#define PS3_AUDIO_AX_IC_AASOIMD_MASK (0x3 << 12) /* RWIVF */
247#define PS3_AUDIO_AX_IC_AASOIMD_EVERY1 (0x0 << 12) /* RWI-V */
248#define PS3_AUDIO_AX_IC_AASOIMD_EVERY2 (0x1 << 12) /* RW--V */
249#define PS3_AUDIO_AX_IC_AASOIMD_EVERY4 (0x2 << 12) /* RW--V */
250
251/*
252S/PDIF Output Channel Interrupt Modes
253Configures the Interrupt and signal Notification
254conditions of S/PDIF output channels.
255*/
256#define PS3_AUDIO_AX_IC_SPO1IMD_MASK (0x3 << 16) /* RWIVF */
257#define PS3_AUDIO_AX_IC_SPO1IMD_EVERY1 (0x0 << 16) /* RWI-V */
258#define PS3_AUDIO_AX_IC_SPO1IMD_EVERY2 (0x1 << 16) /* RW--V */
259#define PS3_AUDIO_AX_IC_SPO1IMD_EVERY4 (0x2 << 16) /* RW--V */
260
261#define PS3_AUDIO_AX_IC_SPO0IMD_MASK (0x3 << 20) /* RWIVF */
262#define PS3_AUDIO_AX_IC_SPO0IMD_EVERY1 (0x0 << 20) /* RWI-V */
263#define PS3_AUDIO_AX_IC_SPO0IMD_EVERY2 (0x1 << 20) /* RW--V */
264#define PS3_AUDIO_AX_IC_SPO0IMD_EVERY4 (0x2 << 20) /* RW--V */
265
266/*
267Audio Port interrupt Enable Register
268Configures whether to enable or disable each Interrupt Generation.
269
270
271 31 24 23 16 15 8 7 0
272 +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
273 |0 0 0 0 0 0 0 0|S|S|0 0|A|A|A|A|0 0 0 0|S|S|0 0|S|S|0 0|A|A|A|A| AX_IE
274 +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
275
276*/
277
278/*
2793 Wire Audio Serial Output Channel Buffer Underflow
280Interrupt Enables
281Select enable/disable of Buffer Underflow Interrupts for
2823-Wire Audio Serial Output Channels
283DISABLED=Interrupt generation disabled.
284*/
285#define PS3_AUDIO_AX_IE_ASOBUIE(n) (1 << (3 - (n))) /* RWIVF */
286#define PS3_AUDIO_AX_IE_ASO3BUIE (1 << 0) /* RWIVF */
287#define PS3_AUDIO_AX_IE_ASO2BUIE (1 << 1) /* RWIVF */
288#define PS3_AUDIO_AX_IE_ASO1BUIE (1 << 2) /* RWIVF */
289#define PS3_AUDIO_AX_IE_ASO0BUIE (1 << 3) /* RWIVF */
290
291/* S/PDIF Output Channel Buffer Underflow Interrupt Enables */
292
293#define PS3_AUDIO_AX_IE_SPOBUIE(n) (1 << (7 - (n))) /* RWIVF */
294#define PS3_AUDIO_AX_IE_SPO1BUIE (1 << 6) /* RWIVF */
295#define PS3_AUDIO_AX_IE_SPO0BUIE (1 << 7) /* RWIVF */
296
297/* S/PDIF Output Channel One Block Transfer Completion Interrupt Enables */
298
299#define PS3_AUDIO_AX_IE_SPOBTCIE(n) (1 << (11 - (n))) /* RWIVF */
300#define PS3_AUDIO_AX_IE_SPO1BTCIE (1 << 10) /* RWIVF */
301#define PS3_AUDIO_AX_IE_SPO0BTCIE (1 << 11) /* RWIVF */
302
303/* 3-Wire Audio Serial Output Channel Buffer Empty Interrupt Enables */
304
305#define PS3_AUDIO_AX_IE_ASOBEIE(n) (1 << (19 - (n))) /* RWIVF */
306#define PS3_AUDIO_AX_IE_ASO3BEIE (1 << 16) /* RWIVF */
307#define PS3_AUDIO_AX_IE_ASO2BEIE (1 << 17) /* RWIVF */
308#define PS3_AUDIO_AX_IE_ASO1BEIE (1 << 18) /* RWIVF */
309#define PS3_AUDIO_AX_IE_ASO0BEIE (1 << 19) /* RWIVF */
310
311/* S/PDIF Output Channel Buffer Empty Interrupt Enables */
312
313#define PS3_AUDIO_AX_IE_SPOBEIE(n) (1 << (23 - (n))) /* RWIVF */
314#define PS3_AUDIO_AX_IE_SPO1BEIE (1 << 22) /* RWIVF */
315#define PS3_AUDIO_AX_IE_SPO0BEIE (1 << 23) /* RWIVF */
316
317/*
318Audio Port Interrupt Status Register
319Indicates Interrupt status, which interrupt has occured, and can clear
320each interrupt in this register.
321Writing 1b to a field containing 1b clears field and de-asserts interrupt.
322Writing 0b to a field has no effect.
323Field vaules are the following:
3240 - Interrupt hasn't occured.
3251 - Interrupt has occured.
326
327
328 31 24 23 16 15 8 7 0
329 +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
330 |0 0 0 0 0 0 0 0|S|S|0 0|A|A|A|A|0 0 0 0|S|S|0 0|S|S|0 0|A|A|A|A| AX_IS
331 +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
332
333 Bit assignment are same as AX_IE
334*/
335
336/*
337Audio Output Master Control Register
338Configures Master Clock and other master Audio Output Settings
339
340
341 31 24 23 16 15 8 7 0
342 +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
343 |0|SCKSE|0|SCKSE| MR0 | MR1 |MCL|MCL|0 0 0 0|0 0 0 0 0 0 0 0| AO_MCTRL
344 +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
345*/
346
347/*
348MCLK Output Control
349Controls mclko[1] output.
3500 - Disable output (fixed at High)
3511 - Output clock produced by clock selected
352with scksel1 by mr1
3532 - Reserved
3543 - Reserved
355*/
356
357#define PS3_AUDIO_AO_MCTRL_MCLKC1_MASK (0x3 << 12) /* RWIVF */
358#define PS3_AUDIO_AO_MCTRL_MCLKC1_DISABLED (0x0 << 12) /* RWI-V */
359#define PS3_AUDIO_AO_MCTRL_MCLKC1_ENABLED (0x1 << 12) /* RW--V */
360#define PS3_AUDIO_AO_MCTRL_MCLKC1_RESVD2 (0x2 << 12) /* RW--V */
361#define PS3_AUDIO_AO_MCTRL_MCLKC1_RESVD3 (0x3 << 12) /* RW--V */
362
363/*
364MCLK Output Control
365Controls mclko[0] output.
3660 - Disable output (fixed at High)
3671 - Output clock produced by clock selected
368with SCKSEL0 by MR0
3692 - Reserved
3703 - Reserved
371*/
372#define PS3_AUDIO_AO_MCTRL_MCLKC0_MASK (0x3 << 14) /* RWIVF */
373#define PS3_AUDIO_AO_MCTRL_MCLKC0_DISABLED (0x0 << 14) /* RWI-V */
374#define PS3_AUDIO_AO_MCTRL_MCLKC0_ENABLED (0x1 << 14) /* RW--V */
375#define PS3_AUDIO_AO_MCTRL_MCLKC0_RESVD2 (0x2 << 14) /* RW--V */
376#define PS3_AUDIO_AO_MCTRL_MCLKC0_RESVD3 (0x3 << 14) /* RW--V */
377/*
378Master Clock Rate 1
379Sets the divide ration of Master Clock1 (clock output from
380mclko[1] for the input clock selected by scksel1.
381*/
382#define PS3_AUDIO_AO_MCTRL_MR1_MASK (0xf << 16)
383#define PS3_AUDIO_AO_MCTRL_MR1_DEFAULT (0x0 << 16) /* RWI-V */
384/*
385Master Clock Rate 0
386Sets the divide ratio of Master Clock0 (clock output from
387mclko[0] for the input clock selected by scksel0).
388*/
389#define PS3_AUDIO_AO_MCTRL_MR0_MASK (0xf << 20) /* RWIVF */
390#define PS3_AUDIO_AO_MCTRL_MR0_DEFAULT (0x0 << 20) /* RWI-V */
391/*
392System Clock Select 0/1
393Selects the system clock to be used as Master Clock 0/1
394Input the system clock that is appropriate for the sampling
395rate.
396*/
397#define PS3_AUDIO_AO_MCTRL_SCKSEL1_MASK (0x7 << 24) /* RWIVF */
398#define PS3_AUDIO_AO_MCTRL_SCKSEL1_DEFAULT (0x2 << 24) /* RWI-V */
399
400#define PS3_AUDIO_AO_MCTRL_SCKSEL0_MASK (0x7 << 28) /* RWIVF */
401#define PS3_AUDIO_AO_MCTRL_SCKSEL0_DEFAULT (0x2 << 28) /* RWI-V */
402
403
404/*
4053-Wire Audio Output Master Control Register
406Configures clock, 3-Wire Audio Serial Output Enable, and
407other 3-Wire Audio Serial Output Master Settings
408
409
410 31 24 23 16 15 8 7 0
411 +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
412 |A|A|A|A|0 0 0|A| ASOSR |0 0 0 0|A|A|A|A|A|A|0|1|0 0 0 0 0 0 0 0| AO_3WMCTRL
413 +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
414*/
415
416
417/*
418LRCKO Polarity
4190 - Reserved
4201 - default
421*/
422#define PS3_AUDIO_AO_3WMCTRL_ASOPLRCK (1 << 8) /* RWIVF */
423#define PS3_AUDIO_AO_3WMCTRL_ASOPLRCK_DEFAULT (1 << 8) /* RW--V */
424
425/* LRCK Output Disable */
426
427#define PS3_AUDIO_AO_3WMCTRL_ASOLRCKD (1 << 10) /* RWIVF */
428#define PS3_AUDIO_AO_3WMCTRL_ASOLRCKD_ENABLED (0 << 10) /* RW--V */
429#define PS3_AUDIO_AO_3WMCTRL_ASOLRCKD_DISABLED (1 << 10) /* RWI-V */
430
431/* Bit Clock Output Disable */
432
433#define PS3_AUDIO_AO_3WMCTRL_ASOBCLKD (1 << 11) /* RWIVF */
434#define PS3_AUDIO_AO_3WMCTRL_ASOBCLKD_ENABLED (0 << 11) /* RW--V */
435#define PS3_AUDIO_AO_3WMCTRL_ASOBCLKD_DISABLED (1 << 11) /* RWI-V */
436
437/*
4383-Wire Audio Serial Output Channel 0-3 Operational
439Status. Each bit becomes 1 after each 3-Wire Audio
440Serial Output Channel N is in action by setting 1 to
441asoen.
442Each bit becomes 0 after each 3-Wire Audio Serial Output
443Channel N is out of action by setting 0 to asoen.
444*/
445#define PS3_AUDIO_AO_3WMCTRL_ASORUN(n) (1 << (15 - (n))) /* R-IVF */
446#define PS3_AUDIO_AO_3WMCTRL_ASORUN_STOPPED(n) (0 << (15 - (n))) /* R-I-V */
447#define PS3_AUDIO_AO_3WMCTRL_ASORUN_RUNNING(n) (1 << (15 - (n))) /* R---V */
448#define PS3_AUDIO_AO_3WMCTRL_ASORUN0 \
449 PS3_AUDIO_AO_3WMCTRL_ASORUN(0)
450#define PS3_AUDIO_AO_3WMCTRL_ASORUN0_STOPPED \
451 PS3_AUDIO_AO_3WMCTRL_ASORUN_STOPPED(0)
452#define PS3_AUDIO_AO_3WMCTRL_ASORUN0_RUNNING \
453 PS3_AUDIO_AO_3WMCTRL_ASORUN_RUNNING(0)
454#define PS3_AUDIO_AO_3WMCTRL_ASORUN1 \
455 PS3_AUDIO_AO_3WMCTRL_ASORUN(1)
456#define PS3_AUDIO_AO_3WMCTRL_ASORUN1_STOPPED \
457 PS3_AUDIO_AO_3WMCTRL_ASORUN_STOPPED(1)
458#define PS3_AUDIO_AO_3WMCTRL_ASORUN1_RUNNING \
459 PS3_AUDIO_AO_3WMCTRL_ASORUN_RUNNING(1)
460#define PS3_AUDIO_AO_3WMCTRL_ASORUN2 \
461 PS3_AUDIO_AO_3WMCTRL_ASORUN(2)
462#define PS3_AUDIO_AO_3WMCTRL_ASORUN2_STOPPED \
463 PS3_AUDIO_AO_3WMCTRL_ASORUN_STOPPED(2)
464#define PS3_AUDIO_AO_3WMCTRL_ASORUN2_RUNNING \
465 PS3_AUDIO_AO_3WMCTRL_ASORUN_RUNNING(2)
466#define PS3_AUDIO_AO_3WMCTRL_ASORUN3 \
467 PS3_AUDIO_AO_3WMCTRL_ASORUN(3)
468#define PS3_AUDIO_AO_3WMCTRL_ASORUN3_STOPPED \
469 PS3_AUDIO_AO_3WMCTRL_ASORUN_STOPPED(3)
470#define PS3_AUDIO_AO_3WMCTRL_ASORUN3_RUNNING \
471 PS3_AUDIO_AO_3WMCTRL_ASORUN_RUNNING(3)
472
473/*
474Sampling Rate
475Specifies the divide ratio of the bit clock (clock output
476from bclko) used by the 3-wire Audio Output Clock, whcih
477is applied to the master clock selected by mcksel.
478Data output is synchronized with this clock.
479*/
480#define PS3_AUDIO_AO_3WMCTRL_ASOSR_MASK (0xf << 20) /* RWIVF */
481#define PS3_AUDIO_AO_3WMCTRL_ASOSR_DIV2 (0x1 << 20) /* RWI-V */
482#define PS3_AUDIO_AO_3WMCTRL_ASOSR_DIV4 (0x2 << 20) /* RW--V */
483#define PS3_AUDIO_AO_3WMCTRL_ASOSR_DIV8 (0x4 << 20) /* RW--V */
484#define PS3_AUDIO_AO_3WMCTRL_ASOSR_DIV12 (0x6 << 20) /* RW--V */
485
486/*
487Master Clock Select
4880 - Master Clock 0
4891 - Master Clock 1
490*/
491#define PS3_AUDIO_AO_3WMCTRL_ASOMCKSEL (1 << 24) /* RWIVF */
492#define PS3_AUDIO_AO_3WMCTRL_ASOMCKSEL_CLK0 (0 << 24) /* RWI-V */
493#define PS3_AUDIO_AO_3WMCTRL_ASOMCKSEL_CLK1 (1 << 24) /* RW--V */
494
495/*
496Enables and disables 4ch 3-Wire Audio Serial Output
497operation. Each Bit from 0 to 3 corresponds to an
498output channel, which means that each output channel
499can be enabled or disabled individually. When
500multiple channels are enabled at the same time, output
501operations are performed in synchronization.
502Bit 0 - Output Channel 0 (SDOUT[0])
503Bit 1 - Output Channel 1 (SDOUT[1])
504Bit 2 - Output Channel 2 (SDOUT[2])
505Bit 3 - Output Channel 3 (SDOUT[3])
506*/
507#define PS3_AUDIO_AO_3WMCTRL_ASOEN(n) (1 << (31 - (n))) /* RWIVF */
508#define PS3_AUDIO_AO_3WMCTRL_ASOEN_DISABLED(n) (0 << (31 - (n))) /* RWI-V */
509#define PS3_AUDIO_AO_3WMCTRL_ASOEN_ENABLED(n) (1 << (31 - (n))) /* RW--V */
510
511#define PS3_AUDIO_AO_3WMCTRL_ASOEN0 \
512 PS3_AUDIO_AO_3WMCTRL_ASOEN(0) /* RWIVF */
513#define PS3_AUDIO_AO_3WMCTRL_ASOEN0_DISABLED \
514 PS3_AUDIO_AO_3WMCTRL_ASOEN_DISABLED(0) /* RWI-V */
515#define PS3_AUDIO_AO_3WMCTRL_ASOEN0_ENABLED \
516 PS3_AUDIO_AO_3WMCTRL_ASOEN_ENABLED(0) /* RW--V */
517#define PS3_AUDIO_A1_3WMCTRL_ASOEN0 \
518 PS3_AUDIO_AO_3WMCTRL_ASOEN(1) /* RWIVF */
519#define PS3_AUDIO_A1_3WMCTRL_ASOEN0_DISABLED \
520 PS3_AUDIO_AO_3WMCTRL_ASOEN_DISABLED(1) /* RWI-V */
521#define PS3_AUDIO_A1_3WMCTRL_ASOEN0_ENABLED \
522 PS3_AUDIO_AO_3WMCTRL_ASOEN_ENABLED(1) /* RW--V */
523#define PS3_AUDIO_A2_3WMCTRL_ASOEN0 \
524 PS3_AUDIO_AO_3WMCTRL_ASOEN(2) /* RWIVF */
525#define PS3_AUDIO_A2_3WMCTRL_ASOEN0_DISABLED \
526 PS3_AUDIO_AO_3WMCTRL_ASOEN_DISABLED(2) /* RWI-V */
527#define PS3_AUDIO_A2_3WMCTRL_ASOEN0_ENABLED \
528 PS3_AUDIO_AO_3WMCTRL_ASOEN_ENABLED(2) /* RW--V */
529#define PS3_AUDIO_A3_3WMCTRL_ASOEN0 \
530 PS3_AUDIO_AO_3WMCTRL_ASOEN(3) /* RWIVF */
531#define PS3_AUDIO_A3_3WMCTRL_ASOEN0_DISABLED \
532 PS3_AUDIO_AO_3WMCTRL_ASOEN_DISABLED(3) /* RWI-V */
533#define PS3_AUDIO_A3_3WMCTRL_ASOEN0_ENABLED \
534 PS3_AUDIO_AO_3WMCTRL_ASOEN_ENABLED(3) /* RW--V */
535
536/*
5373-Wire Audio Serial output Channel 0-3 Control Register
538Configures settings for 3-Wire Serial Audio Output Channel 0-3
539
540
541 31 24 23 16 15 8 7 0
542 +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
543 |0 0 0 0 0 0 0 0 0 0 0 0 0 0 0|A|0 0 0 0|A|0|ASO|0 0 0|0|0|0|0|0| AO_3WCTRL
544 +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
545
546*/
547/*
548Data Bit Mode
549Specifies the number of data bits
5500 - 16 bits
5511 - reserved
5522 - 20 bits
5533 - 24 bits
554*/
555#define PS3_AUDIO_AO_3WCTRL_ASODB_MASK (0x3 << 8) /* RWIVF */
556#define PS3_AUDIO_AO_3WCTRL_ASODB_16BIT (0x0 << 8) /* RWI-V */
557#define PS3_AUDIO_AO_3WCTRL_ASODB_RESVD (0x1 << 8) /* RWI-V */
558#define PS3_AUDIO_AO_3WCTRL_ASODB_20BIT (0x2 << 8) /* RW--V */
559#define PS3_AUDIO_AO_3WCTRL_ASODB_24BIT (0x3 << 8) /* RW--V */
560/*
561Data Format Mode
562Specifies the data format where (LSB side or MSB) the data(in 20 bit
563or 24 bit resolution mode) is put in a 32 bit field.
5640 - Data put on LSB side
5651 - Data put on MSB side
566*/
567#define PS3_AUDIO_AO_3WCTRL_ASODF (1 << 11) /* RWIVF */
568#define PS3_AUDIO_AO_3WCTRL_ASODF_LSB (0 << 11) /* RWI-V */
569#define PS3_AUDIO_AO_3WCTRL_ASODF_MSB (1 << 11) /* RW--V */
570/*
571Buffer Reset
572Performs buffer reset. Writing 1 to this bit initializes the
573corresponding 3-Wire Audio Output buffers(both L and R).
574*/
575#define PS3_AUDIO_AO_3WCTRL_ASOBRST (1 << 16) /* CWIVF */
576#define PS3_AUDIO_AO_3WCTRL_ASOBRST_IDLE (0 << 16) /* -WI-V */
577#define PS3_AUDIO_AO_3WCTRL_ASOBRST_RESET (1 << 16) /* -W--T */
578
579/*
580S/PDIF Audio Output Channel 0/1 Control Register
581Configures settings for S/PDIF Audio Output Channel 0/1.
582
583 31 24 23 16 15 8 7 0
584 +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
585 |S|0 0 0|S|0 0|S| SPOSR |0 0|SPO|0 0 0 0|S|0|SPO|0 0 0 0 0 0 0|S| AO_SPDCTRL
586 +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
587*/
588/*
589Buffer reset. Writing 1 to this bit initializes the
590corresponding S/PDIF output buffer pointer.
591*/
592#define PS3_AUDIO_AO_SPDCTRL_SPOBRST (1 << 0) /* CWIVF */
593#define PS3_AUDIO_AO_SPDCTRL_SPOBRST_IDLE (0 << 0) /* -WI-V */
594#define PS3_AUDIO_AO_SPDCTRL_SPOBRST_RESET (1 << 0) /* -W--T */
595
596/*
597Data Bit Mode
598Specifies number of data bits
5990 - 16 bits
6001 - Reserved
6012 - 20 bits
6023 - 24 bits
603*/
604#define PS3_AUDIO_AO_SPDCTRL_SPODB_MASK (0x3 << 8) /* RWIVF */
605#define PS3_AUDIO_AO_SPDCTRL_SPODB_16BIT (0x0 << 8) /* RWI-V */
606#define PS3_AUDIO_AO_SPDCTRL_SPODB_RESVD (0x1 << 8) /* RW--V */
607#define PS3_AUDIO_AO_SPDCTRL_SPODB_20BIT (0x2 << 8) /* RW--V */
608#define PS3_AUDIO_AO_SPDCTRL_SPODB_24BIT (0x3 << 8) /* RW--V */
609/*
610Data format Mode
611Specifies the data format, where (LSB side or MSB)
612the data(in 20 or 24 bit resolution) is put in the
61332 bit field.
6140 - LSB Side
6151 - MSB Side
616*/
617#define PS3_AUDIO_AO_SPDCTRL_SPODF (1 << 11) /* RWIVF */
618#define PS3_AUDIO_AO_SPDCTRL_SPODF_LSB (0 << 11) /* RWI-V */
619#define PS3_AUDIO_AO_SPDCTRL_SPODF_MSB (1 << 11) /* RW--V */
620/*
621Source Select
622Specifies the source of the S/PDIF output. When 0, output
623operation is controlled by 3wen[0] of AO_3WMCTRL register.
624The SR must have the same setting as the a0_3wmctrl reg.
6250 - 3-Wire Audio OUT Ch0 Buffer
6261 - S/PDIF buffer
627*/
628#define PS3_AUDIO_AO_SPDCTRL_SPOSS_MASK (0x3 << 16) /* RWIVF */
629#define PS3_AUDIO_AO_SPDCTRL_SPOSS_3WEN (0x0 << 16) /* RWI-V */
630#define PS3_AUDIO_AO_SPDCTRL_SPOSS_SPDIF (0x1 << 16) /* RW--V */
631/*
632Sampling Rate
633Specifies the divide ratio of the bit clock (clock output
634from bclko) used by the S/PDIF Output Clock, which
635is applied to the master clock selected by mcksel.
636*/
637#define PS3_AUDIO_AO_SPDCTRL_SPOSR (0xf << 20) /* RWIVF */
638#define PS3_AUDIO_AO_SPDCTRL_SPOSR_DIV2 (0x1 << 20) /* RWI-V */
639#define PS3_AUDIO_AO_SPDCTRL_SPOSR_DIV4 (0x2 << 20) /* RW--V */
640#define PS3_AUDIO_AO_SPDCTRL_SPOSR_DIV8 (0x4 << 20) /* RW--V */
641#define PS3_AUDIO_AO_SPDCTRL_SPOSR_DIV12 (0x6 << 20) /* RW--V */
642/*
643Master Clock Select
6440 - Master Clock 0
6451 - Master Clock 1
646*/
647#define PS3_AUDIO_AO_SPDCTRL_SPOMCKSEL (1 << 24) /* RWIVF */
648#define PS3_AUDIO_AO_SPDCTRL_SPOMCKSEL_CLK0 (0 << 24) /* RWI-V */
649#define PS3_AUDIO_AO_SPDCTRL_SPOMCKSEL_CLK1 (1 << 24) /* RW--V */
650
651/*
652S/PDIF Output Channel Operational Status
653This bit becomes 1 after S/PDIF Output Channel is in
654action by setting 1 to spoen. This bit becomes 0
655after S/PDIF Output Channel is out of action by setting
6560 to spoen.
657*/
658#define PS3_AUDIO_AO_SPDCTRL_SPORUN (1 << 27) /* R-IVF */
659#define PS3_AUDIO_AO_SPDCTRL_SPORUN_STOPPED (0 << 27) /* R-I-V */
660#define PS3_AUDIO_AO_SPDCTRL_SPORUN_RUNNING (1 << 27) /* R---V */
661
662/*
663S/PDIF Audio Output Channel Output Enable
664Enables and disables output operation. This bit is used
665only when sposs = 1
666*/
667#define PS3_AUDIO_AO_SPDCTRL_SPOEN (1 << 31) /* RWIVF */
668#define PS3_AUDIO_AO_SPDCTRL_SPOEN_DISABLED (0 << 31) /* RWI-V */
669#define PS3_AUDIO_AO_SPDCTRL_SPOEN_ENABLED (1 << 31) /* RW--V */
670
671/*
672S/PDIF Audio Output Channel Channel Status
673Setting Registers.
674Configures channel status bit settings for each block
675(192 bits).
676Output is performed from the MSB(AO_SPDCS0 register bit 31).
677The same value is added for subframes within the same frame.
678 31 24 23 16 15 8 7 0
679 +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
680 | SPOCS | AO_SPDCS
681 +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
682
683S/PDIF Audio Output Channel User Bit Setting
684Configures user bit settings for each block (384 bits).
685Output is performed from the MSB(ao_spdub0 register bit 31).
686
687
688 31 24 23 16 15 8 7 0
689 +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
690 | SPOUB | AO_SPDUB
691 +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
692*/
693/*****************************************************************************
694 *
695 * DMAC register
696 *
697 *****************************************************************************/
698/*
699The PS3_AUDIO_KICK register is used to initiate a DMA transfer and monitor
700its status
701
702 31 24 23 16 15 8 7 0
703 +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
704 |0 0 0 0 0|STATU|0 0 0| EVENT |0 0 0 0 0 0 0 0 0 0 0 0 0 0 0|R| KICK
705 +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
706*/
707/*
708The REQUEST field is written to ACTIVE to initiate a DMA request when EVENT
709occurs.
710It will return to the DONE state when the request is completed.
711The registers for a DMA channel should only be written if REQUEST is IDLE.
712*/
713
714#define PS3_AUDIO_KICK_REQUEST (1 << 0) /* RWIVF */
715#define PS3_AUDIO_KICK_REQUEST_IDLE (0 << 0) /* RWI-V */
716#define PS3_AUDIO_KICK_REQUEST_ACTIVE (1 << 0) /* -W--T */
717
718/*
719 *The EVENT field is used to set the event in which
720 *the DMA request becomes active.
721 */
722#define PS3_AUDIO_KICK_EVENT_MASK (0x1f << 16) /* RWIVF */
723#define PS3_AUDIO_KICK_EVENT_ALWAYS (0x00 << 16) /* RWI-V */
724#define PS3_AUDIO_KICK_EVENT_SERIALOUT0_EMPTY (0x01 << 16) /* RW--V */
725#define PS3_AUDIO_KICK_EVENT_SERIALOUT0_UNDERFLOW (0x02 << 16) /* RW--V */
726#define PS3_AUDIO_KICK_EVENT_SERIALOUT1_EMPTY (0x03 << 16) /* RW--V */
727#define PS3_AUDIO_KICK_EVENT_SERIALOUT1_UNDERFLOW (0x04 << 16) /* RW--V */
728#define PS3_AUDIO_KICK_EVENT_SERIALOUT2_EMPTY (0x05 << 16) /* RW--V */
729#define PS3_AUDIO_KICK_EVENT_SERIALOUT2_UNDERFLOW (0x06 << 16) /* RW--V */
730#define PS3_AUDIO_KICK_EVENT_SERIALOUT3_EMPTY (0x07 << 16) /* RW--V */
731#define PS3_AUDIO_KICK_EVENT_SERIALOUT3_UNDERFLOW (0x08 << 16) /* RW--V */
732#define PS3_AUDIO_KICK_EVENT_SPDIF0_BLOCKTRANSFERCOMPLETE \
733 (0x09 << 16) /* RW--V */
734#define PS3_AUDIO_KICK_EVENT_SPDIF0_UNDERFLOW (0x0A << 16) /* RW--V */
735#define PS3_AUDIO_KICK_EVENT_SPDIF0_EMPTY (0x0B << 16) /* RW--V */
736#define PS3_AUDIO_KICK_EVENT_SPDIF1_BLOCKTRANSFERCOMPLETE \
737 (0x0C << 16) /* RW--V */
738#define PS3_AUDIO_KICK_EVENT_SPDIF1_UNDERFLOW (0x0D << 16) /* RW--V */
739#define PS3_AUDIO_KICK_EVENT_SPDIF1_EMPTY (0x0E << 16) /* RW--V */
740
741#define PS3_AUDIO_KICK_EVENT_AUDIO_DMA(n) \
742 ((0x13 + (n)) << 16) /* RW--V */
743#define PS3_AUDIO_KICK_EVENT_AUDIO_DMA0 (0x13 << 16) /* RW--V */
744#define PS3_AUDIO_KICK_EVENT_AUDIO_DMA1 (0x14 << 16) /* RW--V */
745#define PS3_AUDIO_KICK_EVENT_AUDIO_DMA2 (0x15 << 16) /* RW--V */
746#define PS3_AUDIO_KICK_EVENT_AUDIO_DMA3 (0x16 << 16) /* RW--V */
747#define PS3_AUDIO_KICK_EVENT_AUDIO_DMA4 (0x17 << 16) /* RW--V */
748#define PS3_AUDIO_KICK_EVENT_AUDIO_DMA5 (0x18 << 16) /* RW--V */
749#define PS3_AUDIO_KICK_EVENT_AUDIO_DMA6 (0x19 << 16) /* RW--V */
750#define PS3_AUDIO_KICK_EVENT_AUDIO_DMA7 (0x1A << 16) /* RW--V */
751#define PS3_AUDIO_KICK_EVENT_AUDIO_DMA8 (0x1B << 16) /* RW--V */
752#define PS3_AUDIO_KICK_EVENT_AUDIO_DMA9 (0x1C << 16) /* RW--V */
753
754/*
755The STATUS field can be used to monitor the progress of a DMA request.
756DONE indicates the previous request has completed.
757EVENT indicates that the DMA engine is waiting for the EVENT to occur.
758PENDING indicates that the DMA engine has not started processing this
759request, but the EVENT has occured.
760DMA indicates that the data transfer is in progress.
761NOTIFY indicates that the notifier signalling end of transfer is being written.
762CLEAR indicated that the previous transfer was cleared.
763ERROR indicates the previous transfer requested an unsupported
764source/destination combination.
765*/
766
767#define PS3_AUDIO_KICK_STATUS_MASK (0x7 << 24) /* R-IVF */
768#define PS3_AUDIO_KICK_STATUS_DONE (0x0 << 24) /* R-I-V */
769#define PS3_AUDIO_KICK_STATUS_EVENT (0x1 << 24) /* R---V */
770#define PS3_AUDIO_KICK_STATUS_PENDING (0x2 << 24) /* R---V */
771#define PS3_AUDIO_KICK_STATUS_DMA (0x3 << 24) /* R---V */
772#define PS3_AUDIO_KICK_STATUS_NOTIFY (0x4 << 24) /* R---V */
773#define PS3_AUDIO_KICK_STATUS_CLEAR (0x5 << 24) /* R---V */
774#define PS3_AUDIO_KICK_STATUS_ERROR (0x6 << 24) /* R---V */
775
776/*
777The PS3_AUDIO_SOURCE register specifies the source address for transfers.
778
779
780 31 24 23 16 15 8 7 0
781 +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
782 | START |0 0 0 0 0|TAR| SOURCE
783 +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
784*/
785
786/*
787The Audio DMA engine uses 128-byte transfers, thus the address must be aligned
788to a 128 byte boundary. The low seven bits are assumed to be 0.
789*/
790
791#define PS3_AUDIO_SOURCE_START_MASK (0x01FFFFFF << 7) /* RWIUF */
792
793/*
794The TARGET field specifies the memory space containing the source address.
795*/
796
797#define PS3_AUDIO_SOURCE_TARGET_MASK (3 << 0) /* RWIVF */
798#define PS3_AUDIO_SOURCE_TARGET_SYSTEM_MEMORY (2 << 0) /* RW--V */
799
800/*
801The PS3_AUDIO_DEST register specifies the destination address for transfers.
802
803
804 31 24 23 16 15 8 7 0
805 +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
806 | START |0 0 0 0 0|TAR| DEST
807 +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
808*/
809
810/*
811The Audio DMA engine uses 128-byte transfers, thus the address must be aligned
812to a 128 byte boundary. The low seven bits are assumed to be 0.
813*/
814
815#define PS3_AUDIO_DEST_START_MASK (0x01FFFFFF << 7) /* RWIUF */
816
817/*
818The TARGET field specifies the memory space containing the destination address
819AUDIOFIFO = Audio WriteData FIFO,
820*/
821
822#define PS3_AUDIO_DEST_TARGET_MASK (3 << 0) /* RWIVF */
823#define PS3_AUDIO_DEST_TARGET_AUDIOFIFO (1 << 0) /* RW--V */
824
825/*
826PS3_AUDIO_DMASIZE specifies the number of 128-byte blocks + 1 to transfer.
827So a value of 0 means 128-bytes will get transfered.
828
829
830 31 24 23 16 15 8 7 0
831 +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
832 |0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0| BLOCKS | DMASIZE
833 +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
834*/
835
836
837#define PS3_AUDIO_DMASIZE_BLOCKS_MASK (0x7f << 0) /* RWIUF */
838
839/*
840 * source/destination address for internal fifos
841 */
842#define PS3_AUDIO_AO_3W_LDATA(n) (0x1000 + (0x100 * (n)))
843#define PS3_AUDIO_AO_3W_RDATA(n) (0x1080 + (0x100 * (n)))
844
845#define PS3_AUDIO_AO_SPD_DATA(n) (0x2000 + (0x400 * (n)))
846
847
848/*
849 * field attiribute
850 *
851 * Read
852 * ' ' = Other Information
853 * '-' = Field is part of a write-only register
854 * 'C' = Value read is always the same, constant value line follows (C)
855 * 'R' = Value is read
856 *
857 * Write
858 * ' ' = Other Information
859 * '-' = Must not be written (D), value ignored when written (R,A,F)
860 * 'W' = Can be written
861 *
862 * Internal State
863 * ' ' = Other Information
864 * '-' = No internal state
865 * 'X' = Internal state, initial value is unknown
866 * 'I' = Internal state, initial value is known and follows (I)
867 *
868 * Declaration/Size
869 * ' ' = Other Information
870 * '-' = Does Not Apply
871 * 'V' = Type is void
872 * 'U' = Type is unsigned integer
873 * 'S' = Type is signed integer
874 * 'F' = Type is IEEE floating point
875 * '1' = Byte size (008)
876 * '2' = Short size (016)
877 * '3' = Three byte size (024)
878 * '4' = Word size (032)
879 * '8' = Double size (064)
880 *
881 * Define Indicator
882 * ' ' = Other Information
883 * 'D' = Device
884 * 'M' = Memory
885 * 'R' = Register
886 * 'A' = Array of Registers
887 * 'F' = Field
888 * 'V' = Value
889 * 'T' = Task
890 */
891
diff --git a/sound/sh/Kconfig b/sound/sh/Kconfig
new file mode 100644
index 000000000000..b7e08ef22a94
--- /dev/null
+++ b/sound/sh/Kconfig
@@ -0,0 +1,14 @@
1# ALSA SH drivers
2
3menu "SUPERH devices"
4 depends on SND!=n && SUPERH
5
6config SND_AICA
7 tristate "Dreamcast Yamaha AICA sound"
8 depends on SH_DREAMCAST && SND
9 select SND_PCM
10 help
11 ALSA Sound driver for the SEGA Dreamcast console.
12
13endmenu
14
diff --git a/sound/sh/Makefile b/sound/sh/Makefile
new file mode 100644
index 000000000000..8fdcb6e26f00
--- /dev/null
+++ b/sound/sh/Makefile
@@ -0,0 +1,8 @@
1#
2# Makefile for ALSA
3#
4
5snd-aica-objs := aica.o
6
7# Toplevel Module Dependency
8obj-$(CONFIG_SND_AICA) += snd-aica.o
diff --git a/sound/sh/aica.c b/sound/sh/aica.c
new file mode 100644
index 000000000000..739786529ca5
--- /dev/null
+++ b/sound/sh/aica.c
@@ -0,0 +1,665 @@
1/*
2* This code is licenced under
3* the General Public Licence
4* version 2
5*
6* Copyright Adrian McMenamin 2005, 2006, 2007
7* <adrian@mcmen.demon.co.uk>
8* Requires firmware (BSD licenced) available from:
9* http://linuxdc.cvs.sourceforge.net/linuxdc/linux-sh-dc/sound/oss/aica/firmware/
10* or the maintainer
11*
12* This program is free software; you can redistribute it and/or modify
13* it under the terms of version 2 of the GNU General Public License as published by
14* the Free Software Foundation.
15*
16* This program is distributed in the hope that it will be useful,
17* but WITHOUT ANY WARRANTY; without even the implied warranty of
18* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19* GNU General Public License for more details.
20*
21* You should have received a copy of the GNU General Public License
22* along with this program; if not, write to the Free Software
23* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24*
25*/
26
27#include <linux/init.h>
28#include <linux/jiffies.h>
29#include <linux/slab.h>
30#include <linux/time.h>
31#include <linux/wait.h>
32#include <linux/moduleparam.h>
33#include <linux/platform_device.h>
34#include <linux/firmware.h>
35#include <linux/timer.h>
36#include <linux/delay.h>
37#include <linux/workqueue.h>
38#include <sound/driver.h>
39#include <sound/core.h>
40#include <sound/control.h>
41#include <sound/pcm.h>
42#include <sound/initval.h>
43#include <sound/info.h>
44#include <asm/io.h>
45#include <asm/dma.h>
46#include <asm/dreamcast/sysasic.h>
47#include "aica.h"
48
49MODULE_AUTHOR("Adrian McMenamin <adrian@mcmen.demon.co.uk>");
50MODULE_DESCRIPTION("Dreamcast AICA sound (pcm) driver");
51MODULE_LICENSE("GPL");
52MODULE_SUPPORTED_DEVICE("{{Yamaha/SEGA, AICA}}");
53
54/* module parameters */
55#define CARD_NAME "AICA"
56static int index = -1;
57static char *id;
58static int enable = 1;
59module_param(index, int, 0444);
60MODULE_PARM_DESC(index, "Index value for " CARD_NAME " soundcard.");
61module_param(id, charp, 0444);
62MODULE_PARM_DESC(id, "ID string for " CARD_NAME " soundcard.");
63module_param(enable, bool, 0644);
64MODULE_PARM_DESC(enable, "Enable " CARD_NAME " soundcard.");
65
66/* Use workqueue */
67static struct workqueue_struct *aica_queue;
68
69/* Simple platform device */
70static struct platform_device *pd;
71static struct resource aica_memory_space[2] = {
72 {
73 .name = "AICA ARM CONTROL",
74 .start = ARM_RESET_REGISTER,
75 .flags = IORESOURCE_MEM,
76 .end = ARM_RESET_REGISTER + 3,
77 },
78 {
79 .name = "AICA Sound RAM",
80 .start = SPU_MEMORY_BASE,
81 .flags = IORESOURCE_MEM,
82 .end = SPU_MEMORY_BASE + 0x200000 - 1,
83 },
84};
85
86/* SPU specific functions */
87/* spu_write_wait - wait for G2-SH FIFO to clear */
88static void spu_write_wait(void)
89{
90 int time_count;
91 time_count = 0;
92 while (1) {
93 if (!(readl(G2_FIFO) & 0x11))
94 break;
95 /* To ensure hardware failure doesn't wedge kernel */
96 time_count++;
97 if (time_count > 0x10000) {
98 snd_printk
99 ("WARNING: G2 FIFO appears to be blocked.\n");
100 break;
101 }
102 }
103}
104
105/* spu_memset - write to memory in SPU address space */
106static void spu_memset(u32 toi, u32 what, int length)
107{
108 int i;
109 snd_assert(length % 4 == 0, return);
110 for (i = 0; i < length; i++) {
111 if (!(i % 8))
112 spu_write_wait();
113 writel(what, toi + SPU_MEMORY_BASE);
114 toi++;
115 }
116}
117
118/* spu_memload - write to SPU address space */
119static void spu_memload(u32 toi, void *from, int length)
120{
121 u32 *froml = from;
122 u32 __iomem *to = (u32 __iomem *) (SPU_MEMORY_BASE + toi);
123 int i;
124 u32 val;
125 length = DIV_ROUND_UP(length, 4);
126 spu_write_wait();
127 for (i = 0; i < length; i++) {
128 if (!(i % 8))
129 spu_write_wait();
130 val = *froml;
131 writel(val, to);
132 froml++;
133 to++;
134 }
135}
136
137/* spu_disable - set spu registers to stop sound output */
138static void spu_disable(void)
139{
140 int i;
141 u32 regval;
142 spu_write_wait();
143 regval = readl(ARM_RESET_REGISTER);
144 regval |= 1;
145 spu_write_wait();
146 writel(regval, ARM_RESET_REGISTER);
147 for (i = 0; i < 64; i++) {
148 spu_write_wait();
149 regval = readl(SPU_REGISTER_BASE + (i * 0x80));
150 regval = (regval & ~0x4000) | 0x8000;
151 spu_write_wait();
152 writel(regval, SPU_REGISTER_BASE + (i * 0x80));
153 }
154}
155
156/* spu_enable - set spu registers to enable sound output */
157static void spu_enable(void)
158{
159 u32 regval = readl(ARM_RESET_REGISTER);
160 regval &= ~1;
161 spu_write_wait();
162 writel(regval, ARM_RESET_REGISTER);
163}
164
165/*
166 * Halt the sound processor, clear the memory,
167 * load some default ARM7 code, and then restart ARM7
168*/
169static void spu_reset(void)
170{
171 spu_disable();
172 spu_memset(0, 0, 0x200000 / 4);
173 /* Put ARM7 in endless loop */
174 ctrl_outl(0xea000002, SPU_MEMORY_BASE);
175 spu_enable();
176}
177
178/* aica_chn_start - write to spu to start playback */
179static void aica_chn_start(void)
180{
181 spu_write_wait();
182 writel(AICA_CMD_KICK | AICA_CMD_START, (u32 *) AICA_CONTROL_POINT);
183}
184
185/* aica_chn_halt - write to spu to halt playback */
186static void aica_chn_halt(void)
187{
188 spu_write_wait();
189 writel(AICA_CMD_KICK | AICA_CMD_STOP, (u32 *) AICA_CONTROL_POINT);
190}
191
192/* ALSA code below */
193static struct snd_pcm_hardware snd_pcm_aica_playback_hw = {
194 .info = (SNDRV_PCM_INFO_NONINTERLEAVED),
195 .formats =
196 (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE |
197 SNDRV_PCM_FMTBIT_IMA_ADPCM),
198 .rates = SNDRV_PCM_RATE_8000_48000,
199 .rate_min = 8000,
200 .rate_max = 48000,
201 .channels_min = 1,
202 .channels_max = 2,
203 .buffer_bytes_max = AICA_BUFFER_SIZE,
204 .period_bytes_min = AICA_PERIOD_SIZE,
205 .period_bytes_max = AICA_PERIOD_SIZE,
206 .periods_min = AICA_PERIOD_NUMBER,
207 .periods_max = AICA_PERIOD_NUMBER,
208};
209
210static int aica_dma_transfer(int channels, int buffer_size,
211 struct snd_pcm_substream *substream)
212{
213 int q, err, period_offset;
214 struct snd_card_aica *dreamcastcard;
215 struct snd_pcm_runtime *runtime;
216 err = 0;
217 dreamcastcard = substream->pcm->private_data;
218 period_offset = dreamcastcard->clicks;
219 period_offset %= (AICA_PERIOD_NUMBER / channels);
220 runtime = substream->runtime;
221 for (q = 0; q < channels; q++) {
222 err = dma_xfer(AICA_DMA_CHANNEL,
223 (unsigned long) (runtime->dma_area +
224 (AICA_BUFFER_SIZE * q) /
225 channels +
226 AICA_PERIOD_SIZE *
227 period_offset),
228 AICA_CHANNEL0_OFFSET + q * CHANNEL_OFFSET +
229 AICA_PERIOD_SIZE * period_offset,
230 buffer_size / channels, AICA_DMA_MODE);
231 if (unlikely(err < 0))
232 break;
233 dma_wait_for_completion(AICA_DMA_CHANNEL);
234 }
235 return err;
236}
237
238static void startup_aica(struct snd_card_aica *dreamcastcard)
239{
240 spu_memload(AICA_CHANNEL0_CONTROL_OFFSET,
241 dreamcastcard->channel, sizeof(struct aica_channel));
242 aica_chn_start();
243}
244
245static void run_spu_dma(struct work_struct *work)
246{
247 int buffer_size;
248 struct snd_pcm_runtime *runtime;
249 struct snd_card_aica *dreamcastcard;
250 dreamcastcard =
251 container_of(work, struct snd_card_aica, spu_dma_work);
252 runtime = dreamcastcard->substream->runtime;
253 if (unlikely(dreamcastcard->dma_check == 0)) {
254 buffer_size =
255 frames_to_bytes(runtime, runtime->buffer_size);
256 if (runtime->channels > 1)
257 dreamcastcard->channel->flags |= 0x01;
258 aica_dma_transfer(runtime->channels, buffer_size,
259 dreamcastcard->substream);
260 startup_aica(dreamcastcard);
261 dreamcastcard->clicks =
262 buffer_size / (AICA_PERIOD_SIZE * runtime->channels);
263 return;
264 } else {
265 aica_dma_transfer(runtime->channels,
266 AICA_PERIOD_SIZE * runtime->channels,
267 dreamcastcard->substream);
268 snd_pcm_period_elapsed(dreamcastcard->substream);
269 dreamcastcard->clicks++;
270 if (unlikely(dreamcastcard->clicks >= AICA_PERIOD_NUMBER))
271 dreamcastcard->clicks %= AICA_PERIOD_NUMBER;
272 mod_timer(&dreamcastcard->timer, jiffies + 1);
273 }
274}
275
276static void aica_period_elapsed(unsigned long timer_var)
277{
278 /*timer function - so cannot sleep */
279 int play_period;
280 struct snd_pcm_runtime *runtime;
281 struct snd_pcm_substream *substream;
282 struct snd_card_aica *dreamcastcard;
283 substream = (struct snd_pcm_substream *) timer_var;
284 runtime = substream->runtime;
285 dreamcastcard = substream->pcm->private_data;
286 /* Have we played out an additional period? */
287 play_period =
288 frames_to_bytes(runtime,
289 readl
290 (AICA_CONTROL_CHANNEL_SAMPLE_NUMBER)) /
291 AICA_PERIOD_SIZE;
292 if (play_period == dreamcastcard->current_period) {
293 /* reschedule the timer */
294 mod_timer(&(dreamcastcard->timer), jiffies + 1);
295 return;
296 }
297 if (runtime->channels > 1)
298 dreamcastcard->current_period = play_period;
299 if (unlikely(dreamcastcard->dma_check == 0))
300 dreamcastcard->dma_check = 1;
301 queue_work(aica_queue, &(dreamcastcard->spu_dma_work));
302}
303
304static void spu_begin_dma(struct snd_pcm_substream *substream)
305{
306 struct snd_card_aica *dreamcastcard;
307 struct snd_pcm_runtime *runtime;
308 runtime = substream->runtime;
309 dreamcastcard = substream->pcm->private_data;
310 /*get the queue to do the work */
311 queue_work(aica_queue, &(dreamcastcard->spu_dma_work));
312 /* Timer may already be running */
313 if (unlikely(dreamcastcard->timer.data)) {
314 mod_timer(&dreamcastcard->timer, jiffies + 4);
315 return;
316 }
317 init_timer(&(dreamcastcard->timer));
318 dreamcastcard->timer.data = (unsigned long) substream;
319 dreamcastcard->timer.function = aica_period_elapsed;
320 dreamcastcard->timer.expires = jiffies + 4;
321 add_timer(&(dreamcastcard->timer));
322}
323
324static int snd_aicapcm_pcm_open(struct snd_pcm_substream
325 *substream)
326{
327 struct snd_pcm_runtime *runtime;
328 struct aica_channel *channel;
329 struct snd_card_aica *dreamcastcard;
330 if (!enable)
331 return -ENOENT;
332 dreamcastcard = substream->pcm->private_data;
333 channel = kmalloc(sizeof(struct aica_channel), GFP_KERNEL);
334 if (!channel)
335 return -ENOMEM;
336 /* set defaults for channel */
337 channel->sfmt = SM_8BIT;
338 channel->cmd = AICA_CMD_START;
339 channel->vol = dreamcastcard->master_volume;
340 channel->pan = 0x80;
341 channel->pos = 0;
342 channel->flags = 0; /* default to mono */
343 dreamcastcard->channel = channel;
344 runtime = substream->runtime;
345 runtime->hw = snd_pcm_aica_playback_hw;
346 spu_enable();
347 dreamcastcard->clicks = 0;
348 dreamcastcard->current_period = 0;
349 dreamcastcard->dma_check = 0;
350 return 0;
351}
352
353static int snd_aicapcm_pcm_close(struct snd_pcm_substream
354 *substream)
355{
356 struct snd_card_aica *dreamcastcard = substream->pcm->private_data;
357 flush_workqueue(aica_queue);
358 if (dreamcastcard->timer.data)
359 del_timer(&dreamcastcard->timer);
360 kfree(dreamcastcard->channel);
361 spu_disable();
362 return 0;
363}
364
365static int snd_aicapcm_pcm_hw_free(struct snd_pcm_substream
366 *substream)
367{
368 /* Free the DMA buffer */
369 return snd_pcm_lib_free_pages(substream);
370}
371
372static int snd_aicapcm_pcm_hw_params(struct snd_pcm_substream
373 *substream, struct snd_pcm_hw_params
374 *hw_params)
375{
376 /* Allocate a DMA buffer using ALSA built-ins */
377 return
378 snd_pcm_lib_malloc_pages(substream,
379 params_buffer_bytes(hw_params));
380}
381
382static int snd_aicapcm_pcm_prepare(struct snd_pcm_substream
383 *substream)
384{
385 struct snd_card_aica *dreamcastcard = substream->pcm->private_data;
386 if ((substream->runtime)->format == SNDRV_PCM_FORMAT_S16_LE)
387 dreamcastcard->channel->sfmt = SM_16BIT;
388 dreamcastcard->channel->freq = substream->runtime->rate;
389 dreamcastcard->substream = substream;
390 return 0;
391}
392
393static int snd_aicapcm_pcm_trigger(struct snd_pcm_substream
394 *substream, int cmd)
395{
396 switch (cmd) {
397 case SNDRV_PCM_TRIGGER_START:
398 spu_begin_dma(substream);
399 break;
400 case SNDRV_PCM_TRIGGER_STOP:
401 aica_chn_halt();
402 break;
403 default:
404 return -EINVAL;
405 }
406 return 0;
407}
408
409static unsigned long snd_aicapcm_pcm_pointer(struct snd_pcm_substream
410 *substream)
411{
412 return readl(AICA_CONTROL_CHANNEL_SAMPLE_NUMBER);
413}
414
415static struct snd_pcm_ops snd_aicapcm_playback_ops = {
416 .open = snd_aicapcm_pcm_open,
417 .close = snd_aicapcm_pcm_close,
418 .ioctl = snd_pcm_lib_ioctl,
419 .hw_params = snd_aicapcm_pcm_hw_params,
420 .hw_free = snd_aicapcm_pcm_hw_free,
421 .prepare = snd_aicapcm_pcm_prepare,
422 .trigger = snd_aicapcm_pcm_trigger,
423 .pointer = snd_aicapcm_pcm_pointer,
424};
425
426/* TO DO: set up to handle more than one pcm instance */
427static int __init snd_aicapcmchip(struct snd_card_aica
428 *dreamcastcard, int pcm_index)
429{
430 struct snd_pcm *pcm;
431 int err;
432 /* AICA has no capture ability */
433 err =
434 snd_pcm_new(dreamcastcard->card, "AICA PCM", pcm_index, 1, 0,
435 &pcm);
436 if (unlikely(err < 0))
437 return err;
438 pcm->private_data = dreamcastcard;
439 strcpy(pcm->name, "AICA PCM");
440 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
441 &snd_aicapcm_playback_ops);
442 /* Allocate the DMA buffers */
443 err =
444 snd_pcm_lib_preallocate_pages_for_all(pcm,
445 SNDRV_DMA_TYPE_CONTINUOUS,
446 snd_dma_continuous_data
447 (GFP_KERNEL),
448 AICA_BUFFER_SIZE,
449 AICA_BUFFER_SIZE);
450 return err;
451}
452
453/* Mixer controls */
454static int aica_pcmswitch_info(struct snd_kcontrol *kcontrol,
455 struct snd_ctl_elem_info *uinfo)
456{
457 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
458 uinfo->count = 1;
459 uinfo->value.integer.min = 0;
460 uinfo->value.integer.max = 1;
461 return 0;
462}
463
464static int aica_pcmswitch_get(struct snd_kcontrol *kcontrol,
465 struct snd_ctl_elem_value *ucontrol)
466{
467 ucontrol->value.integer.value[0] = 1; /* TO DO: Fix me */
468 return 0;
469}
470
471static int aica_pcmswitch_put(struct snd_kcontrol *kcontrol,
472 struct snd_ctl_elem_value *ucontrol)
473{
474 if (ucontrol->value.integer.value[0] == 1)
475 return 0; /* TO DO: Fix me */
476 else
477 aica_chn_halt();
478 return 0;
479}
480
481static int aica_pcmvolume_info(struct snd_kcontrol *kcontrol,
482 struct snd_ctl_elem_info *uinfo)
483{
484 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
485 uinfo->count = 1;
486 uinfo->value.integer.min = 0;
487 uinfo->value.integer.max = 0xFF;
488 return 0;
489}
490
491static int aica_pcmvolume_get(struct snd_kcontrol *kcontrol,
492 struct snd_ctl_elem_value *ucontrol)
493{
494 struct snd_card_aica *dreamcastcard;
495 dreamcastcard = kcontrol->private_data;
496 if (unlikely(!dreamcastcard->channel))
497 return -ETXTBSY; /* we've not yet been set up */
498 ucontrol->value.integer.value[0] = dreamcastcard->channel->vol;
499 return 0;
500}
501
502static int aica_pcmvolume_put(struct snd_kcontrol *kcontrol,
503 struct snd_ctl_elem_value *ucontrol)
504{
505 struct snd_card_aica *dreamcastcard;
506 dreamcastcard = kcontrol->private_data;
507 if (unlikely(!dreamcastcard->channel))
508 return -ETXTBSY;
509 if (unlikely(dreamcastcard->channel->vol ==
510 ucontrol->value.integer.value[0]))
511 return 0;
512 dreamcastcard->channel->vol = ucontrol->value.integer.value[0];
513 dreamcastcard->master_volume = ucontrol->value.integer.value[0];
514 spu_memload(AICA_CHANNEL0_CONTROL_OFFSET,
515 dreamcastcard->channel, sizeof(struct aica_channel));
516 return 1;
517}
518
519static struct snd_kcontrol_new snd_aica_pcmswitch_control __devinitdata = {
520 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
521 .name = "PCM Playback Switch",
522 .index = 0,
523 .info = aica_pcmswitch_info,
524 .get = aica_pcmswitch_get,
525 .put = aica_pcmswitch_put
526};
527
528static struct snd_kcontrol_new snd_aica_pcmvolume_control __devinitdata = {
529 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
530 .name = "PCM Playback Volume",
531 .index = 0,
532 .info = aica_pcmvolume_info,
533 .get = aica_pcmvolume_get,
534 .put = aica_pcmvolume_put
535};
536
537static int load_aica_firmware(void)
538{
539 int err;
540 const struct firmware *fw_entry;
541 spu_reset();
542 err = request_firmware(&fw_entry, "aica_firmware.bin", &pd->dev);
543 if (unlikely(err))
544 return err;
545 /* write firware into memory */
546 spu_disable();
547 spu_memload(0, fw_entry->data, fw_entry->size);
548 spu_enable();
549 release_firmware(fw_entry);
550 return err;
551}
552
553static int __devinit add_aicamixer_controls(struct snd_card_aica
554 *dreamcastcard)
555{
556 int err;
557 err = snd_ctl_add
558 (dreamcastcard->card,
559 snd_ctl_new1(&snd_aica_pcmvolume_control, dreamcastcard));
560 if (unlikely(err < 0))
561 return err;
562 err = snd_ctl_add
563 (dreamcastcard->card,
564 snd_ctl_new1(&snd_aica_pcmswitch_control, dreamcastcard));
565 if (unlikely(err < 0))
566 return err;
567 return 0;
568}
569
570static int snd_aica_remove(struct platform_device *devptr)
571{
572 struct snd_card_aica *dreamcastcard;
573 dreamcastcard = platform_get_drvdata(devptr);
574 if (unlikely(!dreamcastcard))
575 return -ENODEV;
576 snd_card_free(dreamcastcard->card);
577 kfree(dreamcastcard);
578 platform_set_drvdata(devptr, NULL);
579 return 0;
580}
581
582static int __init snd_aica_probe(struct platform_device *devptr)
583{
584 int err;
585 struct snd_card_aica *dreamcastcard;
586 dreamcastcard = kmalloc(sizeof(struct snd_card_aica), GFP_KERNEL);
587 if (unlikely(!dreamcastcard))
588 return -ENOMEM;
589 dreamcastcard->card =
590 snd_card_new(index, SND_AICA_DRIVER, THIS_MODULE, 0);
591 if (unlikely(!dreamcastcard->card)) {
592 kfree(dreamcastcard);
593 return -ENODEV;
594 }
595 strcpy(dreamcastcard->card->driver, "snd_aica");
596 strcpy(dreamcastcard->card->shortname, SND_AICA_DRIVER);
597 strcpy(dreamcastcard->card->longname,
598 "Yamaha AICA Super Intelligent Sound Processor for SEGA Dreamcast");
599 /* Prepare to use the queue */
600 INIT_WORK(&(dreamcastcard->spu_dma_work), run_spu_dma);
601 /* Load the PCM 'chip' */
602 err = snd_aicapcmchip(dreamcastcard, 0);
603 if (unlikely(err < 0))
604 goto freedreamcast;
605 snd_card_set_dev(dreamcastcard->card, &devptr->dev);
606 dreamcastcard->timer.data = 0;
607 dreamcastcard->channel = NULL;
608 /* Add basic controls */
609 err = add_aicamixer_controls(dreamcastcard);
610 if (unlikely(err < 0))
611 goto freedreamcast;
612 /* Register the card with ALSA subsystem */
613 err = snd_card_register(dreamcastcard->card);
614 if (unlikely(err < 0))
615 goto freedreamcast;
616 platform_set_drvdata(devptr, dreamcastcard);
617 aica_queue = create_workqueue(CARD_NAME);
618 if (unlikely(!aica_queue))
619 goto freedreamcast;
620 snd_printk
621 ("ALSA Driver for Yamaha AICA Super Intelligent Sound Processor\n");
622 return 0;
623 freedreamcast:
624 snd_card_free(dreamcastcard->card);
625 kfree(dreamcastcard);
626 return err;
627}
628
629static struct platform_driver snd_aica_driver = {
630 .probe = snd_aica_probe,
631 .remove = snd_aica_remove,
632 .driver = {
633 .name = SND_AICA_DRIVER},
634};
635
636static int __init aica_init(void)
637{
638 int err;
639 err = platform_driver_register(&snd_aica_driver);
640 if (unlikely(err < 0))
641 return err;
642 pd = platform_device_register_simple(SND_AICA_DRIVER, -1,
643 aica_memory_space, 2);
644 if (unlikely(IS_ERR(pd))) {
645 platform_driver_unregister(&snd_aica_driver);
646 return PTR_ERR(pd);
647 }
648 /* Load the firmware */
649 return load_aica_firmware();
650}
651
652static void __exit aica_exit(void)
653{
654 /* Destroy the aica kernel thread *
655 * being extra cautious to check if it exists*/
656 if (likely(aica_queue))
657 destroy_workqueue(aica_queue);
658 platform_device_unregister(pd);
659 platform_driver_unregister(&snd_aica_driver);
660 /* Kill any sound still playing and reset ARM7 to safe state */
661 spu_reset();
662}
663
664module_init(aica_init);
665module_exit(aica_exit);
diff --git a/sound/sh/aica.h b/sound/sh/aica.h
new file mode 100644
index 000000000000..8c11e3d10a50
--- /dev/null
+++ b/sound/sh/aica.h
@@ -0,0 +1,81 @@
1/* aica.h
2 * Header file for ALSA driver for
3 * Sega Dreamcast Yamaha AICA sound
4 * Copyright Adrian McMenamin
5 * <adrian@mcmen.demon.co.uk>
6 * 2006
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of version 2 of the GNU General Public License as published by
10 * the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 */
22
23/* SPU memory and register constants etc */
24#define G2_FIFO 0xa05f688c
25#define SPU_MEMORY_BASE 0xA0800000
26#define ARM_RESET_REGISTER 0xA0702C00
27#define SPU_REGISTER_BASE 0xA0700000
28
29/* AICA channels stuff */
30#define AICA_CONTROL_POINT 0xA0810000
31#define AICA_CONTROL_CHANNEL_SAMPLE_NUMBER 0xA0810008
32#define AICA_CHANNEL0_CONTROL_OFFSET 0x10004
33
34/* Command values */
35#define AICA_CMD_KICK 0x80000000
36#define AICA_CMD_NONE 0
37#define AICA_CMD_START 1
38#define AICA_CMD_STOP 2
39#define AICA_CMD_VOL 3
40
41/* Sound modes */
42#define SM_8BIT 1
43#define SM_16BIT 0
44#define SM_ADPCM 2
45
46/* Buffer and period size */
47#define AICA_BUFFER_SIZE 0x8000
48#define AICA_PERIOD_SIZE 0x800
49#define AICA_PERIOD_NUMBER 16
50
51#define AICA_CHANNEL0_OFFSET 0x11000
52#define AICA_CHANNEL1_OFFSET 0x21000
53#define CHANNEL_OFFSET 0x10000
54
55#define AICA_DMA_CHANNEL 0
56#define AICA_DMA_MODE 5
57
58#define SND_AICA_DRIVER "AICA"
59
60struct aica_channel {
61 uint32_t cmd; /* Command ID */
62 uint32_t pos; /* Sample position */
63 uint32_t length; /* Sample length */
64 uint32_t freq; /* Frequency */
65 uint32_t vol; /* Volume 0-255 */
66 uint32_t pan; /* Pan 0-255 */
67 uint32_t sfmt; /* Sound format */
68 uint32_t flags; /* Bit flags */
69};
70
71struct snd_card_aica {
72 struct work_struct spu_dma_work;
73 struct snd_card *card;
74 struct aica_channel *channel;
75 struct snd_pcm_substream *substream;
76 int clicks;
77 int current_period;
78 struct timer_list timer;
79 int master_volume;
80 int dma_check;
81};
diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig
index 10cffc087181..97b255233175 100644
--- a/sound/soc/Kconfig
+++ b/sound/soc/Kconfig
@@ -27,6 +27,7 @@ config SND_SOC
27source "sound/soc/at91/Kconfig" 27source "sound/soc/at91/Kconfig"
28source "sound/soc/pxa/Kconfig" 28source "sound/soc/pxa/Kconfig"
29source "sound/soc/s3c24xx/Kconfig" 29source "sound/soc/s3c24xx/Kconfig"
30source "sound/soc/sh/Kconfig"
30 31
31# Supported codecs 32# Supported codecs
32source "sound/soc/codecs/Kconfig" 33source "sound/soc/codecs/Kconfig"
diff --git a/sound/soc/Makefile b/sound/soc/Makefile
index 0ae2e49036f9..304140377632 100644
--- a/sound/soc/Makefile
+++ b/sound/soc/Makefile
@@ -1,4 +1,4 @@
1snd-soc-core-objs := soc-core.o soc-dapm.o 1snd-soc-core-objs := soc-core.o soc-dapm.o
2 2
3obj-$(CONFIG_SND_SOC) += snd-soc-core.o 3obj-$(CONFIG_SND_SOC) += snd-soc-core.o
4obj-$(CONFIG_SND_SOC) += codecs/ at91/ pxa/ s3c24xx/ 4obj-$(CONFIG_SND_SOC) += codecs/ at91/ pxa/ s3c24xx/ sh/
diff --git a/sound/soc/s3c24xx/Kconfig b/sound/soc/s3c24xx/Kconfig
index 044a3712077a..e97c68306a9a 100644
--- a/sound/soc/s3c24xx/Kconfig
+++ b/sound/soc/s3c24xx/Kconfig
@@ -1,6 +1,7 @@
1config SND_S3C24XX_SOC 1config SND_S3C24XX_SOC
2 tristate "SoC Audio for the Samsung S3C24XX chips" 2 tristate "SoC Audio for the Samsung S3C24XX chips"
3 depends on ARCH_S3C2410 && SND_SOC 3 depends on ARCH_S3C2410 && SND_SOC
4 select SND_PCM
4 help 5 help
5 Say Y or M if you want to add support for codecs attached to 6 Say Y or M if you want to add support for codecs attached to
6 the S3C24XX AC97, I2S or SSP interface. You will also need 7 the S3C24XX AC97, I2S or SSP interface. You will also need
@@ -8,3 +9,29 @@ config SND_S3C24XX_SOC
8 9
9config SND_S3C24XX_SOC_I2S 10config SND_S3C24XX_SOC_I2S
10 tristate 11 tristate
12
13config SND_S3C2443_SOC_AC97
14 tristate
15 select AC97_BUS
16 select SND_AC97_CODEC
17 select SND_SOC_AC97_BUS
18
19config SND_S3C24XX_SOC_NEO1973_WM8753
20 tristate "SoC I2S Audio support for NEO1973 - WM8753"
21 depends on SND_S3C24XX_SOC && MACH_GTA01
22 select SND_S3C24XX_SOC_I2S
23 select SND_SOC_WM8753
24 help
25 Say Y if you want to add support for SoC audio on smdk2440
26 with the WM8753.
27
28config SND_S3C24XX_SOC_SMDK2443_WM9710
29 tristate "SoC AC97 Audio support for SMDK2443 - WM9710"
30 depends on SND_S3C24XX_SOC && MACH_SMDK2443
31 select SND_S3C2443_SOC_AC97
32 select SND_SOC_AC97_CODEC
33 help
34 Say Y if you want to add support for SoC audio on smdk2443
35 with the WM9710.
36
37
diff --git a/sound/soc/s3c24xx/Makefile b/sound/soc/s3c24xx/Makefile
index 6f0fffcb30f5..13c92f0fa1e4 100644
--- a/sound/soc/s3c24xx/Makefile
+++ b/sound/soc/s3c24xx/Makefile
@@ -1,6 +1,15 @@
1# S3c24XX Platform Support 1# S3c24XX Platform Support
2snd-soc-s3c24xx-objs := s3c24xx-pcm.o 2snd-soc-s3c24xx-objs := s3c24xx-pcm.o
3snd-soc-s3c24xx-i2s-objs := s3c24xx-i2s.o 3snd-soc-s3c24xx-i2s-objs := s3c24xx-i2s.o
4snd-soc-s3c2443-ac97-objs := s3c2443-ac97.o
4 5
5obj-$(CONFIG_SND_S3C24XX_SOC) += snd-soc-s3c24xx.o 6obj-$(CONFIG_SND_S3C24XX_SOC) += snd-soc-s3c24xx.o
6obj-$(CONFIG_SND_S3C24XX_SOC_I2S) += snd-soc-s3c24xx-i2s.o 7obj-$(CONFIG_SND_S3C24XX_SOC_I2S) += snd-soc-s3c24xx-i2s.o
8obj-$(CONFIG_SND_S3C2443_SOC_AC97) += snd-soc-s3c2443-ac97.o
9
10# S3C24XX Machine Support
11snd-soc-neo1973-wm8753-objs := neo1973_wm8753.o
12snd-soc-smdk2443-wm9710-objs := smdk2443_wm9710.o
13
14obj-$(CONFIG_SND_S3C24XX_SOC_NEO1973_WM8753) += snd-soc-neo1973-wm8753.o
15obj-$(CONFIG_SND_S3C24XX_SOC_SMDK2443_WM9710) += snd-soc-smdk2443-wm9710.o
diff --git a/sound/soc/s3c24xx/lm4857.h b/sound/soc/s3c24xx/lm4857.h
new file mode 100644
index 000000000000..0cf5b7011d6f
--- /dev/null
+++ b/sound/soc/s3c24xx/lm4857.h
@@ -0,0 +1,32 @@
1/*
2 * lm4857.h -- ALSA Soc Audio Layer
3 *
4 * Copyright 2007 Wolfson Microelectronics PLC.
5 * Author: Graeme Gregory
6 * graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 *
13 * Revision history
14 * 18th Jun 2007 Initial version.
15 */
16
17#ifndef LM4857_H_
18#define LM4857_H_
19
20/* The register offsets in the cache array */
21#define LM4857_MVOL 0
22#define LM4857_LVOL 1
23#define LM4857_RVOL 2
24#define LM4857_CTRL 3
25
26/* the shifts required to set these bits */
27#define LM4857_3D 5
28#define LM4857_WAKEUP 5
29#define LM4857_EPGAIN 4
30
31#endif /*LM4857_H_*/
32
diff --git a/sound/soc/s3c24xx/neo1973_wm8753.c b/sound/soc/s3c24xx/neo1973_wm8753.c
new file mode 100644
index 000000000000..d5a8fc2cf8d6
--- /dev/null
+++ b/sound/soc/s3c24xx/neo1973_wm8753.c
@@ -0,0 +1,670 @@
1/*
2 * neo1973_wm8753.c -- SoC audio for Neo1973
3 *
4 * Copyright 2007 Wolfson Microelectronics PLC.
5 * Author: Graeme Gregory
6 * graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 *
13 * Revision history
14 * 20th Jan 2007 Initial version.
15 * 05th Feb 2007 Rename all to Neo1973
16 *
17 */
18
19#include <linux/module.h>
20#include <linux/moduleparam.h>
21#include <linux/timer.h>
22#include <linux/interrupt.h>
23#include <linux/platform_device.h>
24#include <linux/i2c.h>
25#include <sound/driver.h>
26#include <sound/core.h>
27#include <sound/pcm.h>
28#include <sound/soc.h>
29#include <sound/soc-dapm.h>
30
31#include <asm/mach-types.h>
32#include <asm/hardware/scoop.h>
33#include <asm/arch/regs-iis.h>
34#include <asm/arch/regs-clock.h>
35#include <asm/arch/regs-gpio.h>
36#include <asm/hardware.h>
37#include <asm/arch/audio.h>
38#include <asm/io.h>
39#include <asm/arch/spi-gpio.h>
40#include "../codecs/wm8753.h"
41#include "lm4857.h"
42#include "s3c24xx-pcm.h"
43#include "s3c24xx-i2s.h"
44
45/* define the scenarios */
46#define NEO_AUDIO_OFF 0
47#define NEO_GSM_CALL_AUDIO_HANDSET 1
48#define NEO_GSM_CALL_AUDIO_HEADSET 2
49#define NEO_GSM_CALL_AUDIO_BLUETOOTH 3
50#define NEO_STEREO_TO_SPEAKERS 4
51#define NEO_STEREO_TO_HEADPHONES 5
52#define NEO_CAPTURE_HANDSET 6
53#define NEO_CAPTURE_HEADSET 7
54#define NEO_CAPTURE_BLUETOOTH 8
55
56static struct snd_soc_machine neo1973;
57static struct i2c_client *i2c;
58
59static int neo1973_hifi_hw_params(struct snd_pcm_substream *substream,
60 struct snd_pcm_hw_params *params)
61{
62 struct snd_soc_pcm_runtime *rtd = substream->private_data;
63 struct snd_soc_codec_dai *codec_dai = rtd->dai->codec_dai;
64 struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai;
65 unsigned int pll_out = 0, bclk = 0;
66 int ret = 0;
67 unsigned long iis_clkrate;
68
69 iis_clkrate = s3c24xx_i2s_get_clockrate();
70
71 switch (params_rate(params)) {
72 case 8000:
73 case 16000:
74 pll_out = 12288000;
75 break;
76 case 48000:
77 bclk = WM8753_BCLK_DIV_4;
78 pll_out = 12288000;
79 break;
80 case 96000:
81 bclk = WM8753_BCLK_DIV_2;
82 pll_out = 12288000;
83 break;
84 case 11025:
85 bclk = WM8753_BCLK_DIV_16;
86 pll_out = 11289600;
87 break;
88 case 22050:
89 bclk = WM8753_BCLK_DIV_8;
90 pll_out = 11289600;
91 break;
92 case 44100:
93 bclk = WM8753_BCLK_DIV_4;
94 pll_out = 11289600;
95 break;
96 case 88200:
97 bclk = WM8753_BCLK_DIV_2;
98 pll_out = 11289600;
99 break;
100 }
101
102 /* set codec DAI configuration */
103 ret = codec_dai->dai_ops.set_fmt(codec_dai,
104 SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
105 SND_SOC_DAIFMT_CBM_CFM);
106 if (ret < 0)
107 return ret;
108
109 /* set cpu DAI configuration */
110 ret = cpu_dai->dai_ops.set_fmt(cpu_dai,
111 SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
112 SND_SOC_DAIFMT_CBM_CFM);
113 if (ret < 0)
114 return ret;
115
116 /* set the codec system clock for DAC and ADC */
117 ret = codec_dai->dai_ops.set_sysclk(codec_dai, WM8753_MCLK, pll_out,
118 SND_SOC_CLOCK_IN);
119 if (ret < 0)
120 return ret;
121
122 /* set MCLK division for sample rate */
123 ret = cpu_dai->dai_ops.set_clkdiv(cpu_dai, S3C24XX_DIV_MCLK,
124 S3C2410_IISMOD_32FS );
125 if (ret < 0)
126 return ret;
127
128 /* set codec BCLK division for sample rate */
129 ret = codec_dai->dai_ops.set_clkdiv(codec_dai, WM8753_BCLKDIV, bclk);
130 if (ret < 0)
131 return ret;
132
133 /* set prescaler division for sample rate */
134 ret = cpu_dai->dai_ops.set_clkdiv(cpu_dai, S3C24XX_DIV_PRESCALER,
135 S3C24XX_PRESCALE(4,4));
136 if (ret < 0)
137 return ret;
138
139 /* codec PLL input is PCLK/4 */
140 ret = codec_dai->dai_ops.set_pll(codec_dai, WM8753_PLL1,
141 iis_clkrate / 4, pll_out);
142 if (ret < 0)
143 return ret;
144
145 return 0;
146}
147
148static int neo1973_hifi_hw_free(struct snd_pcm_substream *substream)
149{
150 struct snd_soc_pcm_runtime *rtd = substream->private_data;
151 struct snd_soc_codec_dai *codec_dai = rtd->dai->codec_dai;
152
153 /* disable the PLL */
154 return codec_dai->dai_ops.set_pll(codec_dai, WM8753_PLL1, 0, 0);
155}
156
157/*
158 * Neo1973 WM8753 HiFi DAI opserations.
159 */
160static struct snd_soc_ops neo1973_hifi_ops = {
161 .hw_params = neo1973_hifi_hw_params,
162 .hw_free = neo1973_hifi_hw_free,
163};
164
165static int neo1973_voice_hw_params(struct snd_pcm_substream *substream,
166 struct snd_pcm_hw_params *params)
167{
168 struct snd_soc_pcm_runtime *rtd = substream->private_data;
169 struct snd_soc_codec_dai *codec_dai = rtd->dai->codec_dai;
170 unsigned int pcmdiv = 0;
171 int ret = 0;
172 unsigned long iis_clkrate;
173
174 iis_clkrate = s3c24xx_i2s_get_clockrate();
175
176 if (params_rate(params) != 8000)
177 return -EINVAL;
178 if (params_channels(params) != 1)
179 return -EINVAL;
180
181 pcmdiv = WM8753_PCM_DIV_6; /* 2.048 MHz */
182
183 /* todo: gg check mode (DSP_B) against CSR datasheet */
184 /* set codec DAI configuration */
185 ret = codec_dai->dai_ops.set_fmt(codec_dai, SND_SOC_DAIFMT_DSP_B |
186 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
187 if (ret < 0)
188 return ret;
189
190 /* set the codec system clock for DAC and ADC */
191 ret = codec_dai->dai_ops.set_sysclk(codec_dai, WM8753_PCMCLK, 12288000,
192 SND_SOC_CLOCK_IN);
193 if (ret < 0)
194 return ret;
195
196 /* set codec PCM division for sample rate */
197 ret = codec_dai->dai_ops.set_clkdiv(codec_dai, WM8753_PCMDIV, pcmdiv);
198 if (ret < 0)
199 return ret;
200
201 /* configue and enable PLL for 12.288MHz output */
202 ret = codec_dai->dai_ops.set_pll(codec_dai, WM8753_PLL2,
203 iis_clkrate / 4, 12288000);
204 if (ret < 0)
205 return ret;
206
207 return 0;
208}
209
210static int neo1973_voice_hw_free(struct snd_pcm_substream *substream)
211{
212 struct snd_soc_pcm_runtime *rtd = substream->private_data;
213 struct snd_soc_codec_dai *codec_dai = rtd->dai->codec_dai;
214
215 /* disable the PLL */
216 return codec_dai->dai_ops.set_pll(codec_dai, WM8753_PLL2, 0, 0);
217}
218
219static struct snd_soc_ops neo1973_voice_ops = {
220 .hw_params = neo1973_voice_hw_params,
221 .hw_free = neo1973_voice_hw_free,
222};
223
224static int neo1973_scenario = 0;
225
226static int neo1973_get_scenario(struct snd_kcontrol *kcontrol,
227 struct snd_ctl_elem_value *ucontrol)
228{
229 ucontrol->value.integer.value[0] = neo1973_scenario;
230 return 0;
231}
232
233static int set_scenario_endpoints(struct snd_soc_codec *codec, int scenario)
234{
235 switch(neo1973_scenario) {
236 case NEO_AUDIO_OFF:
237 snd_soc_dapm_set_endpoint(codec, "Audio Out", 0);
238 snd_soc_dapm_set_endpoint(codec, "GSM Line Out", 0);
239 snd_soc_dapm_set_endpoint(codec, "GSM Line In", 0);
240 snd_soc_dapm_set_endpoint(codec, "Headset Mic", 0);
241 snd_soc_dapm_set_endpoint(codec, "Call Mic", 0);
242 break;
243 case NEO_GSM_CALL_AUDIO_HANDSET:
244 snd_soc_dapm_set_endpoint(codec, "Audio Out", 1);
245 snd_soc_dapm_set_endpoint(codec, "GSM Line Out", 1);
246 snd_soc_dapm_set_endpoint(codec, "GSM Line In", 1);
247 snd_soc_dapm_set_endpoint(codec, "Headset Mic", 0);
248 snd_soc_dapm_set_endpoint(codec, "Call Mic", 1);
249 break;
250 case NEO_GSM_CALL_AUDIO_HEADSET:
251 snd_soc_dapm_set_endpoint(codec, "Audio Out", 1);
252 snd_soc_dapm_set_endpoint(codec, "GSM Line Out", 1);
253 snd_soc_dapm_set_endpoint(codec, "GSM Line In", 1);
254 snd_soc_dapm_set_endpoint(codec, "Headset Mic", 1);
255 snd_soc_dapm_set_endpoint(codec, "Call Mic", 0);
256 break;
257 case NEO_GSM_CALL_AUDIO_BLUETOOTH:
258 snd_soc_dapm_set_endpoint(codec, "Audio Out", 0);
259 snd_soc_dapm_set_endpoint(codec, "GSM Line Out", 1);
260 snd_soc_dapm_set_endpoint(codec, "GSM Line In", 1);
261 snd_soc_dapm_set_endpoint(codec, "Headset Mic", 0);
262 snd_soc_dapm_set_endpoint(codec, "Call Mic", 0);
263 break;
264 case NEO_STEREO_TO_SPEAKERS:
265 snd_soc_dapm_set_endpoint(codec, "Audio Out", 1);
266 snd_soc_dapm_set_endpoint(codec, "GSM Line Out", 0);
267 snd_soc_dapm_set_endpoint(codec, "GSM Line In", 0);
268 snd_soc_dapm_set_endpoint(codec, "Headset Mic", 0);
269 snd_soc_dapm_set_endpoint(codec, "Call Mic", 0);
270 break;
271 case NEO_STEREO_TO_HEADPHONES:
272 snd_soc_dapm_set_endpoint(codec, "Audio Out", 1);
273 snd_soc_dapm_set_endpoint(codec, "GSM Line Out", 0);
274 snd_soc_dapm_set_endpoint(codec, "GSM Line In", 0);
275 snd_soc_dapm_set_endpoint(codec, "Headset Mic", 0);
276 snd_soc_dapm_set_endpoint(codec, "Call Mic", 0);
277 break;
278 case NEO_CAPTURE_HANDSET:
279 snd_soc_dapm_set_endpoint(codec, "Audio Out", 0);
280 snd_soc_dapm_set_endpoint(codec, "GSM Line Out", 0);
281 snd_soc_dapm_set_endpoint(codec, "GSM Line In", 0);
282 snd_soc_dapm_set_endpoint(codec, "Headset Mic", 0);
283 snd_soc_dapm_set_endpoint(codec, "Call Mic", 1);
284 break;
285 case NEO_CAPTURE_HEADSET:
286 snd_soc_dapm_set_endpoint(codec, "Audio Out", 0);
287 snd_soc_dapm_set_endpoint(codec, "GSM Line Out", 0);
288 snd_soc_dapm_set_endpoint(codec, "GSM Line In", 0);
289 snd_soc_dapm_set_endpoint(codec, "Headset Mic", 1);
290 snd_soc_dapm_set_endpoint(codec, "Call Mic", 0);
291 break;
292 case NEO_CAPTURE_BLUETOOTH:
293 snd_soc_dapm_set_endpoint(codec, "Audio Out", 0);
294 snd_soc_dapm_set_endpoint(codec, "GSM Line Out", 0);
295 snd_soc_dapm_set_endpoint(codec, "GSM Line In", 0);
296 snd_soc_dapm_set_endpoint(codec, "Headset Mic", 0);
297 snd_soc_dapm_set_endpoint(codec, "Call Mic", 0);
298 break;
299 default:
300 snd_soc_dapm_set_endpoint(codec, "Audio Out", 0);
301 snd_soc_dapm_set_endpoint(codec, "GSM Line Out", 0);
302 snd_soc_dapm_set_endpoint(codec, "GSM Line In", 0);
303 snd_soc_dapm_set_endpoint(codec, "Headset Mic", 0);
304 snd_soc_dapm_set_endpoint(codec, "Call Mic", 0);
305 }
306
307 snd_soc_dapm_sync_endpoints(codec);
308
309 return 0;
310}
311
312static int neo1973_set_scenario(struct snd_kcontrol *kcontrol,
313 struct snd_ctl_elem_value *ucontrol)
314{
315 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
316
317 if (neo1973_scenario == ucontrol->value.integer.value[0])
318 return 0;
319
320 neo1973_scenario = ucontrol->value.integer.value[0];
321 set_scenario_endpoints(codec, neo1973_scenario);
322 return 1;
323}
324
325static u8 lm4857_regs[4] = {0x00, 0x40, 0x80, 0xC0};
326
327static void lm4857_write_regs(void)
328{
329 if (i2c_master_send(i2c, lm4857_regs, 4) != 4)
330 printk(KERN_ERR "lm4857: i2c write failed\n");
331}
332
333static int lm4857_get_reg(struct snd_kcontrol *kcontrol,
334 struct snd_ctl_elem_value *ucontrol)
335{
336 int reg=kcontrol->private_value & 0xFF;
337 int shift = (kcontrol->private_value >> 8) & 0x0F;
338 int mask = (kcontrol->private_value >> 16) & 0xFF;
339
340 ucontrol->value.integer.value[0] = (lm4857_regs[reg] >> shift) & mask;
341 return 0;
342}
343
344static int lm4857_set_reg(struct snd_kcontrol *kcontrol,
345 struct snd_ctl_elem_value *ucontrol)
346{
347 int reg = kcontrol->private_value & 0xFF;
348 int shift = (kcontrol->private_value >> 8) & 0x0F;
349 int mask = (kcontrol->private_value >> 16) & 0xFF;
350
351 if (((lm4857_regs[reg] >> shift ) & mask) ==
352 ucontrol->value.integer.value[0])
353 return 0;
354
355 lm4857_regs[reg] &= ~ (mask << shift);
356 lm4857_regs[reg] |= ucontrol->value.integer.value[0] << shift;
357 lm4857_write_regs();
358 return 1;
359}
360
361static int lm4857_get_mode(struct snd_kcontrol *kcontrol,
362 struct snd_ctl_elem_value *ucontrol)
363{
364 u8 value = lm4857_regs[LM4857_CTRL] & 0x0F;
365
366 if (value)
367 value -= 5;
368
369 ucontrol->value.integer.value[0] = value;
370 return 0;
371}
372
373static int lm4857_set_mode(struct snd_kcontrol *kcontrol,
374 struct snd_ctl_elem_value *ucontrol)
375{
376 u8 value = ucontrol->value.integer.value[0];
377
378 if (value)
379 value += 5;
380
381 if ((lm4857_regs[LM4857_CTRL] & 0x0F) == value)
382 return 0;
383
384 lm4857_regs[LM4857_CTRL] &= 0xF0;
385 lm4857_regs[LM4857_CTRL] |= value;
386 lm4857_write_regs();
387 return 1;
388}
389
390static const struct snd_soc_dapm_widget wm8753_dapm_widgets[] = {
391 SND_SOC_DAPM_LINE("Audio Out", NULL),
392 SND_SOC_DAPM_LINE("GSM Line Out", NULL),
393 SND_SOC_DAPM_LINE("GSM Line In", NULL),
394 SND_SOC_DAPM_MIC("Headset Mic", NULL),
395 SND_SOC_DAPM_MIC("Call Mic", NULL),
396};
397
398
399/* example machine audio_mapnections */
400static const char* audio_map[][3] = {
401
402 /* Connections to the lm4857 amp */
403 {"Audio Out", NULL, "LOUT1"},
404 {"Audio Out", NULL, "ROUT1"},
405
406 /* Connections to the GSM Module */
407 {"GSM Line Out", NULL, "MONO1"},
408 {"GSM Line Out", NULL, "MONO2"},
409 {"RXP", NULL, "GSM Line In"},
410 {"RXN", NULL, "GSM Line In"},
411
412 /* Connections to Headset */
413 {"MIC1", NULL, "Mic Bias"},
414 {"Mic Bias", NULL, "Headset Mic"},
415
416 /* Call Mic */
417 {"MIC2", NULL, "Mic Bias"},
418 {"MIC2N", NULL, "Mic Bias"},
419 {"Mic Bias", NULL, "Call Mic"},
420
421 /* Connect the ALC pins */
422 {"ACIN", NULL, "ACOP"},
423
424 {NULL, NULL, NULL},
425};
426
427static const char *lm4857_mode[] = {
428 "Off",
429 "Call Speaker",
430 "Stereo Speakers",
431 "Stereo Speakers + Headphones",
432 "Headphones"
433};
434
435static const struct soc_enum lm4857_mode_enum[] = {
436 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(lm4857_mode), lm4857_mode),
437};
438
439static const char *neo_scenarios[] = {
440 "Off",
441 "GSM Handset",
442 "GSM Headset",
443 "GSM Bluetooth",
444 "Speakers",
445 "Headphones",
446 "Capture Handset",
447 "Capture Headset",
448 "Capture Bluetooth"
449};
450
451static const struct soc_enum neo_scenario_enum[] = {
452 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(neo_scenarios),neo_scenarios),
453};
454
455static const struct snd_kcontrol_new wm8753_neo1973_controls[] = {
456 SOC_SINGLE_EXT("Amp Left Playback Volume", LM4857_LVOL, 0, 31, 0,
457 lm4857_get_reg, lm4857_set_reg),
458 SOC_SINGLE_EXT("Amp Right Playback Volume", LM4857_RVOL, 0, 31, 0,
459 lm4857_get_reg, lm4857_set_reg),
460 SOC_SINGLE_EXT("Amp Mono Playback Volume", LM4857_MVOL, 0, 31, 0,
461 lm4857_get_reg, lm4857_set_reg),
462 SOC_ENUM_EXT("Amp Mode", lm4857_mode_enum[0],
463 lm4857_get_mode, lm4857_set_mode),
464 SOC_ENUM_EXT("Neo Mode", neo_scenario_enum[0],
465 neo1973_get_scenario, neo1973_set_scenario),
466 SOC_SINGLE_EXT("Amp Spk 3D Playback Switch", LM4857_LVOL, 5, 1, 0,
467 lm4857_get_reg, lm4857_set_reg),
468 SOC_SINGLE_EXT("Amp HP 3d Playback Switch", LM4857_RVOL, 5, 1, 0,
469 lm4857_get_reg, lm4857_set_reg),
470 SOC_SINGLE_EXT("Amp Fast Wakeup Playback Switch", LM4857_CTRL, 5, 1, 0,
471 lm4857_get_reg, lm4857_set_reg),
472 SOC_SINGLE_EXT("Amp Earpiece 6dB Playback Switch", LM4857_CTRL, 4, 1, 0,
473 lm4857_get_reg, lm4857_set_reg),
474};
475
476/*
477 * This is an example machine initialisation for a wm8753 connected to a
478 * neo1973 II. It is missing logic to detect hp/mic insertions and logic
479 * to re-route the audio in such an event.
480 */
481static int neo1973_wm8753_init(struct snd_soc_codec *codec)
482{
483 int i, err;
484
485 /* set up NC codec pins */
486 snd_soc_dapm_set_endpoint(codec, "LOUT2", 0);
487 snd_soc_dapm_set_endpoint(codec, "ROUT2", 0);
488 snd_soc_dapm_set_endpoint(codec, "OUT3", 0);
489 snd_soc_dapm_set_endpoint(codec, "OUT4", 0);
490 snd_soc_dapm_set_endpoint(codec, "LINE1", 0);
491 snd_soc_dapm_set_endpoint(codec, "LINE2", 0);
492
493
494 /* set endpoints to default mode */
495 set_scenario_endpoints(codec, NEO_AUDIO_OFF);
496
497 /* Add neo1973 specific widgets */
498 for (i = 0; i < ARRAY_SIZE(wm8753_dapm_widgets); i++)
499 snd_soc_dapm_new_control(codec, &wm8753_dapm_widgets[i]);
500
501 /* add neo1973 specific controls */
502 for (i = 0; i < ARRAY_SIZE(wm8753_neo1973_controls); i++) {
503 err = snd_ctl_add(codec->card,
504 snd_soc_cnew(&wm8753_neo1973_controls[i],
505 codec, NULL));
506 if (err < 0)
507 return err;
508 }
509
510 /* set up neo1973 specific audio path audio_mapnects */
511 for (i = 0; audio_map[i][0] != NULL; i++) {
512 snd_soc_dapm_connect_input(codec, audio_map[i][0],
513 audio_map[i][1], audio_map[i][2]);
514 }
515
516 snd_soc_dapm_sync_endpoints(codec);
517 return 0;
518}
519
520/*
521 * BT Codec DAI
522 */
523static struct snd_soc_cpu_dai bt_dai =
524{ .name = "Bluetooth",
525 .id = 0,
526 .type = SND_SOC_DAI_PCM,
527 .playback = {
528 .channels_min = 1,
529 .channels_max = 1,
530 .rates = SNDRV_PCM_RATE_8000,
531 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
532 .capture = {
533 .channels_min = 1,
534 .channels_max = 1,
535 .rates = SNDRV_PCM_RATE_8000,
536 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
537};
538
539static struct snd_soc_dai_link neo1973_dai[] = {
540{ /* Hifi Playback - for similatious use with voice below */
541 .name = "WM8753",
542 .stream_name = "WM8753 HiFi",
543 .cpu_dai = &s3c24xx_i2s_dai,
544 .codec_dai = &wm8753_dai[WM8753_DAI_HIFI],
545 .init = neo1973_wm8753_init,
546 .ops = &neo1973_hifi_ops,
547},
548{ /* Voice via BT */
549 .name = "Bluetooth",
550 .stream_name = "Voice",
551 .cpu_dai = &bt_dai,
552 .codec_dai = &wm8753_dai[WM8753_DAI_VOICE],
553 .ops = &neo1973_voice_ops,
554},
555};
556
557static struct snd_soc_machine neo1973 = {
558 .name = "neo1973",
559 .dai_link = neo1973_dai,
560 .num_links = ARRAY_SIZE(neo1973_dai),
561};
562
563static struct wm8753_setup_data neo1973_wm8753_setup = {
564 .i2c_address = 0x1a,
565};
566
567static struct snd_soc_device neo1973_snd_devdata = {
568 .machine = &neo1973,
569 .platform = &s3c24xx_soc_platform,
570 .codec_dev = &soc_codec_dev_wm8753,
571 .codec_data = &neo1973_wm8753_setup,
572};
573
574static struct i2c_client client_template;
575
576static unsigned short normal_i2c[] = { 0x7C, I2C_CLIENT_END };
577
578/* Magic definition of all other variables and things */
579I2C_CLIENT_INSMOD;
580
581static int lm4857_amp_probe(struct i2c_adapter *adap, int addr, int kind)
582{
583 int ret;
584
585 client_template.adapter = adap;
586 client_template.addr = addr;
587
588 i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL);
589 if (i2c == NULL)
590 return -ENOMEM;
591
592 ret = i2c_attach_client(i2c);
593 if (ret < 0) {
594 printk(KERN_ERR "LM4857 failed to attach at addr %x\n", addr);
595 goto exit_err;
596 }
597
598 lm4857_write_regs();
599 return ret;
600
601exit_err:
602 kfree(i2c);
603 return ret;
604}
605
606static int lm4857_i2c_detach(struct i2c_client *client)
607{
608 i2c_detach_client(client);
609 kfree(client);
610 return 0;
611}
612
613static int lm4857_i2c_attach(struct i2c_adapter *adap)
614{
615 return i2c_probe(adap, &addr_data, lm4857_amp_probe);
616}
617
618/* corgi i2c codec control layer */
619static struct i2c_driver lm4857_i2c_driver = {
620 .driver = {
621 .name = "LM4857 I2C Amp",
622 .owner = THIS_MODULE,
623 },
624 .id = I2C_DRIVERID_LM4857,
625 .attach_adapter = lm4857_i2c_attach,
626 .detach_client = lm4857_i2c_detach,
627 .command = NULL,
628};
629
630static struct i2c_client client_template = {
631 .name = "LM4857",
632 .driver = &lm4857_i2c_driver,
633};
634
635static struct platform_device *neo1973_snd_device;
636
637static int __init neo1973_init(void)
638{
639 int ret;
640
641 neo1973_snd_device = platform_device_alloc("soc-audio", -1);
642 if (!neo1973_snd_device)
643 return -ENOMEM;
644
645 platform_set_drvdata(neo1973_snd_device, &neo1973_snd_devdata);
646 neo1973_snd_devdata.dev = &neo1973_snd_device->dev;
647 ret = platform_device_add(neo1973_snd_device);
648
649 if (ret)
650 platform_device_put(neo1973_snd_device);
651
652 ret = i2c_add_driver(&lm4857_i2c_driver);
653 if (ret != 0)
654 printk(KERN_ERR "can't add i2c driver");
655
656 return ret;
657}
658
659static void __exit neo1973_exit(void)
660{
661 platform_device_unregister(neo1973_snd_device);
662}
663
664module_init(neo1973_init);
665module_exit(neo1973_exit);
666
667/* Module information */
668MODULE_AUTHOR("Graeme Gregory, graeme.gregory@wolfsonmicro.com, www.wolfsonmicro.com");
669MODULE_DESCRIPTION("ALSA SoC WM8753 Neo1973");
670MODULE_LICENSE("GPL");
diff --git a/sound/soc/s3c24xx/s3c2443-ac97.c b/sound/soc/s3c24xx/s3c2443-ac97.c
new file mode 100644
index 000000000000..75acf7ef5528
--- /dev/null
+++ b/sound/soc/s3c24xx/s3c2443-ac97.c
@@ -0,0 +1,401 @@
1/*
2 * s3c2443-ac97.c -- ALSA Soc Audio Layer
3 *
4 * (c) 2007 Wolfson Microelectronics PLC.
5 * Graeme Gregory graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com
6 *
7 * Copyright (C) 2005, Sean Choi <sh428.choi@samsung.com>
8 * All rights reserved.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 *
14 * Revision history
15 * 21st Mar 2007 Initial Version
16 */
17
18#include <linux/init.h>
19#include <linux/module.h>
20#include <linux/platform_device.h>
21#include <linux/interrupt.h>
22#include <linux/wait.h>
23#include <linux/delay.h>
24#include <linux/clk.h>
25
26#include <sound/driver.h>
27#include <sound/core.h>
28#include <sound/pcm.h>
29#include <sound/ac97_codec.h>
30#include <sound/initval.h>
31#include <sound/soc.h>
32
33#include <asm/hardware.h>
34#include <asm/io.h>
35#include <asm/arch/regs-ac97.h>
36#include <asm/arch/regs-gpio.h>
37#include <asm/arch/regs-clock.h>
38#include <asm/arch/audio.h>
39#include <asm/dma.h>
40#include <asm/arch/dma.h>
41
42#include "s3c24xx-pcm.h"
43#include "s3c24xx-ac97.h"
44
45struct s3c24xx_ac97_info {
46 void __iomem *regs;
47 struct clk *ac97_clk;
48};
49static struct s3c24xx_ac97_info s3c24xx_ac97;
50
51DECLARE_COMPLETION(ac97_completion);
52static u32 codec_ready;
53static DECLARE_MUTEX(ac97_mutex);
54
55static unsigned short s3c2443_ac97_read(struct snd_ac97 *ac97,
56 unsigned short reg)
57{
58 u32 ac_glbctrl;
59 u32 ac_codec_cmd;
60 u32 stat, addr, data;
61
62 down(&ac97_mutex);
63
64 codec_ready = S3C_AC97_GLBSTAT_CODECREADY;
65 ac_codec_cmd = readl(s3c24xx_ac97.regs + S3C_AC97_CODEC_CMD);
66 ac_codec_cmd = S3C_AC97_CODEC_CMD_READ | AC_CMD_ADDR(reg);
67 writel(ac_codec_cmd, s3c24xx_ac97.regs + S3C_AC97_CODEC_CMD);
68
69 udelay(50);
70
71 ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
72 ac_glbctrl |= S3C_AC97_GLBCTRL_CODECREADYIE;
73 writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
74
75 wait_for_completion(&ac97_completion);
76
77 stat = readl(s3c24xx_ac97.regs + S3C_AC97_STAT);
78 addr = (stat >> 16) & 0x7f;
79 data = (stat & 0xffff);
80
81 if (addr != reg)
82 printk(KERN_ERR "s3c24xx-ac97: req addr = %02x,"
83 " rep addr = %02x\n", reg, addr);
84
85 up(&ac97_mutex);
86
87 return (unsigned short)data;
88}
89
90static void s3c2443_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
91 unsigned short val)
92{
93 u32 ac_glbctrl;
94 u32 ac_codec_cmd;
95
96 down(&ac97_mutex);
97
98 codec_ready = S3C_AC97_GLBSTAT_CODECREADY;
99 ac_codec_cmd = readl(s3c24xx_ac97.regs + S3C_AC97_CODEC_CMD);
100 ac_codec_cmd = AC_CMD_ADDR(reg) | AC_CMD_DATA(val);
101 writel(ac_codec_cmd, s3c24xx_ac97.regs + S3C_AC97_CODEC_CMD);
102
103 udelay(50);
104
105 ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
106 ac_glbctrl |= S3C_AC97_GLBCTRL_CODECREADYIE;
107 writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
108
109 wait_for_completion(&ac97_completion);
110
111 ac_codec_cmd = readl(s3c24xx_ac97.regs + S3C_AC97_CODEC_CMD);
112 ac_codec_cmd |= S3C_AC97_CODEC_CMD_READ;
113 writel(ac_codec_cmd, s3c24xx_ac97.regs + S3C_AC97_CODEC_CMD);
114
115 up(&ac97_mutex);
116
117}
118
119static void s3c2443_ac97_warm_reset(struct snd_ac97 *ac97)
120{
121 u32 ac_glbctrl;
122
123 ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
124 ac_glbctrl = S3C_AC97_GLBCTRL_WARMRESET;
125 writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
126 msleep(1);
127
128 ac_glbctrl = 0;
129 writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
130 msleep(1);
131}
132
133static void s3c2443_ac97_cold_reset(struct snd_ac97 *ac97)
134{
135 u32 ac_glbctrl;
136
137 ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
138 ac_glbctrl = S3C_AC97_GLBCTRL_COLDRESET;
139 writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
140 msleep(1);
141
142 ac_glbctrl = 0;
143 writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
144 msleep(1);
145
146 ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
147 ac_glbctrl = S3C_AC97_GLBCTRL_ACLINKON;
148 writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
149 msleep(1);
150
151 ac_glbctrl |= S3C_AC97_GLBCTRL_TRANSFERDATAENABLE;
152 writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
153 msleep(1);
154
155 ac_glbctrl |= S3C_AC97_GLBCTRL_PCMOUTTM_DMA |
156 S3C_AC97_GLBCTRL_PCMINTM_DMA | S3C_AC97_GLBCTRL_MICINTM_DMA;
157 writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
158}
159
160static irqreturn_t s3c2443_ac97_irq(int irq, void *dev_id)
161{
162 int status;
163 u32 ac_glbctrl;
164
165 status = readl(s3c24xx_ac97.regs + S3C_AC97_GLBSTAT) & codec_ready;
166
167 if (status) {
168 ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
169 ac_glbctrl &= ~S3C_AC97_GLBCTRL_CODECREADYIE;
170 writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
171 complete(&ac97_completion);
172 }
173 return IRQ_HANDLED;
174}
175
176struct snd_ac97_bus_ops soc_ac97_ops = {
177 .read = s3c2443_ac97_read,
178 .write = s3c2443_ac97_write,
179 .warm_reset = s3c2443_ac97_warm_reset,
180 .reset = s3c2443_ac97_cold_reset,
181};
182
183static struct s3c2410_dma_client s3c2443_dma_client_out = {
184 .name = "AC97 PCM Stereo out"
185};
186
187static struct s3c2410_dma_client s3c2443_dma_client_in = {
188 .name = "AC97 PCM Stereo in"
189};
190
191static struct s3c2410_dma_client s3c2443_dma_client_micin = {
192 .name = "AC97 Mic Mono in"
193};
194
195static struct s3c24xx_pcm_dma_params s3c2443_ac97_pcm_stereo_out = {
196 .client = &s3c2443_dma_client_out,
197 .channel = DMACH_PCM_OUT,
198 .dma_addr = S3C2440_PA_AC97 + S3C_AC97_PCM_DATA,
199 .dma_size = 4,
200};
201
202static struct s3c24xx_pcm_dma_params s3c2443_ac97_pcm_stereo_in = {
203 .client = &s3c2443_dma_client_in,
204 .channel = DMACH_PCM_IN,
205 .dma_addr = S3C2440_PA_AC97 + S3C_AC97_PCM_DATA,
206 .dma_size = 4,
207};
208
209static struct s3c24xx_pcm_dma_params s3c2443_ac97_mic_mono_in = {
210 .client = &s3c2443_dma_client_micin,
211 .channel = DMACH_MIC_IN,
212 .dma_addr = S3C2440_PA_AC97 + S3C_AC97_MIC_DATA,
213 .dma_size = 4,
214};
215
216static int s3c2443_ac97_probe(struct platform_device *pdev)
217{
218 int ret;
219 u32 ac_glbctrl;
220
221 s3c24xx_ac97.regs = ioremap(S3C2440_PA_AC97, 0x100);
222 if (s3c24xx_ac97.regs == NULL)
223 return -ENXIO;
224
225 s3c24xx_ac97.ac97_clk = clk_get(&pdev->dev, "ac97");
226 if (s3c24xx_ac97.ac97_clk == NULL) {
227 printk(KERN_ERR "s3c2443-ac97 failed to get ac97_clock\n");
228 iounmap(s3c24xx_ac97.regs);
229 return -ENODEV;
230 }
231 clk_enable(s3c24xx_ac97.ac97_clk);
232
233 s3c2410_gpio_cfgpin(S3C2410_GPE0, S3C2443_GPE0_AC_nRESET);
234 s3c2410_gpio_cfgpin(S3C2410_GPE1, S3C2443_GPE1_AC_SYNC);
235 s3c2410_gpio_cfgpin(S3C2410_GPE2, S3C2443_GPE2_AC_BITCLK);
236 s3c2410_gpio_cfgpin(S3C2410_GPE3, S3C2443_GPE3_AC_SDI);
237 s3c2410_gpio_cfgpin(S3C2410_GPE4, S3C2443_GPE4_AC_SDO);
238
239 ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
240 ac_glbctrl = S3C_AC97_GLBCTRL_COLDRESET;
241 writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
242 msleep(1);
243
244 ac_glbctrl = 0;
245 writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
246 msleep(1);
247
248 ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
249 ac_glbctrl = S3C_AC97_GLBCTRL_ACLINKON;
250 writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
251 msleep(1);
252
253 ac_glbctrl |= S3C_AC97_GLBCTRL_TRANSFERDATAENABLE;
254 writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
255
256 ret = request_irq(IRQ_S3C2443_AC97, s3c2443_ac97_irq,
257 IRQF_DISABLED, "AC97", NULL);
258 if (ret < 0) {
259 printk(KERN_ERR "s3c24xx-ac97: interrupt request failed.\n");
260 clk_disable(s3c24xx_ac97.ac97_clk);
261 clk_put(s3c24xx_ac97.ac97_clk);
262 iounmap(s3c24xx_ac97.regs);
263 }
264 return ret;
265}
266
267static void s3c2443_ac97_remove(struct platform_device *pdev)
268{
269 free_irq(IRQ_S3C2443_AC97, NULL);
270 clk_disable(s3c24xx_ac97.ac97_clk);
271 clk_put(s3c24xx_ac97.ac97_clk);
272 iounmap(s3c24xx_ac97.regs);
273}
274
275static int s3c2443_ac97_hw_params(struct snd_pcm_substream *substream,
276 struct snd_pcm_hw_params *params)
277{
278 struct snd_soc_pcm_runtime *rtd = substream->private_data;
279 struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai;
280
281 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
282 cpu_dai->dma_data = &s3c2443_ac97_pcm_stereo_out;
283 else
284 cpu_dai->dma_data = &s3c2443_ac97_pcm_stereo_in;
285
286 return 0;
287}
288
289static int s3c2443_ac97_trigger(struct snd_pcm_substream *substream, int cmd)
290{
291 u32 ac_glbctrl;
292
293 ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
294 switch(cmd) {
295 case SNDRV_PCM_TRIGGER_START:
296 case SNDRV_PCM_TRIGGER_RESUME:
297 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
298 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
299 ac_glbctrl |= S3C_AC97_GLBCTRL_PCMINTM_DMA;
300 else
301 ac_glbctrl |= S3C_AC97_GLBCTRL_PCMOUTTM_DMA;
302 break;
303 case SNDRV_PCM_TRIGGER_STOP:
304 case SNDRV_PCM_TRIGGER_SUSPEND:
305 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
306 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
307 ac_glbctrl &= ~S3C_AC97_GLBCTRL_PCMINTM_MASK;
308 else
309 ac_glbctrl &= ~S3C_AC97_GLBCTRL_PCMOUTTM_MASK;
310 break;
311 }
312 writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
313
314 return 0;
315}
316
317static int s3c2443_ac97_hw_mic_params(struct snd_pcm_substream *substream,
318 struct snd_pcm_hw_params *params)
319{
320 struct snd_soc_pcm_runtime *rtd = substream->private_data;
321 struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai;
322
323 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
324 return -ENODEV;
325 else
326 cpu_dai->dma_data = &s3c2443_ac97_mic_mono_in;
327
328 return 0;
329}
330
331static int s3c2443_ac97_mic_trigger(struct snd_pcm_substream *substream,
332 int cmd)
333{
334 u32 ac_glbctrl;
335
336 ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
337 switch(cmd) {
338 case SNDRV_PCM_TRIGGER_START:
339 case SNDRV_PCM_TRIGGER_RESUME:
340 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
341 ac_glbctrl |= S3C_AC97_GLBCTRL_PCMINTM_DMA;
342 break;
343 case SNDRV_PCM_TRIGGER_STOP:
344 case SNDRV_PCM_TRIGGER_SUSPEND:
345 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
346 ac_glbctrl &= ~S3C_AC97_GLBCTRL_PCMINTM_MASK;
347 }
348 writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
349
350 return 0;
351}
352
353#define s3c2443_AC97_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
354 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | \
355 SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000)
356
357struct snd_soc_cpu_dai s3c2443_ac97_dai[] = {
358{
359 .name = "s3c2443-ac97",
360 .id = 0,
361 .type = SND_SOC_DAI_AC97,
362 .probe = s3c2443_ac97_probe,
363 .remove = s3c2443_ac97_remove,
364 .playback = {
365 .stream_name = "AC97 Playback",
366 .channels_min = 2,
367 .channels_max = 2,
368 .rates = s3c2443_AC97_RATES,
369 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
370 .capture = {
371 .stream_name = "AC97 Capture",
372 .channels_min = 2,
373 .channels_max = 2,
374 .rates = s3c2443_AC97_RATES,
375 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
376 .ops = {
377 .hw_params = s3c2443_ac97_hw_params,
378 .trigger = s3c2443_ac97_trigger},
379},
380{
381 .name = "pxa2xx-ac97-mic",
382 .id = 1,
383 .type = SND_SOC_DAI_AC97,
384 .capture = {
385 .stream_name = "AC97 Mic Capture",
386 .channels_min = 1,
387 .channels_max = 1,
388 .rates = s3c2443_AC97_RATES,
389 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
390 .ops = {
391 .hw_params = s3c2443_ac97_hw_mic_params,
392 .trigger = s3c2443_ac97_mic_trigger,},
393},
394};
395
396EXPORT_SYMBOL_GPL(s3c2443_ac97_dai);
397EXPORT_SYMBOL_GPL(soc_ac97_ops);
398
399MODULE_AUTHOR("Graeme Gregory");
400MODULE_DESCRIPTION("AC97 driver for the Samsung s3c2443 chip");
401MODULE_LICENSE("GPL");
diff --git a/sound/soc/s3c24xx/s3c24xx-ac97.h b/sound/soc/s3c24xx/s3c24xx-ac97.h
new file mode 100644
index 000000000000..2b835e8260fa
--- /dev/null
+++ b/sound/soc/s3c24xx/s3c24xx-ac97.h
@@ -0,0 +1,25 @@
1/*
2 * s3c24xx-ac97.c -- ALSA Soc Audio Layer
3 *
4 * (c) 2007 Wolfson Microelectronics PLC.
5 * Author: Graeme Gregory
6 * graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 *
13 * Revision history
14 * 10th Nov 2006 Initial version.
15 */
16
17#ifndef S3C24XXAC97_H_
18#define S3C24XXAC97_H_
19
20#define AC_CMD_ADDR(x) (x << 16)
21#define AC_CMD_DATA(x) (x & 0xffff)
22
23extern struct snd_soc_cpu_dai s3c2443_ac97_dai[];
24
25#endif /*S3C24XXAC97_H_*/
diff --git a/sound/soc/s3c24xx/s3c24xx-i2s.c b/sound/soc/s3c24xx/s3c24xx-i2s.c
index 8ca314dc8891..39f02462e07d 100644
--- a/sound/soc/s3c24xx/s3c24xx-i2s.c
+++ b/sound/soc/s3c24xx/s3c24xx-i2s.c
@@ -344,11 +344,11 @@ static int s3c24xx_i2s_set_clkdiv(struct snd_soc_cpu_dai *cpu_dai,
344 DBG("Entered %s\n", __FUNCTION__); 344 DBG("Entered %s\n", __FUNCTION__);
345 345
346 switch (div_id) { 346 switch (div_id) {
347 case S3C24XX_DIV_MCLK: 347 case S3C24XX_DIV_BCLK:
348 reg = readl(s3c24xx_i2s.regs + S3C2410_IISMOD) & ~S3C2410_IISMOD_FS_MASK; 348 reg = readl(s3c24xx_i2s.regs + S3C2410_IISMOD) & ~S3C2410_IISMOD_FS_MASK;
349 writel(reg | div, s3c24xx_i2s.regs + S3C2410_IISMOD); 349 writel(reg | div, s3c24xx_i2s.regs + S3C2410_IISMOD);
350 break; 350 break;
351 case S3C24XX_DIV_BCLK: 351 case S3C24XX_DIV_MCLK:
352 reg = readl(s3c24xx_i2s.regs + S3C2410_IISMOD) & ~(S3C2410_IISMOD_384FS); 352 reg = readl(s3c24xx_i2s.regs + S3C2410_IISMOD) & ~(S3C2410_IISMOD_384FS);
353 writel(reg | div, s3c24xx_i2s.regs + S3C2410_IISMOD); 353 writel(reg | div, s3c24xx_i2s.regs + S3C2410_IISMOD);
354 break; 354 break;
diff --git a/sound/soc/s3c24xx/smdk2443_wm9710.c b/sound/soc/s3c24xx/smdk2443_wm9710.c
new file mode 100644
index 000000000000..d46cd811ceb3
--- /dev/null
+++ b/sound/soc/s3c24xx/smdk2443_wm9710.c
@@ -0,0 +1,85 @@
1/*
2 * smdk2443_wm9710.c -- SoC audio for smdk2443
3 *
4 * Copyright 2007 Wolfson Microelectronics PLC.
5 * Author: Graeme Gregory
6 * graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 *
13 * Revision history
14 * 8th Mar 2007 Initial version.
15 *
16 */
17
18#include <linux/module.h>
19#include <linux/device.h>
20#include <sound/driver.h>
21#include <sound/core.h>
22#include <sound/pcm.h>
23#include <sound/soc.h>
24#include <sound/soc-dapm.h>
25
26#include "../codecs/ac97.h"
27#include "s3c24xx-pcm.h"
28#include "s3c24xx-ac97.h"
29
30static struct snd_soc_machine smdk2443;
31
32static struct snd_soc_dai_link smdk2443_dai[] = {
33{
34 .name = "AC97",
35 .stream_name = "AC97 HiFi",
36 .cpu_dai = &s3c2443_ac97_dai[0],
37 .codec_dai = &ac97_dai,
38},
39};
40
41static struct snd_soc_machine smdk2443 = {
42 .name = "SMDK2443",
43 .dai_link = smdk2443_dai,
44 .num_links = ARRAY_SIZE(smdk2443_dai),
45};
46
47static struct snd_soc_device smdk2443_snd_ac97_devdata = {
48 .machine = &smdk2443,
49 .platform = &s3c24xx_soc_platform,
50 .codec_dev = &soc_codec_dev_ac97,
51};
52
53static struct platform_device *smdk2443_snd_ac97_device;
54
55static int __init smdk2443_init(void)
56{
57 int ret;
58
59 smdk2443_snd_ac97_device = platform_device_alloc("soc-audio", -1);
60 if (!smdk2443_snd_ac97_device)
61 return -ENOMEM;
62
63 platform_set_drvdata(smdk2443_snd_ac97_device,
64 &smdk2443_snd_ac97_devdata);
65 smdk2443_snd_ac97_devdata.dev = &smdk2443_snd_ac97_device->dev;
66 ret = platform_device_add(smdk2443_snd_ac97_device);
67
68 if (ret)
69 platform_device_put(smdk2443_snd_ac97_device);
70
71 return ret;
72}
73
74static void __exit smdk2443_exit(void)
75{
76 platform_device_unregister(smdk2443_snd_ac97_device);
77}
78
79module_init(smdk2443_init);
80module_exit(smdk2443_exit);
81
82/* Module information */
83MODULE_AUTHOR("Graeme Gregory, graeme.gregory@wolfsonmicro.com, www.wolfsonmicro.com");
84MODULE_DESCRIPTION("ALSA SoC WM9710 SMDK2443");
85MODULE_LICENSE("GPL");
diff --git a/sound/soc/sh/Kconfig b/sound/soc/sh/Kconfig
new file mode 100644
index 000000000000..f03220d23e73
--- /dev/null
+++ b/sound/soc/sh/Kconfig
@@ -0,0 +1,38 @@
1menu "SoC Audio support for SuperH"
2
3config SND_SOC_PCM_SH7760
4 tristate "SoC Audio support for Renesas SH7760"
5 depends on CPU_SUBTYPE_SH7760 && SND_SOC && SH_DMABRG
6 help
7 Enable this option for SH7760 AC97/I2S audio support.
8
9
10##
11## Audio unit modules
12##
13
14config SND_SOC_SH4_HAC
15 select AC97_BUS
16 select SND_SOC_AC97_BUS
17 select SND_AC97_CODEC
18 tristate
19
20config SND_SOC_SH4_SSI
21 tristate
22
23
24
25##
26## Boards
27##
28
29config SND_SH7760_AC97
30 tristate "SH7760 AC97 sound support"
31 depends on CPU_SUBTYPE_SH7760 && SND_SOC_PCM_SH7760
32 select SND_SOC_SH4_HAC
33 select SND_SOC_AC97_CODEC
34 help
35 This option enables generic sound support for the first
36 AC97 unit of the SH7760.
37
38endmenu
diff --git a/sound/soc/sh/Makefile b/sound/soc/sh/Makefile
new file mode 100644
index 000000000000..a8e8ab81cc6a
--- /dev/null
+++ b/sound/soc/sh/Makefile
@@ -0,0 +1,14 @@
1## DMA engines
2snd-soc-dma-sh7760-objs := dma-sh7760.o
3obj-$(CONFIG_SND_SOC_PCM_SH7760) += snd-soc-dma-sh7760.o
4
5## audio units found on some SH-4
6snd-soc-hac-objs := hac.o
7snd-soc-ssi-objs := ssi.o
8obj-$(CONFIG_SND_SOC_SH4_HAC) += snd-soc-hac.o
9obj-$(CONFIG_SND_SOC_SH4_SSI) += snd-soc-ssi.o
10
11## boards
12snd-soc-sh7760-ac97-objs := sh7760-ac97.o
13
14obj-$(CONFIG_SND_SH7760_AC97) += snd-soc-sh7760-ac97.o
diff --git a/sound/soc/sh/dma-sh7760.c b/sound/soc/sh/dma-sh7760.c
new file mode 100644
index 000000000000..cdee374b843e
--- /dev/null
+++ b/sound/soc/sh/dma-sh7760.c
@@ -0,0 +1,354 @@
1/*
2 * SH7760 ("camelot") DMABRG audio DMA unit support
3 *
4 * Copyright (C) 2007 Manuel Lauss <mano@roarinelk.homelinux.net>
5 * licensed under the terms outlined in the file COPYING at the root
6 * of the linux kernel sources.
7 *
8 * The SH7760 DMABRG provides 4 dma channels (2x rec, 2x play), which
9 * trigger an interrupt when one half of the programmed transfer size
10 * has been xmitted.
11 *
12 * FIXME: little-endian only for now
13 */
14
15#include <linux/module.h>
16#include <linux/init.h>
17#include <linux/platform_device.h>
18#include <linux/dma-mapping.h>
19#include <sound/driver.h>
20#include <sound/core.h>
21#include <sound/pcm.h>
22#include <sound/pcm_params.h>
23#include <sound/soc.h>
24#include <asm/dmabrg.h>
25
26
27/* registers and bits */
28#define BRGATXSAR 0x00
29#define BRGARXDAR 0x04
30#define BRGATXTCR 0x08
31#define BRGARXTCR 0x0C
32#define BRGACR 0x10
33#define BRGATXTCNT 0x14
34#define BRGARXTCNT 0x18
35
36#define ACR_RAR (1 << 18)
37#define ACR_RDS (1 << 17)
38#define ACR_RDE (1 << 16)
39#define ACR_TAR (1 << 2)
40#define ACR_TDS (1 << 1)
41#define ACR_TDE (1 << 0)
42
43/* receiver/transmitter data alignment */
44#define ACR_RAM_NONE (0 << 24)
45#define ACR_RAM_4BYTE (1 << 24)
46#define ACR_RAM_2WORD (2 << 24)
47#define ACR_TAM_NONE (0 << 8)
48#define ACR_TAM_4BYTE (1 << 8)
49#define ACR_TAM_2WORD (2 << 8)
50
51
52struct camelot_pcm {
53 unsigned long mmio; /* DMABRG audio channel control reg MMIO */
54 unsigned int txid; /* ID of first DMABRG IRQ for this unit */
55
56 struct snd_pcm_substream *tx_ss;
57 unsigned long tx_period_size;
58 unsigned int tx_period;
59
60 struct snd_pcm_substream *rx_ss;
61 unsigned long rx_period_size;
62 unsigned int rx_period;
63
64} cam_pcm_data[2] = {
65 {
66 .mmio = 0xFE3C0040,
67 .txid = DMABRGIRQ_A0TXF,
68 },
69 {
70 .mmio = 0xFE3C0060,
71 .txid = DMABRGIRQ_A1TXF,
72 },
73};
74
75#define BRGREG(x) (*(unsigned long *)(cam->mmio + (x)))
76
77/*
78 * set a minimum of 16kb per period, to avoid interrupt-"storm" and
79 * resulting skipping. In general, the bigger the minimum size, the
80 * better for overall system performance. (The SH7760 is a puny CPU
81 * with a slow SDRAM interface and poor internal bus bandwidth,
82 * *especially* when the LCDC is active). The minimum for the DMAC
83 * is 8 bytes; 16kbytes are enough to get skip-free playback of a
84 * 44kHz/16bit/stereo MP3 on a lightly loaded system, and maintain
85 * reasonable responsiveness in MPlayer.
86 */
87#define DMABRG_PERIOD_MIN 16 * 1024
88#define DMABRG_PERIOD_MAX 0x03fffffc
89#define DMABRG_PREALLOC_BUFFER 32 * 1024
90#define DMABRG_PREALLOC_BUFFER_MAX 32 * 1024
91
92/* support everything the SSI supports */
93#define DMABRG_RATES \
94 SNDRV_PCM_RATE_8000_192000
95
96#define DMABRG_FMTS \
97 (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 | \
98 SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE | \
99 SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_U20_3LE | \
100 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_U24_3LE | \
101 SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_U32_LE)
102
103static struct snd_pcm_hardware camelot_pcm_hardware = {
104 .info = (SNDRV_PCM_INFO_MMAP |
105 SNDRV_PCM_INFO_INTERLEAVED |
106 SNDRV_PCM_INFO_BLOCK_TRANSFER |
107 SNDRV_PCM_INFO_MMAP_VALID),
108 .formats = DMABRG_FMTS,
109 .rates = DMABRG_RATES,
110 .rate_min = 8000,
111 .rate_max = 192000,
112 .channels_min = 2,
113 .channels_max = 8, /* max of the SSI */
114 .buffer_bytes_max = DMABRG_PERIOD_MAX,
115 .period_bytes_min = DMABRG_PERIOD_MIN,
116 .period_bytes_max = DMABRG_PERIOD_MAX / 2,
117 .periods_min = 2,
118 .periods_max = 2,
119 .fifo_size = 128,
120};
121
122static void camelot_txdma(void *data)
123{
124 struct camelot_pcm *cam = data;
125 cam->tx_period ^= 1;
126 snd_pcm_period_elapsed(cam->tx_ss);
127}
128
129static void camelot_rxdma(void *data)
130{
131 struct camelot_pcm *cam = data;
132 cam->rx_period ^= 1;
133 snd_pcm_period_elapsed(cam->rx_ss);
134}
135
136static int camelot_pcm_open(struct snd_pcm_substream *substream)
137{
138 struct snd_soc_pcm_runtime *rtd = substream->private_data;
139 struct camelot_pcm *cam = &cam_pcm_data[rtd->dai->cpu_dai->id];
140 int recv = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0:1;
141 int ret, dmairq;
142
143 snd_soc_set_runtime_hwparams(substream, &camelot_pcm_hardware);
144
145 /* DMABRG buffer half/full events */
146 dmairq = (recv) ? cam->txid + 2 : cam->txid;
147 if (recv) {
148 cam->rx_ss = substream;
149 ret = dmabrg_request_irq(dmairq, camelot_rxdma, cam);
150 if (unlikely(ret)) {
151 pr_debug("audio unit %d irqs already taken!\n",
152 rtd->dai->cpu_dai->id);
153 return -EBUSY;
154 }
155 (void)dmabrg_request_irq(dmairq + 1,camelot_rxdma, cam);
156 } else {
157 cam->tx_ss = substream;
158 ret = dmabrg_request_irq(dmairq, camelot_txdma, cam);
159 if (unlikely(ret)) {
160 pr_debug("audio unit %d irqs already taken!\n",
161 rtd->dai->cpu_dai->id);
162 return -EBUSY;
163 }
164 (void)dmabrg_request_irq(dmairq + 1, camelot_txdma, cam);
165 }
166 return 0;
167}
168
169static int camelot_pcm_close(struct snd_pcm_substream *substream)
170{
171 struct snd_soc_pcm_runtime *rtd = substream->private_data;
172 struct camelot_pcm *cam = &cam_pcm_data[rtd->dai->cpu_dai->id];
173 int recv = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0:1;
174 int dmairq;
175
176 dmairq = (recv) ? cam->txid + 2 : cam->txid;
177
178 if (recv)
179 cam->rx_ss = NULL;
180 else
181 cam->tx_ss = NULL;
182
183 dmabrg_free_irq(dmairq + 1);
184 dmabrg_free_irq(dmairq);
185
186 return 0;
187}
188
189static int camelot_hw_params(struct snd_pcm_substream *substream,
190 struct snd_pcm_hw_params *hw_params)
191{
192 struct snd_soc_pcm_runtime *rtd = substream->private_data;
193 struct camelot_pcm *cam = &cam_pcm_data[rtd->dai->cpu_dai->id];
194 int recv = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0:1;
195 int ret;
196
197 ret = snd_pcm_lib_malloc_pages(substream,
198 params_buffer_bytes(hw_params));
199 if (ret < 0)
200 return ret;
201
202 if (recv) {
203 cam->rx_period_size = params_period_bytes(hw_params);
204 cam->rx_period = 0;
205 } else {
206 cam->tx_period_size = params_period_bytes(hw_params);
207 cam->tx_period = 0;
208 }
209 return 0;
210}
211
212static int camelot_hw_free(struct snd_pcm_substream *substream)
213{
214 return snd_pcm_lib_free_pages(substream);
215}
216
217static int camelot_prepare(struct snd_pcm_substream *substream)
218{
219 struct snd_pcm_runtime *runtime = substream->runtime;
220 struct snd_soc_pcm_runtime *rtd = substream->private_data;
221 struct camelot_pcm *cam = &cam_pcm_data[rtd->dai->cpu_dai->id];
222
223 pr_debug("PCM data: addr 0x%08ulx len %d\n",
224 (u32)runtime->dma_addr, runtime->dma_bytes);
225
226 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
227 BRGREG(BRGATXSAR) = (unsigned long)runtime->dma_area;
228 BRGREG(BRGATXTCR) = runtime->dma_bytes;
229 } else {
230 BRGREG(BRGARXDAR) = (unsigned long)runtime->dma_area;
231 BRGREG(BRGARXTCR) = runtime->dma_bytes;
232 }
233
234 return 0;
235}
236
237static inline void dmabrg_play_dma_start(struct camelot_pcm *cam)
238{
239 unsigned long acr = BRGREG(BRGACR) & ~(ACR_TDS | ACR_RDS);
240 /* start DMABRG engine: XFER start, auto-addr-reload */
241 BRGREG(BRGACR) = acr | ACR_TDE | ACR_TAR | ACR_TAM_2WORD;
242}
243
244static inline void dmabrg_play_dma_stop(struct camelot_pcm *cam)
245{
246 unsigned long acr = BRGREG(BRGACR) & ~(ACR_TDS | ACR_RDS);
247 /* forcibly terminate data transmission */
248 BRGREG(BRGACR) = acr | ACR_TDS;
249}
250
251static inline void dmabrg_rec_dma_start(struct camelot_pcm *cam)
252{
253 unsigned long acr = BRGREG(BRGACR) & ~(ACR_TDS | ACR_RDS);
254 /* start DMABRG engine: recv start, auto-reload */
255 BRGREG(BRGACR) = acr | ACR_RDE | ACR_RAR | ACR_RAM_2WORD;
256}
257
258static inline void dmabrg_rec_dma_stop(struct camelot_pcm *cam)
259{
260 unsigned long acr = BRGREG(BRGACR) & ~(ACR_TDS | ACR_RDS);
261 /* forcibly terminate data receiver */
262 BRGREG(BRGACR) = acr | ACR_RDS;
263}
264
265static int camelot_trigger(struct snd_pcm_substream *substream, int cmd)
266{
267 struct snd_soc_pcm_runtime *rtd = substream->private_data;
268 struct camelot_pcm *cam = &cam_pcm_data[rtd->dai->cpu_dai->id];
269 int recv = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0:1;
270
271 switch (cmd) {
272 case SNDRV_PCM_TRIGGER_START:
273 if (recv)
274 dmabrg_rec_dma_start(cam);
275 else
276 dmabrg_play_dma_start(cam);
277 break;
278 case SNDRV_PCM_TRIGGER_STOP:
279 if (recv)
280 dmabrg_rec_dma_stop(cam);
281 else
282 dmabrg_play_dma_stop(cam);
283 break;
284 default:
285 return -EINVAL;
286 }
287
288 return 0;
289}
290
291static snd_pcm_uframes_t camelot_pos(struct snd_pcm_substream *substream)
292{
293 struct snd_pcm_runtime *runtime = substream->runtime;
294 struct snd_soc_pcm_runtime *rtd = substream->private_data;
295 struct camelot_pcm *cam = &cam_pcm_data[rtd->dai->cpu_dai->id];
296 int recv = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0:1;
297 unsigned long pos;
298
299 /* cannot use the DMABRG pointer register: under load, by the
300 * time ALSA comes around to read the register, it is already
301 * far ahead (or worse, already done with the fragment) of the
302 * position at the time the IRQ was triggered, which results in
303 * fast-playback sound in my test application (ScummVM)
304 */
305 if (recv)
306 pos = cam->rx_period ? cam->rx_period_size : 0;
307 else
308 pos = cam->tx_period ? cam->tx_period_size : 0;
309
310 return bytes_to_frames(runtime, pos);
311}
312
313static struct snd_pcm_ops camelot_pcm_ops = {
314 .open = camelot_pcm_open,
315 .close = camelot_pcm_close,
316 .ioctl = snd_pcm_lib_ioctl,
317 .hw_params = camelot_hw_params,
318 .hw_free = camelot_hw_free,
319 .prepare = camelot_prepare,
320 .trigger = camelot_trigger,
321 .pointer = camelot_pos,
322};
323
324static void camelot_pcm_free(struct snd_pcm *pcm)
325{
326 snd_pcm_lib_preallocate_free_for_all(pcm);
327}
328
329static int camelot_pcm_new(struct snd_card *card,
330 struct snd_soc_codec_dai *dai,
331 struct snd_pcm *pcm)
332{
333 /* dont use SNDRV_DMA_TYPE_DEV, since it will oops the SH kernel
334 * in MMAP mode (i.e. aplay -M)
335 */
336 snd_pcm_lib_preallocate_pages_for_all(pcm,
337 SNDRV_DMA_TYPE_CONTINUOUS,
338 snd_dma_continuous_data(GFP_KERNEL),
339 DMABRG_PREALLOC_BUFFER, DMABRG_PREALLOC_BUFFER_MAX);
340
341 return 0;
342}
343
344struct snd_soc_platform sh7760_soc_platform = {
345 .name = "sh7760-pcm",
346 .pcm_ops = &camelot_pcm_ops,
347 .pcm_new = camelot_pcm_new,
348 .pcm_free = camelot_pcm_free,
349};
350EXPORT_SYMBOL_GPL(sh7760_soc_platform);
351
352MODULE_LICENSE("GPL");
353MODULE_DESCRIPTION("SH7760 Audio DMA (DMABRG) driver");
354MODULE_AUTHOR("Manuel Lauss <mano@roarinelk.homelinux.net>");
diff --git a/sound/soc/sh/hac.c b/sound/soc/sh/hac.c
new file mode 100644
index 000000000000..8e3f03908cdb
--- /dev/null
+++ b/sound/soc/sh/hac.c
@@ -0,0 +1,322 @@
1/*
2 * Hitachi Audio Controller (AC97) support for SH7760/SH7780
3 *
4 * Copyright (c) 2007 Manuel Lauss <mano@roarinelk.homelinux.net>
5 * licensed under the terms outlined in the file COPYING at the root
6 * of the linux kernel sources.
7 *
8 * dont forget to set IPSEL/OMSEL register bits (in your board code) to
9 * enable HAC output pins!
10 */
11
12/* BIG FAT FIXME: although the SH7760 has 2 independent AC97 units, only
13 * the FIRST can be used since ASoC does not pass any information to the
14 * ac97_read/write() functions regarding WHICH unit to use. You'll have
15 * to edit the code a bit to use the other AC97 unit. --mlau
16 */
17
18#include <linux/init.h>
19#include <linux/module.h>
20#include <linux/platform_device.h>
21#include <linux/interrupt.h>
22#include <linux/wait.h>
23#include <linux/delay.h>
24#include <sound/driver.h>
25#include <sound/core.h>
26#include <sound/pcm.h>
27#include <sound/ac97_codec.h>
28#include <sound/initval.h>
29#include <sound/soc.h>
30
31/* regs and bits */
32#define HACCR 0x08
33#define HACCSAR 0x20
34#define HACCSDR 0x24
35#define HACPCML 0x28
36#define HACPCMR 0x2C
37#define HACTIER 0x50
38#define HACTSR 0x54
39#define HACRIER 0x58
40#define HACRSR 0x5C
41#define HACACR 0x60
42
43#define CR_CR (1 << 15) /* "codec-ready" indicator */
44#define CR_CDRT (1 << 11) /* cold reset */
45#define CR_WMRT (1 << 10) /* warm reset */
46#define CR_B9 (1 << 9) /* the mysterious "bit 9" */
47#define CR_ST (1 << 5) /* AC97 link start bit */
48
49#define CSAR_RD (1 << 19) /* AC97 data read bit */
50#define CSAR_WR (0)
51
52#define TSR_CMDAMT (1 << 31)
53#define TSR_CMDDMT (1 << 30)
54
55#define RSR_STARY (1 << 22)
56#define RSR_STDRY (1 << 21)
57
58#define ACR_DMARX16 (1 << 30)
59#define ACR_DMATX16 (1 << 29)
60#define ACR_TX12ATOM (1 << 26)
61#define ACR_DMARX20 ((1 << 24) | (1 << 22))
62#define ACR_DMATX20 ((1 << 23) | (1 << 21))
63
64#define CSDR_SHIFT 4
65#define CSDR_MASK (0xffff << CSDR_SHIFT)
66#define CSAR_SHIFT 12
67#define CSAR_MASK (0x7f << CSAR_SHIFT)
68
69#define AC97_WRITE_RETRY 1
70#define AC97_READ_RETRY 5
71
72/* manual-suggested AC97 codec access timeouts (us) */
73#define TMO_E1 500 /* 21 < E1 < 1000 */
74#define TMO_E2 13 /* 13 < E2 */
75#define TMO_E3 21 /* 21 < E3 */
76#define TMO_E4 500 /* 21 < E4 < 1000 */
77
78struct hac_priv {
79 unsigned long mmio; /* HAC base address */
80} hac_cpu_data[] = {
81#if defined(CONFIG_CPU_SUBTYPE_SH7760)
82 {
83 .mmio = 0xFE240000,
84 },
85 {
86 .mmio = 0xFE250000,
87 },
88#elif defined(CONFIG_CPU_SUBTYPE_SH7780)
89 {
90 .mmio = 0xFFE40000,
91 },
92#else
93#error "Unsupported SuperH SoC"
94#endif
95};
96
97#define HACREG(reg) (*(unsigned long *)(hac->mmio + (reg)))
98
99/*
100 * AC97 read/write flow as outlined in the SH7760 manual (pages 903-906)
101 */
102static int hac_get_codec_data(struct hac_priv *hac, unsigned short r,
103 unsigned short *v)
104{
105 unsigned int to1, to2, i;
106 unsigned short adr;
107
108 for (i = 0; i < AC97_READ_RETRY; ++i) {
109 *v = 0;
110 /* wait for HAC to receive something from the codec */
111 for (to1 = TMO_E4;
112 to1 && !(HACREG(HACRSR) & RSR_STARY);
113 --to1)
114 udelay(1);
115 for (to2 = TMO_E4;
116 to2 && !(HACREG(HACRSR) & RSR_STDRY);
117 --to2)
118 udelay(1);
119
120 if (!to1 && !to2)
121 return 0; /* codec comm is down */
122
123 adr = ((HACREG(HACCSAR) & CSAR_MASK) >> CSAR_SHIFT);
124 *v = ((HACREG(HACCSDR) & CSDR_MASK) >> CSDR_SHIFT);
125
126 HACREG(HACRSR) &= ~(RSR_STDRY | RSR_STARY);
127
128 if (r == adr)
129 break;
130
131 /* manual says: wait at least 21 usec before retrying */
132 udelay(21);
133 }
134 HACREG(HACRSR) &= ~(RSR_STDRY | RSR_STARY);
135 return (i < AC97_READ_RETRY);
136}
137
138static unsigned short hac_read_codec_aux(struct hac_priv *hac,
139 unsigned short reg)
140{
141 unsigned short val;
142 unsigned int i, to;
143
144 for (i = 0; i < AC97_READ_RETRY; i++) {
145 /* send_read_request */
146 local_irq_disable();
147 HACREG(HACTSR) &= ~(TSR_CMDAMT);
148 HACREG(HACCSAR) = (reg << CSAR_SHIFT) | CSAR_RD;
149 local_irq_enable();
150
151 for (to = TMO_E3;
152 to && !(HACREG(HACTSR) & TSR_CMDAMT);
153 --to)
154 udelay(1);
155
156 HACREG(HACTSR) &= ~TSR_CMDAMT;
157 val = 0;
158 if (hac_get_codec_data(hac, reg, &val) != 0)
159 break;
160 }
161
162 if (i == AC97_READ_RETRY)
163 return ~0;
164
165 return val;
166}
167
168static void hac_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
169 unsigned short val)
170{
171 int unit_id = 0 /* ac97->private_data */;
172 struct hac_priv *hac = &hac_cpu_data[unit_id];
173 unsigned int i, to;
174 /* write_codec_aux */
175 for (i = 0; i < AC97_WRITE_RETRY; i++) {
176 /* send_write_request */
177 local_irq_disable();
178 HACREG(HACTSR) &= ~(TSR_CMDDMT | TSR_CMDAMT);
179 HACREG(HACCSDR) = (val << CSDR_SHIFT);
180 HACREG(HACCSAR) = (reg << CSAR_SHIFT) & (~CSAR_RD);
181 local_irq_enable();
182
183 /* poll-wait for CMDAMT and CMDDMT */
184 for (to = TMO_E1;
185 to && !(HACREG(HACTSR) & (TSR_CMDAMT|TSR_CMDDMT));
186 --to)
187 udelay(1);
188
189 HACREG(HACTSR) &= ~(TSR_CMDAMT | TSR_CMDDMT);
190 if (to)
191 break;
192 /* timeout, try again */
193 }
194}
195
196static unsigned short hac_ac97_read(struct snd_ac97 *ac97,
197 unsigned short reg)
198{
199 int unit_id = 0 /* ac97->private_data */;
200 struct hac_priv *hac = &hac_cpu_data[unit_id];
201 return hac_read_codec_aux(hac, reg);
202}
203
204static void hac_ac97_warmrst(struct snd_ac97 *ac97)
205{
206 int unit_id = 0 /* ac97->private_data */;
207 struct hac_priv *hac = &hac_cpu_data[unit_id];
208 unsigned int tmo;
209
210 HACREG(HACCR) = CR_WMRT | CR_ST | CR_B9;
211 msleep(10);
212 HACREG(HACCR) = CR_ST | CR_B9;
213 for (tmo = 1000; (tmo > 0) && !(HACREG(HACCR) & CR_CR); tmo--)
214 udelay(1);
215
216 if (!tmo)
217 printk(KERN_INFO "hac: reset: AC97 link down!\n");
218 /* settings this bit lets us have a conversation with codec */
219 HACREG(HACACR) |= ACR_TX12ATOM;
220}
221
222static void hac_ac97_coldrst(struct snd_ac97 *ac97)
223{
224 int unit_id = 0 /* ac97->private_data */;
225 struct hac_priv *hac;
226 hac = &hac_cpu_data[unit_id];
227
228 HACREG(HACCR) = 0;
229 HACREG(HACCR) = CR_CDRT | CR_ST | CR_B9;
230 msleep(10);
231 hac_ac97_warmrst(ac97);
232}
233
234struct snd_ac97_bus_ops soc_ac97_ops = {
235 .read = hac_ac97_read,
236 .write = hac_ac97_write,
237 .reset = hac_ac97_coldrst,
238 .warm_reset = hac_ac97_warmrst,
239};
240EXPORT_SYMBOL_GPL(soc_ac97_ops);
241
242static int hac_hw_params(struct snd_pcm_substream *substream,
243 struct snd_pcm_hw_params *params)
244{
245 struct snd_soc_pcm_runtime *rtd = substream->private_data;
246 struct hac_priv *hac = &hac_cpu_data[rtd->dai->cpu_dai->id];
247 int d = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0 : 1;
248
249 switch (params->msbits) {
250 case 16:
251 HACREG(HACACR) |= d ? ACR_DMARX16 : ACR_DMATX16;
252 HACREG(HACACR) &= d ? ~ACR_DMARX20 : ~ACR_DMATX20;
253 break;
254 case 20:
255 HACREG(HACACR) &= d ? ~ACR_DMARX16 : ~ACR_DMATX16;
256 HACREG(HACACR) |= d ? ACR_DMARX20 : ACR_DMATX20;
257 break;
258 default:
259 pr_debug("hac: invalid depth %d bit\n", params->msbits);
260 return -EINVAL;
261 break;
262 }
263
264 return 0;
265}
266
267#define AC97_RATES \
268 SNDRV_PCM_RATE_8000_192000
269
270#define AC97_FMTS \
271 SNDRV_PCM_FMTBIT_S16_LE
272
273struct snd_soc_cpu_dai sh4_hac_dai[] = {
274{
275 .name = "HAC0",
276 .id = 0,
277 .type = SND_SOC_DAI_AC97,
278 .playback = {
279 .rates = AC97_RATES,
280 .formats = AC97_FMTS,
281 .channels_min = 2,
282 .channels_max = 2,
283 },
284 .capture = {
285 .rates = AC97_RATES,
286 .formats = AC97_FMTS,
287 .channels_min = 2,
288 .channels_max = 2,
289 },
290 .ops = {
291 .hw_params = hac_hw_params,
292 },
293},
294#ifdef CONFIG_CPU_SUBTYPE_SH7760
295{
296 .name = "HAC1",
297 .id = 1,
298 .type = SND_SOC_DAI_AC97,
299 .playback = {
300 .rates = AC97_RATES,
301 .formats = AC97_FMTS,
302 .channels_min = 2,
303 .channels_max = 2,
304 },
305 .capture = {
306 .rates = AC97_RATES,
307 .formats = AC97_FMTS,
308 .channels_min = 2,
309 .channels_max = 2,
310 },
311 .ops = {
312 .hw_params = hac_hw_params,
313 },
314
315},
316#endif
317};
318EXPORT_SYMBOL_GPL(sh4_hac_dai);
319
320MODULE_LICENSE("GPL");
321MODULE_DESCRIPTION("SuperH onchip HAC (AC97) audio driver");
322MODULE_AUTHOR("Manuel Lauss <mano@roarinelk.homelinux.net>");
diff --git a/sound/soc/sh/sh7760-ac97.c b/sound/soc/sh/sh7760-ac97.c
new file mode 100644
index 000000000000..5563f14511fa
--- /dev/null
+++ b/sound/soc/sh/sh7760-ac97.c
@@ -0,0 +1,92 @@
1/*
2 * Generic AC97 sound support for SH7760
3 *
4 * (c) 2007 Manuel Lauss
5 *
6 * Licensed under the GPLv2.
7 */
8
9#include <linux/module.h>
10#include <linux/moduleparam.h>
11#include <linux/platform_device.h>
12#include <sound/driver.h>
13#include <sound/core.h>
14#include <sound/pcm.h>
15#include <sound/soc.h>
16#include <sound/soc-dapm.h>
17#include <asm/io.h>
18
19#include "../codecs/ac97.h"
20
21#define IPSEL 0xFE400034
22
23/* platform specific structs can be declared here */
24extern struct snd_soc_cpu_dai sh4_hac_dai[2];
25extern struct snd_soc_platform sh7760_soc_platform;
26
27static int machine_init(struct snd_soc_codec *codec)
28{
29 snd_soc_dapm_sync_endpoints(codec);
30 return 0;
31}
32
33static struct snd_soc_dai_link sh7760_ac97_dai = {
34 .name = "AC97",
35 .stream_name = "AC97 HiFi",
36 .cpu_dai = &sh4_hac_dai[0], /* HAC0 */
37 .codec_dai = &ac97_dai,
38 .init = machine_init,
39 .ops = NULL,
40};
41
42static struct snd_soc_machine sh7760_ac97_soc_machine = {
43 .name = "SH7760 AC97",
44 .dai_link = &sh7760_ac97_dai,
45 .num_links = 1,
46};
47
48static struct snd_soc_device sh7760_ac97_snd_devdata = {
49 .machine = &sh7760_ac97_soc_machine,
50 .platform = &sh7760_soc_platform,
51 .codec_dev = &soc_codec_dev_ac97,
52};
53
54static struct platform_device *sh7760_ac97_snd_device;
55
56static int __init sh7760_ac97_init(void)
57{
58 int ret;
59 unsigned short ipsel;
60
61 /* enable both AC97 controllers in pinmux reg */
62 ipsel = ctrl_inw(IPSEL);
63 ctrl_outw(ipsel | (3 << 10), IPSEL);
64
65 ret = -ENOMEM;
66 sh7760_ac97_snd_device = platform_device_alloc("soc-audio", -1);
67 if (!sh7760_ac97_snd_device)
68 goto out;
69
70 platform_set_drvdata(sh7760_ac97_snd_device,
71 &sh7760_ac97_snd_devdata);
72 sh7760_ac97_snd_devdata.dev = &sh7760_ac97_snd_device->dev;
73 ret = platform_device_add(sh7760_ac97_snd_device);
74
75 if (ret)
76 platform_device_put(sh7760_ac97_snd_device);
77
78out:
79 return ret;
80}
81
82static void __exit sh7760_ac97_exit(void)
83{
84 platform_device_unregister(sh7760_ac97_snd_device);
85}
86
87module_init(sh7760_ac97_init);
88module_exit(sh7760_ac97_exit);
89
90MODULE_LICENSE("GPL");
91MODULE_DESCRIPTION("Generic SH7760 AC97 sound machine");
92MODULE_AUTHOR("Manuel Lauss <mano@roarinelk.homelinux.net>");
diff --git a/sound/soc/sh/ssi.c b/sound/soc/sh/ssi.c
new file mode 100644
index 000000000000..b72bc316cb8e
--- /dev/null
+++ b/sound/soc/sh/ssi.c
@@ -0,0 +1,400 @@
1/*
2 * Serial Sound Interface (I2S) support for SH7760/SH7780
3 *
4 * Copyright (c) 2007 Manuel Lauss <mano@roarinelk.homelinux.net>
5 *
6 * licensed under the terms outlined in the file COPYING at the root
7 * of the linux kernel sources.
8 *
9 * dont forget to set IPSEL/OMSEL register bits (in your board code) to
10 * enable SSI output pins!
11 */
12
13/*
14 * LIMITATIONS:
15 * The SSI unit has only one physical data line, so full duplex is
16 * impossible. This can be remedied on the SH7760 by using the
17 * other SSI unit for recording; however the SH7780 has only 1 SSI
18 * unit, and its pins are shared with the AC97 unit, among others.
19 *
20 * FEATURES:
21 * The SSI features "compressed mode": in this mode it continuously
22 * streams PCM data over the I2S lines and uses LRCK as a handshake
23 * signal. Can be used to send compressed data (AC3/DTS) to a DSP.
24 * The number of bits sent over the wire in a frame can be adjusted
25 * and can be independent from the actual sample bit depth. This is
26 * useful to support TDM mode codecs like the AD1939 which have a
27 * fixed TDM slot size, regardless of sample resolution.
28 */
29
30#include <linux/init.h>
31#include <linux/module.h>
32#include <linux/platform_device.h>
33#include <sound/driver.h>
34#include <sound/core.h>
35#include <sound/pcm.h>
36#include <sound/initval.h>
37#include <sound/soc.h>
38#include <asm/io.h>
39
40#define SSICR 0x00
41#define SSISR 0x04
42
43#define CR_DMAEN (1 << 28)
44#define CR_CHNL_SHIFT 22
45#define CR_CHNL_MASK (3 << CR_CHNL_SHIFT)
46#define CR_DWL_SHIFT 19
47#define CR_DWL_MASK (7 << CR_DWL_SHIFT)
48#define CR_SWL_SHIFT 16
49#define CR_SWL_MASK (7 << CR_SWL_SHIFT)
50#define CR_SCK_MASTER (1 << 15) /* bitclock master bit */
51#define CR_SWS_MASTER (1 << 14) /* wordselect master bit */
52#define CR_SCKP (1 << 13) /* I2Sclock polarity */
53#define CR_SWSP (1 << 12) /* LRCK polarity */
54#define CR_SPDP (1 << 11)
55#define CR_SDTA (1 << 10) /* i2s alignment (msb/lsb) */
56#define CR_PDTA (1 << 9) /* fifo data alignment */
57#define CR_DEL (1 << 8) /* delay data by 1 i2sclk */
58#define CR_BREN (1 << 7) /* clock gating in burst mode */
59#define CR_CKDIV_SHIFT 4
60#define CR_CKDIV_MASK (7 << CR_CKDIV_SHIFT) /* bitclock divider */
61#define CR_MUTE (1 << 3) /* SSI mute */
62#define CR_CPEN (1 << 2) /* compressed mode */
63#define CR_TRMD (1 << 1) /* transmit/receive select */
64#define CR_EN (1 << 0) /* enable SSI */
65
66#define SSIREG(reg) (*(unsigned long *)(ssi->mmio + (reg)))
67
68struct ssi_priv {
69 unsigned long mmio;
70 unsigned long sysclk;
71 int inuse;
72} ssi_cpu_data[] = {
73#if defined(CONFIG_CPU_SUBTYPE_SH7760)
74 {
75 .mmio = 0xFE680000,
76 },
77 {
78 .mmio = 0xFE690000,
79 },
80#elif defined(CONFIG_CPU_SUBTYPE_SH7780)
81 {
82 .mmio = 0xFFE70000,
83 },
84#else
85#error "Unsupported SuperH SoC"
86#endif
87};
88
89/*
90 * track usage of the SSI; it is simplex-only so prevent attempts of
91 * concurrent playback + capture. FIXME: any locking required?
92 */
93static int ssi_startup(struct snd_pcm_substream *substream)
94{
95 struct snd_soc_pcm_runtime *rtd = substream->private_data;
96 struct ssi_priv *ssi = &ssi_cpu_data[rtd->dai->cpu_dai->id];
97 if (ssi->inuse) {
98 pr_debug("ssi: already in use!\n");
99 return -EBUSY;
100 } else
101 ssi->inuse = 1;
102 return 0;
103}
104
105static void ssi_shutdown(struct snd_pcm_substream *substream)
106{
107 struct snd_soc_pcm_runtime *rtd = substream->private_data;
108 struct ssi_priv *ssi = &ssi_cpu_data[rtd->dai->cpu_dai->id];
109
110 ssi->inuse = 0;
111}
112
113static int ssi_trigger(struct snd_pcm_substream *substream, int cmd)
114{
115 struct snd_soc_pcm_runtime *rtd = substream->private_data;
116 struct ssi_priv *ssi = &ssi_cpu_data[rtd->dai->cpu_dai->id];
117
118 switch (cmd) {
119 case SNDRV_PCM_TRIGGER_START:
120 SSIREG(SSICR) |= CR_DMAEN | CR_EN;
121 break;
122 case SNDRV_PCM_TRIGGER_STOP:
123 SSIREG(SSICR) &= ~(CR_DMAEN | CR_EN);
124 break;
125 default:
126 return -EINVAL;
127 }
128
129 return 0;
130}
131
132static int ssi_hw_params(struct snd_pcm_substream *substream,
133 struct snd_pcm_hw_params *params)
134{
135 struct snd_soc_pcm_runtime *rtd = substream->private_data;
136 struct ssi_priv *ssi = &ssi_cpu_data[rtd->dai->cpu_dai->id];
137 unsigned long ssicr = SSIREG(SSICR);
138 unsigned int bits, channels, swl, recv, i;
139
140 channels = params_channels(params);
141 bits = params->msbits;
142 recv = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? 0 : 1;
143
144 pr_debug("ssi_hw_params() enter\nssicr was %08lx\n", ssicr);
145 pr_debug("bits: %d channels: %d\n", bits, channels);
146
147 ssicr &= ~(CR_TRMD | CR_CHNL_MASK | CR_DWL_MASK | CR_PDTA |
148 CR_SWL_MASK);
149
150 /* direction (send/receive) */
151 if (!recv)
152 ssicr |= CR_TRMD; /* transmit */
153
154 /* channels */
155 if ((channels < 2) || (channels > 8) || (channels & 1)) {
156 pr_debug("ssi: invalid number of channels\n");
157 return -EINVAL;
158 }
159 ssicr |= ((channels >> 1) - 1) << CR_CHNL_SHIFT;
160
161 /* DATA WORD LENGTH (DWL): databits in audio sample */
162 i = 0;
163 switch (bits) {
164 case 32: ++i;
165 case 24: ++i;
166 case 22: ++i;
167 case 20: ++i;
168 case 18: ++i;
169 case 16: ++i;
170 ssicr |= i << CR_DWL_SHIFT;
171 case 8: break;
172 default:
173 pr_debug("ssi: invalid sample width\n");
174 return -EINVAL;
175 }
176
177 /*
178 * SYSTEM WORD LENGTH: size in bits of half a frame over the I2S
179 * wires. This is usually bits_per_sample x channels/2; i.e. in
180 * Stereo mode the SWL equals DWL. SWL can be bigger than the
181 * product of (channels_per_slot x samplebits), e.g. for codecs
182 * like the AD1939 which only accept 32bit wide TDM slots. For
183 * "standard" I2S operation we set SWL = chans / 2 * DWL here.
184 * Waiting for ASoC to get TDM support ;-)
185 */
186 if ((bits > 16) && (bits <= 24)) {
187 bits = 24; /* these are padded by the SSI */
188 /*ssicr |= CR_PDTA;*/ /* cpu/data endianness ? */
189 }
190 i = 0;
191 swl = (bits * channels) / 2;
192 switch (swl) {
193 case 256: ++i;
194 case 128: ++i;
195 case 64: ++i;
196 case 48: ++i;
197 case 32: ++i;
198 case 16: ++i;
199 ssicr |= i << CR_SWL_SHIFT;
200 case 8: break;
201 default:
202 pr_debug("ssi: invalid system word length computed\n");
203 return -EINVAL;
204 }
205
206 SSIREG(SSICR) = ssicr;
207
208 pr_debug("ssi_hw_params() leave\nssicr is now %08lx\n", ssicr);
209 return 0;
210}
211
212static int ssi_set_sysclk(struct snd_soc_cpu_dai *cpu_dai, int clk_id,
213 unsigned int freq, int dir)
214{
215 struct ssi_priv *ssi = &ssi_cpu_data[cpu_dai->id];
216
217 ssi->sysclk = freq;
218
219 return 0;
220}
221
222/*
223 * This divider is used to generate the SSI_SCK (I2S bitclock) from the
224 * clock at the HAC_BIT_CLK ("oversampling clock") pin.
225 */
226static int ssi_set_clkdiv(struct snd_soc_cpu_dai *dai, int did, int div)
227{
228 struct ssi_priv *ssi = &ssi_cpu_data[dai->id];
229 unsigned long ssicr;
230 int i;
231
232 i = 0;
233 ssicr = SSIREG(SSICR) & ~CR_CKDIV_MASK;
234 switch (div) {
235 case 16: ++i;
236 case 8: ++i;
237 case 4: ++i;
238 case 2: ++i;
239 SSIREG(SSICR) = ssicr | (i << CR_CKDIV_SHIFT);
240 case 1: break;
241 default:
242 pr_debug("ssi: invalid sck divider %d\n", div);
243 return -EINVAL;
244 }
245
246 return 0;
247}
248
249static int ssi_set_fmt(struct snd_soc_cpu_dai *dai, unsigned int fmt)
250{
251 struct ssi_priv *ssi = &ssi_cpu_data[dai->id];
252 unsigned long ssicr = SSIREG(SSICR);
253
254 pr_debug("ssi_set_fmt()\nssicr was 0x%08lx\n", ssicr);
255
256 ssicr &= ~(CR_DEL | CR_PDTA | CR_BREN | CR_SWSP | CR_SCKP |
257 CR_SWS_MASTER | CR_SCK_MASTER);
258
259 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
260 case SND_SOC_DAIFMT_I2S:
261 break;
262 case SND_SOC_DAIFMT_RIGHT_J:
263 ssicr |= CR_DEL | CR_PDTA;
264 break;
265 case SND_SOC_DAIFMT_LEFT_J:
266 ssicr |= CR_DEL;
267 break;
268 default:
269 pr_debug("ssi: unsupported format\n");
270 return -EINVAL;
271 }
272
273 switch (fmt & SND_SOC_DAIFMT_CLOCK_MASK) {
274 case SND_SOC_DAIFMT_CONT:
275 break;
276 case SND_SOC_DAIFMT_GATED:
277 ssicr |= CR_BREN;
278 break;
279 }
280
281 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
282 case SND_SOC_DAIFMT_NB_NF:
283 ssicr |= CR_SCKP; /* sample data at low clkedge */
284 break;
285 case SND_SOC_DAIFMT_NB_IF:
286 ssicr |= CR_SCKP | CR_SWSP;
287 break;
288 case SND_SOC_DAIFMT_IB_NF:
289 break;
290 case SND_SOC_DAIFMT_IB_IF:
291 ssicr |= CR_SWSP; /* word select starts low */
292 break;
293 default:
294 pr_debug("ssi: invalid inversion\n");
295 return -EINVAL;
296 }
297
298 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
299 case SND_SOC_DAIFMT_CBM_CFM:
300 break;
301 case SND_SOC_DAIFMT_CBS_CFM:
302 ssicr |= CR_SCK_MASTER;
303 break;
304 case SND_SOC_DAIFMT_CBM_CFS:
305 ssicr |= CR_SWS_MASTER;
306 break;
307 case SND_SOC_DAIFMT_CBS_CFS:
308 ssicr |= CR_SWS_MASTER | CR_SCK_MASTER;
309 break;
310 default:
311 pr_debug("ssi: invalid master/slave configuration\n");
312 return -EINVAL;
313 }
314
315 SSIREG(SSICR) = ssicr;
316 pr_debug("ssi_set_fmt() leave\nssicr is now 0x%08lx\n", ssicr);
317
318 return 0;
319}
320
321/* the SSI depends on an external clocksource (at HAC_BIT_CLK) even in
322 * Master mode, so really this is board specific; the SSI can do any
323 * rate with the right bitclk and divider settings.
324 */
325#define SSI_RATES \
326 SNDRV_PCM_RATE_8000_192000
327
328/* the SSI can do 8-32 bit samples, with 8 possible channels */
329#define SSI_FMTS \
330 (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 | \
331 SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE | \
332 SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_U20_3LE | \
333 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_U24_3LE | \
334 SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_U32_LE)
335
336struct snd_soc_cpu_dai sh4_ssi_dai[] = {
337{
338 .name = "SSI0",
339 .id = 0,
340 .type = SND_SOC_DAI_I2S,
341 .playback = {
342 .rates = SSI_RATES,
343 .formats = SSI_FMTS,
344 .channels_min = 2,
345 .channels_max = 8,
346 },
347 .capture = {
348 .rates = SSI_RATES,
349 .formats = SSI_FMTS,
350 .channels_min = 2,
351 .channels_max = 8,
352 },
353 .ops = {
354 .startup = ssi_startup,
355 .shutdown = ssi_shutdown,
356 .trigger = ssi_trigger,
357 .hw_params = ssi_hw_params,
358 },
359 .dai_ops = {
360 .set_sysclk = ssi_set_sysclk,
361 .set_clkdiv = ssi_set_clkdiv,
362 .set_fmt = ssi_set_fmt,
363 },
364},
365#ifdef CONFIG_CPU_SUBTYPE_SH7760
366{
367 .name = "SSI1",
368 .id = 1,
369 .type = SND_SOC_DAI_I2S,
370 .playback = {
371 .rates = SSI_RATES,
372 .formats = SSI_FMTS,
373 .channels_min = 2,
374 .channels_max = 8,
375 },
376 .capture = {
377 .rates = SSI_RATES,
378 .formats = SSI_FMTS,
379 .channels_min = 2,
380 .channels_max = 8,
381 },
382 .ops = {
383 .startup = ssi_startup,
384 .shutdown = ssi_shutdown,
385 .trigger = ssi_trigger,
386 .hw_params = ssi_hw_params,
387 },
388 .dai_ops = {
389 .set_sysclk = ssi_set_sysclk,
390 .set_clkdiv = ssi_set_clkdiv,
391 .set_fmt = ssi_set_fmt,
392 },
393},
394#endif
395};
396EXPORT_SYMBOL_GPL(sh4_ssi_dai);
397
398MODULE_LICENSE("GPL");
399MODULE_DESCRIPTION("SuperH onchip SSI (I2S) audio driver");
400MODULE_AUTHOR("Manuel Lauss <mano@roarinelk.homelinux.net>");
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c
index 8ebc1adb5ed9..7bd5852fcc0d 100644
--- a/sound/usb/usbaudio.c
+++ b/sound/usb/usbaudio.c
@@ -2350,7 +2350,9 @@ static int is_big_endian_format(struct snd_usb_audio *chip, struct audioformat *
2350 return 1; 2350 return 1;
2351 break; 2351 break;
2352 case USB_ID(0x0763, 0x2003): /* M-Audio Audiophile USB */ 2352 case USB_ID(0x0763, 0x2003): /* M-Audio Audiophile USB */
2353 return 1; 2353 if (device_setup[chip->index] == 0x00 ||
2354 fp->altsetting==1 || fp->altsetting==2 || fp->altsetting==3)
2355 return 1;
2354 } 2356 }
2355 return 0; 2357 return 0;
2356} 2358}
@@ -2530,7 +2532,18 @@ static int parse_audio_format_i(struct snd_usb_audio *chip, struct audioformat *
2530 * but we give normal PCM format to get the existing 2532 * but we give normal PCM format to get the existing
2531 * apps working... 2533 * apps working...
2532 */ 2534 */
2533 pcm_format = SNDRV_PCM_FORMAT_S16_LE; 2535 switch (chip->usb_id) {
2536
2537 case USB_ID(0x0763, 0x2003): /* M-Audio Audiophile USB */
2538 if (device_setup[chip->index] == 0x00 &&
2539 fp->altsetting == 6)
2540 pcm_format = SNDRV_PCM_FORMAT_S16_BE;
2541 else
2542 pcm_format = SNDRV_PCM_FORMAT_S16_LE;
2543 break;
2544 default:
2545 pcm_format = SNDRV_PCM_FORMAT_S16_LE;
2546 }
2534 } else { 2547 } else {
2535 pcm_format = parse_audio_format_i_type(chip, fp, format, fmt); 2548 pcm_format = parse_audio_format_i_type(chip, fp, format, fmt);
2536 if (pcm_format < 0) 2549 if (pcm_format < 0)
@@ -3251,6 +3264,11 @@ static int snd_usb_cm106_boot_quirk(struct usb_device *dev)
3251static int audiophile_skip_setting_quirk(struct snd_usb_audio *chip, 3264static int audiophile_skip_setting_quirk(struct snd_usb_audio *chip,
3252 int iface, int altno) 3265 int iface, int altno)
3253{ 3266{
3267 /* Reset ALL ifaces to 0 altsetting.
3268 * Call it for every possible altsetting of every interface.
3269 */
3270 usb_set_interface(chip->dev, iface, 0);
3271
3254 if (device_setup[chip->index] & AUDIOPHILE_SET) { 3272 if (device_setup[chip->index] & AUDIOPHILE_SET) {
3255 if ((device_setup[chip->index] & AUDIOPHILE_SET_DTS) 3273 if ((device_setup[chip->index] & AUDIOPHILE_SET_DTS)
3256 && altno != 6) 3274 && altno != 6)
diff --git a/sound/usb/usbquirks.h b/sound/usb/usbquirks.h
index 374fbf657a2d..5a2f518c6629 100644
--- a/sound/usb/usbquirks.h
+++ b/sound/usb/usbquirks.h
@@ -57,6 +57,24 @@
57 USB_DEVICE_ID_MATCH_INT_CLASS | 57 USB_DEVICE_ID_MATCH_INT_CLASS |
58 USB_DEVICE_ID_MATCH_INT_SUBCLASS, 58 USB_DEVICE_ID_MATCH_INT_SUBCLASS,
59 .idVendor = 0x046d, 59 .idVendor = 0x046d,
60 .idProduct = 0x08ae,
61 .bInterfaceClass = USB_CLASS_AUDIO,
62 .bInterfaceSubClass = USB_SUBCLASS_AUDIO_CONTROL
63},
64{
65 .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
66 USB_DEVICE_ID_MATCH_INT_CLASS |
67 USB_DEVICE_ID_MATCH_INT_SUBCLASS,
68 .idVendor = 0x046d,
69 .idProduct = 0x08c6,
70 .bInterfaceClass = USB_CLASS_AUDIO,
71 .bInterfaceSubClass = USB_SUBCLASS_AUDIO_CONTROL
72},
73{
74 .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
75 USB_DEVICE_ID_MATCH_INT_CLASS |
76 USB_DEVICE_ID_MATCH_INT_SUBCLASS,
77 .idVendor = 0x046d,
60 .idProduct = 0x08f0, 78 .idProduct = 0x08f0,
61 .bInterfaceClass = USB_CLASS_AUDIO, 79 .bInterfaceClass = USB_CLASS_AUDIO,
62 .bInterfaceSubClass = USB_SUBCLASS_AUDIO_CONTROL 80 .bInterfaceSubClass = USB_SUBCLASS_AUDIO_CONTROL
@@ -1051,7 +1069,15 @@ YAMAHA_DEVICE(0x7010, "UB99"),
1051 .type = QUIRK_MIDI_STANDARD_INTERFACE 1069 .type = QUIRK_MIDI_STANDARD_INTERFACE
1052 } 1070 }
1053}, 1071},
1054 /* TODO: add Roland EXR support */ 1072{
1073 USB_DEVICE(0x0582, 0x0060),
1074 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
1075 .vendor_name = "Roland",
1076 .product_name = "EXR Series",
1077 .ifnum = 0,
1078 .type = QUIRK_MIDI_STANDARD_INTERFACE
1079 }
1080},
1055{ 1081{
1056 /* has ID 0x0067 when not in "Advanced Driver" mode */ 1082 /* has ID 0x0067 when not in "Advanced Driver" mode */
1057 USB_DEVICE(0x0582, 0x0065), 1083 USB_DEVICE(0x0582, 0x0065),
@@ -1094,6 +1120,19 @@ YAMAHA_DEVICE(0x7010, "UB99"),
1094 } 1120 }
1095 } 1121 }
1096}, 1122},
1123{
1124 USB_DEVICE(0x582, 0x00a6),
1125 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
1126 .vendor_name = "Roland",
1127 .product_name = "Juno-G",
1128 .ifnum = 0,
1129 .type = QUIRK_MIDI_FIXED_ENDPOINT,
1130 .data = & (const struct snd_usb_midi_endpoint_info) {
1131 .out_cables = 0x0001,
1132 .in_cables = 0x0001
1133 }
1134 }
1135},
1097{ /* 1136{ /*
1098 * This quirk is for the "Advanced" modes of the Edirol UA-25. 1137 * This quirk is for the "Advanced" modes of the Edirol UA-25.
1099 * If the switch is not in an advanced setting, the UA-25 has 1138 * If the switch is not in an advanced setting, the UA-25 has
@@ -1230,6 +1269,37 @@ YAMAHA_DEVICE(0x7010, "UB99"),
1230 } 1269 }
1231}, 1270},
1232 /* TODO: add Edirol MD-P1 support */ 1271 /* TODO: add Edirol MD-P1 support */
1272{
1273 /* Roland SH-201 */
1274 USB_DEVICE(0x0582, 0x00ad),
1275 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
1276 .vendor_name = "Roland",
1277 .product_name = "SH-201",
1278 .ifnum = QUIRK_ANY_INTERFACE,
1279 .type = QUIRK_COMPOSITE,
1280 .data = (const struct snd_usb_audio_quirk[]) {
1281 {
1282 .ifnum = 0,
1283 .type = QUIRK_AUDIO_STANDARD_INTERFACE
1284 },
1285 {
1286 .ifnum = 1,
1287 .type = QUIRK_AUDIO_STANDARD_INTERFACE
1288 },
1289 {
1290 .ifnum = 2,
1291 .type = QUIRK_MIDI_FIXED_ENDPOINT,
1292 .data = & (const struct snd_usb_midi_endpoint_info) {
1293 .out_cables = 0x0001,
1294 .in_cables = 0x0001
1295 }
1296 },
1297 {
1298 .ifnum = -1
1299 }
1300 }
1301 }
1302},
1233 1303
1234/* Guillemot devices */ 1304/* Guillemot devices */
1235{ 1305{
diff --git a/sound/usb/usx2y/usbusx2yaudio.c b/sound/usb/usx2y/usbusx2yaudio.c
index 0a352e46862f..48e9aa3f18c9 100644
--- a/sound/usb/usx2y/usbusx2yaudio.c
+++ b/sound/usb/usx2y/usbusx2yaudio.c
@@ -935,10 +935,9 @@ static struct snd_pcm_ops snd_usX2Y_pcm_ops =
935 */ 935 */
936static void usX2Y_audio_stream_free(struct snd_usX2Y_substream **usX2Y_substream) 936static void usX2Y_audio_stream_free(struct snd_usX2Y_substream **usX2Y_substream)
937{ 937{
938 if (NULL != usX2Y_substream[SNDRV_PCM_STREAM_PLAYBACK]) { 938 kfree(usX2Y_substream[SNDRV_PCM_STREAM_PLAYBACK]);
939 kfree(usX2Y_substream[SNDRV_PCM_STREAM_PLAYBACK]); 939 usX2Y_substream[SNDRV_PCM_STREAM_PLAYBACK] = NULL;
940 usX2Y_substream[SNDRV_PCM_STREAM_PLAYBACK] = NULL; 940
941 }
942 kfree(usX2Y_substream[SNDRV_PCM_STREAM_CAPTURE]); 941 kfree(usX2Y_substream[SNDRV_PCM_STREAM_CAPTURE]);
943 usX2Y_substream[SNDRV_PCM_STREAM_CAPTURE] = NULL; 942 usX2Y_substream[SNDRV_PCM_STREAM_CAPTURE] = NULL;
944} 943}