aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci')
-rw-r--r--sound/pci/Kconfig10
-rw-r--r--sound/pci/Makefile1
-rw-r--r--sound/pci/ac97/ac97_patch.c7
-rw-r--r--sound/pci/au88x0/au88x0_core.c10
-rw-r--r--sound/pci/ca0106/ca0106_mixer.c12
-rw-r--r--sound/pci/ctxfi/Makefile5
-rw-r--r--sound/pci/ctxfi/ct20k1reg.h636
-rw-r--r--sound/pci/ctxfi/ct20k2reg.h85
-rw-r--r--sound/pci/ctxfi/ctamixer.c488
-rw-r--r--sound/pci/ctxfi/ctamixer.h96
-rw-r--r--sound/pci/ctxfi/ctatc.c1619
-rw-r--r--sound/pci/ctxfi/ctatc.h147
-rw-r--r--sound/pci/ctxfi/ctdaio.c769
-rw-r--r--sound/pci/ctxfi/ctdaio.h122
-rw-r--r--sound/pci/ctxfi/cthardware.c91
-rw-r--r--sound/pci/ctxfi/cthardware.h196
-rw-r--r--sound/pci/ctxfi/cthw20k1.c2248
-rw-r--r--sound/pci/ctxfi/cthw20k1.h26
-rw-r--r--sound/pci/ctxfi/cthw20k2.c2137
-rw-r--r--sound/pci/ctxfi/cthw20k2.h26
-rw-r--r--sound/pci/ctxfi/ctimap.c112
-rw-r--r--sound/pci/ctxfi/ctimap.h40
-rw-r--r--sound/pci/ctxfi/ctmixer.c1123
-rw-r--r--sound/pci/ctxfi/ctmixer.h67
-rw-r--r--sound/pci/ctxfi/ctpcm.c426
-rw-r--r--sound/pci/ctxfi/ctpcm.h27
-rw-r--r--sound/pci/ctxfi/ctresource.c301
-rw-r--r--sound/pci/ctxfi/ctresource.h72
-rw-r--r--sound/pci/ctxfi/ctsrc.c886
-rw-r--r--sound/pci/ctxfi/ctsrc.h149
-rw-r--r--sound/pci/ctxfi/cttimer.c441
-rw-r--r--sound/pci/ctxfi/cttimer.h29
-rw-r--r--sound/pci/ctxfi/ctvmem.c250
-rw-r--r--sound/pci/ctxfi/ctvmem.h61
-rw-r--r--sound/pci/ctxfi/xfi.c142
-rw-r--r--sound/pci/emu10k1/emupcm.c2
-rw-r--r--sound/pci/hda/Kconfig13
-rw-r--r--sound/pci/hda/Makefile4
-rw-r--r--sound/pci/hda/hda_beep.c55
-rw-r--r--sound/pci/hda/hda_beep.h5
-rw-r--r--sound/pci/hda/hda_codec.c239
-rw-r--r--sound/pci/hda/hda_codec.h13
-rw-r--r--sound/pci/hda/hda_hwdep.c9
-rw-r--r--sound/pci/hda/hda_intel.c198
-rw-r--r--sound/pci/hda/hda_proc.c8
-rw-r--r--sound/pci/hda/patch_ca0110.c573
-rw-r--r--sound/pci/hda/patch_conexant.c1
-rw-r--r--sound/pci/hda/patch_nvhdmi.c279
-rw-r--r--sound/pci/hda/patch_realtek.c2333
-rw-r--r--sound/pci/hda/patch_sigmatel.c292
-rw-r--r--sound/pci/hda/patch_via.c111
-rw-r--r--sound/pci/riptide/riptide.c10
-rw-r--r--sound/pci/rme9652/hdsp.c7
-rw-r--r--sound/pci/rme9652/hdspm.c4
-rw-r--r--sound/pci/via82xx.c2
55 files changed, 15664 insertions, 1351 deletions
diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig
index 7478971cd21..feba076b366 100644
--- a/sound/pci/Kconfig
+++ b/sound/pci/Kconfig
@@ -275,6 +275,16 @@ config SND_CS5535AUDIO
275 To compile this driver as a module, choose M here: the module 275 To compile this driver as a module, choose M here: the module
276 will be called snd-cs5535audio. 276 will be called snd-cs5535audio.
277 277
278config SND_CTXFI
279 tristate "Creative Sound Blaster X-Fi"
280 select SND_PCM
281 help
282 If you want to use soundcards based on Creative Sound Blastr X-Fi
283 boards with 20k1 or 20k2 chips, say Y here.
284
285 To compile this driver as a module, choose M here: the module
286 will be called snd-ctxfi.
287
278config SND_DARLA20 288config SND_DARLA20
279 tristate "(Echoaudio) Darla20" 289 tristate "(Echoaudio) Darla20"
280 select FW_LOADER 290 select FW_LOADER
diff --git a/sound/pci/Makefile b/sound/pci/Makefile
index 65b25d221cd..6a1281ec01e 100644
--- a/sound/pci/Makefile
+++ b/sound/pci/Makefile
@@ -59,6 +59,7 @@ obj-$(CONFIG_SND) += \
59 ali5451/ \ 59 ali5451/ \
60 au88x0/ \ 60 au88x0/ \
61 aw2/ \ 61 aw2/ \
62 ctxfi/ \
62 ca0106/ \ 63 ca0106/ \
63 cs46xx/ \ 64 cs46xx/ \
64 cs5535audio/ \ 65 cs5535audio/ \
diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c
index 81bc93e5f1e..7337abdbe4e 100644
--- a/sound/pci/ac97/ac97_patch.c
+++ b/sound/pci/ac97/ac97_patch.c
@@ -958,10 +958,13 @@ static int patch_sigmatel_stac9708_3d(struct snd_ac97 * ac97)
958} 958}
959 959
960static const struct snd_kcontrol_new snd_ac97_sigmatel_4speaker = 960static const struct snd_kcontrol_new snd_ac97_sigmatel_4speaker =
961AC97_SINGLE("Sigmatel 4-Speaker Stereo Playback Switch", AC97_SIGMATEL_DAC2INVERT, 2, 1, 0); 961AC97_SINGLE("Sigmatel 4-Speaker Stereo Playback Switch",
962 AC97_SIGMATEL_DAC2INVERT, 2, 1, 0);
962 963
964/* "Sigmatel " removed due to excessive name length: */
963static const struct snd_kcontrol_new snd_ac97_sigmatel_phaseinvert = 965static const struct snd_kcontrol_new snd_ac97_sigmatel_phaseinvert =
964AC97_SINGLE("Sigmatel Surround Phase Inversion Playback Switch", AC97_SIGMATEL_DAC2INVERT, 3, 1, 0); 966AC97_SINGLE("Surround Phase Inversion Playback Switch",
967 AC97_SIGMATEL_DAC2INVERT, 3, 1, 0);
965 968
966static const struct snd_kcontrol_new snd_ac97_sigmatel_controls[] = { 969static const struct snd_kcontrol_new snd_ac97_sigmatel_controls[] = {
967AC97_SINGLE("Sigmatel DAC 6dB Attenuate", AC97_SIGMATEL_ANALOG, 1, 1, 0), 970AC97_SINGLE("Sigmatel DAC 6dB Attenuate", AC97_SIGMATEL_ANALOG, 1, 1, 0),
diff --git a/sound/pci/au88x0/au88x0_core.c b/sound/pci/au88x0/au88x0_core.c
index 3906f5afe27..23f49f356e0 100644
--- a/sound/pci/au88x0/au88x0_core.c
+++ b/sound/pci/au88x0/au88x0_core.c
@@ -1255,8 +1255,8 @@ static int inline vortex_adbdma_getlinearpos(vortex_t * vortex, int adbdma)
1255 int temp; 1255 int temp;
1256 1256
1257 temp = hwread(vortex->mmio, VORTEX_ADBDMA_STAT + (adbdma << 2)); 1257 temp = hwread(vortex->mmio, VORTEX_ADBDMA_STAT + (adbdma << 2));
1258 temp = (dma->period_virt * dma->period_bytes) + (temp & POS_MASK); 1258 temp = (dma->period_virt * dma->period_bytes) + (temp & (dma->period_bytes - 1));
1259 return (temp); 1259 return temp;
1260} 1260}
1261 1261
1262static void vortex_adbdma_startfifo(vortex_t * vortex, int adbdma) 1262static void vortex_adbdma_startfifo(vortex_t * vortex, int adbdma)
@@ -1504,8 +1504,7 @@ static int inline vortex_wtdma_getlinearpos(vortex_t * vortex, int wtdma)
1504 int temp; 1504 int temp;
1505 1505
1506 temp = hwread(vortex->mmio, VORTEX_WTDMA_STAT + (wtdma << 2)); 1506 temp = hwread(vortex->mmio, VORTEX_WTDMA_STAT + (wtdma << 2));
1507 //temp = (temp & POS_MASK) + (((temp>>WT_SUBBUF_SHIFT) & WT_SUBBUF_MASK)*(dma->cfg0&POS_MASK)); 1507 temp = (dma->period_virt * dma->period_bytes) + (temp & (dma->period_bytes - 1));
1508 temp = (temp & POS_MASK) + ((dma->period_virt) * (dma->period_bytes));
1509 return temp; 1508 return temp;
1510} 1509}
1511 1510
@@ -2441,7 +2440,8 @@ static irqreturn_t vortex_interrupt(int irq, void *dev_id)
2441 spin_lock(&vortex->lock); 2440 spin_lock(&vortex->lock);
2442 for (i = 0; i < NR_ADB; i++) { 2441 for (i = 0; i < NR_ADB; i++) {
2443 if (vortex->dma_adb[i].fifo_status == FIFO_START) { 2442 if (vortex->dma_adb[i].fifo_status == FIFO_START) {
2444 if (vortex_adbdma_bufshift(vortex, i)) ; 2443 if (!vortex_adbdma_bufshift(vortex, i))
2444 continue;
2445 spin_unlock(&vortex->lock); 2445 spin_unlock(&vortex->lock);
2446 snd_pcm_period_elapsed(vortex->dma_adb[i]. 2446 snd_pcm_period_elapsed(vortex->dma_adb[i].
2447 substream); 2447 substream);
diff --git a/sound/pci/ca0106/ca0106_mixer.c b/sound/pci/ca0106/ca0106_mixer.c
index ad2888705d2..c8c6f437f5b 100644
--- a/sound/pci/ca0106/ca0106_mixer.c
+++ b/sound/pci/ca0106/ca0106_mixer.c
@@ -739,7 +739,7 @@ static int __devinit rename_ctl(struct snd_card *card, const char *src, const ch
739 } while (0) 739 } while (0)
740 740
741static __devinitdata 741static __devinitdata
742DECLARE_TLV_DB_SCALE(snd_ca0106_master_db_scale, -6375, 50, 1); 742DECLARE_TLV_DB_SCALE(snd_ca0106_master_db_scale, -6375, 25, 1);
743 743
744static char *slave_vols[] __devinitdata = { 744static char *slave_vols[] __devinitdata = {
745 "Analog Front Playback Volume", 745 "Analog Front Playback Volume",
@@ -800,7 +800,7 @@ int __devinit snd_ca0106_mixer(struct snd_ca0106 *emu)
800 "Capture Volume", 800 "Capture Volume",
801 "External Amplifier", 801 "External Amplifier",
802 "Sigmatel 4-Speaker Stereo Playback Switch", 802 "Sigmatel 4-Speaker Stereo Playback Switch",
803 "Sigmatel Surround Phase Inversion Playback ", 803 "Surround Phase Inversion Playback Switch",
804 NULL 804 NULL
805 }; 805 };
806 static char *ca0106_rename_ctls[] = { 806 static char *ca0106_rename_ctls[] = {
@@ -841,6 +841,9 @@ int __devinit snd_ca0106_mixer(struct snd_ca0106 *emu)
841 snd_ca0106_master_db_scale); 841 snd_ca0106_master_db_scale);
842 if (!vmaster) 842 if (!vmaster)
843 return -ENOMEM; 843 return -ENOMEM;
844 err = snd_ctl_add(card, vmaster);
845 if (err < 0)
846 return err;
844 add_slaves(card, vmaster, slave_vols); 847 add_slaves(card, vmaster, slave_vols);
845 848
846 if (emu->details->spi_dac == 1) { 849 if (emu->details->spi_dac == 1) {
@@ -848,8 +851,13 @@ int __devinit snd_ca0106_mixer(struct snd_ca0106 *emu)
848 NULL); 851 NULL);
849 if (!vmaster) 852 if (!vmaster)
850 return -ENOMEM; 853 return -ENOMEM;
854 err = snd_ctl_add(card, vmaster);
855 if (err < 0)
856 return err;
851 add_slaves(card, vmaster, slave_sws); 857 add_slaves(card, vmaster, slave_sws);
852 } 858 }
859
860 strcpy(card->mixername, "CA0106");
853 return 0; 861 return 0;
854} 862}
855 863
diff --git a/sound/pci/ctxfi/Makefile b/sound/pci/ctxfi/Makefile
new file mode 100644
index 00000000000..15075f89e98
--- /dev/null
+++ b/sound/pci/ctxfi/Makefile
@@ -0,0 +1,5 @@
1snd-ctxfi-objs := xfi.o ctatc.o ctvmem.o ctpcm.o ctmixer.o ctresource.o \
2 ctsrc.o ctamixer.o ctdaio.o ctimap.o cthardware.o cttimer.o \
3 cthw20k2.o cthw20k1.o
4
5obj-$(CONFIG_SND_CTXFI) += snd-ctxfi.o
diff --git a/sound/pci/ctxfi/ct20k1reg.h b/sound/pci/ctxfi/ct20k1reg.h
new file mode 100644
index 00000000000..f2e34e3f27e
--- /dev/null
+++ b/sound/pci/ctxfi/ct20k1reg.h
@@ -0,0 +1,636 @@
1/**
2 * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
3 *
4 * This source file is released under GPL v2 license (no other versions).
5 * See the COPYING file included in the main directory of this source
6 * distribution for the license terms and conditions.
7 */
8
9#ifndef CT20K1REG_H
10#define CT20k1REG_H
11
12/* 20k1 registers */
13#define DSPXRAM_START 0x000000
14#define DSPXRAM_END 0x013FFC
15#define DSPAXRAM_START 0x020000
16#define DSPAXRAM_END 0x023FFC
17#define DSPYRAM_START 0x040000
18#define DSPYRAM_END 0x04FFFC
19#define DSPAYRAM_START 0x020000
20#define DSPAYRAM_END 0x063FFC
21#define DSPMICRO_START 0x080000
22#define DSPMICRO_END 0x0B3FFC
23#define DSP0IO_START 0x100000
24#define DSP0IO_END 0x101FFC
25#define AUDIORINGIPDSP0_START 0x100000
26#define AUDIORINGIPDSP0_END 0x1003FC
27#define AUDIORINGOPDSP0_START 0x100400
28#define AUDIORINGOPDSP0_END 0x1007FC
29#define AUDPARARINGIODSP0_START 0x100800
30#define AUDPARARINGIODSP0_END 0x100BFC
31#define DSP0LOCALHWREG_START 0x100C00
32#define DSP0LOCALHWREG_END 0x100C3C
33#define DSP0XYRAMAGINDEX_START 0x100C40
34#define DSP0XYRAMAGINDEX_END 0x100C5C
35#define DSP0XYRAMAGMDFR_START 0x100C60
36#define DSP0XYRAMAGMDFR_END 0x100C7C
37#define DSP0INTCONTLVEC_START 0x100C80
38#define DSP0INTCONTLVEC_END 0x100CD8
39#define INTCONTLGLOBALREG_START 0x100D1C
40#define INTCONTLGLOBALREG_END 0x100D3C
41#define HOSTINTFPORTADDRCONTDSP0 0x100D40
42#define HOSTINTFPORTDATADSP0 0x100D44
43#define TIME0PERENBDSP0 0x100D60
44#define TIME0COUNTERDSP0 0x100D64
45#define TIME1PERENBDSP0 0x100D68
46#define TIME1COUNTERDSP0 0x100D6C
47#define TIME2PERENBDSP0 0x100D70
48#define TIME2COUNTERDSP0 0x100D74
49#define TIME3PERENBDSP0 0x100D78
50#define TIME3COUNTERDSP0 0x100D7C
51#define XRAMINDOPERREFNOUP_STARTDSP0 0x100D80
52#define XRAMINDOPERREFNOUP_ENDDSP0 0x100D9C
53#define XRAMINDOPERREFUP_STARTDSP0 0x100DA0
54#define XRAMINDOPERREFUP_ENDDSP0 0x100DBC
55#define YRAMINDOPERREFNOUP_STARTDSP0 0x100DC0
56#define YRAMINDOPERREFNOUP_ENDDSP0 0x100DDC
57#define YRAMINDOPERREFUP_STARTDSP0 0x100DE0
58#define YRAMINDOPERREFUP_ENDDSP0 0x100DFC
59#define DSP0CONDCODE 0x100E00
60#define DSP0STACKFLAG 0x100E04
61#define DSP0PROGCOUNTSTACKPTREG 0x100E08
62#define DSP0PROGCOUNTSTACKDATAREG 0x100E0C
63#define DSP0CURLOOPADDRREG 0x100E10
64#define DSP0CURLOOPCOUNT 0x100E14
65#define DSP0TOPLOOPCOUNTSTACK 0x100E18
66#define DSP0TOPLOOPADDRSTACK 0x100E1C
67#define DSP0LOOPSTACKPTR 0x100E20
68#define DSP0STASSTACKDATAREG 0x100E24
69#define DSP0STASSTACKPTR 0x100E28
70#define DSP0PROGCOUNT 0x100E2C
71#define GLOBDSPDEBGREG 0x100E30
72#define GLOBDSPBREPTRREG 0x100E30
73#define DSP0XYRAMBASE_START 0x100EA0
74#define DSP0XYRAMBASE_END 0x100EBC
75#define DSP0XYRAMLENG_START 0x100EC0
76#define DSP0XYRAMLENG_END 0x100EDC
77#define SEMAPHOREREGDSP0 0x100EE0
78#define DSP0INTCONTMASKREG 0x100EE4
79#define DSP0INTCONTPENDREG 0x100EE8
80#define DSP0INTCONTSERVINT 0x100EEC
81#define DSPINTCONTEXTINTMODREG 0x100EEC
82#define GPIODSP0 0x100EFC
83#define DMADSPBASEADDRREG_STARTDSP0 0x100F00
84#define DMADSPBASEADDRREG_ENDDSP0 0x100F1C
85#define DMAHOSTBASEADDRREG_STARTDSP0 0x100F20
86#define DMAHOSTBASEADDRREG_ENDDSP0 0x100F3C
87#define DMADSPCURADDRREG_STARTDSP0 0x100F40
88#define DMADSPCURADDRREG_ENDDSP0 0x100F5C
89#define DMAHOSTCURADDRREG_STARTDSP0 0x100F60
90#define DMAHOSTCURADDRREG_ENDDSP0 0x100F7C
91#define DMATANXCOUNTREG_STARTDSP0 0x100F80
92#define DMATANXCOUNTREG_ENDDSP0 0x100F9C
93#define DMATIMEBUGREG_STARTDSP0 0x100FA0
94#define DMATIMEBUGREG_ENDDSP0 0x100FAC
95#define DMACNTLMODFREG_STARTDSP0 0x100FA0
96#define DMACNTLMODFREG_ENDDSP0 0x100FAC
97
98#define DMAGLOBSTATSREGDSP0 0x100FEC
99#define DSP0XGPRAM_START 0x101000
100#define DSP0XGPRAM_END 0x1017FC
101#define DSP0YGPRAM_START 0x101800
102#define DSP0YGPRAM_END 0x101FFC
103
104
105
106
107#define AUDIORINGIPDSP1_START 0x102000
108#define AUDIORINGIPDSP1_END 0x1023FC
109#define AUDIORINGOPDSP1_START 0x102400
110#define AUDIORINGOPDSP1_END 0x1027FC
111#define AUDPARARINGIODSP1_START 0x102800
112#define AUDPARARINGIODSP1_END 0x102BFC
113#define DSP1LOCALHWREG_START 0x102C00
114#define DSP1LOCALHWREG_END 0x102C3C
115#define DSP1XYRAMAGINDEX_START 0x102C40
116#define DSP1XYRAMAGINDEX_END 0x102C5C
117#define DSP1XYRAMAGMDFR_START 0x102C60
118#define DSP1XYRAMAGMDFR_END 0x102C7C
119#define DSP1INTCONTLVEC_START 0x102C80
120#define DSP1INTCONTLVEC_END 0x102CD8
121#define HOSTINTFPORTADDRCONTDSP1 0x102D40
122#define HOSTINTFPORTDATADSP1 0x102D44
123#define TIME0PERENBDSP1 0x102D60
124#define TIME0COUNTERDSP1 0x102D64
125#define TIME1PERENBDSP1 0x102D68
126#define TIME1COUNTERDSP1 0x102D6C
127#define TIME2PERENBDSP1 0x102D70
128#define TIME2COUNTERDSP1 0x102D74
129#define TIME3PERENBDSP1 0x102D78
130#define TIME3COUNTERDSP1 0x102D7C
131#define XRAMINDOPERREFNOUP_STARTDSP1 0x102D80
132#define XRAMINDOPERREFNOUP_ENDDSP1 0x102D9C
133#define XRAMINDOPERREFUP_STARTDSP1 0x102DA0
134#define XRAMINDOPERREFUP_ENDDSP1 0x102DBC
135#define YRAMINDOPERREFNOUP_STARTDSP1 0x102DC0
136#define YRAMINDOPERREFNOUP_ENDDSP1 0x102DDC
137#define YRAMINDOPERREFUP_STARTDSP1 0x102DE0
138#define YRAMINDOPERREFUP_ENDDSP1 0x102DFC
139
140#define DSP1CONDCODE 0x102E00
141#define DSP1STACKFLAG 0x102E04
142#define DSP1PROGCOUNTSTACKPTREG 0x102E08
143#define DSP1PROGCOUNTSTACKDATAREG 0x102E0C
144#define DSP1CURLOOPADDRREG 0x102E10
145#define DSP1CURLOOPCOUNT 0x102E14
146#define DSP1TOPLOOPCOUNTSTACK 0x102E18
147#define DSP1TOPLOOPADDRSTACK 0x102E1C
148#define DSP1LOOPSTACKPTR 0x102E20
149#define DSP1STASSTACKDATAREG 0x102E24
150#define DSP1STASSTACKPTR 0x102E28
151#define DSP1PROGCOUNT 0x102E2C
152#define DSP1XYRAMBASE_START 0x102EA0
153#define DSP1XYRAMBASE_END 0x102EBC
154#define DSP1XYRAMLENG_START 0x102EC0
155#define DSP1XYRAMLENG_END 0x102EDC
156#define SEMAPHOREREGDSP1 0x102EE0
157#define DSP1INTCONTMASKREG 0x102EE4
158#define DSP1INTCONTPENDREG 0x102EE8
159#define DSP1INTCONTSERVINT 0x102EEC
160#define GPIODSP1 0x102EFC
161#define DMADSPBASEADDRREG_STARTDSP1 0x102F00
162#define DMADSPBASEADDRREG_ENDDSP1 0x102F1C
163#define DMAHOSTBASEADDRREG_STARTDSP1 0x102F20
164#define DMAHOSTBASEADDRREG_ENDDSP1 0x102F3C
165#define DMADSPCURADDRREG_STARTDSP1 0x102F40
166#define DMADSPCURADDRREG_ENDDSP1 0x102F5C
167#define DMAHOSTCURADDRREG_STARTDSP1 0x102F60
168#define DMAHOSTCURADDRREG_ENDDSP1 0x102F7C
169#define DMATANXCOUNTREG_STARTDSP1 0x102F80
170#define DMATANXCOUNTREG_ENDDSP1 0x102F9C
171#define DMATIMEBUGREG_STARTDSP1 0x102FA0
172#define DMATIMEBUGREG_ENDDSP1 0x102FAC
173#define DMACNTLMODFREG_STARTDSP1 0x102FA0
174#define DMACNTLMODFREG_ENDDSP1 0x102FAC
175
176#define DMAGLOBSTATSREGDSP1 0x102FEC
177#define DSP1XGPRAM_START 0x103000
178#define DSP1XGPRAM_END 0x1033FC
179#define DSP1YGPRAM_START 0x103400
180#define DSP1YGPRAM_END 0x1037FC
181
182
183
184#define AUDIORINGIPDSP2_START 0x104000
185#define AUDIORINGIPDSP2_END 0x1043FC
186#define AUDIORINGOPDSP2_START 0x104400
187#define AUDIORINGOPDSP2_END 0x1047FC
188#define AUDPARARINGIODSP2_START 0x104800
189#define AUDPARARINGIODSP2_END 0x104BFC
190#define DSP2LOCALHWREG_START 0x104C00
191#define DSP2LOCALHWREG_END 0x104C3C
192#define DSP2XYRAMAGINDEX_START 0x104C40
193#define DSP2XYRAMAGINDEX_END 0x104C5C
194#define DSP2XYRAMAGMDFR_START 0x104C60
195#define DSP2XYRAMAGMDFR_END 0x104C7C
196#define DSP2INTCONTLVEC_START 0x104C80
197#define DSP2INTCONTLVEC_END 0x104CD8
198#define HOSTINTFPORTADDRCONTDSP2 0x104D40
199#define HOSTINTFPORTDATADSP2 0x104D44
200#define TIME0PERENBDSP2 0x104D60
201#define TIME0COUNTERDSP2 0x104D64
202#define TIME1PERENBDSP2 0x104D68
203#define TIME1COUNTERDSP2 0x104D6C
204#define TIME2PERENBDSP2 0x104D70
205#define TIME2COUNTERDSP2 0x104D74
206#define TIME3PERENBDSP2 0x104D78
207#define TIME3COUNTERDSP2 0x104D7C
208#define XRAMINDOPERREFNOUP_STARTDSP2 0x104D80
209#define XRAMINDOPERREFNOUP_ENDDSP2 0x104D9C
210#define XRAMINDOPERREFUP_STARTDSP2 0x104DA0
211#define XRAMINDOPERREFUP_ENDDSP2 0x104DBC
212#define YRAMINDOPERREFNOUP_STARTDSP2 0x104DC0
213#define YRAMINDOPERREFNOUP_ENDDSP2 0x104DDC
214#define YRAMINDOPERREFUP_STARTDSP2 0x104DE0
215#define YRAMINDOPERREFUP_ENDDSP2 0x104DFC
216#define DSP2CONDCODE 0x104E00
217#define DSP2STACKFLAG 0x104E04
218#define DSP2PROGCOUNTSTACKPTREG 0x104E08
219#define DSP2PROGCOUNTSTACKDATAREG 0x104E0C
220#define DSP2CURLOOPADDRREG 0x104E10
221#define DSP2CURLOOPCOUNT 0x104E14
222#define DSP2TOPLOOPCOUNTSTACK 0x104E18
223#define DSP2TOPLOOPADDRSTACK 0x104E1C
224#define DSP2LOOPSTACKPTR 0x104E20
225#define DSP2STASSTACKDATAREG 0x104E24
226#define DSP2STASSTACKPTR 0x104E28
227#define DSP2PROGCOUNT 0x104E2C
228#define DSP2XYRAMBASE_START 0x104EA0
229#define DSP2XYRAMBASE_END 0x104EBC
230#define DSP2XYRAMLENG_START 0x104EC0
231#define DSP2XYRAMLENG_END 0x104EDC
232#define SEMAPHOREREGDSP2 0x104EE0
233#define DSP2INTCONTMASKREG 0x104EE4
234#define DSP2INTCONTPENDREG 0x104EE8
235#define DSP2INTCONTSERVINT 0x104EEC
236#define GPIODSP2 0x104EFC
237#define DMADSPBASEADDRREG_STARTDSP2 0x104F00
238#define DMADSPBASEADDRREG_ENDDSP2 0x104F1C
239#define DMAHOSTBASEADDRREG_STARTDSP2 0x104F20
240#define DMAHOSTBASEADDRREG_ENDDSP2 0x104F3C
241#define DMADSPCURADDRREG_STARTDSP2 0x104F40
242#define DMADSPCURADDRREG_ENDDSP2 0x104F5C
243#define DMAHOSTCURADDRREG_STARTDSP2 0x104F60
244#define DMAHOSTCURADDRREG_ENDDSP2 0x104F7C
245#define DMATANXCOUNTREG_STARTDSP2 0x104F80
246#define DMATANXCOUNTREG_ENDDSP2 0x104F9C
247#define DMATIMEBUGREG_STARTDSP2 0x104FA0
248#define DMATIMEBUGREG_ENDDSP2 0x104FAC
249#define DMACNTLMODFREG_STARTDSP2 0x104FA0
250#define DMACNTLMODFREG_ENDDSP2 0x104FAC
251
252#define DMAGLOBSTATSREGDSP2 0x104FEC
253#define DSP2XGPRAM_START 0x105000
254#define DSP2XGPRAM_END 0x1051FC
255#define DSP2YGPRAM_START 0x105800
256#define DSP2YGPRAM_END 0x1059FC
257
258
259
260#define AUDIORINGIPDSP3_START 0x106000
261#define AUDIORINGIPDSP3_END 0x1063FC
262#define AUDIORINGOPDSP3_START 0x106400
263#define AUDIORINGOPDSP3_END 0x1067FC
264#define AUDPARARINGIODSP3_START 0x106800
265#define AUDPARARINGIODSP3_END 0x106BFC
266#define DSP3LOCALHWREG_START 0x106C00
267#define DSP3LOCALHWREG_END 0x106C3C
268#define DSP3XYRAMAGINDEX_START 0x106C40
269#define DSP3XYRAMAGINDEX_END 0x106C5C
270#define DSP3XYRAMAGMDFR_START 0x106C60
271#define DSP3XYRAMAGMDFR_END 0x106C7C
272#define DSP3INTCONTLVEC_START 0x106C80
273#define DSP3INTCONTLVEC_END 0x106CD8
274#define HOSTINTFPORTADDRCONTDSP3 0x106D40
275#define HOSTINTFPORTDATADSP3 0x106D44
276#define TIME0PERENBDSP3 0x106D60
277#define TIME0COUNTERDSP3 0x106D64
278#define TIME1PERENBDSP3 0x106D68
279#define TIME1COUNTERDSP3 0x106D6C
280#define TIME2PERENBDSP3 0x106D70
281#define TIME2COUNTERDSP3 0x106D74
282#define TIME3PERENBDSP3 0x106D78
283#define TIME3COUNTERDSP3 0x106D7C
284#define XRAMINDOPERREFNOUP_STARTDSP3 0x106D80
285#define XRAMINDOPERREFNOUP_ENDDSP3 0x106D9C
286#define XRAMINDOPERREFUP_STARTDSP3 0x106DA0
287#define XRAMINDOPERREFUP_ENDDSP3 0x106DBC
288#define YRAMINDOPERREFNOUP_STARTDSP3 0x106DC0
289#define YRAMINDOPERREFNOUP_ENDDSP3 0x106DDC
290#define YRAMINDOPERREFUP_STARTDSP3 0x106DE0
291#define YRAMINDOPERREFUP_ENDDSP3 0x100DFC
292
293#define DSP3CONDCODE 0x106E00
294#define DSP3STACKFLAG 0x106E04
295#define DSP3PROGCOUNTSTACKPTREG 0x106E08
296#define DSP3PROGCOUNTSTACKDATAREG 0x106E0C
297#define DSP3CURLOOPADDRREG 0x106E10
298#define DSP3CURLOOPCOUNT 0x106E14
299#define DSP3TOPLOOPCOUNTSTACK 0x106E18
300#define DSP3TOPLOOPADDRSTACK 0x106E1C
301#define DSP3LOOPSTACKPTR 0x106E20
302#define DSP3STASSTACKDATAREG 0x106E24
303#define DSP3STASSTACKPTR 0x106E28
304#define DSP3PROGCOUNT 0x106E2C
305#define DSP3XYRAMBASE_START 0x106EA0
306#define DSP3XYRAMBASE_END 0x106EBC
307#define DSP3XYRAMLENG_START 0x106EC0
308#define DSP3XYRAMLENG_END 0x106EDC
309#define SEMAPHOREREGDSP3 0x106EE0
310#define DSP3INTCONTMASKREG 0x106EE4
311#define DSP3INTCONTPENDREG 0x106EE8
312#define DSP3INTCONTSERVINT 0x106EEC
313#define GPIODSP3 0x106EFC
314#define DMADSPBASEADDRREG_STARTDSP3 0x106F00
315#define DMADSPBASEADDRREG_ENDDSP3 0x106F1C
316#define DMAHOSTBASEADDRREG_STARTDSP3 0x106F20
317#define DMAHOSTBASEADDRREG_ENDDSP3 0x106F3C
318#define DMADSPCURADDRREG_STARTDSP3 0x106F40
319#define DMADSPCURADDRREG_ENDDSP3 0x106F5C
320#define DMAHOSTCURADDRREG_STARTDSP3 0x106F60
321#define DMAHOSTCURADDRREG_ENDDSP3 0x106F7C
322#define DMATANXCOUNTREG_STARTDSP3 0x106F80
323#define DMATANXCOUNTREG_ENDDSP3 0x106F9C
324#define DMATIMEBUGREG_STARTDSP3 0x106FA0
325#define DMATIMEBUGREG_ENDDSP3 0x106FAC
326#define DMACNTLMODFREG_STARTDSP3 0x106FA0
327#define DMACNTLMODFREG_ENDDSP3 0x106FAC
328
329#define DMAGLOBSTATSREGDSP3 0x106FEC
330#define DSP3XGPRAM_START 0x107000
331#define DSP3XGPRAM_END 0x1071FC
332#define DSP3YGPRAM_START 0x107800
333#define DSP3YGPRAM_END 0x1079FC
334
335/* end of DSP reg definitions */
336
337#define DSPAIMAP_START 0x108000
338#define DSPAIMAP_END 0x1083FC
339#define DSPPIMAP_START 0x108400
340#define DSPPIMAP_END 0x1087FC
341#define DSPPOMAP_START 0x108800
342#define DSPPOMAP_END 0x108BFC
343#define DSPPOCTL 0x108C00
344#define TKCTL_START 0x110000
345#define TKCTL_END 0x110FFC
346#define TKCC_START 0x111000
347#define TKCC_END 0x111FFC
348#define TKIMAP_START 0x112000
349#define TKIMAP_END 0x112FFC
350#define TKDCTR16 0x113000
351#define TKPB16 0x113004
352#define TKBS16 0x113008
353#define TKDCTR32 0x11300C
354#define TKPB32 0x113010
355#define TKBS32 0x113014
356#define ICDCTR16 0x113018
357#define ITBS16 0x11301C
358#define ICDCTR32 0x113020
359#define ITBS32 0x113024
360#define ITSTART 0x113028
361#define TKSQ 0x11302C
362
363#define TKSCCTL_START 0x114000
364#define TKSCCTL_END 0x11403C
365#define TKSCADR_START 0x114100
366#define TKSCADR_END 0x11413C
367#define TKSCDATAX_START 0x114800
368#define TKSCDATAX_END 0x1149FC
369#define TKPCDATAX_START 0x120000
370#define TKPCDATAX_END 0x12FFFC
371
372#define MALSA 0x130000
373#define MAPPHA 0x130004
374#define MAPPLA 0x130008
375#define MALSB 0x130010
376#define MAPPHB 0x130014
377#define MAPPLB 0x130018
378
379#define TANSPORTMAPABREGS_START 0x130020
380#define TANSPORTMAPABREGS_END 0x13A2FC
381
382#define PTPAHX 0x13B000
383#define PTPALX 0x13B004
384
385#define TANSPPAGETABLEPHYADDR015_START 0x13B008
386#define TANSPPAGETABLEPHYADDR015_END 0x13B07C
387#define TRNQADRX_START 0x13B100
388#define TRNQADRX_END 0x13B13C
389#define TRNQTIMX_START 0x13B200
390#define TRNQTIMX_END 0x13B23C
391#define TRNQAPARMX_START 0x13B300
392#define TRNQAPARMX_END 0x13B33C
393
394#define TRNQCNT 0x13B400
395#define TRNCTL 0x13B404
396#define TRNIS 0x13B408
397#define TRNCURTS 0x13B40C
398
399#define AMOP_START 0x140000
400#define AMOPLO 0x140000
401#define AMOPHI 0x140004
402#define AMOP_END 0x147FFC
403#define PMOP_START 0x148000
404#define PMOPLO 0x148000
405#define PMOPHI 0x148004
406#define PMOP_END 0x14FFFC
407#define PCURR_START 0x150000
408#define PCURR_END 0x153FFC
409#define PTRAG_START 0x154000
410#define PTRAG_END 0x157FFC
411#define PSR_START 0x158000
412#define PSR_END 0x15BFFC
413
414#define PFSTAT4SEG_START 0x160000
415#define PFSTAT4SEG_END 0x160BFC
416#define PFSTAT2SEG_START 0x160C00
417#define PFSTAT2SEG_END 0x1617FC
418#define PFTARG4SEG_START 0x164000
419#define PFTARG4SEG_END 0x164BFC
420#define PFTARG2SEG_START 0x164C00
421#define PFTARG2SEG_END 0x1657FC
422#define PFSR4SEG_START 0x168000
423#define PFSR4SEG_END 0x168BFC
424#define PFSR2SEG_START 0x168C00
425#define PFSR2SEG_END 0x1697FC
426#define PCURRMS4SEG_START 0x16C000
427#define PCURRMS4SEG_END 0x16CCFC
428#define PCURRMS2SEG_START 0x16CC00
429#define PCURRMS2SEG_END 0x16D7FC
430#define PTARGMS4SEG_START 0x170000
431#define PTARGMS4SEG_END 0x172FFC
432#define PTARGMS2SEG_START 0x173000
433#define PTARGMS2SEG_END 0x1747FC
434#define PSRMS4SEG_START 0x170000
435#define PSRMS4SEG_END 0x172FFC
436#define PSRMS2SEG_START 0x173000
437#define PSRMS2SEG_END 0x1747FC
438
439#define PRING_LO_START 0x190000
440#define PRING_LO_END 0x193FFC
441#define PRING_HI_START 0x194000
442#define PRING_HI_END 0x197FFC
443#define PRING_LO_HI_START 0x198000
444#define PRING_LO_HI 0x198000
445#define PRING_LO_HI_END 0x19BFFC
446
447#define PINTFIFO 0x1A0000
448#define SRCCTL 0x1B0000
449#define SRCCCR 0x1B0004
450#define SRCIMAP 0x1B0008
451#define SRCODDC 0x1B000C
452#define SRCCA 0x1B0010
453#define SRCCF 0x1B0014
454#define SRCSA 0x1B0018
455#define SRCLA 0x1B001C
456#define SRCCTLSWR 0x1B0020
457
458/* SRC HERE */
459#define SRCALBA 0x1B002C
460#define SRCMCTL 0x1B012C
461#define SRCCERR 0x1B022C
462#define SRCITB 0x1B032C
463#define SRCIPM 0x1B082C
464#define SRCIP 0x1B102C
465#define SRCENBSTAT 0x1B202C
466#define SRCENBLO 0x1B212C
467#define SRCENBHI 0x1B222C
468#define SRCENBS 0x1B232C
469#define SRCENB 0x1B282C
470#define SRCENB07 0x1B282C
471#define SRCENBS07 0x1B302C
472
473#define SRCDN0Z 0x1B0030
474#define SRCDN0Z0 0x1B0030
475#define SRCDN0Z1 0x1B0034
476#define SRCDN0Z2 0x1B0038
477#define SRCDN0Z3 0x1B003C
478#define SRCDN1Z 0x1B0040
479#define SRCDN1Z0 0x1B0040
480#define SRCDN1Z1 0x1B0044
481#define SRCDN1Z2 0x1B0048
482#define SRCDN1Z3 0x1B004C
483#define SRCDN1Z4 0x1B0050
484#define SRCDN1Z5 0x1B0054
485#define SRCDN1Z6 0x1B0058
486#define SRCDN1Z7 0x1B005C
487#define SRCUPZ 0x1B0060
488#define SRCUPZ0 0x1B0060
489#define SRCUPZ1 0x1B0064
490#define SRCUPZ2 0x1B0068
491#define SRCUPZ3 0x1B006C
492#define SRCUPZ4 0x1B0070
493#define SRCUPZ5 0x1B0074
494#define SRCUPZ6 0x1B0078
495#define SRCUPZ7 0x1B007C
496#define SRCCD0 0x1B0080
497#define SRCCD1 0x1B0084
498#define SRCCD2 0x1B0088
499#define SRCCD3 0x1B008C
500#define SRCCD4 0x1B0090
501#define SRCCD5 0x1B0094
502#define SRCCD6 0x1B0098
503#define SRCCD7 0x1B009C
504#define SRCCD8 0x1B00A0
505#define SRCCD9 0x1B00A4
506#define SRCCDA 0x1B00A8
507#define SRCCDB 0x1B00AC
508#define SRCCDC 0x1B00B0
509#define SRCCDD 0x1B00B4
510#define SRCCDE 0x1B00B8
511#define SRCCDF 0x1B00BC
512#define SRCCD10 0x1B00C0
513#define SRCCD11 0x1B00C4
514#define SRCCD12 0x1B00C8
515#define SRCCD13 0x1B00CC
516#define SRCCD14 0x1B00D0
517#define SRCCD15 0x1B00D4
518#define SRCCD16 0x1B00D8
519#define SRCCD17 0x1B00DC
520#define SRCCD18 0x1B00E0
521#define SRCCD19 0x1B00E4
522#define SRCCD1A 0x1B00E8
523#define SRCCD1B 0x1B00EC
524#define SRCCD1C 0x1B00F0
525#define SRCCD1D 0x1B00F4
526#define SRCCD1E 0x1B00F8
527#define SRCCD1F 0x1B00FC
528
529#define SRCCONTRBLOCK_START 0x1B0100
530#define SRCCONTRBLOCK_END 0x1BFFFC
531#define FILTOP_START 0x1C0000
532#define FILTOP_END 0x1C05FC
533#define FILTIMAP_START 0x1C0800
534#define FILTIMAP_END 0x1C0DFC
535#define FILTZ1_START 0x1C1000
536#define FILTZ1_END 0x1C15FC
537#define FILTZ2_START 0x1C1800
538#define FILTZ2_END 0x1C1DFC
539#define DAOIMAP_START 0x1C5000
540#define DAOIMAP 0x1C5000
541#define DAOIMAP_END 0x1C5124
542
543#define AC97D 0x1C5400
544#define AC97A 0x1C5404
545#define AC97CTL 0x1C5408
546#define I2SCTL 0x1C5420
547
548#define SPOS 0x1C5440
549#define SPOSA 0x1C5440
550#define SPOSB 0x1C5444
551#define SPOSC 0x1C5448
552#define SPOSD 0x1C544C
553
554#define SPISA 0x1C5450
555#define SPISB 0x1C5454
556#define SPISC 0x1C5458
557#define SPISD 0x1C545C
558
559#define SPFSCTL 0x1C5460
560
561#define SPFS0 0x1C5468
562#define SPFS1 0x1C546C
563#define SPFS2 0x1C5470
564#define SPFS3 0x1C5474
565#define SPFS4 0x1C5478
566#define SPFS5 0x1C547C
567
568#define SPOCTL 0x1C5480
569#define SPICTL 0x1C5484
570#define SPISTS 0x1C5488
571#define SPINTP 0x1C548C
572#define SPINTE 0x1C5490
573#define SPUTCTLAB 0x1C5494
574#define SPUTCTLCD 0x1C5498
575
576#define SRTSPA 0x1C54C0
577#define SRTSPB 0x1C54C4
578#define SRTSPC 0x1C54C8
579#define SRTSPD 0x1C54CC
580
581#define SRTSCTL 0x1C54D0
582#define SRTSCTLA 0x1C54D0
583#define SRTSCTLB 0x1C54D4
584#define SRTSCTLC 0x1C54D8
585#define SRTSCTLD 0x1C54DC
586
587#define SRTI2S 0x1C54E0
588#define SRTICTL 0x1C54F0
589
590#define WC 0x1C6000
591#define TIMR 0x1C6004
592# define TIMR_IE (1<<15)
593# define TIMR_IP (1<<14)
594
595#define GIP 0x1C6010
596#define GIE 0x1C6014
597#define DIE 0x1C6018
598#define DIC 0x1C601C
599#define GPIO 0x1C6020
600#define GPIOCTL 0x1C6024
601#define GPIP 0x1C6028
602#define GPIE 0x1C602C
603#define DSPINT0 0x1C6030
604#define DSPEIOC 0x1C6034
605#define MUADAT 0x1C6040
606#define MUACMD 0x1C6044
607#define MUASTAT 0x1C6044
608#define MUBDAT 0x1C6048
609#define MUBCMD 0x1C604C
610#define MUBSTAT 0x1C604C
611#define UARTCMA 0x1C6050
612#define UARTCMB 0x1C6054
613#define UARTIP 0x1C6058
614#define UARTIE 0x1C605C
615#define PLLCTL 0x1C6060
616#define PLLDCD 0x1C6064
617#define GCTL 0x1C6070
618#define ID0 0x1C6080
619#define ID1 0x1C6084
620#define ID2 0x1C6088
621#define ID3 0x1C608C
622#define SDRCTL 0x1C7000
623
624
625#define I2SA_L 0x0L
626#define I2SA_R 0x1L
627#define I2SB_L 0x8L
628#define I2SB_R 0x9L
629#define I2SC_L 0x10L
630#define I2SC_R 0x11L
631#define I2SD_L 0x18L
632#define I2SD_R 0x19L
633
634#endif /* CT20K1REG_H */
635
636
diff --git a/sound/pci/ctxfi/ct20k2reg.h b/sound/pci/ctxfi/ct20k2reg.h
new file mode 100644
index 00000000000..2d07986f57c
--- /dev/null
+++ b/sound/pci/ctxfi/ct20k2reg.h
@@ -0,0 +1,85 @@
1/**
2 * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
3 *
4 * This source file is released under GPL v2 license (no other versions).
5 * See the COPYING file included in the main directory of this source
6 * distribution for the license terms and conditions.
7 */
8
9#ifndef _20K2REGISTERS_H_
10#define _20K2REGISTERS_H_
11
12
13/* Timer Registers */
14#define TIMER_TIMR 0x1B7004
15#define INTERRUPT_GIP 0x1B7010
16#define INTERRUPT_GIE 0x1B7014
17
18/* I2C Registers */
19#define I2C_IF_ADDRESS 0x1B9000
20#define I2C_IF_WDATA 0x1B9004
21#define I2C_IF_RDATA 0x1B9008
22#define I2C_IF_STATUS 0x1B900C
23#define I2C_IF_WLOCK 0x1B9010
24
25/* Global Control Registers */
26#define GLOBAL_CNTL_GCTL 0x1B7090
27
28/* PLL Registers */
29#define PLL_CTL 0x1B7080
30#define PLL_STAT 0x1B7084
31#define PLL_ENB 0x1B7088
32
33/* SRC Registers */
34#define SRC_CTL 0x1A0000 /* 0x1A0000 + (256 * Chn) */
35#define SRC_CCR 0x1A0004 /* 0x1A0004 + (256 * Chn) */
36#define SRC_IMAP 0x1A0008 /* 0x1A0008 + (256 * Chn) */
37#define SRC_CA 0x1A0010 /* 0x1A0010 + (256 * Chn) */
38#define SRC_CF 0x1A0014 /* 0x1A0014 + (256 * Chn) */
39#define SRC_SA 0x1A0018 /* 0x1A0018 + (256 * Chn) */
40#define SRC_LA 0x1A001C /* 0x1A001C + (256 * Chn) */
41#define SRC_CTLSWR 0x1A0020 /* 0x1A0020 + (256 * Chn) */
42#define SRC_CD 0x1A0080 /* 0x1A0080 + (256 * Chn) + (4 * Regn) */
43#define SRC_MCTL 0x1A012C
44#define SRC_IP 0x1A102C /* 0x1A102C + (256 * Regn) */
45#define SRC_ENB 0x1A282C /* 0x1A282C + (256 * Regn) */
46#define SRC_ENBSTAT 0x1A202C
47#define SRC_ENBSA 0x1A232C
48#define SRC_DN0Z 0x1A0030
49#define SRC_DN1Z 0x1A0040
50#define SRC_UPZ 0x1A0060
51
52/* GPIO Registers */
53#define GPIO_DATA 0x1B7020
54#define GPIO_CTRL 0x1B7024
55
56/* Virtual memory registers */
57#define VMEM_PTPAL 0x1C6300 /* 0x1C6300 + (16 * Chn) */
58#define VMEM_PTPAH 0x1C6304 /* 0x1C6304 + (16 * Chn) */
59#define VMEM_CTL 0x1C7000
60
61/* Transport Registers */
62#define TRANSPORT_ENB 0x1B6000
63#define TRANSPORT_CTL 0x1B6004
64#define TRANSPORT_INT 0x1B6008
65
66/* Audio IO */
67#define AUDIO_IO_AIM 0x1B5000 /* 0x1B5000 + (0x04 * Chn) */
68#define AUDIO_IO_TX_CTL 0x1B5400 /* 0x1B5400 + (0x40 * Chn) */
69#define AUDIO_IO_TX_CSTAT_L 0x1B5408 /* 0x1B5408 + (0x40 * Chn) */
70#define AUDIO_IO_TX_CSTAT_H 0x1B540C /* 0x1B540C + (0x40 * Chn) */
71#define AUDIO_IO_RX_CTL 0x1B5410 /* 0x1B5410 + (0x40 * Chn) */
72#define AUDIO_IO_RX_SRT_CTL 0x1B5420 /* 0x1B5420 + (0x40 * Chn) */
73#define AUDIO_IO_MCLK 0x1B5600
74#define AUDIO_IO_TX_BLRCLK 0x1B5604
75#define AUDIO_IO_RX_BLRCLK 0x1B5608
76
77/* Mixer */
78#define MIXER_AMOPLO 0x130000 /* 0x130000 + (8 * Chn) [4095 : 0] */
79#define MIXER_AMOPHI 0x130004 /* 0x130004 + (8 * Chn) [4095 : 0] */
80#define MIXER_PRING_LO_HI 0x188000 /* 0x188000 + (4 * Chn) [4095 : 0] */
81#define MIXER_PMOPLO 0x138000 /* 0x138000 + (8 * Chn) [4095 : 0] */
82#define MIXER_PMOPHI 0x138004 /* 0x138004 + (8 * Chn) [4095 : 0] */
83#define MIXER_AR_ENABLE 0x19000C
84
85#endif
diff --git a/sound/pci/ctxfi/ctamixer.c b/sound/pci/ctxfi/ctamixer.c
new file mode 100644
index 00000000000..a1db51b3ead
--- /dev/null
+++ b/sound/pci/ctxfi/ctamixer.c
@@ -0,0 +1,488 @@
1/**
2 * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
3 *
4 * This source file is released under GPL v2 license (no other versions).
5 * See the COPYING file included in the main directory of this source
6 * distribution for the license terms and conditions.
7 *
8 * @File ctamixer.c
9 *
10 * @Brief
11 * This file contains the implementation of the Audio Mixer
12 * resource management object.
13 *
14 * @Author Liu Chun
15 * @Date May 21 2008
16 *
17 */
18
19#include "ctamixer.h"
20#include "cthardware.h"
21#include <linux/slab.h>
22
23#define AMIXER_RESOURCE_NUM 256
24#define SUM_RESOURCE_NUM 256
25
26#define AMIXER_Y_IMMEDIATE 1
27
28#define BLANK_SLOT 4094
29
30static int amixer_master(struct rsc *rsc)
31{
32 rsc->conj = 0;
33 return rsc->idx = container_of(rsc, struct amixer, rsc)->idx[0];
34}
35
36static int amixer_next_conj(struct rsc *rsc)
37{
38 rsc->conj++;
39 return container_of(rsc, struct amixer, rsc)->idx[rsc->conj];
40}
41
42static int amixer_index(const struct rsc *rsc)
43{
44 return container_of(rsc, struct amixer, rsc)->idx[rsc->conj];
45}
46
47static int amixer_output_slot(const struct rsc *rsc)
48{
49 return (amixer_index(rsc) << 4) + 0x4;
50}
51
52static struct rsc_ops amixer_basic_rsc_ops = {
53 .master = amixer_master,
54 .next_conj = amixer_next_conj,
55 .index = amixer_index,
56 .output_slot = amixer_output_slot,
57};
58
59static int amixer_set_input(struct amixer *amixer, struct rsc *rsc)
60{
61 struct hw *hw;
62
63 hw = amixer->rsc.hw;
64 hw->amixer_set_mode(amixer->rsc.ctrl_blk, AMIXER_Y_IMMEDIATE);
65 amixer->input = rsc;
66 if (NULL == rsc)
67 hw->amixer_set_x(amixer->rsc.ctrl_blk, BLANK_SLOT);
68 else
69 hw->amixer_set_x(amixer->rsc.ctrl_blk,
70 rsc->ops->output_slot(rsc));
71
72 return 0;
73}
74
75/* y is a 14-bit immediate constant */
76static int amixer_set_y(struct amixer *amixer, unsigned int y)
77{
78 struct hw *hw;
79
80 hw = amixer->rsc.hw;
81 hw->amixer_set_y(amixer->rsc.ctrl_blk, y);
82
83 return 0;
84}
85
86static int amixer_set_invalid_squash(struct amixer *amixer, unsigned int iv)
87{
88 struct hw *hw;
89
90 hw = amixer->rsc.hw;
91 hw->amixer_set_iv(amixer->rsc.ctrl_blk, iv);
92
93 return 0;
94}
95
96static int amixer_set_sum(struct amixer *amixer, struct sum *sum)
97{
98 struct hw *hw;
99
100 hw = amixer->rsc.hw;
101 amixer->sum = sum;
102 if (NULL == sum) {
103 hw->amixer_set_se(amixer->rsc.ctrl_blk, 0);
104 } else {
105 hw->amixer_set_se(amixer->rsc.ctrl_blk, 1);
106 hw->amixer_set_sadr(amixer->rsc.ctrl_blk,
107 sum->rsc.ops->index(&sum->rsc));
108 }
109
110 return 0;
111}
112
113static int amixer_commit_write(struct amixer *amixer)
114{
115 struct hw *hw;
116 unsigned int index;
117 int i;
118 struct rsc *input;
119 struct sum *sum;
120
121 hw = amixer->rsc.hw;
122 input = amixer->input;
123 sum = amixer->sum;
124
125 /* Program master and conjugate resources */
126 amixer->rsc.ops->master(&amixer->rsc);
127 if (NULL != input)
128 input->ops->master(input);
129
130 if (NULL != sum)
131 sum->rsc.ops->master(&sum->rsc);
132
133 for (i = 0; i < amixer->rsc.msr; i++) {
134 hw->amixer_set_dirty_all(amixer->rsc.ctrl_blk);
135 if (NULL != input) {
136 hw->amixer_set_x(amixer->rsc.ctrl_blk,
137 input->ops->output_slot(input));
138 input->ops->next_conj(input);
139 }
140 if (NULL != sum) {
141 hw->amixer_set_sadr(amixer->rsc.ctrl_blk,
142 sum->rsc.ops->index(&sum->rsc));
143 sum->rsc.ops->next_conj(&sum->rsc);
144 }
145 index = amixer->rsc.ops->output_slot(&amixer->rsc);
146 hw->amixer_commit_write(hw, index, amixer->rsc.ctrl_blk);
147 amixer->rsc.ops->next_conj(&amixer->rsc);
148 }
149 amixer->rsc.ops->master(&amixer->rsc);
150 if (NULL != input)
151 input->ops->master(input);
152
153 if (NULL != sum)
154 sum->rsc.ops->master(&sum->rsc);
155
156 return 0;
157}
158
159static int amixer_commit_raw_write(struct amixer *amixer)
160{
161 struct hw *hw;
162 unsigned int index;
163
164 hw = amixer->rsc.hw;
165 index = amixer->rsc.ops->output_slot(&amixer->rsc);
166 hw->amixer_commit_write(hw, index, amixer->rsc.ctrl_blk);
167
168 return 0;
169}
170
171static int amixer_get_y(struct amixer *amixer)
172{
173 struct hw *hw;
174
175 hw = amixer->rsc.hw;
176 return hw->amixer_get_y(amixer->rsc.ctrl_blk);
177}
178
179static int amixer_setup(struct amixer *amixer, struct rsc *input,
180 unsigned int scale, struct sum *sum)
181{
182 amixer_set_input(amixer, input);
183 amixer_set_y(amixer, scale);
184 amixer_set_sum(amixer, sum);
185 amixer_commit_write(amixer);
186 return 0;
187}
188
189static struct amixer_rsc_ops amixer_ops = {
190 .set_input = amixer_set_input,
191 .set_invalid_squash = amixer_set_invalid_squash,
192 .set_scale = amixer_set_y,
193 .set_sum = amixer_set_sum,
194 .commit_write = amixer_commit_write,
195 .commit_raw_write = amixer_commit_raw_write,
196 .setup = amixer_setup,
197 .get_scale = amixer_get_y,
198};
199
200static int amixer_rsc_init(struct amixer *amixer,
201 const struct amixer_desc *desc,
202 struct amixer_mgr *mgr)
203{
204 int err;
205
206 err = rsc_init(&amixer->rsc, amixer->idx[0],
207 AMIXER, desc->msr, mgr->mgr.hw);
208 if (err)
209 return err;
210
211 /* Set amixer specific operations */
212 amixer->rsc.ops = &amixer_basic_rsc_ops;
213 amixer->ops = &amixer_ops;
214 amixer->input = NULL;
215 amixer->sum = NULL;
216
217 amixer_setup(amixer, NULL, 0, NULL);
218
219 return 0;
220}
221
222static int amixer_rsc_uninit(struct amixer *amixer)
223{
224 amixer_setup(amixer, NULL, 0, NULL);
225 rsc_uninit(&amixer->rsc);
226 amixer->ops = NULL;
227 amixer->input = NULL;
228 amixer->sum = NULL;
229 return 0;
230}
231
232static int get_amixer_rsc(struct amixer_mgr *mgr,
233 const struct amixer_desc *desc,
234 struct amixer **ramixer)
235{
236 int err, i;
237 unsigned int idx;
238 struct amixer *amixer;
239 unsigned long flags;
240
241 *ramixer = NULL;
242
243 /* Allocate mem for amixer resource */
244 amixer = kzalloc(sizeof(*amixer), GFP_KERNEL);
245 if (NULL == amixer) {
246 err = -ENOMEM;
247 return err;
248 }
249
250 /* Check whether there are sufficient
251 * amixer resources to meet request. */
252 spin_lock_irqsave(&mgr->mgr_lock, flags);
253 for (i = 0; i < desc->msr; i++) {
254 err = mgr_get_resource(&mgr->mgr, 1, &idx);
255 if (err)
256 break;
257
258 amixer->idx[i] = idx;
259 }
260 spin_unlock_irqrestore(&mgr->mgr_lock, flags);
261 if (err) {
262 printk(KERN_ERR "ctxfi: Can't meet AMIXER resource request!\n");
263 goto error;
264 }
265
266 err = amixer_rsc_init(amixer, desc, mgr);
267 if (err)
268 goto error;
269
270 *ramixer = amixer;
271
272 return 0;
273
274error:
275 spin_lock_irqsave(&mgr->mgr_lock, flags);
276 for (i--; i >= 0; i--)
277 mgr_put_resource(&mgr->mgr, 1, amixer->idx[i]);
278
279 spin_unlock_irqrestore(&mgr->mgr_lock, flags);
280 kfree(amixer);
281 return err;
282}
283
284static int put_amixer_rsc(struct amixer_mgr *mgr, struct amixer *amixer)
285{
286 unsigned long flags;
287 int i;
288
289 spin_lock_irqsave(&mgr->mgr_lock, flags);
290 for (i = 0; i < amixer->rsc.msr; i++)
291 mgr_put_resource(&mgr->mgr, 1, amixer->idx[i]);
292
293 spin_unlock_irqrestore(&mgr->mgr_lock, flags);
294 amixer_rsc_uninit(amixer);
295 kfree(amixer);
296
297 return 0;
298}
299
300int amixer_mgr_create(void *hw, struct amixer_mgr **ramixer_mgr)
301{
302 int err;
303 struct amixer_mgr *amixer_mgr;
304
305 *ramixer_mgr = NULL;
306 amixer_mgr = kzalloc(sizeof(*amixer_mgr), GFP_KERNEL);
307 if (NULL == amixer_mgr)
308 return -ENOMEM;
309
310 err = rsc_mgr_init(&amixer_mgr->mgr, AMIXER, AMIXER_RESOURCE_NUM, hw);
311 if (err)
312 goto error;
313
314 spin_lock_init(&amixer_mgr->mgr_lock);
315
316 amixer_mgr->get_amixer = get_amixer_rsc;
317 amixer_mgr->put_amixer = put_amixer_rsc;
318
319 *ramixer_mgr = amixer_mgr;
320
321 return 0;
322
323error:
324 kfree(amixer_mgr);
325 return err;
326}
327
328int amixer_mgr_destroy(struct amixer_mgr *amixer_mgr)
329{
330 rsc_mgr_uninit(&amixer_mgr->mgr);
331 kfree(amixer_mgr);
332 return 0;
333}
334
335/* SUM resource management */
336
337static int sum_master(struct rsc *rsc)
338{
339 rsc->conj = 0;
340 return rsc->idx = container_of(rsc, struct sum, rsc)->idx[0];
341}
342
343static int sum_next_conj(struct rsc *rsc)
344{
345 rsc->conj++;
346 return container_of(rsc, struct sum, rsc)->idx[rsc->conj];
347}
348
349static int sum_index(const struct rsc *rsc)
350{
351 return container_of(rsc, struct sum, rsc)->idx[rsc->conj];
352}
353
354static int sum_output_slot(const struct rsc *rsc)
355{
356 return (sum_index(rsc) << 4) + 0xc;
357}
358
359static struct rsc_ops sum_basic_rsc_ops = {
360 .master = sum_master,
361 .next_conj = sum_next_conj,
362 .index = sum_index,
363 .output_slot = sum_output_slot,
364};
365
366static int sum_rsc_init(struct sum *sum,
367 const struct sum_desc *desc,
368 struct sum_mgr *mgr)
369{
370 int err;
371
372 err = rsc_init(&sum->rsc, sum->idx[0], SUM, desc->msr, mgr->mgr.hw);
373 if (err)
374 return err;
375
376 sum->rsc.ops = &sum_basic_rsc_ops;
377
378 return 0;
379}
380
381static int sum_rsc_uninit(struct sum *sum)
382{
383 rsc_uninit(&sum->rsc);
384 return 0;
385}
386
387static int get_sum_rsc(struct sum_mgr *mgr,
388 const struct sum_desc *desc,
389 struct sum **rsum)
390{
391 int err, i;
392 unsigned int idx;
393 struct sum *sum;
394 unsigned long flags;
395
396 *rsum = NULL;
397
398 /* Allocate mem for sum resource */
399 sum = kzalloc(sizeof(*sum), GFP_KERNEL);
400 if (NULL == sum) {
401 err = -ENOMEM;
402 return err;
403 }
404
405 /* Check whether there are sufficient sum resources to meet request. */
406 spin_lock_irqsave(&mgr->mgr_lock, flags);
407 for (i = 0; i < desc->msr; i++) {
408 err = mgr_get_resource(&mgr->mgr, 1, &idx);
409 if (err)
410 break;
411
412 sum->idx[i] = idx;
413 }
414 spin_unlock_irqrestore(&mgr->mgr_lock, flags);
415 if (err) {
416 printk(KERN_ERR "ctxfi: Can't meet SUM resource request!\n");
417 goto error;
418 }
419
420 err = sum_rsc_init(sum, desc, mgr);
421 if (err)
422 goto error;
423
424 *rsum = sum;
425
426 return 0;
427
428error:
429 spin_lock_irqsave(&mgr->mgr_lock, flags);
430 for (i--; i >= 0; i--)
431 mgr_put_resource(&mgr->mgr, 1, sum->idx[i]);
432
433 spin_unlock_irqrestore(&mgr->mgr_lock, flags);
434 kfree(sum);
435 return err;
436}
437
438static int put_sum_rsc(struct sum_mgr *mgr, struct sum *sum)
439{
440 unsigned long flags;
441 int i;
442
443 spin_lock_irqsave(&mgr->mgr_lock, flags);
444 for (i = 0; i < sum->rsc.msr; i++)
445 mgr_put_resource(&mgr->mgr, 1, sum->idx[i]);
446
447 spin_unlock_irqrestore(&mgr->mgr_lock, flags);
448 sum_rsc_uninit(sum);
449 kfree(sum);
450
451 return 0;
452}
453
454int sum_mgr_create(void *hw, struct sum_mgr **rsum_mgr)
455{
456 int err;
457 struct sum_mgr *sum_mgr;
458
459 *rsum_mgr = NULL;
460 sum_mgr = kzalloc(sizeof(*sum_mgr), GFP_KERNEL);
461 if (NULL == sum_mgr)
462 return -ENOMEM;
463
464 err = rsc_mgr_init(&sum_mgr->mgr, SUM, SUM_RESOURCE_NUM, hw);
465 if (err)
466 goto error;
467
468 spin_lock_init(&sum_mgr->mgr_lock);
469
470 sum_mgr->get_sum = get_sum_rsc;
471 sum_mgr->put_sum = put_sum_rsc;
472
473 *rsum_mgr = sum_mgr;
474
475 return 0;
476
477error:
478 kfree(sum_mgr);
479 return err;
480}
481
482int sum_mgr_destroy(struct sum_mgr *sum_mgr)
483{
484 rsc_mgr_uninit(&sum_mgr->mgr);
485 kfree(sum_mgr);
486 return 0;
487}
488
diff --git a/sound/pci/ctxfi/ctamixer.h b/sound/pci/ctxfi/ctamixer.h
new file mode 100644
index 00000000000..cc49e5ab475
--- /dev/null
+++ b/sound/pci/ctxfi/ctamixer.h
@@ -0,0 +1,96 @@
1/**
2 * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
3 *
4 * This source file is released under GPL v2 license (no other versions).
5 * See the COPYING file included in the main directory of this source
6 * distribution for the license terms and conditions.
7 *
8 * @File ctamixer.h
9 *
10 * @Brief
11 * This file contains the definition of the Audio Mixer
12 * resource management object.
13 *
14 * @Author Liu Chun
15 * @Date May 21 2008
16 *
17 */
18
19#ifndef CTAMIXER_H
20#define CTAMIXER_H
21
22#include "ctresource.h"
23#include <linux/spinlock.h>
24
25/* Define the descriptor of a summation node resource */
26struct sum {
27 struct rsc rsc; /* Basic resource info */
28 unsigned char idx[8];
29};
30
31/* Define sum resource request description info */
32struct sum_desc {
33 unsigned int msr;
34};
35
36struct sum_mgr {
37 struct rsc_mgr mgr; /* Basic resource manager info */
38 spinlock_t mgr_lock;
39
40 /* request one sum resource */
41 int (*get_sum)(struct sum_mgr *mgr,
42 const struct sum_desc *desc, struct sum **rsum);
43 /* return one sum resource */
44 int (*put_sum)(struct sum_mgr *mgr, struct sum *sum);
45};
46
47/* Constructor and destructor of daio resource manager */
48int sum_mgr_create(void *hw, struct sum_mgr **rsum_mgr);
49int sum_mgr_destroy(struct sum_mgr *sum_mgr);
50
51/* Define the descriptor of a amixer resource */
52struct amixer_rsc_ops;
53
54struct amixer {
55 struct rsc rsc; /* Basic resource info */
56 unsigned char idx[8];
57 struct rsc *input; /* pointer to a resource acting as source */
58 struct sum *sum; /* Put amixer output to this summation node */
59 struct amixer_rsc_ops *ops; /* AMixer specific operations */
60};
61
62struct amixer_rsc_ops {
63 int (*set_input)(struct amixer *amixer, struct rsc *rsc);
64 int (*set_scale)(struct amixer *amixer, unsigned int scale);
65 int (*set_invalid_squash)(struct amixer *amixer, unsigned int iv);
66 int (*set_sum)(struct amixer *amixer, struct sum *sum);
67 int (*commit_write)(struct amixer *amixer);
68 /* Only for interleaved recording */
69 int (*commit_raw_write)(struct amixer *amixer);
70 int (*setup)(struct amixer *amixer, struct rsc *input,
71 unsigned int scale, struct sum *sum);
72 int (*get_scale)(struct amixer *amixer);
73};
74
75/* Define amixer resource request description info */
76struct amixer_desc {
77 unsigned int msr;
78};
79
80struct amixer_mgr {
81 struct rsc_mgr mgr; /* Basic resource manager info */
82 spinlock_t mgr_lock;
83
84 /* request one amixer resource */
85 int (*get_amixer)(struct amixer_mgr *mgr,
86 const struct amixer_desc *desc,
87 struct amixer **ramixer);
88 /* return one amixer resource */
89 int (*put_amixer)(struct amixer_mgr *mgr, struct amixer *amixer);
90};
91
92/* Constructor and destructor of amixer resource manager */
93int amixer_mgr_create(void *hw, struct amixer_mgr **ramixer_mgr);
94int amixer_mgr_destroy(struct amixer_mgr *amixer_mgr);
95
96#endif /* CTAMIXER_H */
diff --git a/sound/pci/ctxfi/ctatc.c b/sound/pci/ctxfi/ctatc.c
new file mode 100644
index 00000000000..80fb2baed7a
--- /dev/null
+++ b/sound/pci/ctxfi/ctatc.c
@@ -0,0 +1,1619 @@
1/**
2 * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
3 *
4 * This source file is released under GPL v2 license (no other versions).
5 * See the COPYING file included in the main directory of this source
6 * distribution for the license terms and conditions.
7 *
8 * @File ctatc.c
9 *
10 * @Brief
11 * This file contains the implementation of the device resource management
12 * object.
13 *
14 * @Author Liu Chun
15 * @Date Mar 28 2008
16 */
17
18#include "ctatc.h"
19#include "ctpcm.h"
20#include "ctmixer.h"
21#include "cthardware.h"
22#include "ctsrc.h"
23#include "ctamixer.h"
24#include "ctdaio.h"
25#include "cttimer.h"
26#include <linux/delay.h>
27#include <sound/pcm.h>
28#include <sound/control.h>
29#include <sound/asoundef.h>
30
31#define MONO_SUM_SCALE 0x19a8 /* 2^(-0.5) in 14-bit floating format */
32#define DAIONUM 7
33#define MAX_MULTI_CHN 8
34
35#define IEC958_DEFAULT_CON ((IEC958_AES0_NONAUDIO \
36 | IEC958_AES0_CON_NOT_COPYRIGHT) \
37 | ((IEC958_AES1_CON_MIXER \
38 | IEC958_AES1_CON_ORIGINAL) << 8) \
39 | (0x10 << 16) \
40 | ((IEC958_AES3_CON_FS_48000) << 24))
41
42static struct snd_pci_quirk __devinitdata subsys_20k1_list[] = {
43 SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, 0x0022, "SB055x", CTSB055X),
44 SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, 0x002f, "SB055x", CTSB055X),
45 SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, 0x0029, "SB073x", CTSB073X),
46 SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, 0x0031, "SB073x", CTSB073X),
47 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_CREATIVE, 0xf000, 0x6000,
48 "UAA", CTUAA),
49 SND_PCI_QUIRK_VENDOR(PCI_VENDOR_ID_CREATIVE,
50 "Unknown", CT20K1_UNKNOWN),
51 { } /* terminator */
52};
53
54static struct snd_pci_quirk __devinitdata subsys_20k2_list[] = {
55 SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, PCI_SUBDEVICE_ID_CREATIVE_SB0760,
56 "SB0760", CTSB0760),
57 SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, PCI_SUBDEVICE_ID_CREATIVE_SB08801,
58 "SB0880", CTSB0880),
59 SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, PCI_SUBDEVICE_ID_CREATIVE_SB08802,
60 "SB0880", CTSB0880),
61 SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, PCI_SUBDEVICE_ID_CREATIVE_SB08803,
62 "SB0880", CTSB0880),
63 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_CREATIVE, 0xf000,
64 PCI_SUBDEVICE_ID_CREATIVE_HENDRIX, "HENDRIX",
65 CTHENDRIX),
66 { } /* terminator */
67};
68
69static const char *ct_subsys_name[NUM_CTCARDS] = {
70 [CTSB055X] = "SB055x",
71 [CTSB073X] = "SB073x",
72 [CTSB0760] = "SB076x",
73 [CTUAA] = "UAA",
74 [CT20K1_UNKNOWN] = "Unknown",
75 [CTHENDRIX] = "Hendrix",
76 [CTSB0880] = "SB0880",
77};
78
79static struct {
80 int (*create)(struct ct_atc *atc,
81 enum CTALSADEVS device, const char *device_name);
82 int (*destroy)(void *alsa_dev);
83 const char *public_name;
84} alsa_dev_funcs[NUM_CTALSADEVS] = {
85 [FRONT] = { .create = ct_alsa_pcm_create,
86 .destroy = NULL,
87 .public_name = "Front/WaveIn"},
88 [SURROUND] = { .create = ct_alsa_pcm_create,
89 .destroy = NULL,
90 .public_name = "Surround"},
91 [CLFE] = { .create = ct_alsa_pcm_create,
92 .destroy = NULL,
93 .public_name = "Center/LFE"},
94 [SIDE] = { .create = ct_alsa_pcm_create,
95 .destroy = NULL,
96 .public_name = "Side"},
97 [IEC958] = { .create = ct_alsa_pcm_create,
98 .destroy = NULL,
99 .public_name = "IEC958 Non-audio"},
100
101 [MIXER] = { .create = ct_alsa_mix_create,
102 .destroy = NULL,
103 .public_name = "Mixer"}
104};
105
106typedef int (*create_t)(void *, void **);
107typedef int (*destroy_t)(void *);
108
109static struct {
110 int (*create)(void *hw, void **rmgr);
111 int (*destroy)(void *mgr);
112} rsc_mgr_funcs[NUM_RSCTYP] = {
113 [SRC] = { .create = (create_t)src_mgr_create,
114 .destroy = (destroy_t)src_mgr_destroy },
115 [SRCIMP] = { .create = (create_t)srcimp_mgr_create,
116 .destroy = (destroy_t)srcimp_mgr_destroy },
117 [AMIXER] = { .create = (create_t)amixer_mgr_create,
118 .destroy = (destroy_t)amixer_mgr_destroy },
119 [SUM] = { .create = (create_t)sum_mgr_create,
120 .destroy = (destroy_t)sum_mgr_destroy },
121 [DAIO] = { .create = (create_t)daio_mgr_create,
122 .destroy = (destroy_t)daio_mgr_destroy }
123};
124
125static int
126atc_pcm_release_resources(struct ct_atc *atc, struct ct_atc_pcm *apcm);
127
128/* *
129 * Only mono and interleaved modes are supported now.
130 * Always allocates a contiguous channel block.
131 * */
132
133static int ct_map_audio_buffer(struct ct_atc *atc, struct ct_atc_pcm *apcm)
134{
135 struct snd_pcm_runtime *runtime;
136 struct ct_vm *vm;
137
138 if (NULL == apcm->substream)
139 return 0;
140
141 runtime = apcm->substream->runtime;
142 vm = atc->vm;
143
144 apcm->vm_block = vm->map(vm, apcm->substream, runtime->dma_bytes);
145
146 if (NULL == apcm->vm_block)
147 return -ENOENT;
148
149 return 0;
150}
151
152static void ct_unmap_audio_buffer(struct ct_atc *atc, struct ct_atc_pcm *apcm)
153{
154 struct ct_vm *vm;
155
156 if (NULL == apcm->vm_block)
157 return;
158
159 vm = atc->vm;
160
161 vm->unmap(vm, apcm->vm_block);
162
163 apcm->vm_block = NULL;
164}
165
166static unsigned long atc_get_ptp_phys(struct ct_atc *atc, int index)
167{
168 struct ct_vm *vm;
169 void *kvirt_addr;
170 unsigned long phys_addr;
171
172 vm = atc->vm;
173 kvirt_addr = vm->get_ptp_virt(vm, index);
174 if (kvirt_addr == NULL)
175 phys_addr = (~0UL);
176 else
177 phys_addr = virt_to_phys(kvirt_addr);
178
179 return phys_addr;
180}
181
182static unsigned int convert_format(snd_pcm_format_t snd_format)
183{
184 switch (snd_format) {
185 case SNDRV_PCM_FORMAT_U8:
186 return SRC_SF_U8;
187 case SNDRV_PCM_FORMAT_S16_LE:
188 return SRC_SF_S16;
189 case SNDRV_PCM_FORMAT_S24_3LE:
190 return SRC_SF_S24;
191 case SNDRV_PCM_FORMAT_S32_LE:
192 return SRC_SF_S32;
193 case SNDRV_PCM_FORMAT_FLOAT_LE:
194 return SRC_SF_F32;
195 default:
196 printk(KERN_ERR "ctxfi: not recognized snd format is %d \n",
197 snd_format);
198 return SRC_SF_S16;
199 }
200}
201
202static unsigned int
203atc_get_pitch(unsigned int input_rate, unsigned int output_rate)
204{
205 unsigned int pitch;
206 int b;
207
208 /* get pitch and convert to fixed-point 8.24 format. */
209 pitch = (input_rate / output_rate) << 24;
210 input_rate %= output_rate;
211 input_rate /= 100;
212 output_rate /= 100;
213 for (b = 31; ((b >= 0) && !(input_rate >> b)); )
214 b--;
215
216 if (b >= 0) {
217 input_rate <<= (31 - b);
218 input_rate /= output_rate;
219 b = 24 - (31 - b);
220 if (b >= 0)
221 input_rate <<= b;
222 else
223 input_rate >>= -b;
224
225 pitch |= input_rate;
226 }
227
228 return pitch;
229}
230
231static int select_rom(unsigned int pitch)
232{
233 if ((pitch > 0x00428f5c) && (pitch < 0x01b851ec)) {
234 /* 0.26 <= pitch <= 1.72 */
235 return 1;
236 } else if ((0x01d66666 == pitch) || (0x01d66667 == pitch)) {
237 /* pitch == 1.8375 */
238 return 2;
239 } else if (0x02000000 == pitch) {
240 /* pitch == 2 */
241 return 3;
242 } else if ((pitch >= 0x0) && (pitch <= 0x08000000)) {
243 /* 0 <= pitch <= 8 */
244 return 0;
245 } else {
246 return -ENOENT;
247 }
248}
249
250static int atc_pcm_playback_prepare(struct ct_atc *atc, struct ct_atc_pcm *apcm)
251{
252 struct src_mgr *src_mgr = atc->rsc_mgrs[SRC];
253 struct amixer_mgr *amixer_mgr = atc->rsc_mgrs[AMIXER];
254 struct src_desc desc = {0};
255 struct amixer_desc mix_dsc = {0};
256 struct src *src;
257 struct amixer *amixer;
258 int err;
259 int n_amixer = apcm->substream->runtime->channels, i = 0;
260 int device = apcm->substream->pcm->device;
261 unsigned int pitch;
262 unsigned long flags;
263
264 if (NULL != apcm->src) {
265 /* Prepared pcm playback */
266 return 0;
267 }
268
269 /* first release old resources */
270 atc->pcm_release_resources(atc, apcm);
271
272 /* Get SRC resource */
273 desc.multi = apcm->substream->runtime->channels;
274 desc.msr = atc->msr;
275 desc.mode = MEMRD;
276 err = src_mgr->get_src(src_mgr, &desc, (struct src **)&apcm->src);
277 if (err)
278 goto error1;
279
280 pitch = atc_get_pitch(apcm->substream->runtime->rate,
281 (atc->rsr * atc->msr));
282 src = apcm->src;
283 src->ops->set_pitch(src, pitch);
284 src->ops->set_rom(src, select_rom(pitch));
285 src->ops->set_sf(src, convert_format(apcm->substream->runtime->format));
286 src->ops->set_pm(src, (src->ops->next_interleave(src) != NULL));
287
288 /* Get AMIXER resource */
289 n_amixer = (n_amixer < 2) ? 2 : n_amixer;
290 apcm->amixers = kzalloc(sizeof(void *)*n_amixer, GFP_KERNEL);
291 if (NULL == apcm->amixers) {
292 err = -ENOMEM;
293 goto error1;
294 }
295 mix_dsc.msr = atc->msr;
296 for (i = 0, apcm->n_amixer = 0; i < n_amixer; i++) {
297 err = amixer_mgr->get_amixer(amixer_mgr, &mix_dsc,
298 (struct amixer **)&apcm->amixers[i]);
299 if (err)
300 goto error1;
301
302 apcm->n_amixer++;
303 }
304
305 /* Set up device virtual mem map */
306 err = ct_map_audio_buffer(atc, apcm);
307 if (err < 0)
308 goto error1;
309
310 /* Connect resources */
311 src = apcm->src;
312 for (i = 0; i < n_amixer; i++) {
313 amixer = apcm->amixers[i];
314 spin_lock_irqsave(&atc->atc_lock, flags);
315 amixer->ops->setup(amixer, &src->rsc,
316 INIT_VOL, atc->pcm[i+device*2]);
317 spin_unlock_irqrestore(&atc->atc_lock, flags);
318 src = src->ops->next_interleave(src);
319 if (NULL == src)
320 src = apcm->src;
321 }
322
323 ct_timer_prepare(apcm->timer);
324
325 return 0;
326
327error1:
328 atc_pcm_release_resources(atc, apcm);
329 return err;
330}
331
332static int
333atc_pcm_release_resources(struct ct_atc *atc, struct ct_atc_pcm *apcm)
334{
335 struct src_mgr *src_mgr = atc->rsc_mgrs[SRC];
336 struct srcimp_mgr *srcimp_mgr = atc->rsc_mgrs[SRCIMP];
337 struct amixer_mgr *amixer_mgr = atc->rsc_mgrs[AMIXER];
338 struct sum_mgr *sum_mgr = atc->rsc_mgrs[SUM];
339 struct srcimp *srcimp;
340 int i;
341
342 if (NULL != apcm->srcimps) {
343 for (i = 0; i < apcm->n_srcimp; i++) {
344 srcimp = apcm->srcimps[i];
345 srcimp->ops->unmap(srcimp);
346 srcimp_mgr->put_srcimp(srcimp_mgr, srcimp);
347 apcm->srcimps[i] = NULL;
348 }
349 kfree(apcm->srcimps);
350 apcm->srcimps = NULL;
351 }
352
353 if (NULL != apcm->srccs) {
354 for (i = 0; i < apcm->n_srcc; i++) {
355 src_mgr->put_src(src_mgr, apcm->srccs[i]);
356 apcm->srccs[i] = NULL;
357 }
358 kfree(apcm->srccs);
359 apcm->srccs = NULL;
360 }
361
362 if (NULL != apcm->amixers) {
363 for (i = 0; i < apcm->n_amixer; i++) {
364 amixer_mgr->put_amixer(amixer_mgr, apcm->amixers[i]);
365 apcm->amixers[i] = NULL;
366 }
367 kfree(apcm->amixers);
368 apcm->amixers = NULL;
369 }
370
371 if (NULL != apcm->mono) {
372 sum_mgr->put_sum(sum_mgr, apcm->mono);
373 apcm->mono = NULL;
374 }
375
376 if (NULL != apcm->src) {
377 src_mgr->put_src(src_mgr, apcm->src);
378 apcm->src = NULL;
379 }
380
381 if (NULL != apcm->vm_block) {
382 /* Undo device virtual mem map */
383 ct_unmap_audio_buffer(atc, apcm);
384 apcm->vm_block = NULL;
385 }
386
387 return 0;
388}
389
390static int atc_pcm_playback_start(struct ct_atc *atc, struct ct_atc_pcm *apcm)
391{
392 unsigned int max_cisz;
393 struct src *src = apcm->src;
394
395 if (apcm->started)
396 return 0;
397 apcm->started = 1;
398
399 max_cisz = src->multi * src->rsc.msr;
400 max_cisz = 0x80 * (max_cisz < 8 ? max_cisz : 8);
401
402 src->ops->set_sa(src, apcm->vm_block->addr);
403 src->ops->set_la(src, apcm->vm_block->addr + apcm->vm_block->size);
404 src->ops->set_ca(src, apcm->vm_block->addr + max_cisz);
405 src->ops->set_cisz(src, max_cisz);
406
407 src->ops->set_bm(src, 1);
408 src->ops->set_state(src, SRC_STATE_INIT);
409 src->ops->commit_write(src);
410
411 ct_timer_start(apcm->timer);
412 return 0;
413}
414
415static int atc_pcm_stop(struct ct_atc *atc, struct ct_atc_pcm *apcm)
416{
417 struct src *src;
418 int i;
419
420 ct_timer_stop(apcm->timer);
421
422 src = apcm->src;
423 src->ops->set_bm(src, 0);
424 src->ops->set_state(src, SRC_STATE_OFF);
425 src->ops->commit_write(src);
426
427 if (NULL != apcm->srccs) {
428 for (i = 0; i < apcm->n_srcc; i++) {
429 src = apcm->srccs[i];
430 src->ops->set_bm(src, 0);
431 src->ops->set_state(src, SRC_STATE_OFF);
432 src->ops->commit_write(src);
433 }
434 }
435
436 apcm->started = 0;
437
438 return 0;
439}
440
441static int
442atc_pcm_playback_position(struct ct_atc *atc, struct ct_atc_pcm *apcm)
443{
444 struct src *src = apcm->src;
445 u32 size, max_cisz;
446 int position;
447
448 if (!src)
449 return 0;
450 position = src->ops->get_ca(src);
451
452 size = apcm->vm_block->size;
453 max_cisz = src->multi * src->rsc.msr;
454 max_cisz = 128 * (max_cisz < 8 ? max_cisz : 8);
455
456 return (position + size - max_cisz - apcm->vm_block->addr) % size;
457}
458
459struct src_node_conf_t {
460 unsigned int pitch;
461 unsigned int msr:8;
462 unsigned int mix_msr:8;
463 unsigned int imp_msr:8;
464 unsigned int vo:1;
465};
466
467static void setup_src_node_conf(struct ct_atc *atc, struct ct_atc_pcm *apcm,
468 struct src_node_conf_t *conf, int *n_srcc)
469{
470 unsigned int pitch;
471
472 /* get pitch and convert to fixed-point 8.24 format. */
473 pitch = atc_get_pitch((atc->rsr * atc->msr),
474 apcm->substream->runtime->rate);
475 *n_srcc = 0;
476
477 if (1 == atc->msr) {
478 *n_srcc = apcm->substream->runtime->channels;
479 conf[0].pitch = pitch;
480 conf[0].mix_msr = conf[0].imp_msr = conf[0].msr = 1;
481 conf[0].vo = 1;
482 } else if (2 == atc->msr) {
483 if (0x8000000 < pitch) {
484 /* Need two-stage SRCs, SRCIMPs and
485 * AMIXERs for converting format */
486 conf[0].pitch = (atc->msr << 24);
487 conf[0].msr = conf[0].mix_msr = 1;
488 conf[0].imp_msr = atc->msr;
489 conf[0].vo = 0;
490 conf[1].pitch = atc_get_pitch(atc->rsr,
491 apcm->substream->runtime->rate);
492 conf[1].msr = conf[1].mix_msr = conf[1].imp_msr = 1;
493 conf[1].vo = 1;
494 *n_srcc = apcm->substream->runtime->channels * 2;
495 } else if (0x1000000 < pitch) {
496 /* Need one-stage SRCs, SRCIMPs and
497 * AMIXERs for converting format */
498 conf[0].pitch = pitch;
499 conf[0].msr = conf[0].mix_msr
500 = conf[0].imp_msr = atc->msr;
501 conf[0].vo = 1;
502 *n_srcc = apcm->substream->runtime->channels;
503 }
504 }
505}
506
507static int
508atc_pcm_capture_get_resources(struct ct_atc *atc, struct ct_atc_pcm *apcm)
509{
510 struct src_mgr *src_mgr = atc->rsc_mgrs[SRC];
511 struct srcimp_mgr *srcimp_mgr = atc->rsc_mgrs[SRCIMP];
512 struct amixer_mgr *amixer_mgr = atc->rsc_mgrs[AMIXER];
513 struct sum_mgr *sum_mgr = atc->rsc_mgrs[SUM];
514 struct src_desc src_dsc = {0};
515 struct src *src;
516 struct srcimp_desc srcimp_dsc = {0};
517 struct srcimp *srcimp;
518 struct amixer_desc mix_dsc = {0};
519 struct sum_desc sum_dsc = {0};
520 unsigned int pitch;
521 int multi, err, i;
522 int n_srcimp, n_amixer, n_srcc, n_sum;
523 struct src_node_conf_t src_node_conf[2] = {{0} };
524
525 /* first release old resources */
526 atc_pcm_release_resources(atc, apcm);
527
528 /* The numbers of converting SRCs and SRCIMPs should be determined
529 * by pitch value. */
530
531 multi = apcm->substream->runtime->channels;
532
533 /* get pitch and convert to fixed-point 8.24 format. */
534 pitch = atc_get_pitch((atc->rsr * atc->msr),
535 apcm->substream->runtime->rate);
536
537 setup_src_node_conf(atc, apcm, src_node_conf, &n_srcc);
538 n_sum = (1 == multi) ? 1 : 0;
539 n_amixer = n_sum * 2 + n_srcc;
540 n_srcimp = n_srcc;
541 if ((multi > 1) && (0x8000000 >= pitch)) {
542 /* Need extra AMIXERs and SRCIMPs for special treatment
543 * of interleaved recording of conjugate channels */
544 n_amixer += multi * atc->msr;
545 n_srcimp += multi * atc->msr;
546 } else {
547 n_srcimp += multi;
548 }
549
550 if (n_srcc) {
551 apcm->srccs = kzalloc(sizeof(void *)*n_srcc, GFP_KERNEL);
552 if (NULL == apcm->srccs)
553 return -ENOMEM;
554 }
555 if (n_amixer) {
556 apcm->amixers = kzalloc(sizeof(void *)*n_amixer, GFP_KERNEL);
557 if (NULL == apcm->amixers) {
558 err = -ENOMEM;
559 goto error1;
560 }
561 }
562 apcm->srcimps = kzalloc(sizeof(void *)*n_srcimp, GFP_KERNEL);
563 if (NULL == apcm->srcimps) {
564 err = -ENOMEM;
565 goto error1;
566 }
567
568 /* Allocate SRCs for sample rate conversion if needed */
569 src_dsc.multi = 1;
570 src_dsc.mode = ARCRW;
571 for (i = 0, apcm->n_srcc = 0; i < n_srcc; i++) {
572 src_dsc.msr = src_node_conf[i/multi].msr;
573 err = src_mgr->get_src(src_mgr, &src_dsc,
574 (struct src **)&apcm->srccs[i]);
575 if (err)
576 goto error1;
577
578 src = apcm->srccs[i];
579 pitch = src_node_conf[i/multi].pitch;
580 src->ops->set_pitch(src, pitch);
581 src->ops->set_rom(src, select_rom(pitch));
582 src->ops->set_vo(src, src_node_conf[i/multi].vo);
583
584 apcm->n_srcc++;
585 }
586
587 /* Allocate AMIXERs for routing SRCs of conversion if needed */
588 for (i = 0, apcm->n_amixer = 0; i < n_amixer; i++) {
589 if (i < (n_sum*2))
590 mix_dsc.msr = atc->msr;
591 else if (i < (n_sum*2+n_srcc))
592 mix_dsc.msr = src_node_conf[(i-n_sum*2)/multi].mix_msr;
593 else
594 mix_dsc.msr = 1;
595
596 err = amixer_mgr->get_amixer(amixer_mgr, &mix_dsc,
597 (struct amixer **)&apcm->amixers[i]);
598 if (err)
599 goto error1;
600
601 apcm->n_amixer++;
602 }
603
604 /* Allocate a SUM resource to mix all input channels together */
605 sum_dsc.msr = atc->msr;
606 err = sum_mgr->get_sum(sum_mgr, &sum_dsc, (struct sum **)&apcm->mono);
607 if (err)
608 goto error1;
609
610 pitch = atc_get_pitch((atc->rsr * atc->msr),
611 apcm->substream->runtime->rate);
612 /* Allocate SRCIMP resources */
613 for (i = 0, apcm->n_srcimp = 0; i < n_srcimp; i++) {
614 if (i < (n_srcc))
615 srcimp_dsc.msr = src_node_conf[i/multi].imp_msr;
616 else if (1 == multi)
617 srcimp_dsc.msr = (pitch <= 0x8000000) ? atc->msr : 1;
618 else
619 srcimp_dsc.msr = 1;
620
621 err = srcimp_mgr->get_srcimp(srcimp_mgr, &srcimp_dsc, &srcimp);
622 if (err)
623 goto error1;
624
625 apcm->srcimps[i] = srcimp;
626 apcm->n_srcimp++;
627 }
628
629 /* Allocate a SRC for writing data to host memory */
630 src_dsc.multi = apcm->substream->runtime->channels;
631 src_dsc.msr = 1;
632 src_dsc.mode = MEMWR;
633 err = src_mgr->get_src(src_mgr, &src_dsc, (struct src **)&apcm->src);
634 if (err)
635 goto error1;
636
637 src = apcm->src;
638 src->ops->set_pitch(src, pitch);
639
640 /* Set up device virtual mem map */
641 err = ct_map_audio_buffer(atc, apcm);
642 if (err < 0)
643 goto error1;
644
645 return 0;
646
647error1:
648 atc_pcm_release_resources(atc, apcm);
649 return err;
650}
651
652static int atc_pcm_capture_prepare(struct ct_atc *atc, struct ct_atc_pcm *apcm)
653{
654 struct src *src;
655 struct amixer *amixer;
656 struct srcimp *srcimp;
657 struct ct_mixer *mixer = atc->mixer;
658 struct sum *mono;
659 struct rsc *out_ports[8] = {NULL};
660 int err, i, j, n_sum, multi;
661 unsigned int pitch;
662 int mix_base = 0, imp_base = 0;
663
664 if (NULL != apcm->src) {
665 /* Prepared pcm capture */
666 return 0;
667 }
668
669 /* Get needed resources. */
670 err = atc_pcm_capture_get_resources(atc, apcm);
671 if (err)
672 return err;
673
674 /* Connect resources */
675 mixer->get_output_ports(mixer, MIX_PCMO_FRONT,
676 &out_ports[0], &out_ports[1]);
677
678 multi = apcm->substream->runtime->channels;
679 if (1 == multi) {
680 mono = apcm->mono;
681 for (i = 0; i < 2; i++) {
682 amixer = apcm->amixers[i];
683 amixer->ops->setup(amixer, out_ports[i],
684 MONO_SUM_SCALE, mono);
685 }
686 out_ports[0] = &mono->rsc;
687 n_sum = 1;
688 mix_base = n_sum * 2;
689 }
690
691 for (i = 0; i < apcm->n_srcc; i++) {
692 src = apcm->srccs[i];
693 srcimp = apcm->srcimps[imp_base+i];
694 amixer = apcm->amixers[mix_base+i];
695 srcimp->ops->map(srcimp, src, out_ports[i%multi]);
696 amixer->ops->setup(amixer, &src->rsc, INIT_VOL, NULL);
697 out_ports[i%multi] = &amixer->rsc;
698 }
699
700 pitch = atc_get_pitch((atc->rsr * atc->msr),
701 apcm->substream->runtime->rate);
702
703 if ((multi > 1) && (pitch <= 0x8000000)) {
704 /* Special connection for interleaved
705 * recording with conjugate channels */
706 for (i = 0; i < multi; i++) {
707 out_ports[i]->ops->master(out_ports[i]);
708 for (j = 0; j < atc->msr; j++) {
709 amixer = apcm->amixers[apcm->n_srcc+j*multi+i];
710 amixer->ops->set_input(amixer, out_ports[i]);
711 amixer->ops->set_scale(amixer, INIT_VOL);
712 amixer->ops->set_sum(amixer, NULL);
713 amixer->ops->commit_raw_write(amixer);
714 out_ports[i]->ops->next_conj(out_ports[i]);
715
716 srcimp = apcm->srcimps[apcm->n_srcc+j*multi+i];
717 srcimp->ops->map(srcimp, apcm->src,
718 &amixer->rsc);
719 }
720 }
721 } else {
722 for (i = 0; i < multi; i++) {
723 srcimp = apcm->srcimps[apcm->n_srcc+i];
724 srcimp->ops->map(srcimp, apcm->src, out_ports[i]);
725 }
726 }
727
728 ct_timer_prepare(apcm->timer);
729
730 return 0;
731}
732
733static int atc_pcm_capture_start(struct ct_atc *atc, struct ct_atc_pcm *apcm)
734{
735 struct src *src;
736 struct src_mgr *src_mgr = atc->rsc_mgrs[SRC];
737 int i, multi;
738
739 if (apcm->started)
740 return 0;
741
742 apcm->started = 1;
743 multi = apcm->substream->runtime->channels;
744 /* Set up converting SRCs */
745 for (i = 0; i < apcm->n_srcc; i++) {
746 src = apcm->srccs[i];
747 src->ops->set_pm(src, ((i%multi) != (multi-1)));
748 src_mgr->src_disable(src_mgr, src);
749 }
750
751 /* Set up recording SRC */
752 src = apcm->src;
753 src->ops->set_sf(src, convert_format(apcm->substream->runtime->format));
754 src->ops->set_sa(src, apcm->vm_block->addr);
755 src->ops->set_la(src, apcm->vm_block->addr + apcm->vm_block->size);
756 src->ops->set_ca(src, apcm->vm_block->addr);
757 src_mgr->src_disable(src_mgr, src);
758
759 /* Disable relevant SRCs firstly */
760 src_mgr->commit_write(src_mgr);
761
762 /* Enable SRCs respectively */
763 for (i = 0; i < apcm->n_srcc; i++) {
764 src = apcm->srccs[i];
765 src->ops->set_state(src, SRC_STATE_RUN);
766 src->ops->commit_write(src);
767 src_mgr->src_enable_s(src_mgr, src);
768 }
769 src = apcm->src;
770 src->ops->set_bm(src, 1);
771 src->ops->set_state(src, SRC_STATE_RUN);
772 src->ops->commit_write(src);
773 src_mgr->src_enable_s(src_mgr, src);
774
775 /* Enable relevant SRCs synchronously */
776 src_mgr->commit_write(src_mgr);
777
778 ct_timer_start(apcm->timer);
779 return 0;
780}
781
782static int
783atc_pcm_capture_position(struct ct_atc *atc, struct ct_atc_pcm *apcm)
784{
785 struct src *src = apcm->src;
786
787 if (!src)
788 return 0;
789 return src->ops->get_ca(src) - apcm->vm_block->addr;
790}
791
792static int spdif_passthru_playback_get_resources(struct ct_atc *atc,
793 struct ct_atc_pcm *apcm)
794{
795 struct src_mgr *src_mgr = atc->rsc_mgrs[SRC];
796 struct amixer_mgr *amixer_mgr = atc->rsc_mgrs[AMIXER];
797 struct src_desc desc = {0};
798 struct amixer_desc mix_dsc = {0};
799 struct src *src;
800 int err;
801 int n_amixer = apcm->substream->runtime->channels, i;
802 unsigned int pitch, rsr = atc->pll_rate;
803
804 /* first release old resources */
805 atc_pcm_release_resources(atc, apcm);
806
807 /* Get SRC resource */
808 desc.multi = apcm->substream->runtime->channels;
809 desc.msr = 1;
810 while (apcm->substream->runtime->rate > (rsr * desc.msr))
811 desc.msr <<= 1;
812
813 desc.mode = MEMRD;
814 err = src_mgr->get_src(src_mgr, &desc, (struct src **)&apcm->src);
815 if (err)
816 goto error1;
817
818 pitch = atc_get_pitch(apcm->substream->runtime->rate, (rsr * desc.msr));
819 src = apcm->src;
820 src->ops->set_pitch(src, pitch);
821 src->ops->set_rom(src, select_rom(pitch));
822 src->ops->set_sf(src, convert_format(apcm->substream->runtime->format));
823 src->ops->set_pm(src, (src->ops->next_interleave(src) != NULL));
824 src->ops->set_bp(src, 1);
825
826 /* Get AMIXER resource */
827 n_amixer = (n_amixer < 2) ? 2 : n_amixer;
828 apcm->amixers = kzalloc(sizeof(void *)*n_amixer, GFP_KERNEL);
829 if (NULL == apcm->amixers) {
830 err = -ENOMEM;
831 goto error1;
832 }
833 mix_dsc.msr = desc.msr;
834 for (i = 0, apcm->n_amixer = 0; i < n_amixer; i++) {
835 err = amixer_mgr->get_amixer(amixer_mgr, &mix_dsc,
836 (struct amixer **)&apcm->amixers[i]);
837 if (err)
838 goto error1;
839
840 apcm->n_amixer++;
841 }
842
843 /* Set up device virtual mem map */
844 err = ct_map_audio_buffer(atc, apcm);
845 if (err < 0)
846 goto error1;
847
848 return 0;
849
850error1:
851 atc_pcm_release_resources(atc, apcm);
852 return err;
853}
854
855static int atc_pll_init(struct ct_atc *atc, int rate)
856{
857 struct hw *hw = atc->hw;
858 int err;
859 err = hw->pll_init(hw, rate);
860 atc->pll_rate = err ? 0 : rate;
861 return err;
862}
863
864static int
865spdif_passthru_playback_setup(struct ct_atc *atc, struct ct_atc_pcm *apcm)
866{
867 struct dao *dao = container_of(atc->daios[SPDIFOO], struct dao, daio);
868 unsigned long flags;
869 unsigned int rate = apcm->substream->runtime->rate;
870 unsigned int status;
871 int err;
872 unsigned char iec958_con_fs;
873
874 switch (rate) {
875 case 48000:
876 iec958_con_fs = IEC958_AES3_CON_FS_48000;
877 break;
878 case 44100:
879 iec958_con_fs = IEC958_AES3_CON_FS_44100;
880 break;
881 case 32000:
882 iec958_con_fs = IEC958_AES3_CON_FS_32000;
883 break;
884 default:
885 return -ENOENT;
886 }
887
888 spin_lock_irqsave(&atc->atc_lock, flags);
889 dao->ops->get_spos(dao, &status);
890 if (((status >> 24) & IEC958_AES3_CON_FS) != iec958_con_fs) {
891 status &= ((~IEC958_AES3_CON_FS) << 24);
892 status |= (iec958_con_fs << 24);
893 dao->ops->set_spos(dao, status);
894 dao->ops->commit_write(dao);
895 }
896 if ((rate != atc->pll_rate) && (32000 != rate))
897 err = atc_pll_init(atc, rate);
898 spin_unlock_irqrestore(&atc->atc_lock, flags);
899
900 return err;
901}
902
903static int
904spdif_passthru_playback_prepare(struct ct_atc *atc, struct ct_atc_pcm *apcm)
905{
906 struct src *src;
907 struct amixer *amixer;
908 struct dao *dao;
909 int err;
910 int i;
911 unsigned long flags;
912
913 if (NULL != apcm->src)
914 return 0;
915
916 /* Configure SPDIFOO and PLL to passthrough mode;
917 * determine pll_rate. */
918 err = spdif_passthru_playback_setup(atc, apcm);
919 if (err)
920 return err;
921
922 /* Get needed resources. */
923 err = spdif_passthru_playback_get_resources(atc, apcm);
924 if (err)
925 return err;
926
927 /* Connect resources */
928 src = apcm->src;
929 for (i = 0; i < apcm->n_amixer; i++) {
930 amixer = apcm->amixers[i];
931 amixer->ops->setup(amixer, &src->rsc, INIT_VOL, NULL);
932 src = src->ops->next_interleave(src);
933 if (NULL == src)
934 src = apcm->src;
935 }
936 /* Connect to SPDIFOO */
937 spin_lock_irqsave(&atc->atc_lock, flags);
938 dao = container_of(atc->daios[SPDIFOO], struct dao, daio);
939 amixer = apcm->amixers[0];
940 dao->ops->set_left_input(dao, &amixer->rsc);
941 amixer = apcm->amixers[1];
942 dao->ops->set_right_input(dao, &amixer->rsc);
943 spin_unlock_irqrestore(&atc->atc_lock, flags);
944
945 ct_timer_prepare(apcm->timer);
946
947 return 0;
948}
949
950static int atc_select_line_in(struct ct_atc *atc)
951{
952 struct hw *hw = atc->hw;
953 struct ct_mixer *mixer = atc->mixer;
954 struct src *src;
955
956 if (hw->is_adc_source_selected(hw, ADC_LINEIN))
957 return 0;
958
959 mixer->set_input_left(mixer, MIX_MIC_IN, NULL);
960 mixer->set_input_right(mixer, MIX_MIC_IN, NULL);
961
962 hw->select_adc_source(hw, ADC_LINEIN);
963
964 src = atc->srcs[2];
965 mixer->set_input_left(mixer, MIX_LINE_IN, &src->rsc);
966 src = atc->srcs[3];
967 mixer->set_input_right(mixer, MIX_LINE_IN, &src->rsc);
968
969 return 0;
970}
971
972static int atc_select_mic_in(struct ct_atc *atc)
973{
974 struct hw *hw = atc->hw;
975 struct ct_mixer *mixer = atc->mixer;
976 struct src *src;
977
978 if (hw->is_adc_source_selected(hw, ADC_MICIN))
979 return 0;
980
981 mixer->set_input_left(mixer, MIX_LINE_IN, NULL);
982 mixer->set_input_right(mixer, MIX_LINE_IN, NULL);
983
984 hw->select_adc_source(hw, ADC_MICIN);
985
986 src = atc->srcs[2];
987 mixer->set_input_left(mixer, MIX_MIC_IN, &src->rsc);
988 src = atc->srcs[3];
989 mixer->set_input_right(mixer, MIX_MIC_IN, &src->rsc);
990
991 return 0;
992}
993
994static int atc_have_digit_io_switch(struct ct_atc *atc)
995{
996 struct hw *hw = atc->hw;
997
998 return hw->have_digit_io_switch(hw);
999}
1000
1001static int atc_select_digit_io(struct ct_atc *atc)
1002{
1003 struct hw *hw = atc->hw;
1004
1005 if (hw->is_adc_source_selected(hw, ADC_NONE))
1006 return 0;
1007
1008 hw->select_adc_source(hw, ADC_NONE);
1009
1010 return 0;
1011}
1012
1013static int atc_daio_unmute(struct ct_atc *atc, unsigned char state, int type)
1014{
1015 struct daio_mgr *daio_mgr = atc->rsc_mgrs[DAIO];
1016
1017 if (state)
1018 daio_mgr->daio_enable(daio_mgr, atc->daios[type]);
1019 else
1020 daio_mgr->daio_disable(daio_mgr, atc->daios[type]);
1021
1022 daio_mgr->commit_write(daio_mgr);
1023
1024 return 0;
1025}
1026
1027static int
1028atc_dao_get_status(struct ct_atc *atc, unsigned int *status, int type)
1029{
1030 struct dao *dao = container_of(atc->daios[type], struct dao, daio);
1031 return dao->ops->get_spos(dao, status);
1032}
1033
1034static int
1035atc_dao_set_status(struct ct_atc *atc, unsigned int status, int type)
1036{
1037 struct dao *dao = container_of(atc->daios[type], struct dao, daio);
1038
1039 dao->ops->set_spos(dao, status);
1040 dao->ops->commit_write(dao);
1041 return 0;
1042}
1043
1044static int atc_line_front_unmute(struct ct_atc *atc, unsigned char state)
1045{
1046 return atc_daio_unmute(atc, state, LINEO1);
1047}
1048
1049static int atc_line_surround_unmute(struct ct_atc *atc, unsigned char state)
1050{
1051 return atc_daio_unmute(atc, state, LINEO4);
1052}
1053
1054static int atc_line_clfe_unmute(struct ct_atc *atc, unsigned char state)
1055{
1056 return atc_daio_unmute(atc, state, LINEO3);
1057}
1058
1059static int atc_line_rear_unmute(struct ct_atc *atc, unsigned char state)
1060{
1061 return atc_daio_unmute(atc, state, LINEO2);
1062}
1063
1064static int atc_line_in_unmute(struct ct_atc *atc, unsigned char state)
1065{
1066 return atc_daio_unmute(atc, state, LINEIM);
1067}
1068
1069static int atc_spdif_out_unmute(struct ct_atc *atc, unsigned char state)
1070{
1071 return atc_daio_unmute(atc, state, SPDIFOO);
1072}
1073
1074static int atc_spdif_in_unmute(struct ct_atc *atc, unsigned char state)
1075{
1076 return atc_daio_unmute(atc, state, SPDIFIO);
1077}
1078
1079static int atc_spdif_out_get_status(struct ct_atc *atc, unsigned int *status)
1080{
1081 return atc_dao_get_status(atc, status, SPDIFOO);
1082}
1083
1084static int atc_spdif_out_set_status(struct ct_atc *atc, unsigned int status)
1085{
1086 return atc_dao_set_status(atc, status, SPDIFOO);
1087}
1088
1089static int atc_spdif_out_passthru(struct ct_atc *atc, unsigned char state)
1090{
1091 unsigned long flags;
1092 struct dao_desc da_dsc = {0};
1093 struct dao *dao;
1094 int err;
1095 struct ct_mixer *mixer = atc->mixer;
1096 struct rsc *rscs[2] = {NULL};
1097 unsigned int spos = 0;
1098
1099 spin_lock_irqsave(&atc->atc_lock, flags);
1100 dao = container_of(atc->daios[SPDIFOO], struct dao, daio);
1101 da_dsc.msr = state ? 1 : atc->msr;
1102 da_dsc.passthru = state ? 1 : 0;
1103 err = dao->ops->reinit(dao, &da_dsc);
1104 if (state) {
1105 spos = IEC958_DEFAULT_CON;
1106 } else {
1107 mixer->get_output_ports(mixer, MIX_SPDIF_OUT,
1108 &rscs[0], &rscs[1]);
1109 dao->ops->set_left_input(dao, rscs[0]);
1110 dao->ops->set_right_input(dao, rscs[1]);
1111 /* Restore PLL to atc->rsr if needed. */
1112 if (atc->pll_rate != atc->rsr)
1113 err = atc_pll_init(atc, atc->rsr);
1114 }
1115 dao->ops->set_spos(dao, spos);
1116 dao->ops->commit_write(dao);
1117 spin_unlock_irqrestore(&atc->atc_lock, flags);
1118
1119 return err;
1120}
1121
1122static int ct_atc_destroy(struct ct_atc *atc)
1123{
1124 struct daio_mgr *daio_mgr;
1125 struct dao *dao;
1126 struct dai *dai;
1127 struct daio *daio;
1128 struct sum_mgr *sum_mgr;
1129 struct src_mgr *src_mgr;
1130 struct srcimp_mgr *srcimp_mgr;
1131 struct srcimp *srcimp;
1132 struct ct_mixer *mixer;
1133 int i = 0;
1134
1135 if (NULL == atc)
1136 return 0;
1137
1138 if (atc->timer) {
1139 ct_timer_free(atc->timer);
1140 atc->timer = NULL;
1141 }
1142
1143 /* Stop hardware and disable all interrupts */
1144 if (NULL != atc->hw)
1145 ((struct hw *)atc->hw)->card_stop(atc->hw);
1146
1147 /* Destroy internal mixer objects */
1148 if (NULL != atc->mixer) {
1149 mixer = atc->mixer;
1150 mixer->set_input_left(mixer, MIX_LINE_IN, NULL);
1151 mixer->set_input_right(mixer, MIX_LINE_IN, NULL);
1152 mixer->set_input_left(mixer, MIX_MIC_IN, NULL);
1153 mixer->set_input_right(mixer, MIX_MIC_IN, NULL);
1154 mixer->set_input_left(mixer, MIX_SPDIF_IN, NULL);
1155 mixer->set_input_right(mixer, MIX_SPDIF_IN, NULL);
1156 ct_mixer_destroy(atc->mixer);
1157 }
1158
1159 if (NULL != atc->daios) {
1160 daio_mgr = (struct daio_mgr *)atc->rsc_mgrs[DAIO];
1161 for (i = 0; i < atc->n_daio; i++) {
1162 daio = atc->daios[i];
1163 if (daio->type < LINEIM) {
1164 dao = container_of(daio, struct dao, daio);
1165 dao->ops->clear_left_input(dao);
1166 dao->ops->clear_right_input(dao);
1167 } else {
1168 dai = container_of(daio, struct dai, daio);
1169 /* some thing to do for dai ... */
1170 }
1171 daio_mgr->put_daio(daio_mgr, daio);
1172 }
1173 kfree(atc->daios);
1174 }
1175
1176 if (NULL != atc->pcm) {
1177 sum_mgr = atc->rsc_mgrs[SUM];
1178 for (i = 0; i < atc->n_pcm; i++)
1179 sum_mgr->put_sum(sum_mgr, atc->pcm[i]);
1180
1181 kfree(atc->pcm);
1182 }
1183
1184 if (NULL != atc->srcs) {
1185 src_mgr = atc->rsc_mgrs[SRC];
1186 for (i = 0; i < atc->n_src; i++)
1187 src_mgr->put_src(src_mgr, atc->srcs[i]);
1188
1189 kfree(atc->srcs);
1190 }
1191
1192 if (NULL != atc->srcimps) {
1193 srcimp_mgr = atc->rsc_mgrs[SRCIMP];
1194 for (i = 0; i < atc->n_srcimp; i++) {
1195 srcimp = atc->srcimps[i];
1196 srcimp->ops->unmap(srcimp);
1197 srcimp_mgr->put_srcimp(srcimp_mgr, atc->srcimps[i]);
1198 }
1199 kfree(atc->srcimps);
1200 }
1201
1202 for (i = 0; i < NUM_RSCTYP; i++) {
1203 if ((NULL != rsc_mgr_funcs[i].destroy) &&
1204 (NULL != atc->rsc_mgrs[i]))
1205 rsc_mgr_funcs[i].destroy(atc->rsc_mgrs[i]);
1206
1207 }
1208
1209 if (NULL != atc->hw)
1210 destroy_hw_obj((struct hw *)atc->hw);
1211
1212 /* Destroy device virtual memory manager object */
1213 if (NULL != atc->vm) {
1214 ct_vm_destroy(atc->vm);
1215 atc->vm = NULL;
1216 }
1217
1218 kfree(atc);
1219
1220 return 0;
1221}
1222
1223static int atc_dev_free(struct snd_device *dev)
1224{
1225 struct ct_atc *atc = dev->device_data;
1226 return ct_atc_destroy(atc);
1227}
1228
1229static int __devinit atc_identify_card(struct ct_atc *atc)
1230{
1231 const struct snd_pci_quirk *p;
1232 const struct snd_pci_quirk *list;
1233
1234 switch (atc->chip_type) {
1235 case ATC20K1:
1236 atc->chip_name = "20K1";
1237 list = subsys_20k1_list;
1238 break;
1239 case ATC20K2:
1240 atc->chip_name = "20K2";
1241 list = subsys_20k2_list;
1242 break;
1243 default:
1244 return -ENOENT;
1245 }
1246 p = snd_pci_quirk_lookup(atc->pci, list);
1247 if (!p)
1248 return -ENOENT;
1249 atc->model = p->value;
1250 atc->model_name = ct_subsys_name[atc->model];
1251 snd_printd("ctxfi: chip %s model %s (%04x:%04x) is found\n",
1252 atc->chip_name, atc->model_name,
1253 atc->pci->subsystem_vendor,
1254 atc->pci->subsystem_device);
1255 return 0;
1256}
1257
1258int __devinit ct_atc_create_alsa_devs(struct ct_atc *atc)
1259{
1260 enum CTALSADEVS i;
1261 int err;
1262
1263 alsa_dev_funcs[MIXER].public_name = atc->chip_name;
1264
1265 for (i = 0; i < NUM_CTALSADEVS; i++) {
1266 if (NULL == alsa_dev_funcs[i].create)
1267 continue;
1268
1269 err = alsa_dev_funcs[i].create(atc, i,
1270 alsa_dev_funcs[i].public_name);
1271 if (err) {
1272 printk(KERN_ERR "ctxfi: "
1273 "Creating alsa device %d failed!\n", i);
1274 return err;
1275 }
1276 }
1277
1278 return 0;
1279}
1280
1281static int __devinit atc_create_hw_devs(struct ct_atc *atc)
1282{
1283 struct hw *hw;
1284 struct card_conf info = {0};
1285 int i, err;
1286
1287 err = create_hw_obj(atc->pci, atc->chip_type, atc->model, &hw);
1288 if (err) {
1289 printk(KERN_ERR "Failed to create hw obj!!!\n");
1290 return err;
1291 }
1292 atc->hw = hw;
1293
1294 /* Initialize card hardware. */
1295 info.rsr = atc->rsr;
1296 info.msr = atc->msr;
1297 info.vm_pgt_phys = atc_get_ptp_phys(atc, 0);
1298 err = hw->card_init(hw, &info);
1299 if (err < 0)
1300 return err;
1301
1302 for (i = 0; i < NUM_RSCTYP; i++) {
1303 if (NULL == rsc_mgr_funcs[i].create)
1304 continue;
1305
1306 err = rsc_mgr_funcs[i].create(atc->hw, &atc->rsc_mgrs[i]);
1307 if (err) {
1308 printk(KERN_ERR "ctxfi: "
1309 "Failed to create rsc_mgr %d!!!\n", i);
1310 return err;
1311 }
1312 }
1313
1314 return 0;
1315}
1316
1317static int __devinit atc_get_resources(struct ct_atc *atc)
1318{
1319 struct daio_desc da_desc = {0};
1320 struct daio_mgr *daio_mgr;
1321 struct src_desc src_dsc = {0};
1322 struct src_mgr *src_mgr;
1323 struct srcimp_desc srcimp_dsc = {0};
1324 struct srcimp_mgr *srcimp_mgr;
1325 struct sum_desc sum_dsc = {0};
1326 struct sum_mgr *sum_mgr;
1327 int err, i;
1328
1329 atc->daios = kzalloc(sizeof(void *)*(DAIONUM), GFP_KERNEL);
1330 if (NULL == atc->daios)
1331 return -ENOMEM;
1332
1333 atc->srcs = kzalloc(sizeof(void *)*(2*2), GFP_KERNEL);
1334 if (NULL == atc->srcs)
1335 return -ENOMEM;
1336
1337 atc->srcimps = kzalloc(sizeof(void *)*(2*2), GFP_KERNEL);
1338 if (NULL == atc->srcimps)
1339 return -ENOMEM;
1340
1341 atc->pcm = kzalloc(sizeof(void *)*(2*4), GFP_KERNEL);
1342 if (NULL == atc->pcm)
1343 return -ENOMEM;
1344
1345 daio_mgr = (struct daio_mgr *)atc->rsc_mgrs[DAIO];
1346 da_desc.msr = atc->msr;
1347 for (i = 0, atc->n_daio = 0; i < DAIONUM-1; i++) {
1348 da_desc.type = i;
1349 err = daio_mgr->get_daio(daio_mgr, &da_desc,
1350 (struct daio **)&atc->daios[i]);
1351 if (err) {
1352 printk(KERN_ERR "ctxfi: Failed to get DAIO "
1353 "resource %d!!!\n", i);
1354 return err;
1355 }
1356 atc->n_daio++;
1357 }
1358 if (atc->model == CTSB073X)
1359 da_desc.type = SPDIFI1;
1360 else
1361 da_desc.type = SPDIFIO;
1362 err = daio_mgr->get_daio(daio_mgr, &da_desc,
1363 (struct daio **)&atc->daios[i]);
1364 if (err) {
1365 printk(KERN_ERR "ctxfi: Failed to get S/PDIF-in resource!!!\n");
1366 return err;
1367 }
1368 atc->n_daio++;
1369
1370 src_mgr = atc->rsc_mgrs[SRC];
1371 src_dsc.multi = 1;
1372 src_dsc.msr = atc->msr;
1373 src_dsc.mode = ARCRW;
1374 for (i = 0, atc->n_src = 0; i < (2*2); i++) {
1375 err = src_mgr->get_src(src_mgr, &src_dsc,
1376 (struct src **)&atc->srcs[i]);
1377 if (err)
1378 return err;
1379
1380 atc->n_src++;
1381 }
1382
1383 srcimp_mgr = atc->rsc_mgrs[SRCIMP];
1384 srcimp_dsc.msr = 8; /* SRCIMPs for S/PDIFIn SRT */
1385 for (i = 0, atc->n_srcimp = 0; i < (2*1); i++) {
1386 err = srcimp_mgr->get_srcimp(srcimp_mgr, &srcimp_dsc,
1387 (struct srcimp **)&atc->srcimps[i]);
1388 if (err)
1389 return err;
1390
1391 atc->n_srcimp++;
1392 }
1393 srcimp_dsc.msr = 8; /* SRCIMPs for LINE/MICIn SRT */
1394 for (i = 0; i < (2*1); i++) {
1395 err = srcimp_mgr->get_srcimp(srcimp_mgr, &srcimp_dsc,
1396 (struct srcimp **)&atc->srcimps[2*1+i]);
1397 if (err)
1398 return err;
1399
1400 atc->n_srcimp++;
1401 }
1402
1403 sum_mgr = atc->rsc_mgrs[SUM];
1404 sum_dsc.msr = atc->msr;
1405 for (i = 0, atc->n_pcm = 0; i < (2*4); i++) {
1406 err = sum_mgr->get_sum(sum_mgr, &sum_dsc,
1407 (struct sum **)&atc->pcm[i]);
1408 if (err)
1409 return err;
1410
1411 atc->n_pcm++;
1412 }
1413
1414 err = ct_mixer_create(atc, (struct ct_mixer **)&atc->mixer);
1415 if (err) {
1416 printk(KERN_ERR "ctxfi: Failed to create mixer obj!!!\n");
1417 return err;
1418 }
1419
1420 return 0;
1421}
1422
1423static void __devinit
1424atc_connect_dai(struct src_mgr *src_mgr, struct dai *dai,
1425 struct src **srcs, struct srcimp **srcimps)
1426{
1427 struct rsc *rscs[2] = {NULL};
1428 struct src *src;
1429 struct srcimp *srcimp;
1430 int i = 0;
1431
1432 rscs[0] = &dai->daio.rscl;
1433 rscs[1] = &dai->daio.rscr;
1434 for (i = 0; i < 2; i++) {
1435 src = srcs[i];
1436 srcimp = srcimps[i];
1437 srcimp->ops->map(srcimp, src, rscs[i]);
1438 src_mgr->src_disable(src_mgr, src);
1439 }
1440
1441 src_mgr->commit_write(src_mgr); /* Actually disable SRCs */
1442
1443 src = srcs[0];
1444 src->ops->set_pm(src, 1);
1445 for (i = 0; i < 2; i++) {
1446 src = srcs[i];
1447 src->ops->set_state(src, SRC_STATE_RUN);
1448 src->ops->commit_write(src);
1449 src_mgr->src_enable_s(src_mgr, src);
1450 }
1451
1452 dai->ops->set_srt_srcl(dai, &(srcs[0]->rsc));
1453 dai->ops->set_srt_srcr(dai, &(srcs[1]->rsc));
1454
1455 dai->ops->set_enb_src(dai, 1);
1456 dai->ops->set_enb_srt(dai, 1);
1457 dai->ops->commit_write(dai);
1458
1459 src_mgr->commit_write(src_mgr); /* Synchronously enable SRCs */
1460}
1461
1462static void __devinit atc_connect_resources(struct ct_atc *atc)
1463{
1464 struct dai *dai;
1465 struct dao *dao;
1466 struct src *src;
1467 struct sum *sum;
1468 struct ct_mixer *mixer;
1469 struct rsc *rscs[2] = {NULL};
1470 int i, j;
1471
1472 mixer = atc->mixer;
1473
1474 for (i = MIX_WAVE_FRONT, j = LINEO1; i <= MIX_SPDIF_OUT; i++, j++) {
1475 mixer->get_output_ports(mixer, i, &rscs[0], &rscs[1]);
1476 dao = container_of(atc->daios[j], struct dao, daio);
1477 dao->ops->set_left_input(dao, rscs[0]);
1478 dao->ops->set_right_input(dao, rscs[1]);
1479 }
1480
1481 dai = container_of(atc->daios[LINEIM], struct dai, daio);
1482 atc_connect_dai(atc->rsc_mgrs[SRC], dai,
1483 (struct src **)&atc->srcs[2],
1484 (struct srcimp **)&atc->srcimps[2]);
1485 src = atc->srcs[2];
1486 mixer->set_input_left(mixer, MIX_LINE_IN, &src->rsc);
1487 src = atc->srcs[3];
1488 mixer->set_input_right(mixer, MIX_LINE_IN, &src->rsc);
1489
1490 dai = container_of(atc->daios[SPDIFIO], struct dai, daio);
1491 atc_connect_dai(atc->rsc_mgrs[SRC], dai,
1492 (struct src **)&atc->srcs[0],
1493 (struct srcimp **)&atc->srcimps[0]);
1494
1495 src = atc->srcs[0];
1496 mixer->set_input_left(mixer, MIX_SPDIF_IN, &src->rsc);
1497 src = atc->srcs[1];
1498 mixer->set_input_right(mixer, MIX_SPDIF_IN, &src->rsc);
1499
1500 for (i = MIX_PCMI_FRONT, j = 0; i <= MIX_PCMI_SURROUND; i++, j += 2) {
1501 sum = atc->pcm[j];
1502 mixer->set_input_left(mixer, i, &sum->rsc);
1503 sum = atc->pcm[j+1];
1504 mixer->set_input_right(mixer, i, &sum->rsc);
1505 }
1506}
1507
1508static struct ct_atc atc_preset __devinitdata = {
1509 .map_audio_buffer = ct_map_audio_buffer,
1510 .unmap_audio_buffer = ct_unmap_audio_buffer,
1511 .pcm_playback_prepare = atc_pcm_playback_prepare,
1512 .pcm_release_resources = atc_pcm_release_resources,
1513 .pcm_playback_start = atc_pcm_playback_start,
1514 .pcm_playback_stop = atc_pcm_stop,
1515 .pcm_playback_position = atc_pcm_playback_position,
1516 .pcm_capture_prepare = atc_pcm_capture_prepare,
1517 .pcm_capture_start = atc_pcm_capture_start,
1518 .pcm_capture_stop = atc_pcm_stop,
1519 .pcm_capture_position = atc_pcm_capture_position,
1520 .spdif_passthru_playback_prepare = spdif_passthru_playback_prepare,
1521 .get_ptp_phys = atc_get_ptp_phys,
1522 .select_line_in = atc_select_line_in,
1523 .select_mic_in = atc_select_mic_in,
1524 .select_digit_io = atc_select_digit_io,
1525 .line_front_unmute = atc_line_front_unmute,
1526 .line_surround_unmute = atc_line_surround_unmute,
1527 .line_clfe_unmute = atc_line_clfe_unmute,
1528 .line_rear_unmute = atc_line_rear_unmute,
1529 .line_in_unmute = atc_line_in_unmute,
1530 .spdif_out_unmute = atc_spdif_out_unmute,
1531 .spdif_in_unmute = atc_spdif_in_unmute,
1532 .spdif_out_get_status = atc_spdif_out_get_status,
1533 .spdif_out_set_status = atc_spdif_out_set_status,
1534 .spdif_out_passthru = atc_spdif_out_passthru,
1535 .have_digit_io_switch = atc_have_digit_io_switch,
1536};
1537
1538/**
1539 * ct_atc_create - create and initialize a hardware manager
1540 * @card: corresponding alsa card object
1541 * @pci: corresponding kernel pci device object
1542 * @ratc: return created object address in it
1543 *
1544 * Creates and initializes a hardware manager.
1545 *
1546 * Creates kmallocated ct_atc structure. Initializes hardware.
1547 * Returns 0 if suceeds, or negative error code if fails.
1548 */
1549
1550int __devinit ct_atc_create(struct snd_card *card, struct pci_dev *pci,
1551 unsigned int rsr, unsigned int msr,
1552 int chip_type, struct ct_atc **ratc)
1553{
1554 struct ct_atc *atc;
1555 static struct snd_device_ops ops = {
1556 .dev_free = atc_dev_free,
1557 };
1558 int err;
1559
1560 *ratc = NULL;
1561
1562 atc = kzalloc(sizeof(*atc), GFP_KERNEL);
1563 if (NULL == atc)
1564 return -ENOMEM;
1565
1566 /* Set operations */
1567 *atc = atc_preset;
1568
1569 atc->card = card;
1570 atc->pci = pci;
1571 atc->rsr = rsr;
1572 atc->msr = msr;
1573 atc->chip_type = chip_type;
1574
1575 spin_lock_init(&atc->atc_lock);
1576
1577 /* Find card model */
1578 err = atc_identify_card(atc);
1579 if (err < 0) {
1580 printk(KERN_ERR "ctatc: Card not recognised\n");
1581 goto error1;
1582 }
1583
1584 /* Set up device virtual memory management object */
1585 err = ct_vm_create(&atc->vm);
1586 if (err < 0)
1587 goto error1;
1588
1589 /* Create all atc hw devices */
1590 err = atc_create_hw_devs(atc);
1591 if (err < 0)
1592 goto error1;
1593
1594 /* Get resources */
1595 err = atc_get_resources(atc);
1596 if (err < 0)
1597 goto error1;
1598
1599 /* Build topology */
1600 atc_connect_resources(atc);
1601
1602 atc->timer = ct_timer_new(atc);
1603 if (!atc->timer)
1604 goto error1;
1605
1606 err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, atc, &ops);
1607 if (err < 0)
1608 goto error1;
1609
1610 snd_card_set_dev(card, &pci->dev);
1611
1612 *ratc = atc;
1613 return 0;
1614
1615error1:
1616 ct_atc_destroy(atc);
1617 printk(KERN_ERR "ctxfi: Something wrong!!!\n");
1618 return err;
1619}
diff --git a/sound/pci/ctxfi/ctatc.h b/sound/pci/ctxfi/ctatc.h
new file mode 100644
index 00000000000..a03347232e8
--- /dev/null
+++ b/sound/pci/ctxfi/ctatc.h
@@ -0,0 +1,147 @@
1/**
2 * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
3 *
4 * This source file is released under GPL v2 license (no other versions).
5 * See the COPYING file included in the main directory of this source
6 * distribution for the license terms and conditions.
7 *
8 * @File ctatc.h
9 *
10 * @Brief
11 * This file contains the definition of the device resource management object.
12 *
13 * @Author Liu Chun
14 * @Date Mar 28 2008
15 *
16 */
17
18#ifndef CTATC_H
19#define CTATC_H
20
21#include <linux/types.h>
22#include <linux/spinlock_types.h>
23#include <linux/pci.h>
24#include <linux/timer.h>
25#include <sound/core.h>
26
27#include "ctvmem.h"
28#include "ctresource.h"
29
30enum CTALSADEVS { /* Types of alsa devices */
31 FRONT,
32 SURROUND,
33 CLFE,
34 SIDE,
35 IEC958,
36 MIXER,
37 NUM_CTALSADEVS /* This should always be the last */
38};
39
40struct ct_atc_chip_sub_details {
41 u16 subsys;
42 const char *nm_model;
43};
44
45struct ct_atc_chip_details {
46 u16 vendor;
47 u16 device;
48 const struct ct_atc_chip_sub_details *sub_details;
49 const char *nm_card;
50};
51
52struct ct_atc;
53struct ct_timer;
54struct ct_timer_instance;
55
56/* alsa pcm stream descriptor */
57struct ct_atc_pcm {
58 struct snd_pcm_substream *substream;
59 void (*interrupt)(struct ct_atc_pcm *apcm);
60 struct ct_timer_instance *timer;
61 unsigned int started:1;
62
63 /* Only mono and interleaved modes are supported now. */
64 struct ct_vm_block *vm_block;
65 void *src; /* SRC for interacting with host memory */
66 void **srccs; /* SRCs for sample rate conversion */
67 void **srcimps; /* SRC Input Mappers */
68 void **amixers; /* AMIXERs for routing converted data */
69 void *mono; /* A SUM resource for mixing chs to one */
70 unsigned char n_srcc; /* Number of converting SRCs */
71 unsigned char n_srcimp; /* Number of SRC Input Mappers */
72 unsigned char n_amixer; /* Number of AMIXERs */
73};
74
75/* Chip resource management object */
76struct ct_atc {
77 struct pci_dev *pci;
78 struct snd_card *card;
79 unsigned int rsr; /* reference sample rate in Hz */
80 unsigned int msr; /* master sample rate in rsr */
81 unsigned int pll_rate; /* current rate of Phase Lock Loop */
82
83 int chip_type;
84 int model;
85 const char *chip_name;
86 const char *model_name;
87
88 struct ct_vm *vm; /* device virtual memory manager for this card */
89 int (*map_audio_buffer)(struct ct_atc *atc, struct ct_atc_pcm *apcm);
90 void (*unmap_audio_buffer)(struct ct_atc *atc, struct ct_atc_pcm *apcm);
91 unsigned long (*get_ptp_phys)(struct ct_atc *atc, int index);
92
93 spinlock_t atc_lock;
94
95 int (*pcm_playback_prepare)(struct ct_atc *atc,
96 struct ct_atc_pcm *apcm);
97 int (*pcm_playback_start)(struct ct_atc *atc, struct ct_atc_pcm *apcm);
98 int (*pcm_playback_stop)(struct ct_atc *atc, struct ct_atc_pcm *apcm);
99 int (*pcm_playback_position)(struct ct_atc *atc,
100 struct ct_atc_pcm *apcm);
101 int (*spdif_passthru_playback_prepare)(struct ct_atc *atc,
102 struct ct_atc_pcm *apcm);
103 int (*pcm_capture_prepare)(struct ct_atc *atc, struct ct_atc_pcm *apcm);
104 int (*pcm_capture_start)(struct ct_atc *atc, struct ct_atc_pcm *apcm);
105 int (*pcm_capture_stop)(struct ct_atc *atc, struct ct_atc_pcm *apcm);
106 int (*pcm_capture_position)(struct ct_atc *atc,
107 struct ct_atc_pcm *apcm);
108 int (*pcm_release_resources)(struct ct_atc *atc,
109 struct ct_atc_pcm *apcm);
110 int (*select_line_in)(struct ct_atc *atc);
111 int (*select_mic_in)(struct ct_atc *atc);
112 int (*select_digit_io)(struct ct_atc *atc);
113 int (*line_front_unmute)(struct ct_atc *atc, unsigned char state);
114 int (*line_surround_unmute)(struct ct_atc *atc, unsigned char state);
115 int (*line_clfe_unmute)(struct ct_atc *atc, unsigned char state);
116 int (*line_rear_unmute)(struct ct_atc *atc, unsigned char state);
117 int (*line_in_unmute)(struct ct_atc *atc, unsigned char state);
118 int (*spdif_out_unmute)(struct ct_atc *atc, unsigned char state);
119 int (*spdif_in_unmute)(struct ct_atc *atc, unsigned char state);
120 int (*spdif_out_get_status)(struct ct_atc *atc, unsigned int *status);
121 int (*spdif_out_set_status)(struct ct_atc *atc, unsigned int status);
122 int (*spdif_out_passthru)(struct ct_atc *atc, unsigned char state);
123 int (*have_digit_io_switch)(struct ct_atc *atc);
124
125 /* Don't touch! Used for internal object. */
126 void *rsc_mgrs[NUM_RSCTYP]; /* chip resource managers */
127 void *mixer; /* internal mixer object */
128 void *hw; /* chip specific hardware access object */
129 void **daios; /* digital audio io resources */
130 void **pcm; /* SUMs for collecting all pcm stream */
131 void **srcs; /* Sample Rate Converters for input signal */
132 void **srcimps; /* input mappers for SRCs */
133 unsigned char n_daio;
134 unsigned char n_src;
135 unsigned char n_srcimp;
136 unsigned char n_pcm;
137
138 struct ct_timer *timer;
139};
140
141
142int __devinit ct_atc_create(struct snd_card *card, struct pci_dev *pci,
143 unsigned int rsr, unsigned int msr, int chip_type,
144 struct ct_atc **ratc);
145int __devinit ct_atc_create_alsa_devs(struct ct_atc *atc);
146
147#endif /* CTATC_H */
diff --git a/sound/pci/ctxfi/ctdaio.c b/sound/pci/ctxfi/ctdaio.c
new file mode 100644
index 00000000000..082e35c08c0
--- /dev/null
+++ b/sound/pci/ctxfi/ctdaio.c
@@ -0,0 +1,769 @@
1/**
2 * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
3 *
4 * This source file is released under GPL v2 license (no other versions).
5 * See the COPYING file included in the main directory of this source
6 * distribution for the license terms and conditions.
7 *
8 * @File ctdaio.c
9 *
10 * @Brief
11 * This file contains the implementation of Digital Audio Input Output
12 * resource management object.
13 *
14 * @Author Liu Chun
15 * @Date May 23 2008
16 *
17 */
18
19#include "ctdaio.h"
20#include "cthardware.h"
21#include "ctimap.h"
22#include <linux/slab.h>
23#include <linux/kernel.h>
24
25#define DAIO_RESOURCE_NUM NUM_DAIOTYP
26#define DAIO_OUT_MAX SPDIFOO
27
28union daio_usage {
29 struct {
30 unsigned short lineo1:1;
31 unsigned short lineo2:1;
32 unsigned short lineo3:1;
33 unsigned short lineo4:1;
34 unsigned short spdifoo:1;
35 unsigned short lineim:1;
36 unsigned short spdifio:1;
37 unsigned short spdifi1:1;
38 } bf;
39 unsigned short data;
40};
41
42struct daio_rsc_idx {
43 unsigned short left;
44 unsigned short right;
45};
46
47struct daio_rsc_idx idx_20k1[NUM_DAIOTYP] = {
48 [LINEO1] = {.left = 0x00, .right = 0x01},
49 [LINEO2] = {.left = 0x18, .right = 0x19},
50 [LINEO3] = {.left = 0x08, .right = 0x09},
51 [LINEO4] = {.left = 0x10, .right = 0x11},
52 [LINEIM] = {.left = 0x1b5, .right = 0x1bd},
53 [SPDIFOO] = {.left = 0x20, .right = 0x21},
54 [SPDIFIO] = {.left = 0x15, .right = 0x1d},
55 [SPDIFI1] = {.left = 0x95, .right = 0x9d},
56};
57
58struct daio_rsc_idx idx_20k2[NUM_DAIOTYP] = {
59 [LINEO1] = {.left = 0x40, .right = 0x41},
60 [LINEO2] = {.left = 0x70, .right = 0x71},
61 [LINEO3] = {.left = 0x50, .right = 0x51},
62 [LINEO4] = {.left = 0x60, .right = 0x61},
63 [LINEIM] = {.left = 0x45, .right = 0xc5},
64 [SPDIFOO] = {.left = 0x00, .right = 0x01},
65 [SPDIFIO] = {.left = 0x05, .right = 0x85},
66};
67
68static int daio_master(struct rsc *rsc)
69{
70 /* Actually, this is not the resource index of DAIO.
71 * For DAO, it is the input mapper index. And, for DAI,
72 * it is the output time-slot index. */
73 return rsc->conj = rsc->idx;
74}
75
76static int daio_index(const struct rsc *rsc)
77{
78 return rsc->conj;
79}
80
81static int daio_out_next_conj(struct rsc *rsc)
82{
83 return rsc->conj += 2;
84}
85
86static int daio_in_next_conj_20k1(struct rsc *rsc)
87{
88 return rsc->conj += 0x200;
89}
90
91static int daio_in_next_conj_20k2(struct rsc *rsc)
92{
93 return rsc->conj += 0x100;
94}
95
96static struct rsc_ops daio_out_rsc_ops = {
97 .master = daio_master,
98 .next_conj = daio_out_next_conj,
99 .index = daio_index,
100 .output_slot = NULL,
101};
102
103static struct rsc_ops daio_in_rsc_ops_20k1 = {
104 .master = daio_master,
105 .next_conj = daio_in_next_conj_20k1,
106 .index = NULL,
107 .output_slot = daio_index,
108};
109
110static struct rsc_ops daio_in_rsc_ops_20k2 = {
111 .master = daio_master,
112 .next_conj = daio_in_next_conj_20k2,
113 .index = NULL,
114 .output_slot = daio_index,
115};
116
117static unsigned int daio_device_index(enum DAIOTYP type, struct hw *hw)
118{
119 switch (hw->chip_type) {
120 case ATC20K1:
121 switch (type) {
122 case SPDIFOO: return 0;
123 case SPDIFIO: return 0;
124 case SPDIFI1: return 1;
125 case LINEO1: return 4;
126 case LINEO2: return 7;
127 case LINEO3: return 5;
128 case LINEO4: return 6;
129 case LINEIM: return 7;
130 default: return -EINVAL;
131 }
132 case ATC20K2:
133 switch (type) {
134 case SPDIFOO: return 0;
135 case SPDIFIO: return 0;
136 case LINEO1: return 4;
137 case LINEO2: return 7;
138 case LINEO3: return 5;
139 case LINEO4: return 6;
140 case LINEIM: return 4;
141 default: return -EINVAL;
142 }
143 default:
144 return -EINVAL;
145 }
146}
147
148static int dao_rsc_reinit(struct dao *dao, const struct dao_desc *desc);
149
150static int dao_spdif_get_spos(struct dao *dao, unsigned int *spos)
151{
152 ((struct hw *)dao->hw)->dao_get_spos(dao->ctrl_blk, spos);
153 return 0;
154}
155
156static int dao_spdif_set_spos(struct dao *dao, unsigned int spos)
157{
158 ((struct hw *)dao->hw)->dao_set_spos(dao->ctrl_blk, spos);
159 return 0;
160}
161
162static int dao_commit_write(struct dao *dao)
163{
164 ((struct hw *)dao->hw)->dao_commit_write(dao->hw,
165 daio_device_index(dao->daio.type, dao->hw), dao->ctrl_blk);
166 return 0;
167}
168
169static int dao_set_left_input(struct dao *dao, struct rsc *input)
170{
171 struct imapper *entry;
172 struct daio *daio = &dao->daio;
173 int i;
174
175 entry = kzalloc((sizeof(*entry) * daio->rscl.msr), GFP_KERNEL);
176 if (NULL == entry)
177 return -ENOMEM;
178
179 /* Program master and conjugate resources */
180 input->ops->master(input);
181 daio->rscl.ops->master(&daio->rscl);
182 for (i = 0; i < daio->rscl.msr; i++, entry++) {
183 entry->slot = input->ops->output_slot(input);
184 entry->user = entry->addr = daio->rscl.ops->index(&daio->rscl);
185 dao->mgr->imap_add(dao->mgr, entry);
186 dao->imappers[i] = entry;
187
188 input->ops->next_conj(input);
189 daio->rscl.ops->next_conj(&daio->rscl);
190 }
191 input->ops->master(input);
192 daio->rscl.ops->master(&daio->rscl);
193
194 return 0;
195}
196
197static int dao_set_right_input(struct dao *dao, struct rsc *input)
198{
199 struct imapper *entry;
200 struct daio *daio = &dao->daio;
201 int i;
202
203 entry = kzalloc((sizeof(*entry) * daio->rscr.msr), GFP_KERNEL);
204 if (NULL == entry)
205 return -ENOMEM;
206
207 /* Program master and conjugate resources */
208 input->ops->master(input);
209 daio->rscr.ops->master(&daio->rscr);
210 for (i = 0; i < daio->rscr.msr; i++, entry++) {
211 entry->slot = input->ops->output_slot(input);
212 entry->user = entry->addr = daio->rscr.ops->index(&daio->rscr);
213 dao->mgr->imap_add(dao->mgr, entry);
214 dao->imappers[daio->rscl.msr + i] = entry;
215
216 input->ops->next_conj(input);
217 daio->rscr.ops->next_conj(&daio->rscr);
218 }
219 input->ops->master(input);
220 daio->rscr.ops->master(&daio->rscr);
221
222 return 0;
223}
224
225static int dao_clear_left_input(struct dao *dao)
226{
227 struct imapper *entry;
228 struct daio *daio = &dao->daio;
229 int i;
230
231 if (NULL == dao->imappers[0])
232 return 0;
233
234 entry = dao->imappers[0];
235 dao->mgr->imap_delete(dao->mgr, entry);
236 /* Program conjugate resources */
237 for (i = 1; i < daio->rscl.msr; i++) {
238 entry = dao->imappers[i];
239 dao->mgr->imap_delete(dao->mgr, entry);
240 dao->imappers[i] = NULL;
241 }
242
243 kfree(dao->imappers[0]);
244 dao->imappers[0] = NULL;
245
246 return 0;
247}
248
249static int dao_clear_right_input(struct dao *dao)
250{
251 struct imapper *entry;
252 struct daio *daio = &dao->daio;
253 int i;
254
255 if (NULL == dao->imappers[daio->rscl.msr])
256 return 0;
257
258 entry = dao->imappers[daio->rscl.msr];
259 dao->mgr->imap_delete(dao->mgr, entry);
260 /* Program conjugate resources */
261 for (i = 1; i < daio->rscr.msr; i++) {
262 entry = dao->imappers[daio->rscl.msr + i];
263 dao->mgr->imap_delete(dao->mgr, entry);
264 dao->imappers[daio->rscl.msr + i] = NULL;
265 }
266
267 kfree(dao->imappers[daio->rscl.msr]);
268 dao->imappers[daio->rscl.msr] = NULL;
269
270 return 0;
271}
272
273static struct dao_rsc_ops dao_ops = {
274 .set_spos = dao_spdif_set_spos,
275 .commit_write = dao_commit_write,
276 .get_spos = dao_spdif_get_spos,
277 .reinit = dao_rsc_reinit,
278 .set_left_input = dao_set_left_input,
279 .set_right_input = dao_set_right_input,
280 .clear_left_input = dao_clear_left_input,
281 .clear_right_input = dao_clear_right_input,
282};
283
284static int dai_set_srt_srcl(struct dai *dai, struct rsc *src)
285{
286 src->ops->master(src);
287 ((struct hw *)dai->hw)->dai_srt_set_srcm(dai->ctrl_blk,
288 src->ops->index(src));
289 return 0;
290}
291
292static int dai_set_srt_srcr(struct dai *dai, struct rsc *src)
293{
294 src->ops->master(src);
295 ((struct hw *)dai->hw)->dai_srt_set_srco(dai->ctrl_blk,
296 src->ops->index(src));
297 return 0;
298}
299
300static int dai_set_srt_msr(struct dai *dai, unsigned int msr)
301{
302 unsigned int rsr;
303
304 for (rsr = 0; msr > 1; msr >>= 1)
305 rsr++;
306
307 ((struct hw *)dai->hw)->dai_srt_set_rsr(dai->ctrl_blk, rsr);
308 return 0;
309}
310
311static int dai_set_enb_src(struct dai *dai, unsigned int enb)
312{
313 ((struct hw *)dai->hw)->dai_srt_set_ec(dai->ctrl_blk, enb);
314 return 0;
315}
316
317static int dai_set_enb_srt(struct dai *dai, unsigned int enb)
318{
319 ((struct hw *)dai->hw)->dai_srt_set_et(dai->ctrl_blk, enb);
320 return 0;
321}
322
323static int dai_commit_write(struct dai *dai)
324{
325 ((struct hw *)dai->hw)->dai_commit_write(dai->hw,
326 daio_device_index(dai->daio.type, dai->hw), dai->ctrl_blk);
327 return 0;
328}
329
330static struct dai_rsc_ops dai_ops = {
331 .set_srt_srcl = dai_set_srt_srcl,
332 .set_srt_srcr = dai_set_srt_srcr,
333 .set_srt_msr = dai_set_srt_msr,
334 .set_enb_src = dai_set_enb_src,
335 .set_enb_srt = dai_set_enb_srt,
336 .commit_write = dai_commit_write,
337};
338
339static int daio_rsc_init(struct daio *daio,
340 const struct daio_desc *desc,
341 void *hw)
342{
343 int err;
344 unsigned int idx_l, idx_r;
345
346 switch (((struct hw *)hw)->chip_type) {
347 case ATC20K1:
348 idx_l = idx_20k1[desc->type].left;
349 idx_r = idx_20k1[desc->type].right;
350 break;
351 case ATC20K2:
352 idx_l = idx_20k2[desc->type].left;
353 idx_r = idx_20k2[desc->type].right;
354 break;
355 default:
356 return -EINVAL;
357 }
358 err = rsc_init(&daio->rscl, idx_l, DAIO, desc->msr, hw);
359 if (err)
360 return err;
361
362 err = rsc_init(&daio->rscr, idx_r, DAIO, desc->msr, hw);
363 if (err)
364 goto error1;
365
366 /* Set daio->rscl/r->ops to daio specific ones */
367 if (desc->type <= DAIO_OUT_MAX) {
368 daio->rscl.ops = daio->rscr.ops = &daio_out_rsc_ops;
369 } else {
370 switch (((struct hw *)hw)->chip_type) {
371 case ATC20K1:
372 daio->rscl.ops = daio->rscr.ops = &daio_in_rsc_ops_20k1;
373 break;
374 case ATC20K2:
375 daio->rscl.ops = daio->rscr.ops = &daio_in_rsc_ops_20k2;
376 break;
377 default:
378 break;
379 }
380 }
381 daio->type = desc->type;
382
383 return 0;
384
385error1:
386 rsc_uninit(&daio->rscl);
387 return err;
388}
389
390static int daio_rsc_uninit(struct daio *daio)
391{
392 rsc_uninit(&daio->rscl);
393 rsc_uninit(&daio->rscr);
394
395 return 0;
396}
397
398static int dao_rsc_init(struct dao *dao,
399 const struct daio_desc *desc,
400 struct daio_mgr *mgr)
401{
402 struct hw *hw = mgr->mgr.hw;
403 unsigned int conf;
404 int err;
405
406 err = daio_rsc_init(&dao->daio, desc, mgr->mgr.hw);
407 if (err)
408 return err;
409
410 dao->imappers = kzalloc(sizeof(void *)*desc->msr*2, GFP_KERNEL);
411 if (NULL == dao->imappers) {
412 err = -ENOMEM;
413 goto error1;
414 }
415 dao->ops = &dao_ops;
416 dao->mgr = mgr;
417 dao->hw = hw;
418 err = hw->dao_get_ctrl_blk(&dao->ctrl_blk);
419 if (err)
420 goto error2;
421
422 hw->daio_mgr_dsb_dao(mgr->mgr.ctrl_blk,
423 daio_device_index(dao->daio.type, hw));
424 hw->daio_mgr_commit_write(hw, mgr->mgr.ctrl_blk);
425
426 conf = (desc->msr & 0x7) | (desc->passthru << 3);
427 hw->daio_mgr_dao_init(mgr->mgr.ctrl_blk,
428 daio_device_index(dao->daio.type, hw), conf);
429 hw->daio_mgr_enb_dao(mgr->mgr.ctrl_blk,
430 daio_device_index(dao->daio.type, hw));
431 hw->daio_mgr_commit_write(hw, mgr->mgr.ctrl_blk);
432
433 return 0;
434
435error2:
436 kfree(dao->imappers);
437 dao->imappers = NULL;
438error1:
439 daio_rsc_uninit(&dao->daio);
440 return err;
441}
442
443static int dao_rsc_uninit(struct dao *dao)
444{
445 if (NULL != dao->imappers) {
446 if (NULL != dao->imappers[0])
447 dao_clear_left_input(dao);
448
449 if (NULL != dao->imappers[dao->daio.rscl.msr])
450 dao_clear_right_input(dao);
451
452 kfree(dao->imappers);
453 dao->imappers = NULL;
454 }
455 ((struct hw *)dao->hw)->dao_put_ctrl_blk(dao->ctrl_blk);
456 dao->hw = dao->ctrl_blk = NULL;
457 daio_rsc_uninit(&dao->daio);
458
459 return 0;
460}
461
462static int dao_rsc_reinit(struct dao *dao, const struct dao_desc *desc)
463{
464 struct daio_mgr *mgr = dao->mgr;
465 struct daio_desc dsc = {0};
466
467 dsc.type = dao->daio.type;
468 dsc.msr = desc->msr;
469 dsc.passthru = desc->passthru;
470 dao_rsc_uninit(dao);
471 return dao_rsc_init(dao, &dsc, mgr);
472}
473
474static int dai_rsc_init(struct dai *dai,
475 const struct daio_desc *desc,
476 struct daio_mgr *mgr)
477{
478 int err;
479 struct hw *hw = mgr->mgr.hw;
480 unsigned int rsr, msr;
481
482 err = daio_rsc_init(&dai->daio, desc, mgr->mgr.hw);
483 if (err)
484 return err;
485
486 dai->ops = &dai_ops;
487 dai->hw = mgr->mgr.hw;
488 err = hw->dai_get_ctrl_blk(&dai->ctrl_blk);
489 if (err)
490 goto error1;
491
492 for (rsr = 0, msr = desc->msr; msr > 1; msr >>= 1)
493 rsr++;
494
495 hw->dai_srt_set_rsr(dai->ctrl_blk, rsr);
496 hw->dai_srt_set_drat(dai->ctrl_blk, 0);
497 /* default to disabling control of a SRC */
498 hw->dai_srt_set_ec(dai->ctrl_blk, 0);
499 hw->dai_srt_set_et(dai->ctrl_blk, 0); /* default to disabling SRT */
500 hw->dai_commit_write(hw,
501 daio_device_index(dai->daio.type, dai->hw), dai->ctrl_blk);
502
503 return 0;
504
505error1:
506 daio_rsc_uninit(&dai->daio);
507 return err;
508}
509
510static int dai_rsc_uninit(struct dai *dai)
511{
512 ((struct hw *)dai->hw)->dai_put_ctrl_blk(dai->ctrl_blk);
513 dai->hw = dai->ctrl_blk = NULL;
514 daio_rsc_uninit(&dai->daio);
515 return 0;
516}
517
518static int daio_mgr_get_rsc(struct rsc_mgr *mgr, enum DAIOTYP type)
519{
520 if (((union daio_usage *)mgr->rscs)->data & (0x1 << type))
521 return -ENOENT;
522
523 ((union daio_usage *)mgr->rscs)->data |= (0x1 << type);
524
525 return 0;
526}
527
528static int daio_mgr_put_rsc(struct rsc_mgr *mgr, enum DAIOTYP type)
529{
530 ((union daio_usage *)mgr->rscs)->data &= ~(0x1 << type);
531
532 return 0;
533}
534
535static int get_daio_rsc(struct daio_mgr *mgr,
536 const struct daio_desc *desc,
537 struct daio **rdaio)
538{
539 int err;
540 struct dai *dai = NULL;
541 struct dao *dao = NULL;
542 unsigned long flags;
543
544 *rdaio = NULL;
545
546 /* Check whether there are sufficient daio resources to meet request. */
547 spin_lock_irqsave(&mgr->mgr_lock, flags);
548 err = daio_mgr_get_rsc(&mgr->mgr, desc->type);
549 spin_unlock_irqrestore(&mgr->mgr_lock, flags);
550 if (err) {
551 printk(KERN_ERR "Can't meet DAIO resource request!\n");
552 return err;
553 }
554
555 /* Allocate mem for daio resource */
556 if (desc->type <= DAIO_OUT_MAX) {
557 dao = kzalloc(sizeof(*dao), GFP_KERNEL);
558 if (NULL == dao) {
559 err = -ENOMEM;
560 goto error;
561 }
562 err = dao_rsc_init(dao, desc, mgr);
563 if (err)
564 goto error;
565
566 *rdaio = &dao->daio;
567 } else {
568 dai = kzalloc(sizeof(*dai), GFP_KERNEL);
569 if (NULL == dai) {
570 err = -ENOMEM;
571 goto error;
572 }
573 err = dai_rsc_init(dai, desc, mgr);
574 if (err)
575 goto error;
576
577 *rdaio = &dai->daio;
578 }
579
580 mgr->daio_enable(mgr, *rdaio);
581 mgr->commit_write(mgr);
582
583 return 0;
584
585error:
586 if (NULL != dao)
587 kfree(dao);
588 else if (NULL != dai)
589 kfree(dai);
590
591 spin_lock_irqsave(&mgr->mgr_lock, flags);
592 daio_mgr_put_rsc(&mgr->mgr, desc->type);
593 spin_unlock_irqrestore(&mgr->mgr_lock, flags);
594 return err;
595}
596
597static int put_daio_rsc(struct daio_mgr *mgr, struct daio *daio)
598{
599 unsigned long flags;
600
601 mgr->daio_disable(mgr, daio);
602 mgr->commit_write(mgr);
603
604 spin_lock_irqsave(&mgr->mgr_lock, flags);
605 daio_mgr_put_rsc(&mgr->mgr, daio->type);
606 spin_unlock_irqrestore(&mgr->mgr_lock, flags);
607
608 if (daio->type <= DAIO_OUT_MAX) {
609 dao_rsc_uninit(container_of(daio, struct dao, daio));
610 kfree(container_of(daio, struct dao, daio));
611 } else {
612 dai_rsc_uninit(container_of(daio, struct dai, daio));
613 kfree(container_of(daio, struct dai, daio));
614 }
615
616 return 0;
617}
618
619static int daio_mgr_enb_daio(struct daio_mgr *mgr, struct daio *daio)
620{
621 struct hw *hw = mgr->mgr.hw;
622
623 if (DAIO_OUT_MAX >= daio->type) {
624 hw->daio_mgr_enb_dao(mgr->mgr.ctrl_blk,
625 daio_device_index(daio->type, hw));
626 } else {
627 hw->daio_mgr_enb_dai(mgr->mgr.ctrl_blk,
628 daio_device_index(daio->type, hw));
629 }
630 return 0;
631}
632
633static int daio_mgr_dsb_daio(struct daio_mgr *mgr, struct daio *daio)
634{
635 struct hw *hw = mgr->mgr.hw;
636
637 if (DAIO_OUT_MAX >= daio->type) {
638 hw->daio_mgr_dsb_dao(mgr->mgr.ctrl_blk,
639 daio_device_index(daio->type, hw));
640 } else {
641 hw->daio_mgr_dsb_dai(mgr->mgr.ctrl_blk,
642 daio_device_index(daio->type, hw));
643 }
644 return 0;
645}
646
647static int daio_map_op(void *data, struct imapper *entry)
648{
649 struct rsc_mgr *mgr = &((struct daio_mgr *)data)->mgr;
650 struct hw *hw = mgr->hw;
651
652 hw->daio_mgr_set_imaparc(mgr->ctrl_blk, entry->slot);
653 hw->daio_mgr_set_imapnxt(mgr->ctrl_blk, entry->next);
654 hw->daio_mgr_set_imapaddr(mgr->ctrl_blk, entry->addr);
655 hw->daio_mgr_commit_write(mgr->hw, mgr->ctrl_blk);
656
657 return 0;
658}
659
660static int daio_imap_add(struct daio_mgr *mgr, struct imapper *entry)
661{
662 unsigned long flags;
663 int err;
664
665 spin_lock_irqsave(&mgr->imap_lock, flags);
666 if ((0 == entry->addr) && (mgr->init_imap_added)) {
667 input_mapper_delete(&mgr->imappers, mgr->init_imap,
668 daio_map_op, mgr);
669 mgr->init_imap_added = 0;
670 }
671 err = input_mapper_add(&mgr->imappers, entry, daio_map_op, mgr);
672 spin_unlock_irqrestore(&mgr->imap_lock, flags);
673
674 return err;
675}
676
677static int daio_imap_delete(struct daio_mgr *mgr, struct imapper *entry)
678{
679 unsigned long flags;
680 int err;
681
682 spin_lock_irqsave(&mgr->imap_lock, flags);
683 err = input_mapper_delete(&mgr->imappers, entry, daio_map_op, mgr);
684 if (list_empty(&mgr->imappers)) {
685 input_mapper_add(&mgr->imappers, mgr->init_imap,
686 daio_map_op, mgr);
687 mgr->init_imap_added = 1;
688 }
689 spin_unlock_irqrestore(&mgr->imap_lock, flags);
690
691 return err;
692}
693
694static int daio_mgr_commit_write(struct daio_mgr *mgr)
695{
696 struct hw *hw = mgr->mgr.hw;
697
698 hw->daio_mgr_commit_write(hw, mgr->mgr.ctrl_blk);
699 return 0;
700}
701
702int daio_mgr_create(void *hw, struct daio_mgr **rdaio_mgr)
703{
704 int err, i;
705 struct daio_mgr *daio_mgr;
706 struct imapper *entry;
707
708 *rdaio_mgr = NULL;
709 daio_mgr = kzalloc(sizeof(*daio_mgr), GFP_KERNEL);
710 if (NULL == daio_mgr)
711 return -ENOMEM;
712
713 err = rsc_mgr_init(&daio_mgr->mgr, DAIO, DAIO_RESOURCE_NUM, hw);
714 if (err)
715 goto error1;
716
717 spin_lock_init(&daio_mgr->mgr_lock);
718 spin_lock_init(&daio_mgr->imap_lock);
719 INIT_LIST_HEAD(&daio_mgr->imappers);
720 entry = kzalloc(sizeof(*entry), GFP_KERNEL);
721 if (NULL == entry) {
722 err = -ENOMEM;
723 goto error2;
724 }
725 entry->slot = entry->addr = entry->next = entry->user = 0;
726 list_add(&entry->list, &daio_mgr->imappers);
727 daio_mgr->init_imap = entry;
728 daio_mgr->init_imap_added = 1;
729
730 daio_mgr->get_daio = get_daio_rsc;
731 daio_mgr->put_daio = put_daio_rsc;
732 daio_mgr->daio_enable = daio_mgr_enb_daio;
733 daio_mgr->daio_disable = daio_mgr_dsb_daio;
734 daio_mgr->imap_add = daio_imap_add;
735 daio_mgr->imap_delete = daio_imap_delete;
736 daio_mgr->commit_write = daio_mgr_commit_write;
737
738 for (i = 0; i < 8; i++) {
739 ((struct hw *)hw)->daio_mgr_dsb_dao(daio_mgr->mgr.ctrl_blk, i);
740 ((struct hw *)hw)->daio_mgr_dsb_dai(daio_mgr->mgr.ctrl_blk, i);
741 }
742 ((struct hw *)hw)->daio_mgr_commit_write(hw, daio_mgr->mgr.ctrl_blk);
743
744 *rdaio_mgr = daio_mgr;
745
746 return 0;
747
748error2:
749 rsc_mgr_uninit(&daio_mgr->mgr);
750error1:
751 kfree(daio_mgr);
752 return err;
753}
754
755int daio_mgr_destroy(struct daio_mgr *daio_mgr)
756{
757 unsigned long flags;
758
759 /* free daio input mapper list */
760 spin_lock_irqsave(&daio_mgr->imap_lock, flags);
761 free_input_mapper_list(&daio_mgr->imappers);
762 spin_unlock_irqrestore(&daio_mgr->imap_lock, flags);
763
764 rsc_mgr_uninit(&daio_mgr->mgr);
765 kfree(daio_mgr);
766
767 return 0;
768}
769
diff --git a/sound/pci/ctxfi/ctdaio.h b/sound/pci/ctxfi/ctdaio.h
new file mode 100644
index 00000000000..0f52ce571ee
--- /dev/null
+++ b/sound/pci/ctxfi/ctdaio.h
@@ -0,0 +1,122 @@
1/**
2 * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
3 *
4 * This source file is released under GPL v2 license (no other versions).
5 * See the COPYING file included in the main directory of this source
6 * distribution for the license terms and conditions.
7 *
8 * @File ctdaio.h
9 *
10 * @Brief
11 * This file contains the definition of Digital Audio Input Output
12 * resource management object.
13 *
14 * @Author Liu Chun
15 * @Date May 23 2008
16 *
17 */
18
19#ifndef CTDAIO_H
20#define CTDAIO_H
21
22#include "ctresource.h"
23#include "ctimap.h"
24#include <linux/spinlock.h>
25#include <linux/list.h>
26
27/* Define the descriptor of a daio resource */
28enum DAIOTYP {
29 LINEO1,
30 LINEO2,
31 LINEO3,
32 LINEO4,
33 SPDIFOO, /* S/PDIF Out (Flexijack/Optical) */
34 LINEIM,
35 SPDIFIO, /* S/PDIF In (Flexijack/Optical) on the card */
36 SPDIFI1, /* S/PDIF In on internal Drive Bay */
37 NUM_DAIOTYP
38};
39
40struct dao_rsc_ops;
41struct dai_rsc_ops;
42struct daio_mgr;
43
44struct daio {
45 struct rsc rscl; /* Basic resource info for left TX/RX */
46 struct rsc rscr; /* Basic resource info for right TX/RX */
47 enum DAIOTYP type;
48};
49
50struct dao {
51 struct daio daio;
52 struct dao_rsc_ops *ops; /* DAO specific operations */
53 struct imapper **imappers;
54 struct daio_mgr *mgr;
55 void *hw;
56 void *ctrl_blk;
57};
58
59struct dai {
60 struct daio daio;
61 struct dai_rsc_ops *ops; /* DAI specific operations */
62 void *hw;
63 void *ctrl_blk;
64};
65
66struct dao_desc {
67 unsigned int msr:4;
68 unsigned int passthru:1;
69};
70
71struct dao_rsc_ops {
72 int (*set_spos)(struct dao *dao, unsigned int spos);
73 int (*commit_write)(struct dao *dao);
74 int (*get_spos)(struct dao *dao, unsigned int *spos);
75 int (*reinit)(struct dao *dao, const struct dao_desc *desc);
76 int (*set_left_input)(struct dao *dao, struct rsc *input);
77 int (*set_right_input)(struct dao *dao, struct rsc *input);
78 int (*clear_left_input)(struct dao *dao);
79 int (*clear_right_input)(struct dao *dao);
80};
81
82struct dai_rsc_ops {
83 int (*set_srt_srcl)(struct dai *dai, struct rsc *src);
84 int (*set_srt_srcr)(struct dai *dai, struct rsc *src);
85 int (*set_srt_msr)(struct dai *dai, unsigned int msr);
86 int (*set_enb_src)(struct dai *dai, unsigned int enb);
87 int (*set_enb_srt)(struct dai *dai, unsigned int enb);
88 int (*commit_write)(struct dai *dai);
89};
90
91/* Define daio resource request description info */
92struct daio_desc {
93 unsigned int type:4;
94 unsigned int msr:4;
95 unsigned int passthru:1;
96};
97
98struct daio_mgr {
99 struct rsc_mgr mgr; /* Basic resource manager info */
100 spinlock_t mgr_lock;
101 spinlock_t imap_lock;
102 struct list_head imappers;
103 struct imapper *init_imap;
104 unsigned int init_imap_added;
105
106 /* request one daio resource */
107 int (*get_daio)(struct daio_mgr *mgr,
108 const struct daio_desc *desc, struct daio **rdaio);
109 /* return one daio resource */
110 int (*put_daio)(struct daio_mgr *mgr, struct daio *daio);
111 int (*daio_enable)(struct daio_mgr *mgr, struct daio *daio);
112 int (*daio_disable)(struct daio_mgr *mgr, struct daio *daio);
113 int (*imap_add)(struct daio_mgr *mgr, struct imapper *entry);
114 int (*imap_delete)(struct daio_mgr *mgr, struct imapper *entry);
115 int (*commit_write)(struct daio_mgr *mgr);
116};
117
118/* Constructor and destructor of daio resource manager */
119int daio_mgr_create(void *hw, struct daio_mgr **rdaio_mgr);
120int daio_mgr_destroy(struct daio_mgr *daio_mgr);
121
122#endif /* CTDAIO_H */
diff --git a/sound/pci/ctxfi/cthardware.c b/sound/pci/ctxfi/cthardware.c
new file mode 100644
index 00000000000..8e64f4862e8
--- /dev/null
+++ b/sound/pci/ctxfi/cthardware.c
@@ -0,0 +1,91 @@
1/**
2 * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
3 *
4 * This source file is released under GPL v2 license (no other versions).
5 * See the COPYING file included in the main directory of this source
6 * distribution for the license terms and conditions.
7 *
8 * @File cthardware.c
9 *
10 * @Brief
11 * This file contains the implementation of hardware access methord.
12 *
13 * @Author Liu Chun
14 * @Date Jun 26 2008
15 *
16 */
17
18#include "cthardware.h"
19#include "cthw20k1.h"
20#include "cthw20k2.h"
21#include <linux/bug.h>
22
23int __devinit create_hw_obj(struct pci_dev *pci, enum CHIPTYP chip_type,
24 enum CTCARDS model, struct hw **rhw)
25{
26 int err;
27
28 switch (chip_type) {
29 case ATC20K1:
30 err = create_20k1_hw_obj(rhw);
31 break;
32 case ATC20K2:
33 err = create_20k2_hw_obj(rhw);
34 break;
35 default:
36 err = -ENODEV;
37 break;
38 }
39 if (err)
40 return err;
41
42 (*rhw)->pci = pci;
43 (*rhw)->chip_type = chip_type;
44 (*rhw)->model = model;
45
46 return 0;
47}
48
49int destroy_hw_obj(struct hw *hw)
50{
51 int err;
52
53 switch (hw->pci->device) {
54 case 0x0005: /* 20k1 device */
55 err = destroy_20k1_hw_obj(hw);
56 break;
57 case 0x000B: /* 20k2 device */
58 err = destroy_20k2_hw_obj(hw);
59 break;
60 default:
61 err = -ENODEV;
62 break;
63 }
64
65 return err;
66}
67
68unsigned int get_field(unsigned int data, unsigned int field)
69{
70 int i;
71
72 BUG_ON(!field);
73 /* @field should always be greater than 0 */
74 for (i = 0; !(field & (1 << i)); )
75 i++;
76
77 return (data & field) >> i;
78}
79
80void set_field(unsigned int *data, unsigned int field, unsigned int value)
81{
82 int i;
83
84 BUG_ON(!field);
85 /* @field should always be greater than 0 */
86 for (i = 0; !(field & (1 << i)); )
87 i++;
88
89 *data = (*data & (~field)) | ((value << i) & field);
90}
91
diff --git a/sound/pci/ctxfi/cthardware.h b/sound/pci/ctxfi/cthardware.h
new file mode 100644
index 00000000000..4a8e04f090a
--- /dev/null
+++ b/sound/pci/ctxfi/cthardware.h
@@ -0,0 +1,196 @@
1/**
2 * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
3 *
4 * This source file is released under GPL v2 license (no other versions).
5 * See the COPYING file included in the main directory of this source
6 * distribution for the license terms and conditions.
7 *
8 * @File cthardware.h
9 *
10 * @Brief
11 * This file contains the definition of hardware access methord.
12 *
13 * @Author Liu Chun
14 * @Date May 13 2008
15 *
16 */
17
18#ifndef CTHARDWARE_H
19#define CTHARDWARE_H
20
21#include <linux/types.h>
22#include <linux/pci.h>
23
24enum CHIPTYP {
25 ATC20K1,
26 ATC20K2,
27 ATCNONE
28};
29
30enum CTCARDS {
31 /* 20k1 models */
32 CTSB055X,
33 CTSB073X,
34 CTUAA,
35 CT20K1_UNKNOWN,
36 /* 20k2 models */
37 CTSB0760,
38 CTHENDRIX,
39 CTSB0880,
40 NUM_CTCARDS /* This should always be the last */
41};
42
43/* Type of input source for ADC */
44enum ADCSRC{
45 ADC_MICIN,
46 ADC_LINEIN,
47 ADC_VIDEO,
48 ADC_AUX,
49 ADC_NONE /* Switch to digital input */
50};
51
52struct card_conf {
53 /* device virtual mem page table page physical addr
54 * (supporting one page table page now) */
55 unsigned long vm_pgt_phys;
56 unsigned int rsr; /* reference sample rate in Hzs*/
57 unsigned int msr; /* master sample rate in rsrs */
58};
59
60struct hw {
61 int (*card_init)(struct hw *hw, struct card_conf *info);
62 int (*card_stop)(struct hw *hw);
63 int (*pll_init)(struct hw *hw, unsigned int rsr);
64 int (*is_adc_source_selected)(struct hw *hw, enum ADCSRC source);
65 int (*select_adc_source)(struct hw *hw, enum ADCSRC source);
66 int (*have_digit_io_switch)(struct hw *hw);
67
68 /* SRC operations */
69 int (*src_rsc_get_ctrl_blk)(void **rblk);
70 int (*src_rsc_put_ctrl_blk)(void *blk);
71 int (*src_set_state)(void *blk, unsigned int state);
72 int (*src_set_bm)(void *blk, unsigned int bm);
73 int (*src_set_rsr)(void *blk, unsigned int rsr);
74 int (*src_set_sf)(void *blk, unsigned int sf);
75 int (*src_set_wr)(void *blk, unsigned int wr);
76 int (*src_set_pm)(void *blk, unsigned int pm);
77 int (*src_set_rom)(void *blk, unsigned int rom);
78 int (*src_set_vo)(void *blk, unsigned int vo);
79 int (*src_set_st)(void *blk, unsigned int st);
80 int (*src_set_ie)(void *blk, unsigned int ie);
81 int (*src_set_ilsz)(void *blk, unsigned int ilsz);
82 int (*src_set_bp)(void *blk, unsigned int bp);
83 int (*src_set_cisz)(void *blk, unsigned int cisz);
84 int (*src_set_ca)(void *blk, unsigned int ca);
85 int (*src_set_sa)(void *blk, unsigned int sa);
86 int (*src_set_la)(void *blk, unsigned int la);
87 int (*src_set_pitch)(void *blk, unsigned int pitch);
88 int (*src_set_clear_zbufs)(void *blk, unsigned int clear);
89 int (*src_set_dirty)(void *blk, unsigned int flags);
90 int (*src_set_dirty_all)(void *blk);
91 int (*src_commit_write)(struct hw *hw, unsigned int idx, void *blk);
92 int (*src_get_ca)(struct hw *hw, unsigned int idx, void *blk);
93 unsigned int (*src_get_dirty)(void *blk);
94 unsigned int (*src_dirty_conj_mask)(void);
95 int (*src_mgr_get_ctrl_blk)(void **rblk);
96 int (*src_mgr_put_ctrl_blk)(void *blk);
97 /* syncly enable src @idx */
98 int (*src_mgr_enbs_src)(void *blk, unsigned int idx);
99 /* enable src @idx */
100 int (*src_mgr_enb_src)(void *blk, unsigned int idx);
101 /* disable src @idx */
102 int (*src_mgr_dsb_src)(void *blk, unsigned int idx);
103 int (*src_mgr_commit_write)(struct hw *hw, void *blk);
104
105 /* SRC Input Mapper operations */
106 int (*srcimp_mgr_get_ctrl_blk)(void **rblk);
107 int (*srcimp_mgr_put_ctrl_blk)(void *blk);
108 int (*srcimp_mgr_set_imaparc)(void *blk, unsigned int slot);
109 int (*srcimp_mgr_set_imapuser)(void *blk, unsigned int user);
110 int (*srcimp_mgr_set_imapnxt)(void *blk, unsigned int next);
111 int (*srcimp_mgr_set_imapaddr)(void *blk, unsigned int addr);
112 int (*srcimp_mgr_commit_write)(struct hw *hw, void *blk);
113
114 /* AMIXER operations */
115 int (*amixer_rsc_get_ctrl_blk)(void **rblk);
116 int (*amixer_rsc_put_ctrl_blk)(void *blk);
117 int (*amixer_mgr_get_ctrl_blk)(void **rblk);
118 int (*amixer_mgr_put_ctrl_blk)(void *blk);
119 int (*amixer_set_mode)(void *blk, unsigned int mode);
120 int (*amixer_set_iv)(void *blk, unsigned int iv);
121 int (*amixer_set_x)(void *blk, unsigned int x);
122 int (*amixer_set_y)(void *blk, unsigned int y);
123 int (*amixer_set_sadr)(void *blk, unsigned int sadr);
124 int (*amixer_set_se)(void *blk, unsigned int se);
125 int (*amixer_set_dirty)(void *blk, unsigned int flags);
126 int (*amixer_set_dirty_all)(void *blk);
127 int (*amixer_commit_write)(struct hw *hw, unsigned int idx, void *blk);
128 int (*amixer_get_y)(void *blk);
129 unsigned int (*amixer_get_dirty)(void *blk);
130
131 /* DAIO operations */
132 int (*dai_get_ctrl_blk)(void **rblk);
133 int (*dai_put_ctrl_blk)(void *blk);
134 int (*dai_srt_set_srco)(void *blk, unsigned int src);
135 int (*dai_srt_set_srcm)(void *blk, unsigned int src);
136 int (*dai_srt_set_rsr)(void *blk, unsigned int rsr);
137 int (*dai_srt_set_drat)(void *blk, unsigned int drat);
138 int (*dai_srt_set_ec)(void *blk, unsigned int ec);
139 int (*dai_srt_set_et)(void *blk, unsigned int et);
140 int (*dai_commit_write)(struct hw *hw, unsigned int idx, void *blk);
141 int (*dao_get_ctrl_blk)(void **rblk);
142 int (*dao_put_ctrl_blk)(void *blk);
143 int (*dao_set_spos)(void *blk, unsigned int spos);
144 int (*dao_commit_write)(struct hw *hw, unsigned int idx, void *blk);
145 int (*dao_get_spos)(void *blk, unsigned int *spos);
146
147 int (*daio_mgr_get_ctrl_blk)(struct hw *hw, void **rblk);
148 int (*daio_mgr_put_ctrl_blk)(void *blk);
149 int (*daio_mgr_enb_dai)(void *blk, unsigned int idx);
150 int (*daio_mgr_dsb_dai)(void *blk, unsigned int idx);
151 int (*daio_mgr_enb_dao)(void *blk, unsigned int idx);
152 int (*daio_mgr_dsb_dao)(void *blk, unsigned int idx);
153 int (*daio_mgr_dao_init)(void *blk, unsigned int idx,
154 unsigned int conf);
155 int (*daio_mgr_set_imaparc)(void *blk, unsigned int slot);
156 int (*daio_mgr_set_imapnxt)(void *blk, unsigned int next);
157 int (*daio_mgr_set_imapaddr)(void *blk, unsigned int addr);
158 int (*daio_mgr_commit_write)(struct hw *hw, void *blk);
159
160 int (*set_timer_irq)(struct hw *hw, int enable);
161 int (*set_timer_tick)(struct hw *hw, unsigned int tick);
162 unsigned int (*get_wc)(struct hw *hw);
163
164 void (*irq_callback)(void *data, unsigned int bit);
165 void *irq_callback_data;
166
167 struct pci_dev *pci; /* the pci kernel structure of this card */
168 int irq;
169 unsigned long io_base;
170 unsigned long mem_base;
171
172 enum CHIPTYP chip_type;
173 enum CTCARDS model;
174};
175
176int create_hw_obj(struct pci_dev *pci, enum CHIPTYP chip_type,
177 enum CTCARDS model, struct hw **rhw);
178int destroy_hw_obj(struct hw *hw);
179
180unsigned int get_field(unsigned int data, unsigned int field);
181void set_field(unsigned int *data, unsigned int field, unsigned int value);
182
183/* IRQ bits */
184#define PLL_INT (1 << 10) /* PLL input-clock out-of-range */
185#define FI_INT (1 << 9) /* forced interrupt */
186#define IT_INT (1 << 8) /* timer interrupt */
187#define PCI_INT (1 << 7) /* PCI bus error pending */
188#define URT_INT (1 << 6) /* UART Tx/Rx */
189#define GPI_INT (1 << 5) /* GPI pin */
190#define MIX_INT (1 << 4) /* mixer parameter segment FIFO channels */
191#define DAI_INT (1 << 3) /* DAI (SR-tracker or SPDIF-receiver) */
192#define TP_INT (1 << 2) /* transport priority queue */
193#define DSP_INT (1 << 1) /* DSP */
194#define SRC_INT (1 << 0) /* SRC channels */
195
196#endif /* CTHARDWARE_H */
diff --git a/sound/pci/ctxfi/cthw20k1.c b/sound/pci/ctxfi/cthw20k1.c
new file mode 100644
index 00000000000..cb69d9ddfbe
--- /dev/null
+++ b/sound/pci/ctxfi/cthw20k1.c
@@ -0,0 +1,2248 @@
1/**
2 * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
3 *
4 * This source file is released under GPL v2 license (no other versions).
5 * See the COPYING file included in the main directory of this source
6 * distribution for the license terms and conditions.
7 *
8 * @File cthw20k1.c
9 *
10 * @Brief
11 * This file contains the implementation of hardware access methord for 20k1.
12 *
13 * @Author Liu Chun
14 * @Date Jun 24 2008
15 *
16 */
17
18#include <linux/types.h>
19#include <linux/slab.h>
20#include <linux/pci.h>
21#include <linux/io.h>
22#include <linux/string.h>
23#include <linux/spinlock.h>
24#include <linux/kernel.h>
25#include <linux/interrupt.h>
26#include <linux/delay.h>
27#include "cthw20k1.h"
28#include "ct20k1reg.h"
29
30#if BITS_PER_LONG == 32
31#define CT_XFI_DMA_MASK DMA_BIT_MASK(32) /* 32 bit PTE */
32#else
33#define CT_XFI_DMA_MASK DMA_BIT_MASK(64) /* 64 bit PTE */
34#endif
35
36struct hw20k1 {
37 struct hw hw;
38 spinlock_t reg_20k1_lock;
39 spinlock_t reg_pci_lock;
40};
41
42static u32 hw_read_20kx(struct hw *hw, u32 reg);
43static void hw_write_20kx(struct hw *hw, u32 reg, u32 data);
44static u32 hw_read_pci(struct hw *hw, u32 reg);
45static void hw_write_pci(struct hw *hw, u32 reg, u32 data);
46
47/*
48 * Type definition block.
49 * The layout of control structures can be directly applied on 20k2 chip.
50 */
51
52/*
53 * SRC control block definitions.
54 */
55
56/* SRC resource control block */
57#define SRCCTL_STATE 0x00000007
58#define SRCCTL_BM 0x00000008
59#define SRCCTL_RSR 0x00000030
60#define SRCCTL_SF 0x000001C0
61#define SRCCTL_WR 0x00000200
62#define SRCCTL_PM 0x00000400
63#define SRCCTL_ROM 0x00001800
64#define SRCCTL_VO 0x00002000
65#define SRCCTL_ST 0x00004000
66#define SRCCTL_IE 0x00008000
67#define SRCCTL_ILSZ 0x000F0000
68#define SRCCTL_BP 0x00100000
69
70#define SRCCCR_CISZ 0x000007FF
71#define SRCCCR_CWA 0x001FF800
72#define SRCCCR_D 0x00200000
73#define SRCCCR_RS 0x01C00000
74#define SRCCCR_NAL 0x3E000000
75#define SRCCCR_RA 0xC0000000
76
77#define SRCCA_CA 0x03FFFFFF
78#define SRCCA_RS 0x1C000000
79#define SRCCA_NAL 0xE0000000
80
81#define SRCSA_SA 0x03FFFFFF
82
83#define SRCLA_LA 0x03FFFFFF
84
85/* Mixer Parameter Ring ram Low and Hight register.
86 * Fixed-point value in 8.24 format for parameter channel */
87#define MPRLH_PITCH 0xFFFFFFFF
88
89/* SRC resource register dirty flags */
90union src_dirty {
91 struct {
92 u16 ctl:1;
93 u16 ccr:1;
94 u16 sa:1;
95 u16 la:1;
96 u16 ca:1;
97 u16 mpr:1;
98 u16 czbfs:1; /* Clear Z-Buffers */
99 u16 rsv:9;
100 } bf;
101 u16 data;
102};
103
104struct src_rsc_ctrl_blk {
105 unsigned int ctl;
106 unsigned int ccr;
107 unsigned int ca;
108 unsigned int sa;
109 unsigned int la;
110 unsigned int mpr;
111 union src_dirty dirty;
112};
113
114/* SRC manager control block */
115union src_mgr_dirty {
116 struct {
117 u16 enb0:1;
118 u16 enb1:1;
119 u16 enb2:1;
120 u16 enb3:1;
121 u16 enb4:1;
122 u16 enb5:1;
123 u16 enb6:1;
124 u16 enb7:1;
125 u16 enbsa:1;
126 u16 rsv:7;
127 } bf;
128 u16 data;
129};
130
131struct src_mgr_ctrl_blk {
132 unsigned int enbsa;
133 unsigned int enb[8];
134 union src_mgr_dirty dirty;
135};
136
137/* SRCIMP manager control block */
138#define SRCAIM_ARC 0x00000FFF
139#define SRCAIM_NXT 0x00FF0000
140#define SRCAIM_SRC 0xFF000000
141
142struct srcimap {
143 unsigned int srcaim;
144 unsigned int idx;
145};
146
147/* SRCIMP manager register dirty flags */
148union srcimp_mgr_dirty {
149 struct {
150 u16 srcimap:1;
151 u16 rsv:15;
152 } bf;
153 u16 data;
154};
155
156struct srcimp_mgr_ctrl_blk {
157 struct srcimap srcimap;
158 union srcimp_mgr_dirty dirty;
159};
160
161/*
162 * Function implementation block.
163 */
164
165static int src_get_rsc_ctrl_blk(void **rblk)
166{
167 struct src_rsc_ctrl_blk *blk;
168
169 *rblk = NULL;
170 blk = kzalloc(sizeof(*blk), GFP_KERNEL);
171 if (NULL == blk)
172 return -ENOMEM;
173
174 *rblk = blk;
175
176 return 0;
177}
178
179static int src_put_rsc_ctrl_blk(void *blk)
180{
181 kfree((struct src_rsc_ctrl_blk *)blk);
182
183 return 0;
184}
185
186static int src_set_state(void *blk, unsigned int state)
187{
188 struct src_rsc_ctrl_blk *ctl = blk;
189
190 set_field(&ctl->ctl, SRCCTL_STATE, state);
191 ctl->dirty.bf.ctl = 1;
192 return 0;
193}
194
195static int src_set_bm(void *blk, unsigned int bm)
196{
197 struct src_rsc_ctrl_blk *ctl = blk;
198
199 set_field(&ctl->ctl, SRCCTL_BM, bm);
200 ctl->dirty.bf.ctl = 1;
201 return 0;
202}
203
204static int src_set_rsr(void *blk, unsigned int rsr)
205{
206 struct src_rsc_ctrl_blk *ctl = blk;
207
208 set_field(&ctl->ctl, SRCCTL_RSR, rsr);
209 ctl->dirty.bf.ctl = 1;
210 return 0;
211}
212
213static int src_set_sf(void *blk, unsigned int sf)
214{
215 struct src_rsc_ctrl_blk *ctl = blk;
216
217 set_field(&ctl->ctl, SRCCTL_SF, sf);
218 ctl->dirty.bf.ctl = 1;
219 return 0;
220}
221
222static int src_set_wr(void *blk, unsigned int wr)
223{
224 struct src_rsc_ctrl_blk *ctl = blk;
225
226 set_field(&ctl->ctl, SRCCTL_WR, wr);
227 ctl->dirty.bf.ctl = 1;
228 return 0;
229}
230
231static int src_set_pm(void *blk, unsigned int pm)
232{
233 struct src_rsc_ctrl_blk *ctl = blk;
234
235 set_field(&ctl->ctl, SRCCTL_PM, pm);
236 ctl->dirty.bf.ctl = 1;
237 return 0;
238}
239
240static int src_set_rom(void *blk, unsigned int rom)
241{
242 struct src_rsc_ctrl_blk *ctl = blk;
243
244 set_field(&ctl->ctl, SRCCTL_ROM, rom);
245 ctl->dirty.bf.ctl = 1;
246 return 0;
247}
248
249static int src_set_vo(void *blk, unsigned int vo)
250{
251 struct src_rsc_ctrl_blk *ctl = blk;
252
253 set_field(&ctl->ctl, SRCCTL_VO, vo);
254 ctl->dirty.bf.ctl = 1;
255 return 0;
256}
257
258static int src_set_st(void *blk, unsigned int st)
259{
260 struct src_rsc_ctrl_blk *ctl = blk;
261
262 set_field(&ctl->ctl, SRCCTL_ST, st);
263 ctl->dirty.bf.ctl = 1;
264 return 0;
265}
266
267static int src_set_ie(void *blk, unsigned int ie)
268{
269 struct src_rsc_ctrl_blk *ctl = blk;
270
271 set_field(&ctl->ctl, SRCCTL_IE, ie);
272 ctl->dirty.bf.ctl = 1;
273 return 0;
274}
275
276static int src_set_ilsz(void *blk, unsigned int ilsz)
277{
278 struct src_rsc_ctrl_blk *ctl = blk;
279
280 set_field(&ctl->ctl, SRCCTL_ILSZ, ilsz);
281 ctl->dirty.bf.ctl = 1;
282 return 0;
283}
284
285static int src_set_bp(void *blk, unsigned int bp)
286{
287 struct src_rsc_ctrl_blk *ctl = blk;
288
289 set_field(&ctl->ctl, SRCCTL_BP, bp);
290 ctl->dirty.bf.ctl = 1;
291 return 0;
292}
293
294static int src_set_cisz(void *blk, unsigned int cisz)
295{
296 struct src_rsc_ctrl_blk *ctl = blk;
297
298 set_field(&ctl->ccr, SRCCCR_CISZ, cisz);
299 ctl->dirty.bf.ccr = 1;
300 return 0;
301}
302
303static int src_set_ca(void *blk, unsigned int ca)
304{
305 struct src_rsc_ctrl_blk *ctl = blk;
306
307 set_field(&ctl->ca, SRCCA_CA, ca);
308 ctl->dirty.bf.ca = 1;
309 return 0;
310}
311
312static int src_set_sa(void *blk, unsigned int sa)
313{
314 struct src_rsc_ctrl_blk *ctl = blk;
315
316 set_field(&ctl->sa, SRCSA_SA, sa);
317 ctl->dirty.bf.sa = 1;
318 return 0;
319}
320
321static int src_set_la(void *blk, unsigned int la)
322{
323 struct src_rsc_ctrl_blk *ctl = blk;
324
325 set_field(&ctl->la, SRCLA_LA, la);
326 ctl->dirty.bf.la = 1;
327 return 0;
328}
329
330static int src_set_pitch(void *blk, unsigned int pitch)
331{
332 struct src_rsc_ctrl_blk *ctl = blk;
333
334 set_field(&ctl->mpr, MPRLH_PITCH, pitch);
335 ctl->dirty.bf.mpr = 1;
336 return 0;
337}
338
339static int src_set_clear_zbufs(void *blk, unsigned int clear)
340{
341 ((struct src_rsc_ctrl_blk *)blk)->dirty.bf.czbfs = (clear ? 1 : 0);
342 return 0;
343}
344
345static int src_set_dirty(void *blk, unsigned int flags)
346{
347 ((struct src_rsc_ctrl_blk *)blk)->dirty.data = (flags & 0xffff);
348 return 0;
349}
350
351static int src_set_dirty_all(void *blk)
352{
353 ((struct src_rsc_ctrl_blk *)blk)->dirty.data = ~(0x0);
354 return 0;
355}
356
357#define AR_SLOT_SIZE 4096
358#define AR_SLOT_BLOCK_SIZE 16
359#define AR_PTS_PITCH 6
360#define AR_PARAM_SRC_OFFSET 0x60
361
362static unsigned int src_param_pitch_mixer(unsigned int src_idx)
363{
364 return ((src_idx << 4) + AR_PTS_PITCH + AR_SLOT_SIZE
365 - AR_PARAM_SRC_OFFSET) % AR_SLOT_SIZE;
366
367}
368
369static int src_commit_write(struct hw *hw, unsigned int idx, void *blk)
370{
371 struct src_rsc_ctrl_blk *ctl = blk;
372 int i;
373
374 if (ctl->dirty.bf.czbfs) {
375 /* Clear Z-Buffer registers */
376 for (i = 0; i < 8; i++)
377 hw_write_20kx(hw, SRCUPZ+idx*0x100+i*0x4, 0);
378
379 for (i = 0; i < 4; i++)
380 hw_write_20kx(hw, SRCDN0Z+idx*0x100+i*0x4, 0);
381
382 for (i = 0; i < 8; i++)
383 hw_write_20kx(hw, SRCDN1Z+idx*0x100+i*0x4, 0);
384
385 ctl->dirty.bf.czbfs = 0;
386 }
387 if (ctl->dirty.bf.mpr) {
388 /* Take the parameter mixer resource in the same group as that
389 * the idx src is in for simplicity. Unlike src, all conjugate
390 * parameter mixer resources must be programmed for
391 * corresponding conjugate src resources. */
392 unsigned int pm_idx = src_param_pitch_mixer(idx);
393 hw_write_20kx(hw, PRING_LO_HI+4*pm_idx, ctl->mpr);
394 hw_write_20kx(hw, PMOPLO+8*pm_idx, 0x3);
395 hw_write_20kx(hw, PMOPHI+8*pm_idx, 0x0);
396 ctl->dirty.bf.mpr = 0;
397 }
398 if (ctl->dirty.bf.sa) {
399 hw_write_20kx(hw, SRCSA+idx*0x100, ctl->sa);
400 ctl->dirty.bf.sa = 0;
401 }
402 if (ctl->dirty.bf.la) {
403 hw_write_20kx(hw, SRCLA+idx*0x100, ctl->la);
404 ctl->dirty.bf.la = 0;
405 }
406 if (ctl->dirty.bf.ca) {
407 hw_write_20kx(hw, SRCCA+idx*0x100, ctl->ca);
408 ctl->dirty.bf.ca = 0;
409 }
410
411 /* Write srccf register */
412 hw_write_20kx(hw, SRCCF+idx*0x100, 0x0);
413
414 if (ctl->dirty.bf.ccr) {
415 hw_write_20kx(hw, SRCCCR+idx*0x100, ctl->ccr);
416 ctl->dirty.bf.ccr = 0;
417 }
418 if (ctl->dirty.bf.ctl) {
419 hw_write_20kx(hw, SRCCTL+idx*0x100, ctl->ctl);
420 ctl->dirty.bf.ctl = 0;
421 }
422
423 return 0;
424}
425
426static int src_get_ca(struct hw *hw, unsigned int idx, void *blk)
427{
428 struct src_rsc_ctrl_blk *ctl = blk;
429
430 ctl->ca = hw_read_20kx(hw, SRCCA+idx*0x100);
431 ctl->dirty.bf.ca = 0;
432
433 return get_field(ctl->ca, SRCCA_CA);
434}
435
436static unsigned int src_get_dirty(void *blk)
437{
438 return ((struct src_rsc_ctrl_blk *)blk)->dirty.data;
439}
440
441static unsigned int src_dirty_conj_mask(void)
442{
443 return 0x20;
444}
445
446static int src_mgr_enbs_src(void *blk, unsigned int idx)
447{
448 ((struct src_mgr_ctrl_blk *)blk)->enbsa = ~(0x0);
449 ((struct src_mgr_ctrl_blk *)blk)->dirty.bf.enbsa = 1;
450 ((struct src_mgr_ctrl_blk *)blk)->enb[idx/32] |= (0x1 << (idx%32));
451 return 0;
452}
453
454static int src_mgr_enb_src(void *blk, unsigned int idx)
455{
456 ((struct src_mgr_ctrl_blk *)blk)->enb[idx/32] |= (0x1 << (idx%32));
457 ((struct src_mgr_ctrl_blk *)blk)->dirty.data |= (0x1 << (idx/32));
458 return 0;
459}
460
461static int src_mgr_dsb_src(void *blk, unsigned int idx)
462{
463 ((struct src_mgr_ctrl_blk *)blk)->enb[idx/32] &= ~(0x1 << (idx%32));
464 ((struct src_mgr_ctrl_blk *)blk)->dirty.data |= (0x1 << (idx/32));
465 return 0;
466}
467
468static int src_mgr_commit_write(struct hw *hw, void *blk)
469{
470 struct src_mgr_ctrl_blk *ctl = blk;
471 int i;
472 unsigned int ret;
473
474 if (ctl->dirty.bf.enbsa) {
475 do {
476 ret = hw_read_20kx(hw, SRCENBSTAT);
477 } while (ret & 0x1);
478 hw_write_20kx(hw, SRCENBS, ctl->enbsa);
479 ctl->dirty.bf.enbsa = 0;
480 }
481 for (i = 0; i < 8; i++) {
482 if ((ctl->dirty.data & (0x1 << i))) {
483 hw_write_20kx(hw, SRCENB+(i*0x100), ctl->enb[i]);
484 ctl->dirty.data &= ~(0x1 << i);
485 }
486 }
487
488 return 0;
489}
490
491static int src_mgr_get_ctrl_blk(void **rblk)
492{
493 struct src_mgr_ctrl_blk *blk;
494
495 *rblk = NULL;
496 blk = kzalloc(sizeof(*blk), GFP_KERNEL);
497 if (NULL == blk)
498 return -ENOMEM;
499
500 *rblk = blk;
501
502 return 0;
503}
504
505static int src_mgr_put_ctrl_blk(void *blk)
506{
507 kfree((struct src_mgr_ctrl_blk *)blk);
508
509 return 0;
510}
511
512static int srcimp_mgr_get_ctrl_blk(void **rblk)
513{
514 struct srcimp_mgr_ctrl_blk *blk;
515
516 *rblk = NULL;
517 blk = kzalloc(sizeof(*blk), GFP_KERNEL);
518 if (NULL == blk)
519 return -ENOMEM;
520
521 *rblk = blk;
522
523 return 0;
524}
525
526static int srcimp_mgr_put_ctrl_blk(void *blk)
527{
528 kfree((struct srcimp_mgr_ctrl_blk *)blk);
529
530 return 0;
531}
532
533static int srcimp_mgr_set_imaparc(void *blk, unsigned int slot)
534{
535 struct srcimp_mgr_ctrl_blk *ctl = blk;
536
537 set_field(&ctl->srcimap.srcaim, SRCAIM_ARC, slot);
538 ctl->dirty.bf.srcimap = 1;
539 return 0;
540}
541
542static int srcimp_mgr_set_imapuser(void *blk, unsigned int user)
543{
544 struct srcimp_mgr_ctrl_blk *ctl = blk;
545
546 set_field(&ctl->srcimap.srcaim, SRCAIM_SRC, user);
547 ctl->dirty.bf.srcimap = 1;
548 return 0;
549}
550
551static int srcimp_mgr_set_imapnxt(void *blk, unsigned int next)
552{
553 struct srcimp_mgr_ctrl_blk *ctl = blk;
554
555 set_field(&ctl->srcimap.srcaim, SRCAIM_NXT, next);
556 ctl->dirty.bf.srcimap = 1;
557 return 0;
558}
559
560static int srcimp_mgr_set_imapaddr(void *blk, unsigned int addr)
561{
562 struct srcimp_mgr_ctrl_blk *ctl = blk;
563
564 ctl->srcimap.idx = addr;
565 ctl->dirty.bf.srcimap = 1;
566 return 0;
567}
568
569static int srcimp_mgr_commit_write(struct hw *hw, void *blk)
570{
571 struct srcimp_mgr_ctrl_blk *ctl = blk;
572
573 if (ctl->dirty.bf.srcimap) {
574 hw_write_20kx(hw, SRCIMAP+ctl->srcimap.idx*0x100,
575 ctl->srcimap.srcaim);
576 ctl->dirty.bf.srcimap = 0;
577 }
578
579 return 0;
580}
581
582/*
583 * AMIXER control block definitions.
584 */
585
586#define AMOPLO_M 0x00000003
587#define AMOPLO_X 0x0003FFF0
588#define AMOPLO_Y 0xFFFC0000
589
590#define AMOPHI_SADR 0x000000FF
591#define AMOPHI_SE 0x80000000
592
593/* AMIXER resource register dirty flags */
594union amixer_dirty {
595 struct {
596 u16 amoplo:1;
597 u16 amophi:1;
598 u16 rsv:14;
599 } bf;
600 u16 data;
601};
602
603/* AMIXER resource control block */
604struct amixer_rsc_ctrl_blk {
605 unsigned int amoplo;
606 unsigned int amophi;
607 union amixer_dirty dirty;
608};
609
610static int amixer_set_mode(void *blk, unsigned int mode)
611{
612 struct amixer_rsc_ctrl_blk *ctl = blk;
613
614 set_field(&ctl->amoplo, AMOPLO_M, mode);
615 ctl->dirty.bf.amoplo = 1;
616 return 0;
617}
618
619static int amixer_set_iv(void *blk, unsigned int iv)
620{
621 /* 20k1 amixer does not have this field */
622 return 0;
623}
624
625static int amixer_set_x(void *blk, unsigned int x)
626{
627 struct amixer_rsc_ctrl_blk *ctl = blk;
628
629 set_field(&ctl->amoplo, AMOPLO_X, x);
630 ctl->dirty.bf.amoplo = 1;
631 return 0;
632}
633
634static int amixer_set_y(void *blk, unsigned int y)
635{
636 struct amixer_rsc_ctrl_blk *ctl = blk;
637
638 set_field(&ctl->amoplo, AMOPLO_Y, y);
639 ctl->dirty.bf.amoplo = 1;
640 return 0;
641}
642
643static int amixer_set_sadr(void *blk, unsigned int sadr)
644{
645 struct amixer_rsc_ctrl_blk *ctl = blk;
646
647 set_field(&ctl->amophi, AMOPHI_SADR, sadr);
648 ctl->dirty.bf.amophi = 1;
649 return 0;
650}
651
652static int amixer_set_se(void *blk, unsigned int se)
653{
654 struct amixer_rsc_ctrl_blk *ctl = blk;
655
656 set_field(&ctl->amophi, AMOPHI_SE, se);
657 ctl->dirty.bf.amophi = 1;
658 return 0;
659}
660
661static int amixer_set_dirty(void *blk, unsigned int flags)
662{
663 ((struct amixer_rsc_ctrl_blk *)blk)->dirty.data = (flags & 0xffff);
664 return 0;
665}
666
667static int amixer_set_dirty_all(void *blk)
668{
669 ((struct amixer_rsc_ctrl_blk *)blk)->dirty.data = ~(0x0);
670 return 0;
671}
672
673static int amixer_commit_write(struct hw *hw, unsigned int idx, void *blk)
674{
675 struct amixer_rsc_ctrl_blk *ctl = blk;
676
677 if (ctl->dirty.bf.amoplo || ctl->dirty.bf.amophi) {
678 hw_write_20kx(hw, AMOPLO+idx*8, ctl->amoplo);
679 ctl->dirty.bf.amoplo = 0;
680 hw_write_20kx(hw, AMOPHI+idx*8, ctl->amophi);
681 ctl->dirty.bf.amophi = 0;
682 }
683
684 return 0;
685}
686
687static int amixer_get_y(void *blk)
688{
689 struct amixer_rsc_ctrl_blk *ctl = blk;
690
691 return get_field(ctl->amoplo, AMOPLO_Y);
692}
693
694static unsigned int amixer_get_dirty(void *blk)
695{
696 return ((struct amixer_rsc_ctrl_blk *)blk)->dirty.data;
697}
698
699static int amixer_rsc_get_ctrl_blk(void **rblk)
700{
701 struct amixer_rsc_ctrl_blk *blk;
702
703 *rblk = NULL;
704 blk = kzalloc(sizeof(*blk), GFP_KERNEL);
705 if (NULL == blk)
706 return -ENOMEM;
707
708 *rblk = blk;
709
710 return 0;
711}
712
713static int amixer_rsc_put_ctrl_blk(void *blk)
714{
715 kfree((struct amixer_rsc_ctrl_blk *)blk);
716
717 return 0;
718}
719
720static int amixer_mgr_get_ctrl_blk(void **rblk)
721{
722 /*amixer_mgr_ctrl_blk_t *blk;*/
723
724 *rblk = NULL;
725 /*blk = kzalloc(sizeof(*blk), GFP_KERNEL);
726 if (NULL == blk)
727 return -ENOMEM;
728
729 *rblk = blk;*/
730
731 return 0;
732}
733
734static int amixer_mgr_put_ctrl_blk(void *blk)
735{
736 /*kfree((amixer_mgr_ctrl_blk_t *)blk);*/
737
738 return 0;
739}
740
741/*
742 * DAIO control block definitions.
743 */
744
745/* Receiver Sample Rate Tracker Control register */
746#define SRTCTL_SRCR 0x000000FF
747#define SRTCTL_SRCL 0x0000FF00
748#define SRTCTL_RSR 0x00030000
749#define SRTCTL_DRAT 0x000C0000
750#define SRTCTL_RLE 0x10000000
751#define SRTCTL_RLP 0x20000000
752#define SRTCTL_EC 0x40000000
753#define SRTCTL_ET 0x80000000
754
755/* DAIO Receiver register dirty flags */
756union dai_dirty {
757 struct {
758 u16 srtctl:1;
759 u16 rsv:15;
760 } bf;
761 u16 data;
762};
763
764/* DAIO Receiver control block */
765struct dai_ctrl_blk {
766 unsigned int srtctl;
767 union dai_dirty dirty;
768};
769
770/* S/PDIF Transmitter register dirty flags */
771union dao_dirty {
772 struct {
773 u16 spos:1;
774 u16 rsv:15;
775 } bf;
776 u16 data;
777};
778
779/* S/PDIF Transmitter control block */
780struct dao_ctrl_blk {
781 unsigned int spos; /* S/PDIF Output Channel Status Register */
782 union dao_dirty dirty;
783};
784
785/* Audio Input Mapper RAM */
786#define AIM_ARC 0x00000FFF
787#define AIM_NXT 0x007F0000
788
789struct daoimap {
790 unsigned int aim;
791 unsigned int idx;
792};
793
794/* I2S Transmitter/Receiver Control register */
795#define I2SCTL_EA 0x00000004
796#define I2SCTL_EI 0x00000010
797
798/* S/PDIF Transmitter Control register */
799#define SPOCTL_OE 0x00000001
800#define SPOCTL_OS 0x0000000E
801#define SPOCTL_RIV 0x00000010
802#define SPOCTL_LIV 0x00000020
803#define SPOCTL_SR 0x000000C0
804
805/* S/PDIF Receiver Control register */
806#define SPICTL_EN 0x00000001
807#define SPICTL_I24 0x00000002
808#define SPICTL_IB 0x00000004
809#define SPICTL_SM 0x00000008
810#define SPICTL_VM 0x00000010
811
812/* DAIO manager register dirty flags */
813union daio_mgr_dirty {
814 struct {
815 u32 i2soctl:4;
816 u32 i2sictl:4;
817 u32 spoctl:4;
818 u32 spictl:4;
819 u32 daoimap:1;
820 u32 rsv:15;
821 } bf;
822 u32 data;
823};
824
825/* DAIO manager control block */
826struct daio_mgr_ctrl_blk {
827 unsigned int i2sctl;
828 unsigned int spoctl;
829 unsigned int spictl;
830 struct daoimap daoimap;
831 union daio_mgr_dirty dirty;
832};
833
834static int dai_srt_set_srcr(void *blk, unsigned int src)
835{
836 struct dai_ctrl_blk *ctl = blk;
837
838 set_field(&ctl->srtctl, SRTCTL_SRCR, src);
839 ctl->dirty.bf.srtctl = 1;
840 return 0;
841}
842
843static int dai_srt_set_srcl(void *blk, unsigned int src)
844{
845 struct dai_ctrl_blk *ctl = blk;
846
847 set_field(&ctl->srtctl, SRTCTL_SRCL, src);
848 ctl->dirty.bf.srtctl = 1;
849 return 0;
850}
851
852static int dai_srt_set_rsr(void *blk, unsigned int rsr)
853{
854 struct dai_ctrl_blk *ctl = blk;
855
856 set_field(&ctl->srtctl, SRTCTL_RSR, rsr);
857 ctl->dirty.bf.srtctl = 1;
858 return 0;
859}
860
861static int dai_srt_set_drat(void *blk, unsigned int drat)
862{
863 struct dai_ctrl_blk *ctl = blk;
864
865 set_field(&ctl->srtctl, SRTCTL_DRAT, drat);
866 ctl->dirty.bf.srtctl = 1;
867 return 0;
868}
869
870static int dai_srt_set_ec(void *blk, unsigned int ec)
871{
872 struct dai_ctrl_blk *ctl = blk;
873
874 set_field(&ctl->srtctl, SRTCTL_EC, ec ? 1 : 0);
875 ctl->dirty.bf.srtctl = 1;
876 return 0;
877}
878
879static int dai_srt_set_et(void *blk, unsigned int et)
880{
881 struct dai_ctrl_blk *ctl = blk;
882
883 set_field(&ctl->srtctl, SRTCTL_ET, et ? 1 : 0);
884 ctl->dirty.bf.srtctl = 1;
885 return 0;
886}
887
888static int dai_commit_write(struct hw *hw, unsigned int idx, void *blk)
889{
890 struct dai_ctrl_blk *ctl = blk;
891
892 if (ctl->dirty.bf.srtctl) {
893 if (idx < 4) {
894 /* S/PDIF SRTs */
895 hw_write_20kx(hw, SRTSCTL+0x4*idx, ctl->srtctl);
896 } else {
897 /* I2S SRT */
898 hw_write_20kx(hw, SRTICTL, ctl->srtctl);
899 }
900 ctl->dirty.bf.srtctl = 0;
901 }
902
903 return 0;
904}
905
906static int dai_get_ctrl_blk(void **rblk)
907{
908 struct dai_ctrl_blk *blk;
909
910 *rblk = NULL;
911 blk = kzalloc(sizeof(*blk), GFP_KERNEL);
912 if (NULL == blk)
913 return -ENOMEM;
914
915 *rblk = blk;
916
917 return 0;
918}
919
920static int dai_put_ctrl_blk(void *blk)
921{
922 kfree((struct dai_ctrl_blk *)blk);
923
924 return 0;
925}
926
927static int dao_set_spos(void *blk, unsigned int spos)
928{
929 ((struct dao_ctrl_blk *)blk)->spos = spos;
930 ((struct dao_ctrl_blk *)blk)->dirty.bf.spos = 1;
931 return 0;
932}
933
934static int dao_commit_write(struct hw *hw, unsigned int idx, void *blk)
935{
936 struct dao_ctrl_blk *ctl = blk;
937
938 if (ctl->dirty.bf.spos) {
939 if (idx < 4) {
940 /* S/PDIF SPOSx */
941 hw_write_20kx(hw, SPOS+0x4*idx, ctl->spos);
942 }
943 ctl->dirty.bf.spos = 0;
944 }
945
946 return 0;
947}
948
949static int dao_get_spos(void *blk, unsigned int *spos)
950{
951 *spos = ((struct dao_ctrl_blk *)blk)->spos;
952 return 0;
953}
954
955static int dao_get_ctrl_blk(void **rblk)
956{
957 struct dao_ctrl_blk *blk;
958
959 *rblk = NULL;
960 blk = kzalloc(sizeof(*blk), GFP_KERNEL);
961 if (NULL == blk)
962 return -ENOMEM;
963
964 *rblk = blk;
965
966 return 0;
967}
968
969static int dao_put_ctrl_blk(void *blk)
970{
971 kfree((struct dao_ctrl_blk *)blk);
972
973 return 0;
974}
975
976static int daio_mgr_enb_dai(void *blk, unsigned int idx)
977{
978 struct daio_mgr_ctrl_blk *ctl = blk;
979
980 if (idx < 4) {
981 /* S/PDIF input */
982 set_field(&ctl->spictl, SPICTL_EN << (idx*8), 1);
983 ctl->dirty.bf.spictl |= (0x1 << idx);
984 } else {
985 /* I2S input */
986 idx %= 4;
987 set_field(&ctl->i2sctl, I2SCTL_EI << (idx*8), 1);
988 ctl->dirty.bf.i2sictl |= (0x1 << idx);
989 }
990 return 0;
991}
992
993static int daio_mgr_dsb_dai(void *blk, unsigned int idx)
994{
995 struct daio_mgr_ctrl_blk *ctl = blk;
996
997 if (idx < 4) {
998 /* S/PDIF input */
999 set_field(&ctl->spictl, SPICTL_EN << (idx*8), 0);
1000 ctl->dirty.bf.spictl |= (0x1 << idx);
1001 } else {
1002 /* I2S input */
1003 idx %= 4;
1004 set_field(&ctl->i2sctl, I2SCTL_EI << (idx*8), 0);
1005 ctl->dirty.bf.i2sictl |= (0x1 << idx);
1006 }
1007 return 0;
1008}
1009
1010static int daio_mgr_enb_dao(void *blk, unsigned int idx)
1011{
1012 struct daio_mgr_ctrl_blk *ctl = blk;
1013
1014 if (idx < 4) {
1015 /* S/PDIF output */
1016 set_field(&ctl->spoctl, SPOCTL_OE << (idx*8), 1);
1017 ctl->dirty.bf.spoctl |= (0x1 << idx);
1018 } else {
1019 /* I2S output */
1020 idx %= 4;
1021 set_field(&ctl->i2sctl, I2SCTL_EA << (idx*8), 1);
1022 ctl->dirty.bf.i2soctl |= (0x1 << idx);
1023 }
1024 return 0;
1025}
1026
1027static int daio_mgr_dsb_dao(void *blk, unsigned int idx)
1028{
1029 struct daio_mgr_ctrl_blk *ctl = blk;
1030
1031 if (idx < 4) {
1032 /* S/PDIF output */
1033 set_field(&ctl->spoctl, SPOCTL_OE << (idx*8), 0);
1034 ctl->dirty.bf.spoctl |= (0x1 << idx);
1035 } else {
1036 /* I2S output */
1037 idx %= 4;
1038 set_field(&ctl->i2sctl, I2SCTL_EA << (idx*8), 0);
1039 ctl->dirty.bf.i2soctl |= (0x1 << idx);
1040 }
1041 return 0;
1042}
1043
1044static int daio_mgr_dao_init(void *blk, unsigned int idx, unsigned int conf)
1045{
1046 struct daio_mgr_ctrl_blk *ctl = blk;
1047
1048 if (idx < 4) {
1049 /* S/PDIF output */
1050 switch ((conf & 0x7)) {
1051 case 0:
1052 set_field(&ctl->spoctl, SPOCTL_SR << (idx*8), 3);
1053 break; /* CDIF */
1054 case 1:
1055 set_field(&ctl->spoctl, SPOCTL_SR << (idx*8), 0);
1056 break;
1057 case 2:
1058 set_field(&ctl->spoctl, SPOCTL_SR << (idx*8), 1);
1059 break;
1060 case 4:
1061 set_field(&ctl->spoctl, SPOCTL_SR << (idx*8), 2);
1062 break;
1063 default:
1064 break;
1065 }
1066 set_field(&ctl->spoctl, SPOCTL_LIV << (idx*8),
1067 (conf >> 4) & 0x1); /* Non-audio */
1068 set_field(&ctl->spoctl, SPOCTL_RIV << (idx*8),
1069 (conf >> 4) & 0x1); /* Non-audio */
1070 set_field(&ctl->spoctl, SPOCTL_OS << (idx*8),
1071 ((conf >> 3) & 0x1) ? 2 : 2); /* Raw */
1072
1073 ctl->dirty.bf.spoctl |= (0x1 << idx);
1074 } else {
1075 /* I2S output */
1076 /*idx %= 4; */
1077 }
1078 return 0;
1079}
1080
1081static int daio_mgr_set_imaparc(void *blk, unsigned int slot)
1082{
1083 struct daio_mgr_ctrl_blk *ctl = blk;
1084
1085 set_field(&ctl->daoimap.aim, AIM_ARC, slot);
1086 ctl->dirty.bf.daoimap = 1;
1087 return 0;
1088}
1089
1090static int daio_mgr_set_imapnxt(void *blk, unsigned int next)
1091{
1092 struct daio_mgr_ctrl_blk *ctl = blk;
1093
1094 set_field(&ctl->daoimap.aim, AIM_NXT, next);
1095 ctl->dirty.bf.daoimap = 1;
1096 return 0;
1097}
1098
1099static int daio_mgr_set_imapaddr(void *blk, unsigned int addr)
1100{
1101 struct daio_mgr_ctrl_blk *ctl = blk;
1102
1103 ctl->daoimap.idx = addr;
1104 ctl->dirty.bf.daoimap = 1;
1105 return 0;
1106}
1107
1108static int daio_mgr_commit_write(struct hw *hw, void *blk)
1109{
1110 struct daio_mgr_ctrl_blk *ctl = blk;
1111 int i;
1112
1113 if (ctl->dirty.bf.i2sictl || ctl->dirty.bf.i2soctl) {
1114 for (i = 0; i < 4; i++) {
1115 if ((ctl->dirty.bf.i2sictl & (0x1 << i)))
1116 ctl->dirty.bf.i2sictl &= ~(0x1 << i);
1117
1118 if ((ctl->dirty.bf.i2soctl & (0x1 << i)))
1119 ctl->dirty.bf.i2soctl &= ~(0x1 << i);
1120 }
1121 hw_write_20kx(hw, I2SCTL, ctl->i2sctl);
1122 mdelay(1);
1123 }
1124 if (ctl->dirty.bf.spoctl) {
1125 for (i = 0; i < 4; i++) {
1126 if ((ctl->dirty.bf.spoctl & (0x1 << i)))
1127 ctl->dirty.bf.spoctl &= ~(0x1 << i);
1128 }
1129 hw_write_20kx(hw, SPOCTL, ctl->spoctl);
1130 mdelay(1);
1131 }
1132 if (ctl->dirty.bf.spictl) {
1133 for (i = 0; i < 4; i++) {
1134 if ((ctl->dirty.bf.spictl & (0x1 << i)))
1135 ctl->dirty.bf.spictl &= ~(0x1 << i);
1136 }
1137 hw_write_20kx(hw, SPICTL, ctl->spictl);
1138 mdelay(1);
1139 }
1140 if (ctl->dirty.bf.daoimap) {
1141 hw_write_20kx(hw, DAOIMAP+ctl->daoimap.idx*4,
1142 ctl->daoimap.aim);
1143 ctl->dirty.bf.daoimap = 0;
1144 }
1145
1146 return 0;
1147}
1148
1149static int daio_mgr_get_ctrl_blk(struct hw *hw, void **rblk)
1150{
1151 struct daio_mgr_ctrl_blk *blk;
1152
1153 *rblk = NULL;
1154 blk = kzalloc(sizeof(*blk), GFP_KERNEL);
1155 if (NULL == blk)
1156 return -ENOMEM;
1157
1158 blk->i2sctl = hw_read_20kx(hw, I2SCTL);
1159 blk->spoctl = hw_read_20kx(hw, SPOCTL);
1160 blk->spictl = hw_read_20kx(hw, SPICTL);
1161
1162 *rblk = blk;
1163
1164 return 0;
1165}
1166
1167static int daio_mgr_put_ctrl_blk(void *blk)
1168{
1169 kfree((struct daio_mgr_ctrl_blk *)blk);
1170
1171 return 0;
1172}
1173
1174/* Timer interrupt */
1175static int set_timer_irq(struct hw *hw, int enable)
1176{
1177 hw_write_20kx(hw, GIE, enable ? IT_INT : 0);
1178 return 0;
1179}
1180
1181static int set_timer_tick(struct hw *hw, unsigned int ticks)
1182{
1183 if (ticks)
1184 ticks |= TIMR_IE | TIMR_IP;
1185 hw_write_20kx(hw, TIMR, ticks);
1186 return 0;
1187}
1188
1189static unsigned int get_wc(struct hw *hw)
1190{
1191 return hw_read_20kx(hw, WC);
1192}
1193
1194/* Card hardware initialization block */
1195struct dac_conf {
1196 unsigned int msr; /* master sample rate in rsrs */
1197};
1198
1199struct adc_conf {
1200 unsigned int msr; /* master sample rate in rsrs */
1201 unsigned char input; /* the input source of ADC */
1202 unsigned char mic20db; /* boost mic by 20db if input is microphone */
1203};
1204
1205struct daio_conf {
1206 unsigned int msr; /* master sample rate in rsrs */
1207};
1208
1209struct trn_conf {
1210 unsigned long vm_pgt_phys;
1211};
1212
1213static int hw_daio_init(struct hw *hw, const struct daio_conf *info)
1214{
1215 u32 i2sorg;
1216 u32 spdorg;
1217
1218 /* Read I2S CTL. Keep original value. */
1219 /*i2sorg = hw_read_20kx(hw, I2SCTL);*/
1220 i2sorg = 0x94040404; /* enable all audio out and I2S-D input */
1221 /* Program I2S with proper master sample rate and enable
1222 * the correct I2S channel. */
1223 i2sorg &= 0xfffffffc;
1224
1225 /* Enable S/PDIF-out-A in fixed 24-bit data
1226 * format and default to 48kHz. */
1227 /* Disable all before doing any changes. */
1228 hw_write_20kx(hw, SPOCTL, 0x0);
1229 spdorg = 0x05;
1230
1231 switch (info->msr) {
1232 case 1:
1233 i2sorg |= 1;
1234 spdorg |= (0x0 << 6);
1235 break;
1236 case 2:
1237 i2sorg |= 2;
1238 spdorg |= (0x1 << 6);
1239 break;
1240 case 4:
1241 i2sorg |= 3;
1242 spdorg |= (0x2 << 6);
1243 break;
1244 default:
1245 i2sorg |= 1;
1246 break;
1247 }
1248
1249 hw_write_20kx(hw, I2SCTL, i2sorg);
1250 hw_write_20kx(hw, SPOCTL, spdorg);
1251
1252 /* Enable S/PDIF-in-A in fixed 24-bit data format. */
1253 /* Disable all before doing any changes. */
1254 hw_write_20kx(hw, SPICTL, 0x0);
1255 mdelay(1);
1256 spdorg = 0x0a0a0a0a;
1257 hw_write_20kx(hw, SPICTL, spdorg);
1258 mdelay(1);
1259
1260 return 0;
1261}
1262
1263/* TRANSPORT operations */
1264static int hw_trn_init(struct hw *hw, const struct trn_conf *info)
1265{
1266 u32 trnctl;
1267 u32 ptp_phys_low, ptp_phys_high;
1268
1269 /* Set up device page table */
1270 if ((~0UL) == info->vm_pgt_phys) {
1271 printk(KERN_ERR "Wrong device page table page address!\n");
1272 return -1;
1273 }
1274
1275 trnctl = 0x13; /* 32-bit, 4k-size page */
1276 ptp_phys_low = (u32)info->vm_pgt_phys;
1277 ptp_phys_high = upper_32_bits(info->vm_pgt_phys);
1278 if (sizeof(void *) == 8) /* 64bit address */
1279 trnctl |= (1 << 2);
1280#if 0 /* Only 4k h/w pages for simplicitiy */
1281#if PAGE_SIZE == 8192
1282 trnctl |= (1<<5);
1283#endif
1284#endif
1285 hw_write_20kx(hw, PTPALX, ptp_phys_low);
1286 hw_write_20kx(hw, PTPAHX, ptp_phys_high);
1287 hw_write_20kx(hw, TRNCTL, trnctl);
1288 hw_write_20kx(hw, TRNIS, 0x200c01); /* realy needed? */
1289
1290 return 0;
1291}
1292
1293/* Card initialization */
1294#define GCTL_EAC 0x00000001
1295#define GCTL_EAI 0x00000002
1296#define GCTL_BEP 0x00000004
1297#define GCTL_BES 0x00000008
1298#define GCTL_DSP 0x00000010
1299#define GCTL_DBP 0x00000020
1300#define GCTL_ABP 0x00000040
1301#define GCTL_TBP 0x00000080
1302#define GCTL_SBP 0x00000100
1303#define GCTL_FBP 0x00000200
1304#define GCTL_XA 0x00000400
1305#define GCTL_ET 0x00000800
1306#define GCTL_PR 0x00001000
1307#define GCTL_MRL 0x00002000
1308#define GCTL_SDE 0x00004000
1309#define GCTL_SDI 0x00008000
1310#define GCTL_SM 0x00010000
1311#define GCTL_SR 0x00020000
1312#define GCTL_SD 0x00040000
1313#define GCTL_SE 0x00080000
1314#define GCTL_AID 0x00100000
1315
1316static int hw_pll_init(struct hw *hw, unsigned int rsr)
1317{
1318 unsigned int pllctl;
1319 int i;
1320
1321 pllctl = (48000 == rsr) ? 0x1480a001 : 0x1480a731;
1322 for (i = 0; i < 3; i++) {
1323 if (hw_read_20kx(hw, PLLCTL) == pllctl)
1324 break;
1325
1326 hw_write_20kx(hw, PLLCTL, pllctl);
1327 mdelay(40);
1328 }
1329 if (i >= 3) {
1330 printk(KERN_ALERT "PLL initialization failed!!!\n");
1331 return -EBUSY;
1332 }
1333
1334 return 0;
1335}
1336
1337static int hw_auto_init(struct hw *hw)
1338{
1339 unsigned int gctl;
1340 int i;
1341
1342 gctl = hw_read_20kx(hw, GCTL);
1343 set_field(&gctl, GCTL_EAI, 0);
1344 hw_write_20kx(hw, GCTL, gctl);
1345 set_field(&gctl, GCTL_EAI, 1);
1346 hw_write_20kx(hw, GCTL, gctl);
1347 mdelay(10);
1348 for (i = 0; i < 400000; i++) {
1349 gctl = hw_read_20kx(hw, GCTL);
1350 if (get_field(gctl, GCTL_AID))
1351 break;
1352 }
1353 if (!get_field(gctl, GCTL_AID)) {
1354 printk(KERN_ALERT "Card Auto-init failed!!!\n");
1355 return -EBUSY;
1356 }
1357
1358 return 0;
1359}
1360
1361static int i2c_unlock(struct hw *hw)
1362{
1363 if ((hw_read_pci(hw, 0xcc) & 0xff) == 0xaa)
1364 return 0;
1365
1366 hw_write_pci(hw, 0xcc, 0x8c);
1367 hw_write_pci(hw, 0xcc, 0x0e);
1368 if ((hw_read_pci(hw, 0xcc) & 0xff) == 0xaa)
1369 return 0;
1370
1371 hw_write_pci(hw, 0xcc, 0xee);
1372 hw_write_pci(hw, 0xcc, 0xaa);
1373 if ((hw_read_pci(hw, 0xcc) & 0xff) == 0xaa)
1374 return 0;
1375
1376 return -1;
1377}
1378
1379static void i2c_lock(struct hw *hw)
1380{
1381 if ((hw_read_pci(hw, 0xcc) & 0xff) == 0xaa)
1382 hw_write_pci(hw, 0xcc, 0x00);
1383}
1384
1385static void i2c_write(struct hw *hw, u32 device, u32 addr, u32 data)
1386{
1387 unsigned int ret;
1388
1389 do {
1390 ret = hw_read_pci(hw, 0xEC);
1391 } while (!(ret & 0x800000));
1392 hw_write_pci(hw, 0xE0, device);
1393 hw_write_pci(hw, 0xE4, (data << 8) | (addr & 0xff));
1394}
1395
1396/* DAC operations */
1397
1398static int hw_reset_dac(struct hw *hw)
1399{
1400 u32 i;
1401 u16 gpioorg;
1402 unsigned int ret;
1403
1404 if (i2c_unlock(hw))
1405 return -1;
1406
1407 do {
1408 ret = hw_read_pci(hw, 0xEC);
1409 } while (!(ret & 0x800000));
1410 hw_write_pci(hw, 0xEC, 0x05); /* write to i2c status control */
1411
1412 /* To be effective, need to reset the DAC twice. */
1413 for (i = 0; i < 2; i++) {
1414 /* set gpio */
1415 mdelay(100);
1416 gpioorg = (u16)hw_read_20kx(hw, GPIO);
1417 gpioorg &= 0xfffd;
1418 hw_write_20kx(hw, GPIO, gpioorg);
1419 mdelay(1);
1420 hw_write_20kx(hw, GPIO, gpioorg | 0x2);
1421 }
1422
1423 i2c_write(hw, 0x00180080, 0x01, 0x80);
1424 i2c_write(hw, 0x00180080, 0x02, 0x10);
1425
1426 i2c_lock(hw);
1427
1428 return 0;
1429}
1430
1431static int hw_dac_init(struct hw *hw, const struct dac_conf *info)
1432{
1433 u32 data;
1434 u16 gpioorg;
1435 unsigned int ret;
1436
1437 if (hw->model == CTSB055X) {
1438 /* SB055x, unmute outputs */
1439 gpioorg = (u16)hw_read_20kx(hw, GPIO);
1440 gpioorg &= 0xffbf; /* set GPIO6 to low */
1441 gpioorg |= 2; /* set GPIO1 to high */
1442 hw_write_20kx(hw, GPIO, gpioorg);
1443 return 0;
1444 }
1445
1446 /* mute outputs */
1447 gpioorg = (u16)hw_read_20kx(hw, GPIO);
1448 gpioorg &= 0xffbf;
1449 hw_write_20kx(hw, GPIO, gpioorg);
1450
1451 hw_reset_dac(hw);
1452
1453 if (i2c_unlock(hw))
1454 return -1;
1455
1456 hw_write_pci(hw, 0xEC, 0x05); /* write to i2c status control */
1457 do {
1458 ret = hw_read_pci(hw, 0xEC);
1459 } while (!(ret & 0x800000));
1460
1461 switch (info->msr) {
1462 case 1:
1463 data = 0x24;
1464 break;
1465 case 2:
1466 data = 0x25;
1467 break;
1468 case 4:
1469 data = 0x26;
1470 break;
1471 default:
1472 data = 0x24;
1473 break;
1474 }
1475
1476 i2c_write(hw, 0x00180080, 0x06, data);
1477 i2c_write(hw, 0x00180080, 0x09, data);
1478 i2c_write(hw, 0x00180080, 0x0c, data);
1479 i2c_write(hw, 0x00180080, 0x0f, data);
1480
1481 i2c_lock(hw);
1482
1483 /* unmute outputs */
1484 gpioorg = (u16)hw_read_20kx(hw, GPIO);
1485 gpioorg = gpioorg | 0x40;
1486 hw_write_20kx(hw, GPIO, gpioorg);
1487
1488 return 0;
1489}
1490
1491/* ADC operations */
1492
1493static int is_adc_input_selected_SB055x(struct hw *hw, enum ADCSRC type)
1494{
1495 return 0;
1496}
1497
1498static int is_adc_input_selected_SBx(struct hw *hw, enum ADCSRC type)
1499{
1500 u32 data;
1501
1502 data = hw_read_20kx(hw, GPIO);
1503 switch (type) {
1504 case ADC_MICIN:
1505 data = ((data & (0x1<<7)) && (data & (0x1<<8)));
1506 break;
1507 case ADC_LINEIN:
1508 data = (!(data & (0x1<<7)) && (data & (0x1<<8)));
1509 break;
1510 case ADC_NONE: /* Digital I/O */
1511 data = (!(data & (0x1<<8)));
1512 break;
1513 default:
1514 data = 0;
1515 }
1516 return data;
1517}
1518
1519static int is_adc_input_selected_hendrix(struct hw *hw, enum ADCSRC type)
1520{
1521 u32 data;
1522
1523 data = hw_read_20kx(hw, GPIO);
1524 switch (type) {
1525 case ADC_MICIN:
1526 data = (data & (0x1 << 7)) ? 1 : 0;
1527 break;
1528 case ADC_LINEIN:
1529 data = (data & (0x1 << 7)) ? 0 : 1;
1530 break;
1531 default:
1532 data = 0;
1533 }
1534 return data;
1535}
1536
1537static int hw_is_adc_input_selected(struct hw *hw, enum ADCSRC type)
1538{
1539 switch (hw->model) {
1540 case CTSB055X:
1541 return is_adc_input_selected_SB055x(hw, type);
1542 case CTSB073X:
1543 return is_adc_input_selected_hendrix(hw, type);
1544 case CTUAA:
1545 return is_adc_input_selected_hendrix(hw, type);
1546 default:
1547 return is_adc_input_selected_SBx(hw, type);
1548 }
1549}
1550
1551static int
1552adc_input_select_SB055x(struct hw *hw, enum ADCSRC type, unsigned char boost)
1553{
1554 u32 data;
1555
1556 /*
1557 * check and set the following GPIO bits accordingly
1558 * ADC_Gain = GPIO2
1559 * DRM_off = GPIO3
1560 * Mic_Pwr_on = GPIO7
1561 * Digital_IO_Sel = GPIO8
1562 * Mic_Sw = GPIO9
1563 * Aux/MicLine_Sw = GPIO12
1564 */
1565 data = hw_read_20kx(hw, GPIO);
1566 data &= 0xec73;
1567 switch (type) {
1568 case ADC_MICIN:
1569 data |= (0x1<<7) | (0x1<<8) | (0x1<<9) ;
1570 data |= boost ? (0x1<<2) : 0;
1571 break;
1572 case ADC_LINEIN:
1573 data |= (0x1<<8);
1574 break;
1575 case ADC_AUX:
1576 data |= (0x1<<8) | (0x1<<12);
1577 break;
1578 case ADC_NONE:
1579 data |= (0x1<<12); /* set to digital */
1580 break;
1581 default:
1582 return -1;
1583 }
1584
1585 hw_write_20kx(hw, GPIO, data);
1586
1587 return 0;
1588}
1589
1590
1591static int
1592adc_input_select_SBx(struct hw *hw, enum ADCSRC type, unsigned char boost)
1593{
1594 u32 data;
1595 u32 i2c_data;
1596 unsigned int ret;
1597
1598 if (i2c_unlock(hw))
1599 return -1;
1600
1601 do {
1602 ret = hw_read_pci(hw, 0xEC);
1603 } while (!(ret & 0x800000)); /* i2c ready poll */
1604 /* set i2c access mode as Direct Control */
1605 hw_write_pci(hw, 0xEC, 0x05);
1606
1607 data = hw_read_20kx(hw, GPIO);
1608 switch (type) {
1609 case ADC_MICIN:
1610 data |= ((0x1 << 7) | (0x1 << 8));
1611 i2c_data = 0x1; /* Mic-in */
1612 break;
1613 case ADC_LINEIN:
1614 data &= ~(0x1 << 7);
1615 data |= (0x1 << 8);
1616 i2c_data = 0x2; /* Line-in */
1617 break;
1618 case ADC_NONE:
1619 data &= ~(0x1 << 8);
1620 i2c_data = 0x0; /* set to Digital */
1621 break;
1622 default:
1623 i2c_lock(hw);
1624 return -1;
1625 }
1626 hw_write_20kx(hw, GPIO, data);
1627 i2c_write(hw, 0x001a0080, 0x2a, i2c_data);
1628 if (boost) {
1629 i2c_write(hw, 0x001a0080, 0x1c, 0xe7); /* +12dB boost */
1630 i2c_write(hw, 0x001a0080, 0x1e, 0xe7); /* +12dB boost */
1631 } else {
1632 i2c_write(hw, 0x001a0080, 0x1c, 0xcf); /* No boost */
1633 i2c_write(hw, 0x001a0080, 0x1e, 0xcf); /* No boost */
1634 }
1635
1636 i2c_lock(hw);
1637
1638 return 0;
1639}
1640
1641static int
1642adc_input_select_hendrix(struct hw *hw, enum ADCSRC type, unsigned char boost)
1643{
1644 u32 data;
1645 u32 i2c_data;
1646 unsigned int ret;
1647
1648 if (i2c_unlock(hw))
1649 return -1;
1650
1651 do {
1652 ret = hw_read_pci(hw, 0xEC);
1653 } while (!(ret & 0x800000)); /* i2c ready poll */
1654 /* set i2c access mode as Direct Control */
1655 hw_write_pci(hw, 0xEC, 0x05);
1656
1657 data = hw_read_20kx(hw, GPIO);
1658 switch (type) {
1659 case ADC_MICIN:
1660 data |= (0x1 << 7);
1661 i2c_data = 0x1; /* Mic-in */
1662 break;
1663 case ADC_LINEIN:
1664 data &= ~(0x1 << 7);
1665 i2c_data = 0x2; /* Line-in */
1666 break;
1667 default:
1668 i2c_lock(hw);
1669 return -1;
1670 }
1671 hw_write_20kx(hw, GPIO, data);
1672 i2c_write(hw, 0x001a0080, 0x2a, i2c_data);
1673 if (boost) {
1674 i2c_write(hw, 0x001a0080, 0x1c, 0xe7); /* +12dB boost */
1675 i2c_write(hw, 0x001a0080, 0x1e, 0xe7); /* +12dB boost */
1676 } else {
1677 i2c_write(hw, 0x001a0080, 0x1c, 0xcf); /* No boost */
1678 i2c_write(hw, 0x001a0080, 0x1e, 0xcf); /* No boost */
1679 }
1680
1681 i2c_lock(hw);
1682
1683 return 0;
1684}
1685
1686static int hw_adc_input_select(struct hw *hw, enum ADCSRC type)
1687{
1688 int state = type == ADC_MICIN;
1689
1690 switch (hw->model) {
1691 case CTSB055X:
1692 return adc_input_select_SB055x(hw, type, state);
1693 case CTSB073X:
1694 return adc_input_select_hendrix(hw, type, state);
1695 case CTUAA:
1696 return adc_input_select_hendrix(hw, type, state);
1697 default:
1698 return adc_input_select_SBx(hw, type, state);
1699 }
1700}
1701
1702static int adc_init_SB055x(struct hw *hw, int input, int mic20db)
1703{
1704 return adc_input_select_SB055x(hw, input, mic20db);
1705}
1706
1707static int adc_init_SBx(struct hw *hw, int input, int mic20db)
1708{
1709 u16 gpioorg;
1710 u16 input_source;
1711 u32 adcdata;
1712 unsigned int ret;
1713
1714 input_source = 0x100; /* default to analog */
1715 switch (input) {
1716 case ADC_MICIN:
1717 adcdata = 0x1;
1718 input_source = 0x180; /* set GPIO7 to select Mic */
1719 break;
1720 case ADC_LINEIN:
1721 adcdata = 0x2;
1722 break;
1723 case ADC_VIDEO:
1724 adcdata = 0x4;
1725 break;
1726 case ADC_AUX:
1727 adcdata = 0x8;
1728 break;
1729 case ADC_NONE:
1730 adcdata = 0x0;
1731 input_source = 0x0; /* set to Digital */
1732 break;
1733 default:
1734 adcdata = 0x0;
1735 break;
1736 }
1737
1738 if (i2c_unlock(hw))
1739 return -1;
1740
1741 do {
1742 ret = hw_read_pci(hw, 0xEC);
1743 } while (!(ret & 0x800000)); /* i2c ready poll */
1744 hw_write_pci(hw, 0xEC, 0x05); /* write to i2c status control */
1745
1746 i2c_write(hw, 0x001a0080, 0x0e, 0x08);
1747 i2c_write(hw, 0x001a0080, 0x18, 0x0a);
1748 i2c_write(hw, 0x001a0080, 0x28, 0x86);
1749 i2c_write(hw, 0x001a0080, 0x2a, adcdata);
1750
1751 if (mic20db) {
1752 i2c_write(hw, 0x001a0080, 0x1c, 0xf7);
1753 i2c_write(hw, 0x001a0080, 0x1e, 0xf7);
1754 } else {
1755 i2c_write(hw, 0x001a0080, 0x1c, 0xcf);
1756 i2c_write(hw, 0x001a0080, 0x1e, 0xcf);
1757 }
1758
1759 if (!(hw_read_20kx(hw, ID0) & 0x100))
1760 i2c_write(hw, 0x001a0080, 0x16, 0x26);
1761
1762 i2c_lock(hw);
1763
1764 gpioorg = (u16)hw_read_20kx(hw, GPIO);
1765 gpioorg &= 0xfe7f;
1766 gpioorg |= input_source;
1767 hw_write_20kx(hw, GPIO, gpioorg);
1768
1769 return 0;
1770}
1771
1772static int hw_adc_init(struct hw *hw, const struct adc_conf *info)
1773{
1774 if (hw->model == CTSB055X)
1775 return adc_init_SB055x(hw, info->input, info->mic20db);
1776 else
1777 return adc_init_SBx(hw, info->input, info->mic20db);
1778}
1779
1780static int hw_have_digit_io_switch(struct hw *hw)
1781{
1782 /* SB073x and Vista compatible cards have no digit IO switch */
1783 return !(hw->model == CTSB073X || hw->model == CTUAA);
1784}
1785
1786#define CTLBITS(a, b, c, d) (((a) << 24) | ((b) << 16) | ((c) << 8) | (d))
1787
1788#define UAA_CFG_PWRSTATUS 0x44
1789#define UAA_CFG_SPACE_FLAG 0xA0
1790#define UAA_CORE_CHANGE 0x3FFC
1791static int uaa_to_xfi(struct pci_dev *pci)
1792{
1793 unsigned int bar0, bar1, bar2, bar3, bar4, bar5;
1794 unsigned int cmd, irq, cl_size, l_timer, pwr;
1795 unsigned int is_uaa;
1796 unsigned int data[4] = {0};
1797 unsigned int io_base;
1798 void *mem_base;
1799 int i;
1800 const u32 CTLX = CTLBITS('C', 'T', 'L', 'X');
1801 const u32 CTL_ = CTLBITS('C', 'T', 'L', '-');
1802 const u32 CTLF = CTLBITS('C', 'T', 'L', 'F');
1803 const u32 CTLi = CTLBITS('C', 'T', 'L', 'i');
1804 const u32 CTLA = CTLBITS('C', 'T', 'L', 'A');
1805 const u32 CTLZ = CTLBITS('C', 'T', 'L', 'Z');
1806 const u32 CTLL = CTLBITS('C', 'T', 'L', 'L');
1807
1808 /* By default, Hendrix card UAA Bar0 should be using memory... */
1809 io_base = pci_resource_start(pci, 0);
1810 mem_base = ioremap(io_base, pci_resource_len(pci, 0));
1811 if (NULL == mem_base)
1812 return -ENOENT;
1813
1814 /* Read current mode from Mode Change Register */
1815 for (i = 0; i < 4; i++)
1816 data[i] = readl(mem_base + UAA_CORE_CHANGE);
1817
1818 /* Determine current mode... */
1819 if (data[0] == CTLA) {
1820 is_uaa = ((data[1] == CTLZ && data[2] == CTLL
1821 && data[3] == CTLA) || (data[1] == CTLA
1822 && data[2] == CTLZ && data[3] == CTLL));
1823 } else if (data[0] == CTLZ) {
1824 is_uaa = (data[1] == CTLL
1825 && data[2] == CTLA && data[3] == CTLA);
1826 } else if (data[0] == CTLL) {
1827 is_uaa = (data[1] == CTLA
1828 && data[2] == CTLA && data[3] == CTLZ);
1829 } else {
1830 is_uaa = 0;
1831 }
1832
1833 if (!is_uaa) {
1834 /* Not in UAA mode currently. Return directly. */
1835 iounmap(mem_base);
1836 return 0;
1837 }
1838
1839 pci_read_config_dword(pci, PCI_BASE_ADDRESS_0, &bar0);
1840 pci_read_config_dword(pci, PCI_BASE_ADDRESS_1, &bar1);
1841 pci_read_config_dword(pci, PCI_BASE_ADDRESS_2, &bar2);
1842 pci_read_config_dword(pci, PCI_BASE_ADDRESS_3, &bar3);
1843 pci_read_config_dword(pci, PCI_BASE_ADDRESS_4, &bar4);
1844 pci_read_config_dword(pci, PCI_BASE_ADDRESS_5, &bar5);
1845 pci_read_config_dword(pci, PCI_INTERRUPT_LINE, &irq);
1846 pci_read_config_dword(pci, PCI_CACHE_LINE_SIZE, &cl_size);
1847 pci_read_config_dword(pci, PCI_LATENCY_TIMER, &l_timer);
1848 pci_read_config_dword(pci, UAA_CFG_PWRSTATUS, &pwr);
1849 pci_read_config_dword(pci, PCI_COMMAND, &cmd);
1850
1851 /* Set up X-Fi core PCI configuration space. */
1852 /* Switch to X-Fi config space with BAR0 exposed. */
1853 pci_write_config_dword(pci, UAA_CFG_SPACE_FLAG, 0x87654321);
1854 /* Copy UAA's BAR5 into X-Fi BAR0 */
1855 pci_write_config_dword(pci, PCI_BASE_ADDRESS_0, bar5);
1856 /* Switch to X-Fi config space without BAR0 exposed. */
1857 pci_write_config_dword(pci, UAA_CFG_SPACE_FLAG, 0x12345678);
1858 pci_write_config_dword(pci, PCI_BASE_ADDRESS_1, bar1);
1859 pci_write_config_dword(pci, PCI_BASE_ADDRESS_2, bar2);
1860 pci_write_config_dword(pci, PCI_BASE_ADDRESS_3, bar3);
1861 pci_write_config_dword(pci, PCI_BASE_ADDRESS_4, bar4);
1862 pci_write_config_dword(pci, PCI_INTERRUPT_LINE, irq);
1863 pci_write_config_dword(pci, PCI_CACHE_LINE_SIZE, cl_size);
1864 pci_write_config_dword(pci, PCI_LATENCY_TIMER, l_timer);
1865 pci_write_config_dword(pci, UAA_CFG_PWRSTATUS, pwr);
1866 pci_write_config_dword(pci, PCI_COMMAND, cmd);
1867
1868 /* Switch to X-Fi mode */
1869 writel(CTLX, (mem_base + UAA_CORE_CHANGE));
1870 writel(CTL_, (mem_base + UAA_CORE_CHANGE));
1871 writel(CTLF, (mem_base + UAA_CORE_CHANGE));
1872 writel(CTLi, (mem_base + UAA_CORE_CHANGE));
1873
1874 iounmap(mem_base);
1875
1876 return 0;
1877}
1878
1879static irqreturn_t ct_20k1_interrupt(int irq, void *dev_id)
1880{
1881 struct hw *hw = dev_id;
1882 unsigned int status;
1883
1884 status = hw_read_20kx(hw, GIP);
1885 if (!status)
1886 return IRQ_NONE;
1887
1888 if (hw->irq_callback)
1889 hw->irq_callback(hw->irq_callback_data, status);
1890
1891 hw_write_20kx(hw, GIP, status);
1892 return IRQ_HANDLED;
1893}
1894
1895static int hw_card_start(struct hw *hw)
1896{
1897 int err;
1898 struct pci_dev *pci = hw->pci;
1899
1900 err = pci_enable_device(pci);
1901 if (err < 0)
1902 return err;
1903
1904 /* Set DMA transfer mask */
1905 if (pci_set_dma_mask(pci, CT_XFI_DMA_MASK) < 0 ||
1906 pci_set_consistent_dma_mask(pci, CT_XFI_DMA_MASK) < 0) {
1907 printk(KERN_ERR "architecture does not support PCI "
1908 "busmaster DMA with mask 0x%llx\n",
1909 CT_XFI_DMA_MASK);
1910 err = -ENXIO;
1911 goto error1;
1912 }
1913
1914 err = pci_request_regions(pci, "XFi");
1915 if (err < 0)
1916 goto error1;
1917
1918 /* Switch to X-Fi mode from UAA mode if neeeded */
1919 if (hw->model == CTUAA) {
1920 err = uaa_to_xfi(pci);
1921 if (err)
1922 goto error2;
1923
1924 hw->io_base = pci_resource_start(pci, 5);
1925 } else {
1926 hw->io_base = pci_resource_start(pci, 0);
1927 }
1928
1929 err = request_irq(pci->irq, ct_20k1_interrupt, IRQF_SHARED,
1930 "ctxfi", hw);
1931 if (err < 0) {
1932 printk(KERN_ERR "XFi: Cannot get irq %d\n", pci->irq);
1933 goto error2;
1934 }
1935 hw->irq = pci->irq;
1936
1937 pci_set_master(pci);
1938
1939 return 0;
1940
1941error2:
1942 pci_release_regions(pci);
1943 hw->io_base = 0;
1944error1:
1945 pci_disable_device(pci);
1946 return err;
1947}
1948
1949static int hw_card_stop(struct hw *hw)
1950{
1951 /* TODO: Disable interrupt and so on... */
1952 if (hw->irq >= 0)
1953 synchronize_irq(hw->irq);
1954 return 0;
1955}
1956
1957static int hw_card_shutdown(struct hw *hw)
1958{
1959 if (hw->irq >= 0)
1960 free_irq(hw->irq, hw);
1961
1962 hw->irq = -1;
1963
1964 if (NULL != ((void *)hw->mem_base))
1965 iounmap((void *)hw->mem_base);
1966
1967 hw->mem_base = (unsigned long)NULL;
1968
1969 if (hw->io_base)
1970 pci_release_regions(hw->pci);
1971
1972 hw->io_base = 0;
1973
1974 pci_disable_device(hw->pci);
1975
1976 return 0;
1977}
1978
1979static int hw_card_init(struct hw *hw, struct card_conf *info)
1980{
1981 int err;
1982 unsigned int gctl;
1983 u32 data;
1984 struct dac_conf dac_info = {0};
1985 struct adc_conf adc_info = {0};
1986 struct daio_conf daio_info = {0};
1987 struct trn_conf trn_info = {0};
1988
1989 /* Get PCI io port base address and do Hendrix switch if needed. */
1990 if (!hw->io_base) {
1991 err = hw_card_start(hw);
1992 if (err)
1993 return err;
1994 }
1995
1996 /* PLL init */
1997 err = hw_pll_init(hw, info->rsr);
1998 if (err < 0)
1999 return err;
2000
2001 /* kick off auto-init */
2002 err = hw_auto_init(hw);
2003 if (err < 0)
2004 return err;
2005
2006 /* Enable audio ring */
2007 gctl = hw_read_20kx(hw, GCTL);
2008 set_field(&gctl, GCTL_EAC, 1);
2009 set_field(&gctl, GCTL_DBP, 1);
2010 set_field(&gctl, GCTL_TBP, 1);
2011 set_field(&gctl, GCTL_FBP, 1);
2012 set_field(&gctl, GCTL_ET, 1);
2013 hw_write_20kx(hw, GCTL, gctl);
2014 mdelay(10);
2015
2016 /* Reset all global pending interrupts */
2017 hw_write_20kx(hw, GIE, 0);
2018 /* Reset all SRC pending interrupts */
2019 hw_write_20kx(hw, SRCIP, 0);
2020 mdelay(30);
2021
2022 /* Detect the card ID and configure GPIO accordingly. */
2023 switch (hw->model) {
2024 case CTSB055X:
2025 hw_write_20kx(hw, GPIOCTL, 0x13fe);
2026 break;
2027 case CTSB073X:
2028 hw_write_20kx(hw, GPIOCTL, 0x00e6);
2029 break;
2030 case CTUAA:
2031 hw_write_20kx(hw, GPIOCTL, 0x00c2);
2032 break;
2033 default:
2034 hw_write_20kx(hw, GPIOCTL, 0x01e6);
2035 break;
2036 }
2037
2038 trn_info.vm_pgt_phys = info->vm_pgt_phys;
2039 err = hw_trn_init(hw, &trn_info);
2040 if (err < 0)
2041 return err;
2042
2043 daio_info.msr = info->msr;
2044 err = hw_daio_init(hw, &daio_info);
2045 if (err < 0)
2046 return err;
2047
2048 dac_info.msr = info->msr;
2049 err = hw_dac_init(hw, &dac_info);
2050 if (err < 0)
2051 return err;
2052
2053 adc_info.msr = info->msr;
2054 adc_info.input = ADC_LINEIN;
2055 adc_info.mic20db = 0;
2056 err = hw_adc_init(hw, &adc_info);
2057 if (err < 0)
2058 return err;
2059
2060 data = hw_read_20kx(hw, SRCMCTL);
2061 data |= 0x1; /* Enables input from the audio ring */
2062 hw_write_20kx(hw, SRCMCTL, data);
2063
2064 return 0;
2065}
2066
2067static u32 hw_read_20kx(struct hw *hw, u32 reg)
2068{
2069 u32 value;
2070 unsigned long flags;
2071
2072 spin_lock_irqsave(
2073 &container_of(hw, struct hw20k1, hw)->reg_20k1_lock, flags);
2074 outl(reg, hw->io_base + 0x0);
2075 value = inl(hw->io_base + 0x4);
2076 spin_unlock_irqrestore(
2077 &container_of(hw, struct hw20k1, hw)->reg_20k1_lock, flags);
2078
2079 return value;
2080}
2081
2082static void hw_write_20kx(struct hw *hw, u32 reg, u32 data)
2083{
2084 unsigned long flags;
2085
2086 spin_lock_irqsave(
2087 &container_of(hw, struct hw20k1, hw)->reg_20k1_lock, flags);
2088 outl(reg, hw->io_base + 0x0);
2089 outl(data, hw->io_base + 0x4);
2090 spin_unlock_irqrestore(
2091 &container_of(hw, struct hw20k1, hw)->reg_20k1_lock, flags);
2092
2093}
2094
2095static u32 hw_read_pci(struct hw *hw, u32 reg)
2096{
2097 u32 value;
2098 unsigned long flags;
2099
2100 spin_lock_irqsave(
2101 &container_of(hw, struct hw20k1, hw)->reg_pci_lock, flags);
2102 outl(reg, hw->io_base + 0x10);
2103 value = inl(hw->io_base + 0x14);
2104 spin_unlock_irqrestore(
2105 &container_of(hw, struct hw20k1, hw)->reg_pci_lock, flags);
2106
2107 return value;
2108}
2109
2110static void hw_write_pci(struct hw *hw, u32 reg, u32 data)
2111{
2112 unsigned long flags;
2113
2114 spin_lock_irqsave(
2115 &container_of(hw, struct hw20k1, hw)->reg_pci_lock, flags);
2116 outl(reg, hw->io_base + 0x10);
2117 outl(data, hw->io_base + 0x14);
2118 spin_unlock_irqrestore(
2119 &container_of(hw, struct hw20k1, hw)->reg_pci_lock, flags);
2120}
2121
2122static struct hw ct20k1_preset __devinitdata = {
2123 .irq = -1,
2124
2125 .card_init = hw_card_init,
2126 .card_stop = hw_card_stop,
2127 .pll_init = hw_pll_init,
2128 .is_adc_source_selected = hw_is_adc_input_selected,
2129 .select_adc_source = hw_adc_input_select,
2130 .have_digit_io_switch = hw_have_digit_io_switch,
2131
2132 .src_rsc_get_ctrl_blk = src_get_rsc_ctrl_blk,
2133 .src_rsc_put_ctrl_blk = src_put_rsc_ctrl_blk,
2134 .src_mgr_get_ctrl_blk = src_mgr_get_ctrl_blk,
2135 .src_mgr_put_ctrl_blk = src_mgr_put_ctrl_blk,
2136 .src_set_state = src_set_state,
2137 .src_set_bm = src_set_bm,
2138 .src_set_rsr = src_set_rsr,
2139 .src_set_sf = src_set_sf,
2140 .src_set_wr = src_set_wr,
2141 .src_set_pm = src_set_pm,
2142 .src_set_rom = src_set_rom,
2143 .src_set_vo = src_set_vo,
2144 .src_set_st = src_set_st,
2145 .src_set_ie = src_set_ie,
2146 .src_set_ilsz = src_set_ilsz,
2147 .src_set_bp = src_set_bp,
2148 .src_set_cisz = src_set_cisz,
2149 .src_set_ca = src_set_ca,
2150 .src_set_sa = src_set_sa,
2151 .src_set_la = src_set_la,
2152 .src_set_pitch = src_set_pitch,
2153 .src_set_dirty = src_set_dirty,
2154 .src_set_clear_zbufs = src_set_clear_zbufs,
2155 .src_set_dirty_all = src_set_dirty_all,
2156 .src_commit_write = src_commit_write,
2157 .src_get_ca = src_get_ca,
2158 .src_get_dirty = src_get_dirty,
2159 .src_dirty_conj_mask = src_dirty_conj_mask,
2160 .src_mgr_enbs_src = src_mgr_enbs_src,
2161 .src_mgr_enb_src = src_mgr_enb_src,
2162 .src_mgr_dsb_src = src_mgr_dsb_src,
2163 .src_mgr_commit_write = src_mgr_commit_write,
2164
2165 .srcimp_mgr_get_ctrl_blk = srcimp_mgr_get_ctrl_blk,
2166 .srcimp_mgr_put_ctrl_blk = srcimp_mgr_put_ctrl_blk,
2167 .srcimp_mgr_set_imaparc = srcimp_mgr_set_imaparc,
2168 .srcimp_mgr_set_imapuser = srcimp_mgr_set_imapuser,
2169 .srcimp_mgr_set_imapnxt = srcimp_mgr_set_imapnxt,
2170 .srcimp_mgr_set_imapaddr = srcimp_mgr_set_imapaddr,
2171 .srcimp_mgr_commit_write = srcimp_mgr_commit_write,
2172
2173 .amixer_rsc_get_ctrl_blk = amixer_rsc_get_ctrl_blk,
2174 .amixer_rsc_put_ctrl_blk = amixer_rsc_put_ctrl_blk,
2175 .amixer_mgr_get_ctrl_blk = amixer_mgr_get_ctrl_blk,
2176 .amixer_mgr_put_ctrl_blk = amixer_mgr_put_ctrl_blk,
2177 .amixer_set_mode = amixer_set_mode,
2178 .amixer_set_iv = amixer_set_iv,
2179 .amixer_set_x = amixer_set_x,
2180 .amixer_set_y = amixer_set_y,
2181 .amixer_set_sadr = amixer_set_sadr,
2182 .amixer_set_se = amixer_set_se,
2183 .amixer_set_dirty = amixer_set_dirty,
2184 .amixer_set_dirty_all = amixer_set_dirty_all,
2185 .amixer_commit_write = amixer_commit_write,
2186 .amixer_get_y = amixer_get_y,
2187 .amixer_get_dirty = amixer_get_dirty,
2188
2189 .dai_get_ctrl_blk = dai_get_ctrl_blk,
2190 .dai_put_ctrl_blk = dai_put_ctrl_blk,
2191 .dai_srt_set_srco = dai_srt_set_srcr,
2192 .dai_srt_set_srcm = dai_srt_set_srcl,
2193 .dai_srt_set_rsr = dai_srt_set_rsr,
2194 .dai_srt_set_drat = dai_srt_set_drat,
2195 .dai_srt_set_ec = dai_srt_set_ec,
2196 .dai_srt_set_et = dai_srt_set_et,
2197 .dai_commit_write = dai_commit_write,
2198
2199 .dao_get_ctrl_blk = dao_get_ctrl_blk,
2200 .dao_put_ctrl_blk = dao_put_ctrl_blk,
2201 .dao_set_spos = dao_set_spos,
2202 .dao_commit_write = dao_commit_write,
2203 .dao_get_spos = dao_get_spos,
2204
2205 .daio_mgr_get_ctrl_blk = daio_mgr_get_ctrl_blk,
2206 .daio_mgr_put_ctrl_blk = daio_mgr_put_ctrl_blk,
2207 .daio_mgr_enb_dai = daio_mgr_enb_dai,
2208 .daio_mgr_dsb_dai = daio_mgr_dsb_dai,
2209 .daio_mgr_enb_dao = daio_mgr_enb_dao,
2210 .daio_mgr_dsb_dao = daio_mgr_dsb_dao,
2211 .daio_mgr_dao_init = daio_mgr_dao_init,
2212 .daio_mgr_set_imaparc = daio_mgr_set_imaparc,
2213 .daio_mgr_set_imapnxt = daio_mgr_set_imapnxt,
2214 .daio_mgr_set_imapaddr = daio_mgr_set_imapaddr,
2215 .daio_mgr_commit_write = daio_mgr_commit_write,
2216
2217 .set_timer_irq = set_timer_irq,
2218 .set_timer_tick = set_timer_tick,
2219 .get_wc = get_wc,
2220};
2221
2222int __devinit create_20k1_hw_obj(struct hw **rhw)
2223{
2224 struct hw20k1 *hw20k1;
2225
2226 *rhw = NULL;
2227 hw20k1 = kzalloc(sizeof(*hw20k1), GFP_KERNEL);
2228 if (NULL == hw20k1)
2229 return -ENOMEM;
2230
2231 spin_lock_init(&hw20k1->reg_20k1_lock);
2232 spin_lock_init(&hw20k1->reg_pci_lock);
2233
2234 hw20k1->hw = ct20k1_preset;
2235
2236 *rhw = &hw20k1->hw;
2237
2238 return 0;
2239}
2240
2241int destroy_20k1_hw_obj(struct hw *hw)
2242{
2243 if (hw->io_base)
2244 hw_card_shutdown(hw);
2245
2246 kfree(container_of(hw, struct hw20k1, hw));
2247 return 0;
2248}
diff --git a/sound/pci/ctxfi/cthw20k1.h b/sound/pci/ctxfi/cthw20k1.h
new file mode 100644
index 00000000000..02f72fb448a
--- /dev/null
+++ b/sound/pci/ctxfi/cthw20k1.h
@@ -0,0 +1,26 @@
1/**
2 * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
3 *
4 * This source file is released under GPL v2 license (no other versions).
5 * See the COPYING file included in the main directory of this source
6 * distribution for the license terms and conditions.
7 *
8 * @File cthw20k1.h
9 *
10 * @Brief
11 * This file contains the definition of hardware access methord.
12 *
13 * @Author Liu Chun
14 * @Date May 13 2008
15 *
16 */
17
18#ifndef CTHW20K1_H
19#define CTHW20K1_H
20
21#include "cthardware.h"
22
23int create_20k1_hw_obj(struct hw **rhw);
24int destroy_20k1_hw_obj(struct hw *hw);
25
26#endif /* CTHW20K1_H */
diff --git a/sound/pci/ctxfi/cthw20k2.c b/sound/pci/ctxfi/cthw20k2.c
new file mode 100644
index 00000000000..4493a51c6b0
--- /dev/null
+++ b/sound/pci/ctxfi/cthw20k2.c
@@ -0,0 +1,2137 @@
1/**
2 * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
3 *
4 * This source file is released under GPL v2 license (no other versions).
5 * See the COPYING file included in the main directory of this source
6 * distribution for the license terms and conditions.
7 *
8 * @File cthw20k2.c
9 *
10 * @Brief
11 * This file contains the implementation of hardware access methord for 20k2.
12 *
13 * @Author Liu Chun
14 * @Date May 14 2008
15 *
16 */
17
18#include <linux/types.h>
19#include <linux/slab.h>
20#include <linux/pci.h>
21#include <linux/io.h>
22#include <linux/string.h>
23#include <linux/kernel.h>
24#include <linux/interrupt.h>
25#include <linux/delay.h>
26#include "cthw20k2.h"
27#include "ct20k2reg.h"
28
29#if BITS_PER_LONG == 32
30#define CT_XFI_DMA_MASK DMA_BIT_MASK(32) /* 32 bit PTE */
31#else
32#define CT_XFI_DMA_MASK DMA_BIT_MASK(64) /* 64 bit PTE */
33#endif
34
35struct hw20k2 {
36 struct hw hw;
37 /* for i2c */
38 unsigned char dev_id;
39 unsigned char addr_size;
40 unsigned char data_size;
41};
42
43static u32 hw_read_20kx(struct hw *hw, u32 reg);
44static void hw_write_20kx(struct hw *hw, u32 reg, u32 data);
45
46/*
47 * Type definition block.
48 * The layout of control structures can be directly applied on 20k2 chip.
49 */
50
51/*
52 * SRC control block definitions.
53 */
54
55/* SRC resource control block */
56#define SRCCTL_STATE 0x00000007
57#define SRCCTL_BM 0x00000008
58#define SRCCTL_RSR 0x00000030
59#define SRCCTL_SF 0x000001C0
60#define SRCCTL_WR 0x00000200
61#define SRCCTL_PM 0x00000400
62#define SRCCTL_ROM 0x00001800
63#define SRCCTL_VO 0x00002000
64#define SRCCTL_ST 0x00004000
65#define SRCCTL_IE 0x00008000
66#define SRCCTL_ILSZ 0x000F0000
67#define SRCCTL_BP 0x00100000
68
69#define SRCCCR_CISZ 0x000007FF
70#define SRCCCR_CWA 0x001FF800
71#define SRCCCR_D 0x00200000
72#define SRCCCR_RS 0x01C00000
73#define SRCCCR_NAL 0x3E000000
74#define SRCCCR_RA 0xC0000000
75
76#define SRCCA_CA 0x0FFFFFFF
77#define SRCCA_RS 0xE0000000
78
79#define SRCSA_SA 0x0FFFFFFF
80
81#define SRCLA_LA 0x0FFFFFFF
82
83/* Mixer Parameter Ring ram Low and Hight register.
84 * Fixed-point value in 8.24 format for parameter channel */
85#define MPRLH_PITCH 0xFFFFFFFF
86
87/* SRC resource register dirty flags */
88union src_dirty {
89 struct {
90 u16 ctl:1;
91 u16 ccr:1;
92 u16 sa:1;
93 u16 la:1;
94 u16 ca:1;
95 u16 mpr:1;
96 u16 czbfs:1; /* Clear Z-Buffers */
97 u16 rsv:9;
98 } bf;
99 u16 data;
100};
101
102struct src_rsc_ctrl_blk {
103 unsigned int ctl;
104 unsigned int ccr;
105 unsigned int ca;
106 unsigned int sa;
107 unsigned int la;
108 unsigned int mpr;
109 union src_dirty dirty;
110};
111
112/* SRC manager control block */
113union src_mgr_dirty {
114 struct {
115 u16 enb0:1;
116 u16 enb1:1;
117 u16 enb2:1;
118 u16 enb3:1;
119 u16 enb4:1;
120 u16 enb5:1;
121 u16 enb6:1;
122 u16 enb7:1;
123 u16 enbsa:1;
124 u16 rsv:7;
125 } bf;
126 u16 data;
127};
128
129struct src_mgr_ctrl_blk {
130 unsigned int enbsa;
131 unsigned int enb[8];
132 union src_mgr_dirty dirty;
133};
134
135/* SRCIMP manager control block */
136#define SRCAIM_ARC 0x00000FFF
137#define SRCAIM_NXT 0x00FF0000
138#define SRCAIM_SRC 0xFF000000
139
140struct srcimap {
141 unsigned int srcaim;
142 unsigned int idx;
143};
144
145/* SRCIMP manager register dirty flags */
146union srcimp_mgr_dirty {
147 struct {
148 u16 srcimap:1;
149 u16 rsv:15;
150 } bf;
151 u16 data;
152};
153
154struct srcimp_mgr_ctrl_blk {
155 struct srcimap srcimap;
156 union srcimp_mgr_dirty dirty;
157};
158
159/*
160 * Function implementation block.
161 */
162
163static int src_get_rsc_ctrl_blk(void **rblk)
164{
165 struct src_rsc_ctrl_blk *blk;
166
167 *rblk = NULL;
168 blk = kzalloc(sizeof(*blk), GFP_KERNEL);
169 if (NULL == blk)
170 return -ENOMEM;
171
172 *rblk = blk;
173
174 return 0;
175}
176
177static int src_put_rsc_ctrl_blk(void *blk)
178{
179 kfree(blk);
180
181 return 0;
182}
183
184static int src_set_state(void *blk, unsigned int state)
185{
186 struct src_rsc_ctrl_blk *ctl = blk;
187
188 set_field(&ctl->ctl, SRCCTL_STATE, state);
189 ctl->dirty.bf.ctl = 1;
190 return 0;
191}
192
193static int src_set_bm(void *blk, unsigned int bm)
194{
195 struct src_rsc_ctrl_blk *ctl = blk;
196
197 set_field(&ctl->ctl, SRCCTL_BM, bm);
198 ctl->dirty.bf.ctl = 1;
199 return 0;
200}
201
202static int src_set_rsr(void *blk, unsigned int rsr)
203{
204 struct src_rsc_ctrl_blk *ctl = blk;
205
206 set_field(&ctl->ctl, SRCCTL_RSR, rsr);
207 ctl->dirty.bf.ctl = 1;
208 return 0;
209}
210
211static int src_set_sf(void *blk, unsigned int sf)
212{
213 struct src_rsc_ctrl_blk *ctl = blk;
214
215 set_field(&ctl->ctl, SRCCTL_SF, sf);
216 ctl->dirty.bf.ctl = 1;
217 return 0;
218}
219
220static int src_set_wr(void *blk, unsigned int wr)
221{
222 struct src_rsc_ctrl_blk *ctl = blk;
223
224 set_field(&ctl->ctl, SRCCTL_WR, wr);
225 ctl->dirty.bf.ctl = 1;
226 return 0;
227}
228
229static int src_set_pm(void *blk, unsigned int pm)
230{
231 struct src_rsc_ctrl_blk *ctl = blk;
232
233 set_field(&ctl->ctl, SRCCTL_PM, pm);
234 ctl->dirty.bf.ctl = 1;
235 return 0;
236}
237
238static int src_set_rom(void *blk, unsigned int rom)
239{
240 struct src_rsc_ctrl_blk *ctl = blk;
241
242 set_field(&ctl->ctl, SRCCTL_ROM, rom);
243 ctl->dirty.bf.ctl = 1;
244 return 0;
245}
246
247static int src_set_vo(void *blk, unsigned int vo)
248{
249 struct src_rsc_ctrl_blk *ctl = blk;
250
251 set_field(&ctl->ctl, SRCCTL_VO, vo);
252 ctl->dirty.bf.ctl = 1;
253 return 0;
254}
255
256static int src_set_st(void *blk, unsigned int st)
257{
258 struct src_rsc_ctrl_blk *ctl = blk;
259
260 set_field(&ctl->ctl, SRCCTL_ST, st);
261 ctl->dirty.bf.ctl = 1;
262 return 0;
263}
264
265static int src_set_ie(void *blk, unsigned int ie)
266{
267 struct src_rsc_ctrl_blk *ctl = blk;
268
269 set_field(&ctl->ctl, SRCCTL_IE, ie);
270 ctl->dirty.bf.ctl = 1;
271 return 0;
272}
273
274static int src_set_ilsz(void *blk, unsigned int ilsz)
275{
276 struct src_rsc_ctrl_blk *ctl = blk;
277
278 set_field(&ctl->ctl, SRCCTL_ILSZ, ilsz);
279 ctl->dirty.bf.ctl = 1;
280 return 0;
281}
282
283static int src_set_bp(void *blk, unsigned int bp)
284{
285 struct src_rsc_ctrl_blk *ctl = blk;
286
287 set_field(&ctl->ctl, SRCCTL_BP, bp);
288 ctl->dirty.bf.ctl = 1;
289 return 0;
290}
291
292static int src_set_cisz(void *blk, unsigned int cisz)
293{
294 struct src_rsc_ctrl_blk *ctl = blk;
295
296 set_field(&ctl->ccr, SRCCCR_CISZ, cisz);
297 ctl->dirty.bf.ccr = 1;
298 return 0;
299}
300
301static int src_set_ca(void *blk, unsigned int ca)
302{
303 struct src_rsc_ctrl_blk *ctl = blk;
304
305 set_field(&ctl->ca, SRCCA_CA, ca);
306 ctl->dirty.bf.ca = 1;
307 return 0;
308}
309
310static int src_set_sa(void *blk, unsigned int sa)
311{
312 struct src_rsc_ctrl_blk *ctl = blk;
313
314 set_field(&ctl->sa, SRCSA_SA, sa);
315 ctl->dirty.bf.sa = 1;
316 return 0;
317}
318
319static int src_set_la(void *blk, unsigned int la)
320{
321 struct src_rsc_ctrl_blk *ctl = blk;
322
323 set_field(&ctl->la, SRCLA_LA, la);
324 ctl->dirty.bf.la = 1;
325 return 0;
326}
327
328static int src_set_pitch(void *blk, unsigned int pitch)
329{
330 struct src_rsc_ctrl_blk *ctl = blk;
331
332 set_field(&ctl->mpr, MPRLH_PITCH, pitch);
333 ctl->dirty.bf.mpr = 1;
334 return 0;
335}
336
337static int src_set_clear_zbufs(void *blk, unsigned int clear)
338{
339 ((struct src_rsc_ctrl_blk *)blk)->dirty.bf.czbfs = (clear ? 1 : 0);
340 return 0;
341}
342
343static int src_set_dirty(void *blk, unsigned int flags)
344{
345 ((struct src_rsc_ctrl_blk *)blk)->dirty.data = (flags & 0xffff);
346 return 0;
347}
348
349static int src_set_dirty_all(void *blk)
350{
351 ((struct src_rsc_ctrl_blk *)blk)->dirty.data = ~(0x0);
352 return 0;
353}
354
355#define AR_SLOT_SIZE 4096
356#define AR_SLOT_BLOCK_SIZE 16
357#define AR_PTS_PITCH 6
358#define AR_PARAM_SRC_OFFSET 0x60
359
360static unsigned int src_param_pitch_mixer(unsigned int src_idx)
361{
362 return ((src_idx << 4) + AR_PTS_PITCH + AR_SLOT_SIZE
363 - AR_PARAM_SRC_OFFSET) % AR_SLOT_SIZE;
364
365}
366
367static int src_commit_write(struct hw *hw, unsigned int idx, void *blk)
368{
369 struct src_rsc_ctrl_blk *ctl = blk;
370 int i;
371
372 if (ctl->dirty.bf.czbfs) {
373 /* Clear Z-Buffer registers */
374 for (i = 0; i < 8; i++)
375 hw_write_20kx(hw, SRC_UPZ+idx*0x100+i*0x4, 0);
376
377 for (i = 0; i < 4; i++)
378 hw_write_20kx(hw, SRC_DN0Z+idx*0x100+i*0x4, 0);
379
380 for (i = 0; i < 8; i++)
381 hw_write_20kx(hw, SRC_DN1Z+idx*0x100+i*0x4, 0);
382
383 ctl->dirty.bf.czbfs = 0;
384 }
385 if (ctl->dirty.bf.mpr) {
386 /* Take the parameter mixer resource in the same group as that
387 * the idx src is in for simplicity. Unlike src, all conjugate
388 * parameter mixer resources must be programmed for
389 * corresponding conjugate src resources. */
390 unsigned int pm_idx = src_param_pitch_mixer(idx);
391 hw_write_20kx(hw, MIXER_PRING_LO_HI+4*pm_idx, ctl->mpr);
392 hw_write_20kx(hw, MIXER_PMOPLO+8*pm_idx, 0x3);
393 hw_write_20kx(hw, MIXER_PMOPHI+8*pm_idx, 0x0);
394 ctl->dirty.bf.mpr = 0;
395 }
396 if (ctl->dirty.bf.sa) {
397 hw_write_20kx(hw, SRC_SA+idx*0x100, ctl->sa);
398 ctl->dirty.bf.sa = 0;
399 }
400 if (ctl->dirty.bf.la) {
401 hw_write_20kx(hw, SRC_LA+idx*0x100, ctl->la);
402 ctl->dirty.bf.la = 0;
403 }
404 if (ctl->dirty.bf.ca) {
405 hw_write_20kx(hw, SRC_CA+idx*0x100, ctl->ca);
406 ctl->dirty.bf.ca = 0;
407 }
408
409 /* Write srccf register */
410 hw_write_20kx(hw, SRC_CF+idx*0x100, 0x0);
411
412 if (ctl->dirty.bf.ccr) {
413 hw_write_20kx(hw, SRC_CCR+idx*0x100, ctl->ccr);
414 ctl->dirty.bf.ccr = 0;
415 }
416 if (ctl->dirty.bf.ctl) {
417 hw_write_20kx(hw, SRC_CTL+idx*0x100, ctl->ctl);
418 ctl->dirty.bf.ctl = 0;
419 }
420
421 return 0;
422}
423
424static int src_get_ca(struct hw *hw, unsigned int idx, void *blk)
425{
426 struct src_rsc_ctrl_blk *ctl = blk;
427
428 ctl->ca = hw_read_20kx(hw, SRC_CA+idx*0x100);
429 ctl->dirty.bf.ca = 0;
430
431 return get_field(ctl->ca, SRCCA_CA);
432}
433
434static unsigned int src_get_dirty(void *blk)
435{
436 return ((struct src_rsc_ctrl_blk *)blk)->dirty.data;
437}
438
439static unsigned int src_dirty_conj_mask(void)
440{
441 return 0x20;
442}
443
444static int src_mgr_enbs_src(void *blk, unsigned int idx)
445{
446 ((struct src_mgr_ctrl_blk *)blk)->enbsa |= (0x1 << ((idx%128)/4));
447 ((struct src_mgr_ctrl_blk *)blk)->dirty.bf.enbsa = 1;
448 ((struct src_mgr_ctrl_blk *)blk)->enb[idx/32] |= (0x1 << (idx%32));
449 return 0;
450}
451
452static int src_mgr_enb_src(void *blk, unsigned int idx)
453{
454 ((struct src_mgr_ctrl_blk *)blk)->enb[idx/32] |= (0x1 << (idx%32));
455 ((struct src_mgr_ctrl_blk *)blk)->dirty.data |= (0x1 << (idx/32));
456 return 0;
457}
458
459static int src_mgr_dsb_src(void *blk, unsigned int idx)
460{
461 ((struct src_mgr_ctrl_blk *)blk)->enb[idx/32] &= ~(0x1 << (idx%32));
462 ((struct src_mgr_ctrl_blk *)blk)->dirty.data |= (0x1 << (idx/32));
463 return 0;
464}
465
466static int src_mgr_commit_write(struct hw *hw, void *blk)
467{
468 struct src_mgr_ctrl_blk *ctl = blk;
469 int i;
470 unsigned int ret;
471
472 if (ctl->dirty.bf.enbsa) {
473 do {
474 ret = hw_read_20kx(hw, SRC_ENBSTAT);
475 } while (ret & 0x1);
476 hw_write_20kx(hw, SRC_ENBSA, ctl->enbsa);
477 ctl->dirty.bf.enbsa = 0;
478 }
479 for (i = 0; i < 8; i++) {
480 if ((ctl->dirty.data & (0x1 << i))) {
481 hw_write_20kx(hw, SRC_ENB+(i*0x100), ctl->enb[i]);
482 ctl->dirty.data &= ~(0x1 << i);
483 }
484 }
485
486 return 0;
487}
488
489static int src_mgr_get_ctrl_blk(void **rblk)
490{
491 struct src_mgr_ctrl_blk *blk;
492
493 *rblk = NULL;
494 blk = kzalloc(sizeof(*blk), GFP_KERNEL);
495 if (NULL == blk)
496 return -ENOMEM;
497
498 *rblk = blk;
499
500 return 0;
501}
502
503static int src_mgr_put_ctrl_blk(void *blk)
504{
505 kfree(blk);
506
507 return 0;
508}
509
510static int srcimp_mgr_get_ctrl_blk(void **rblk)
511{
512 struct srcimp_mgr_ctrl_blk *blk;
513
514 *rblk = NULL;
515 blk = kzalloc(sizeof(*blk), GFP_KERNEL);
516 if (NULL == blk)
517 return -ENOMEM;
518
519 *rblk = blk;
520
521 return 0;
522}
523
524static int srcimp_mgr_put_ctrl_blk(void *blk)
525{
526 kfree(blk);
527
528 return 0;
529}
530
531static int srcimp_mgr_set_imaparc(void *blk, unsigned int slot)
532{
533 struct srcimp_mgr_ctrl_blk *ctl = blk;
534
535 set_field(&ctl->srcimap.srcaim, SRCAIM_ARC, slot);
536 ctl->dirty.bf.srcimap = 1;
537 return 0;
538}
539
540static int srcimp_mgr_set_imapuser(void *blk, unsigned int user)
541{
542 struct srcimp_mgr_ctrl_blk *ctl = blk;
543
544 set_field(&ctl->srcimap.srcaim, SRCAIM_SRC, user);
545 ctl->dirty.bf.srcimap = 1;
546 return 0;
547}
548
549static int srcimp_mgr_set_imapnxt(void *blk, unsigned int next)
550{
551 struct srcimp_mgr_ctrl_blk *ctl = blk;
552
553 set_field(&ctl->srcimap.srcaim, SRCAIM_NXT, next);
554 ctl->dirty.bf.srcimap = 1;
555 return 0;
556}
557
558static int srcimp_mgr_set_imapaddr(void *blk, unsigned int addr)
559{
560 ((struct srcimp_mgr_ctrl_blk *)blk)->srcimap.idx = addr;
561 ((struct srcimp_mgr_ctrl_blk *)blk)->dirty.bf.srcimap = 1;
562 return 0;
563}
564
565static int srcimp_mgr_commit_write(struct hw *hw, void *blk)
566{
567 struct srcimp_mgr_ctrl_blk *ctl = blk;
568
569 if (ctl->dirty.bf.srcimap) {
570 hw_write_20kx(hw, SRC_IMAP+ctl->srcimap.idx*0x100,
571 ctl->srcimap.srcaim);
572 ctl->dirty.bf.srcimap = 0;
573 }
574
575 return 0;
576}
577
578/*
579 * AMIXER control block definitions.
580 */
581
582#define AMOPLO_M 0x00000003
583#define AMOPLO_IV 0x00000004
584#define AMOPLO_X 0x0003FFF0
585#define AMOPLO_Y 0xFFFC0000
586
587#define AMOPHI_SADR 0x000000FF
588#define AMOPHI_SE 0x80000000
589
590/* AMIXER resource register dirty flags */
591union amixer_dirty {
592 struct {
593 u16 amoplo:1;
594 u16 amophi:1;
595 u16 rsv:14;
596 } bf;
597 u16 data;
598};
599
600/* AMIXER resource control block */
601struct amixer_rsc_ctrl_blk {
602 unsigned int amoplo;
603 unsigned int amophi;
604 union amixer_dirty dirty;
605};
606
607static int amixer_set_mode(void *blk, unsigned int mode)
608{
609 struct amixer_rsc_ctrl_blk *ctl = blk;
610
611 set_field(&ctl->amoplo, AMOPLO_M, mode);
612 ctl->dirty.bf.amoplo = 1;
613 return 0;
614}
615
616static int amixer_set_iv(void *blk, unsigned int iv)
617{
618 struct amixer_rsc_ctrl_blk *ctl = blk;
619
620 set_field(&ctl->amoplo, AMOPLO_IV, iv);
621 ctl->dirty.bf.amoplo = 1;
622 return 0;
623}
624
625static int amixer_set_x(void *blk, unsigned int x)
626{
627 struct amixer_rsc_ctrl_blk *ctl = blk;
628
629 set_field(&ctl->amoplo, AMOPLO_X, x);
630 ctl->dirty.bf.amoplo = 1;
631 return 0;
632}
633
634static int amixer_set_y(void *blk, unsigned int y)
635{
636 struct amixer_rsc_ctrl_blk *ctl = blk;
637
638 set_field(&ctl->amoplo, AMOPLO_Y, y);
639 ctl->dirty.bf.amoplo = 1;
640 return 0;
641}
642
643static int amixer_set_sadr(void *blk, unsigned int sadr)
644{
645 struct amixer_rsc_ctrl_blk *ctl = blk;
646
647 set_field(&ctl->amophi, AMOPHI_SADR, sadr);
648 ctl->dirty.bf.amophi = 1;
649 return 0;
650}
651
652static int amixer_set_se(void *blk, unsigned int se)
653{
654 struct amixer_rsc_ctrl_blk *ctl = blk;
655
656 set_field(&ctl->amophi, AMOPHI_SE, se);
657 ctl->dirty.bf.amophi = 1;
658 return 0;
659}
660
661static int amixer_set_dirty(void *blk, unsigned int flags)
662{
663 ((struct amixer_rsc_ctrl_blk *)blk)->dirty.data = (flags & 0xffff);
664 return 0;
665}
666
667static int amixer_set_dirty_all(void *blk)
668{
669 ((struct amixer_rsc_ctrl_blk *)blk)->dirty.data = ~(0x0);
670 return 0;
671}
672
673static int amixer_commit_write(struct hw *hw, unsigned int idx, void *blk)
674{
675 struct amixer_rsc_ctrl_blk *ctl = blk;
676
677 if (ctl->dirty.bf.amoplo || ctl->dirty.bf.amophi) {
678 hw_write_20kx(hw, MIXER_AMOPLO+idx*8, ctl->amoplo);
679 ctl->dirty.bf.amoplo = 0;
680 hw_write_20kx(hw, MIXER_AMOPHI+idx*8, ctl->amophi);
681 ctl->dirty.bf.amophi = 0;
682 }
683
684 return 0;
685}
686
687static int amixer_get_y(void *blk)
688{
689 struct amixer_rsc_ctrl_blk *ctl = blk;
690
691 return get_field(ctl->amoplo, AMOPLO_Y);
692}
693
694static unsigned int amixer_get_dirty(void *blk)
695{
696 return ((struct amixer_rsc_ctrl_blk *)blk)->dirty.data;
697}
698
699static int amixer_rsc_get_ctrl_blk(void **rblk)
700{
701 struct amixer_rsc_ctrl_blk *blk;
702
703 *rblk = NULL;
704 blk = kzalloc(sizeof(*blk), GFP_KERNEL);
705 if (NULL == blk)
706 return -ENOMEM;
707
708 *rblk = blk;
709
710 return 0;
711}
712
713static int amixer_rsc_put_ctrl_blk(void *blk)
714{
715 kfree(blk);
716
717 return 0;
718}
719
720static int amixer_mgr_get_ctrl_blk(void **rblk)
721{
722 *rblk = NULL;
723
724 return 0;
725}
726
727static int amixer_mgr_put_ctrl_blk(void *blk)
728{
729 return 0;
730}
731
732/*
733 * DAIO control block definitions.
734 */
735
736/* Receiver Sample Rate Tracker Control register */
737#define SRTCTL_SRCO 0x000000FF
738#define SRTCTL_SRCM 0x0000FF00
739#define SRTCTL_RSR 0x00030000
740#define SRTCTL_DRAT 0x00300000
741#define SRTCTL_EC 0x01000000
742#define SRTCTL_ET 0x10000000
743
744/* DAIO Receiver register dirty flags */
745union dai_dirty {
746 struct {
747 u16 srt:1;
748 u16 rsv:15;
749 } bf;
750 u16 data;
751};
752
753/* DAIO Receiver control block */
754struct dai_ctrl_blk {
755 unsigned int srt;
756 union dai_dirty dirty;
757};
758
759/* Audio Input Mapper RAM */
760#define AIM_ARC 0x00000FFF
761#define AIM_NXT 0x007F0000
762
763struct daoimap {
764 unsigned int aim;
765 unsigned int idx;
766};
767
768/* Audio Transmitter Control and Status register */
769#define ATXCTL_EN 0x00000001
770#define ATXCTL_MODE 0x00000010
771#define ATXCTL_CD 0x00000020
772#define ATXCTL_RAW 0x00000100
773#define ATXCTL_MT 0x00000200
774#define ATXCTL_NUC 0x00003000
775#define ATXCTL_BEN 0x00010000
776#define ATXCTL_BMUX 0x00700000
777#define ATXCTL_B24 0x01000000
778#define ATXCTL_CPF 0x02000000
779#define ATXCTL_RIV 0x10000000
780#define ATXCTL_LIV 0x20000000
781#define ATXCTL_RSAT 0x40000000
782#define ATXCTL_LSAT 0x80000000
783
784/* XDIF Transmitter register dirty flags */
785union dao_dirty {
786 struct {
787 u16 atxcsl:1;
788 u16 rsv:15;
789 } bf;
790 u16 data;
791};
792
793/* XDIF Transmitter control block */
794struct dao_ctrl_blk {
795 /* XDIF Transmitter Channel Status Low Register */
796 unsigned int atxcsl;
797 union dao_dirty dirty;
798};
799
800/* Audio Receiver Control register */
801#define ARXCTL_EN 0x00000001
802
803/* DAIO manager register dirty flags */
804union daio_mgr_dirty {
805 struct {
806 u32 atxctl:8;
807 u32 arxctl:8;
808 u32 daoimap:1;
809 u32 rsv:15;
810 } bf;
811 u32 data;
812};
813
814/* DAIO manager control block */
815struct daio_mgr_ctrl_blk {
816 struct daoimap daoimap;
817 unsigned int txctl[8];
818 unsigned int rxctl[8];
819 union daio_mgr_dirty dirty;
820};
821
822static int dai_srt_set_srco(void *blk, unsigned int src)
823{
824 struct dai_ctrl_blk *ctl = blk;
825
826 set_field(&ctl->srt, SRTCTL_SRCO, src);
827 ctl->dirty.bf.srt = 1;
828 return 0;
829}
830
831static int dai_srt_set_srcm(void *blk, unsigned int src)
832{
833 struct dai_ctrl_blk *ctl = blk;
834
835 set_field(&ctl->srt, SRTCTL_SRCM, src);
836 ctl->dirty.bf.srt = 1;
837 return 0;
838}
839
840static int dai_srt_set_rsr(void *blk, unsigned int rsr)
841{
842 struct dai_ctrl_blk *ctl = blk;
843
844 set_field(&ctl->srt, SRTCTL_RSR, rsr);
845 ctl->dirty.bf.srt = 1;
846 return 0;
847}
848
849static int dai_srt_set_drat(void *blk, unsigned int drat)
850{
851 struct dai_ctrl_blk *ctl = blk;
852
853 set_field(&ctl->srt, SRTCTL_DRAT, drat);
854 ctl->dirty.bf.srt = 1;
855 return 0;
856}
857
858static int dai_srt_set_ec(void *blk, unsigned int ec)
859{
860 struct dai_ctrl_blk *ctl = blk;
861
862 set_field(&ctl->srt, SRTCTL_EC, ec ? 1 : 0);
863 ctl->dirty.bf.srt = 1;
864 return 0;
865}
866
867static int dai_srt_set_et(void *blk, unsigned int et)
868{
869 struct dai_ctrl_blk *ctl = blk;
870
871 set_field(&ctl->srt, SRTCTL_ET, et ? 1 : 0);
872 ctl->dirty.bf.srt = 1;
873 return 0;
874}
875
876static int dai_commit_write(struct hw *hw, unsigned int idx, void *blk)
877{
878 struct dai_ctrl_blk *ctl = blk;
879
880 if (ctl->dirty.bf.srt) {
881 hw_write_20kx(hw, AUDIO_IO_RX_SRT_CTL+0x40*idx, ctl->srt);
882 ctl->dirty.bf.srt = 0;
883 }
884
885 return 0;
886}
887
888static int dai_get_ctrl_blk(void **rblk)
889{
890 struct dai_ctrl_blk *blk;
891
892 *rblk = NULL;
893 blk = kzalloc(sizeof(*blk), GFP_KERNEL);
894 if (NULL == blk)
895 return -ENOMEM;
896
897 *rblk = blk;
898
899 return 0;
900}
901
902static int dai_put_ctrl_blk(void *blk)
903{
904 kfree(blk);
905
906 return 0;
907}
908
909static int dao_set_spos(void *blk, unsigned int spos)
910{
911 ((struct dao_ctrl_blk *)blk)->atxcsl = spos;
912 ((struct dao_ctrl_blk *)blk)->dirty.bf.atxcsl = 1;
913 return 0;
914}
915
916static int dao_commit_write(struct hw *hw, unsigned int idx, void *blk)
917{
918 struct dao_ctrl_blk *ctl = blk;
919
920 if (ctl->dirty.bf.atxcsl) {
921 if (idx < 4) {
922 /* S/PDIF SPOSx */
923 hw_write_20kx(hw, AUDIO_IO_TX_CSTAT_L+0x40*idx,
924 ctl->atxcsl);
925 }
926 ctl->dirty.bf.atxcsl = 0;
927 }
928
929 return 0;
930}
931
932static int dao_get_spos(void *blk, unsigned int *spos)
933{
934 *spos = ((struct dao_ctrl_blk *)blk)->atxcsl;
935 return 0;
936}
937
938static int dao_get_ctrl_blk(void **rblk)
939{
940 struct dao_ctrl_blk *blk;
941
942 *rblk = NULL;
943 blk = kzalloc(sizeof(*blk), GFP_KERNEL);
944 if (NULL == blk)
945 return -ENOMEM;
946
947 *rblk = blk;
948
949 return 0;
950}
951
952static int dao_put_ctrl_blk(void *blk)
953{
954 kfree(blk);
955
956 return 0;
957}
958
959static int daio_mgr_enb_dai(void *blk, unsigned int idx)
960{
961 struct daio_mgr_ctrl_blk *ctl = blk;
962
963 set_field(&ctl->rxctl[idx], ARXCTL_EN, 1);
964 ctl->dirty.bf.arxctl |= (0x1 << idx);
965 return 0;
966}
967
968static int daio_mgr_dsb_dai(void *blk, unsigned int idx)
969{
970 struct daio_mgr_ctrl_blk *ctl = blk;
971
972 set_field(&ctl->rxctl[idx], ARXCTL_EN, 0);
973
974 ctl->dirty.bf.arxctl |= (0x1 << idx);
975 return 0;
976}
977
978static int daio_mgr_enb_dao(void *blk, unsigned int idx)
979{
980 struct daio_mgr_ctrl_blk *ctl = blk;
981
982 set_field(&ctl->txctl[idx], ATXCTL_EN, 1);
983 ctl->dirty.bf.atxctl |= (0x1 << idx);
984 return 0;
985}
986
987static int daio_mgr_dsb_dao(void *blk, unsigned int idx)
988{
989 struct daio_mgr_ctrl_blk *ctl = blk;
990
991 set_field(&ctl->txctl[idx], ATXCTL_EN, 0);
992 ctl->dirty.bf.atxctl |= (0x1 << idx);
993 return 0;
994}
995
996static int daio_mgr_dao_init(void *blk, unsigned int idx, unsigned int conf)
997{
998 struct daio_mgr_ctrl_blk *ctl = blk;
999
1000 if (idx < 4) {
1001 /* S/PDIF output */
1002 switch ((conf & 0x7)) {
1003 case 1:
1004 set_field(&ctl->txctl[idx], ATXCTL_NUC, 0);
1005 break;
1006 case 2:
1007 set_field(&ctl->txctl[idx], ATXCTL_NUC, 1);
1008 break;
1009 case 4:
1010 set_field(&ctl->txctl[idx], ATXCTL_NUC, 2);
1011 break;
1012 case 8:
1013 set_field(&ctl->txctl[idx], ATXCTL_NUC, 3);
1014 break;
1015 default:
1016 break;
1017 }
1018 /* CDIF */
1019 set_field(&ctl->txctl[idx], ATXCTL_CD, (!(conf & 0x7)));
1020 /* Non-audio */
1021 set_field(&ctl->txctl[idx], ATXCTL_LIV, (conf >> 4) & 0x1);
1022 /* Non-audio */
1023 set_field(&ctl->txctl[idx], ATXCTL_RIV, (conf >> 4) & 0x1);
1024 set_field(&ctl->txctl[idx], ATXCTL_RAW,
1025 ((conf >> 3) & 0x1) ? 0 : 0);
1026 ctl->dirty.bf.atxctl |= (0x1 << idx);
1027 } else {
1028 /* I2S output */
1029 /*idx %= 4; */
1030 }
1031 return 0;
1032}
1033
1034static int daio_mgr_set_imaparc(void *blk, unsigned int slot)
1035{
1036 struct daio_mgr_ctrl_blk *ctl = blk;
1037
1038 set_field(&ctl->daoimap.aim, AIM_ARC, slot);
1039 ctl->dirty.bf.daoimap = 1;
1040 return 0;
1041}
1042
1043static int daio_mgr_set_imapnxt(void *blk, unsigned int next)
1044{
1045 struct daio_mgr_ctrl_blk *ctl = blk;
1046
1047 set_field(&ctl->daoimap.aim, AIM_NXT, next);
1048 ctl->dirty.bf.daoimap = 1;
1049 return 0;
1050}
1051
1052static int daio_mgr_set_imapaddr(void *blk, unsigned int addr)
1053{
1054 ((struct daio_mgr_ctrl_blk *)blk)->daoimap.idx = addr;
1055 ((struct daio_mgr_ctrl_blk *)blk)->dirty.bf.daoimap = 1;
1056 return 0;
1057}
1058
1059static int daio_mgr_commit_write(struct hw *hw, void *blk)
1060{
1061 struct daio_mgr_ctrl_blk *ctl = blk;
1062 unsigned int data;
1063 int i;
1064
1065 for (i = 0; i < 8; i++) {
1066 if ((ctl->dirty.bf.atxctl & (0x1 << i))) {
1067 data = ctl->txctl[i];
1068 hw_write_20kx(hw, (AUDIO_IO_TX_CTL+(0x40*i)), data);
1069 ctl->dirty.bf.atxctl &= ~(0x1 << i);
1070 mdelay(1);
1071 }
1072 if ((ctl->dirty.bf.arxctl & (0x1 << i))) {
1073 data = ctl->rxctl[i];
1074 hw_write_20kx(hw, (AUDIO_IO_RX_CTL+(0x40*i)), data);
1075 ctl->dirty.bf.arxctl &= ~(0x1 << i);
1076 mdelay(1);
1077 }
1078 }
1079 if (ctl->dirty.bf.daoimap) {
1080 hw_write_20kx(hw, AUDIO_IO_AIM+ctl->daoimap.idx*4,
1081 ctl->daoimap.aim);
1082 ctl->dirty.bf.daoimap = 0;
1083 }
1084
1085 return 0;
1086}
1087
1088static int daio_mgr_get_ctrl_blk(struct hw *hw, void **rblk)
1089{
1090 struct daio_mgr_ctrl_blk *blk;
1091 int i;
1092
1093 *rblk = NULL;
1094 blk = kzalloc(sizeof(*blk), GFP_KERNEL);
1095 if (NULL == blk)
1096 return -ENOMEM;
1097
1098 for (i = 0; i < 8; i++) {
1099 blk->txctl[i] = hw_read_20kx(hw, AUDIO_IO_TX_CTL+(0x40*i));
1100 blk->rxctl[i] = hw_read_20kx(hw, AUDIO_IO_RX_CTL+(0x40*i));
1101 }
1102
1103 *rblk = blk;
1104
1105 return 0;
1106}
1107
1108static int daio_mgr_put_ctrl_blk(void *blk)
1109{
1110 kfree(blk);
1111
1112 return 0;
1113}
1114
1115/* Card hardware initialization block */
1116struct dac_conf {
1117 unsigned int msr; /* master sample rate in rsrs */
1118};
1119
1120struct adc_conf {
1121 unsigned int msr; /* master sample rate in rsrs */
1122 unsigned char input; /* the input source of ADC */
1123 unsigned char mic20db; /* boost mic by 20db if input is microphone */
1124};
1125
1126struct daio_conf {
1127 unsigned int msr; /* master sample rate in rsrs */
1128};
1129
1130struct trn_conf {
1131 unsigned long vm_pgt_phys;
1132};
1133
1134static int hw_daio_init(struct hw *hw, const struct daio_conf *info)
1135{
1136 u32 data;
1137 int i;
1138
1139 /* Program I2S with proper sample rate and enable the correct I2S
1140 * channel. ED(0/8/16/24): Enable all I2S/I2X master clock output */
1141 if (1 == info->msr) {
1142 hw_write_20kx(hw, AUDIO_IO_MCLK, 0x01010101);
1143 hw_write_20kx(hw, AUDIO_IO_TX_BLRCLK, 0x01010101);
1144 hw_write_20kx(hw, AUDIO_IO_RX_BLRCLK, 0);
1145 } else if (2 == info->msr) {
1146 hw_write_20kx(hw, AUDIO_IO_MCLK, 0x11111111);
1147 /* Specify all playing 96khz
1148 * EA [0] - Enabled
1149 * RTA [4:5] - 96kHz
1150 * EB [8] - Enabled
1151 * RTB [12:13] - 96kHz
1152 * EC [16] - Enabled
1153 * RTC [20:21] - 96kHz
1154 * ED [24] - Enabled
1155 * RTD [28:29] - 96kHz */
1156 hw_write_20kx(hw, AUDIO_IO_TX_BLRCLK, 0x11111111);
1157 hw_write_20kx(hw, AUDIO_IO_RX_BLRCLK, 0);
1158 } else {
1159 printk(KERN_ALERT "ctxfi: ERROR!!! Invalid sampling rate!!!\n");
1160 return -EINVAL;
1161 }
1162
1163 for (i = 0; i < 8; i++) {
1164 if (i <= 3) {
1165 /* 1st 3 channels are SPDIFs (SB0960) */
1166 if (i == 3)
1167 data = 0x1001001;
1168 else
1169 data = 0x1000001;
1170
1171 hw_write_20kx(hw, (AUDIO_IO_TX_CTL+(0x40*i)), data);
1172 hw_write_20kx(hw, (AUDIO_IO_RX_CTL+(0x40*i)), data);
1173
1174 /* Initialize the SPDIF Out Channel status registers.
1175 * The value specified here is based on the typical
1176 * values provided in the specification, namely: Clock
1177 * Accuracy of 1000ppm, Sample Rate of 48KHz,
1178 * unspecified source number, Generation status = 1,
1179 * Category code = 0x12 (Digital Signal Mixer),
1180 * Mode = 0, Emph = 0, Copy Permitted, AN = 0
1181 * (indicating that we're transmitting digital audio,
1182 * and the Professional Use bit is 0. */
1183
1184 hw_write_20kx(hw, AUDIO_IO_TX_CSTAT_L+(0x40*i),
1185 0x02109204); /* Default to 48kHz */
1186
1187 hw_write_20kx(hw, AUDIO_IO_TX_CSTAT_H+(0x40*i), 0x0B);
1188 } else {
1189 /* Next 5 channels are I2S (SB0960) */
1190 data = 0x11;
1191 hw_write_20kx(hw, AUDIO_IO_RX_CTL+(0x40*i), data);
1192 if (2 == info->msr) {
1193 /* Four channels per sample period */
1194 data |= 0x1000;
1195 }
1196 hw_write_20kx(hw, AUDIO_IO_TX_CTL+(0x40*i), data);
1197 }
1198 }
1199
1200 return 0;
1201}
1202
1203/* TRANSPORT operations */
1204static int hw_trn_init(struct hw *hw, const struct trn_conf *info)
1205{
1206 u32 vmctl, data;
1207 u32 ptp_phys_low, ptp_phys_high;
1208 int i;
1209
1210 /* Set up device page table */
1211 if ((~0UL) == info->vm_pgt_phys) {
1212 printk(KERN_ALERT "ctxfi: "
1213 "Wrong device page table page address!!!\n");
1214 return -1;
1215 }
1216
1217 vmctl = 0x80000C0F; /* 32-bit, 4k-size page */
1218 ptp_phys_low = (u32)info->vm_pgt_phys;
1219 ptp_phys_high = upper_32_bits(info->vm_pgt_phys);
1220 if (sizeof(void *) == 8) /* 64bit address */
1221 vmctl |= (3 << 8);
1222 /* Write page table physical address to all PTPAL registers */
1223 for (i = 0; i < 64; i++) {
1224 hw_write_20kx(hw, VMEM_PTPAL+(16*i), ptp_phys_low);
1225 hw_write_20kx(hw, VMEM_PTPAH+(16*i), ptp_phys_high);
1226 }
1227 /* Enable virtual memory transfer */
1228 hw_write_20kx(hw, VMEM_CTL, vmctl);
1229 /* Enable transport bus master and queueing of request */
1230 hw_write_20kx(hw, TRANSPORT_CTL, 0x03);
1231 hw_write_20kx(hw, TRANSPORT_INT, 0x200c01);
1232 /* Enable transport ring */
1233 data = hw_read_20kx(hw, TRANSPORT_ENB);
1234 hw_write_20kx(hw, TRANSPORT_ENB, (data | 0x03));
1235
1236 return 0;
1237}
1238
1239/* Card initialization */
1240#define GCTL_AIE 0x00000001
1241#define GCTL_UAA 0x00000002
1242#define GCTL_DPC 0x00000004
1243#define GCTL_DBP 0x00000008
1244#define GCTL_ABP 0x00000010
1245#define GCTL_TBP 0x00000020
1246#define GCTL_SBP 0x00000040
1247#define GCTL_FBP 0x00000080
1248#define GCTL_ME 0x00000100
1249#define GCTL_AID 0x00001000
1250
1251#define PLLCTL_SRC 0x00000007
1252#define PLLCTL_SPE 0x00000008
1253#define PLLCTL_RD 0x000000F0
1254#define PLLCTL_FD 0x0001FF00
1255#define PLLCTL_OD 0x00060000
1256#define PLLCTL_B 0x00080000
1257#define PLLCTL_AS 0x00100000
1258#define PLLCTL_LF 0x03E00000
1259#define PLLCTL_SPS 0x1C000000
1260#define PLLCTL_AD 0x60000000
1261
1262#define PLLSTAT_CCS 0x00000007
1263#define PLLSTAT_SPL 0x00000008
1264#define PLLSTAT_CRD 0x000000F0
1265#define PLLSTAT_CFD 0x0001FF00
1266#define PLLSTAT_SL 0x00020000
1267#define PLLSTAT_FAS 0x00040000
1268#define PLLSTAT_B 0x00080000
1269#define PLLSTAT_PD 0x00100000
1270#define PLLSTAT_OCA 0x00200000
1271#define PLLSTAT_NCA 0x00400000
1272
1273static int hw_pll_init(struct hw *hw, unsigned int rsr)
1274{
1275 unsigned int pllenb;
1276 unsigned int pllctl;
1277 unsigned int pllstat;
1278 int i;
1279
1280 pllenb = 0xB;
1281 hw_write_20kx(hw, PLL_ENB, pllenb);
1282 pllctl = 0x20D00000;
1283 set_field(&pllctl, PLLCTL_FD, 16 - 4);
1284 hw_write_20kx(hw, PLL_CTL, pllctl);
1285 mdelay(40);
1286 pllctl = hw_read_20kx(hw, PLL_CTL);
1287 set_field(&pllctl, PLLCTL_B, 0);
1288 if (48000 == rsr) {
1289 set_field(&pllctl, PLLCTL_FD, 16 - 2);
1290 set_field(&pllctl, PLLCTL_RD, 1 - 1);
1291 } else { /* 44100 */
1292 set_field(&pllctl, PLLCTL_FD, 147 - 2);
1293 set_field(&pllctl, PLLCTL_RD, 10 - 1);
1294 }
1295 hw_write_20kx(hw, PLL_CTL, pllctl);
1296 mdelay(40);
1297 for (i = 0; i < 1000; i++) {
1298 pllstat = hw_read_20kx(hw, PLL_STAT);
1299 if (get_field(pllstat, PLLSTAT_PD))
1300 continue;
1301
1302 if (get_field(pllstat, PLLSTAT_B) !=
1303 get_field(pllctl, PLLCTL_B))
1304 continue;
1305
1306 if (get_field(pllstat, PLLSTAT_CCS) !=
1307 get_field(pllctl, PLLCTL_SRC))
1308 continue;
1309
1310 if (get_field(pllstat, PLLSTAT_CRD) !=
1311 get_field(pllctl, PLLCTL_RD))
1312 continue;
1313
1314 if (get_field(pllstat, PLLSTAT_CFD) !=
1315 get_field(pllctl, PLLCTL_FD))
1316 continue;
1317
1318 break;
1319 }
1320 if (i >= 1000) {
1321 printk(KERN_ALERT "ctxfi: PLL initialization failed!!!\n");
1322 return -EBUSY;
1323 }
1324
1325 return 0;
1326}
1327
1328static int hw_auto_init(struct hw *hw)
1329{
1330 unsigned int gctl;
1331 int i;
1332
1333 gctl = hw_read_20kx(hw, GLOBAL_CNTL_GCTL);
1334 set_field(&gctl, GCTL_AIE, 0);
1335 hw_write_20kx(hw, GLOBAL_CNTL_GCTL, gctl);
1336 set_field(&gctl, GCTL_AIE, 1);
1337 hw_write_20kx(hw, GLOBAL_CNTL_GCTL, gctl);
1338 mdelay(10);
1339 for (i = 0; i < 400000; i++) {
1340 gctl = hw_read_20kx(hw, GLOBAL_CNTL_GCTL);
1341 if (get_field(gctl, GCTL_AID))
1342 break;
1343 }
1344 if (!get_field(gctl, GCTL_AID)) {
1345 printk(KERN_ALERT "ctxfi: Card Auto-init failed!!!\n");
1346 return -EBUSY;
1347 }
1348
1349 return 0;
1350}
1351
1352/* DAC operations */
1353
1354#define CS4382_MC1 0x1
1355#define CS4382_MC2 0x2
1356#define CS4382_MC3 0x3
1357#define CS4382_FC 0x4
1358#define CS4382_IC 0x5
1359#define CS4382_XC1 0x6
1360#define CS4382_VCA1 0x7
1361#define CS4382_VCB1 0x8
1362#define CS4382_XC2 0x9
1363#define CS4382_VCA2 0xA
1364#define CS4382_VCB2 0xB
1365#define CS4382_XC3 0xC
1366#define CS4382_VCA3 0xD
1367#define CS4382_VCB3 0xE
1368#define CS4382_XC4 0xF
1369#define CS4382_VCA4 0x10
1370#define CS4382_VCB4 0x11
1371#define CS4382_CREV 0x12
1372
1373/* I2C status */
1374#define STATE_LOCKED 0x00
1375#define STATE_UNLOCKED 0xAA
1376#define DATA_READY 0x800000 /* Used with I2C_IF_STATUS */
1377#define DATA_ABORT 0x10000 /* Used with I2C_IF_STATUS */
1378
1379#define I2C_STATUS_DCM 0x00000001
1380#define I2C_STATUS_BC 0x00000006
1381#define I2C_STATUS_APD 0x00000008
1382#define I2C_STATUS_AB 0x00010000
1383#define I2C_STATUS_DR 0x00800000
1384
1385#define I2C_ADDRESS_PTAD 0x0000FFFF
1386#define I2C_ADDRESS_SLAD 0x007F0000
1387
1388struct regs_cs4382 {
1389 u32 mode_control_1;
1390 u32 mode_control_2;
1391 u32 mode_control_3;
1392
1393 u32 filter_control;
1394 u32 invert_control;
1395
1396 u32 mix_control_P1;
1397 u32 vol_control_A1;
1398 u32 vol_control_B1;
1399
1400 u32 mix_control_P2;
1401 u32 vol_control_A2;
1402 u32 vol_control_B2;
1403
1404 u32 mix_control_P3;
1405 u32 vol_control_A3;
1406 u32 vol_control_B3;
1407
1408 u32 mix_control_P4;
1409 u32 vol_control_A4;
1410 u32 vol_control_B4;
1411};
1412
1413static int hw20k2_i2c_unlock_full_access(struct hw *hw)
1414{
1415 u8 UnlockKeySequence_FLASH_FULLACCESS_MODE[2] = {0xB3, 0xD4};
1416
1417 /* Send keys for forced BIOS mode */
1418 hw_write_20kx(hw, I2C_IF_WLOCK,
1419 UnlockKeySequence_FLASH_FULLACCESS_MODE[0]);
1420 hw_write_20kx(hw, I2C_IF_WLOCK,
1421 UnlockKeySequence_FLASH_FULLACCESS_MODE[1]);
1422 /* Check whether the chip is unlocked */
1423 if (hw_read_20kx(hw, I2C_IF_WLOCK) == STATE_UNLOCKED)
1424 return 0;
1425
1426 return -1;
1427}
1428
1429static int hw20k2_i2c_lock_chip(struct hw *hw)
1430{
1431 /* Write twice */
1432 hw_write_20kx(hw, I2C_IF_WLOCK, STATE_LOCKED);
1433 hw_write_20kx(hw, I2C_IF_WLOCK, STATE_LOCKED);
1434 if (hw_read_20kx(hw, I2C_IF_WLOCK) == STATE_LOCKED)
1435 return 0;
1436
1437 return -1;
1438}
1439
1440static int hw20k2_i2c_init(struct hw *hw, u8 dev_id, u8 addr_size, u8 data_size)
1441{
1442 struct hw20k2 *hw20k2 = (struct hw20k2 *)hw;
1443 int err;
1444 unsigned int i2c_status;
1445 unsigned int i2c_addr;
1446
1447 err = hw20k2_i2c_unlock_full_access(hw);
1448 if (err < 0)
1449 return err;
1450
1451 hw20k2->addr_size = addr_size;
1452 hw20k2->data_size = data_size;
1453 hw20k2->dev_id = dev_id;
1454
1455 i2c_addr = 0;
1456 set_field(&i2c_addr, I2C_ADDRESS_SLAD, dev_id);
1457
1458 hw_write_20kx(hw, I2C_IF_ADDRESS, i2c_addr);
1459
1460 i2c_status = hw_read_20kx(hw, I2C_IF_STATUS);
1461
1462 set_field(&i2c_status, I2C_STATUS_DCM, 1); /* Direct control mode */
1463
1464 hw_write_20kx(hw, I2C_IF_STATUS, i2c_status);
1465
1466 return 0;
1467}
1468
1469static int hw20k2_i2c_uninit(struct hw *hw)
1470{
1471 unsigned int i2c_status;
1472 unsigned int i2c_addr;
1473
1474 i2c_addr = 0;
1475 set_field(&i2c_addr, I2C_ADDRESS_SLAD, 0x57); /* I2C id */
1476
1477 hw_write_20kx(hw, I2C_IF_ADDRESS, i2c_addr);
1478
1479 i2c_status = hw_read_20kx(hw, I2C_IF_STATUS);
1480
1481 set_field(&i2c_status, I2C_STATUS_DCM, 0); /* I2C mode */
1482
1483 hw_write_20kx(hw, I2C_IF_STATUS, i2c_status);
1484
1485 return hw20k2_i2c_lock_chip(hw);
1486}
1487
1488static int hw20k2_i2c_wait_data_ready(struct hw *hw)
1489{
1490 int i = 0x400000;
1491 unsigned int ret;
1492
1493 do {
1494 ret = hw_read_20kx(hw, I2C_IF_STATUS);
1495 } while ((!(ret & DATA_READY)) && --i);
1496
1497 return i;
1498}
1499
1500static int hw20k2_i2c_read(struct hw *hw, u16 addr, u32 *datap)
1501{
1502 struct hw20k2 *hw20k2 = (struct hw20k2 *)hw;
1503 unsigned int i2c_status;
1504
1505 i2c_status = hw_read_20kx(hw, I2C_IF_STATUS);
1506 set_field(&i2c_status, I2C_STATUS_BC,
1507 (4 == hw20k2->addr_size) ? 0 : hw20k2->addr_size);
1508 hw_write_20kx(hw, I2C_IF_STATUS, i2c_status);
1509 if (!hw20k2_i2c_wait_data_ready(hw))
1510 return -1;
1511
1512 hw_write_20kx(hw, I2C_IF_WDATA, addr);
1513 if (!hw20k2_i2c_wait_data_ready(hw))
1514 return -1;
1515
1516 /* Force a read operation */
1517 hw_write_20kx(hw, I2C_IF_RDATA, 0);
1518 if (!hw20k2_i2c_wait_data_ready(hw))
1519 return -1;
1520
1521 *datap = hw_read_20kx(hw, I2C_IF_RDATA);
1522
1523 return 0;
1524}
1525
1526static int hw20k2_i2c_write(struct hw *hw, u16 addr, u32 data)
1527{
1528 struct hw20k2 *hw20k2 = (struct hw20k2 *)hw;
1529 unsigned int i2c_data = (data << (hw20k2->addr_size * 8)) | addr;
1530 unsigned int i2c_status;
1531
1532 i2c_status = hw_read_20kx(hw, I2C_IF_STATUS);
1533
1534 set_field(&i2c_status, I2C_STATUS_BC,
1535 (4 == (hw20k2->addr_size + hw20k2->data_size)) ?
1536 0 : (hw20k2->addr_size + hw20k2->data_size));
1537
1538 hw_write_20kx(hw, I2C_IF_STATUS, i2c_status);
1539 hw20k2_i2c_wait_data_ready(hw);
1540 /* Dummy write to trigger the write oprtation */
1541 hw_write_20kx(hw, I2C_IF_WDATA, 0);
1542 hw20k2_i2c_wait_data_ready(hw);
1543
1544 /* This is the real data */
1545 hw_write_20kx(hw, I2C_IF_WDATA, i2c_data);
1546 hw20k2_i2c_wait_data_ready(hw);
1547
1548 return 0;
1549}
1550
1551static int hw_dac_init(struct hw *hw, const struct dac_conf *info)
1552{
1553 int err;
1554 u32 data;
1555 int i;
1556 struct regs_cs4382 cs_read = {0};
1557 struct regs_cs4382 cs_def = {
1558 0x00000001, /* Mode Control 1 */
1559 0x00000000, /* Mode Control 2 */
1560 0x00000084, /* Mode Control 3 */
1561 0x00000000, /* Filter Control */
1562 0x00000000, /* Invert Control */
1563 0x00000024, /* Mixing Control Pair 1 */
1564 0x00000000, /* Vol Control A1 */
1565 0x00000000, /* Vol Control B1 */
1566 0x00000024, /* Mixing Control Pair 2 */
1567 0x00000000, /* Vol Control A2 */
1568 0x00000000, /* Vol Control B2 */
1569 0x00000024, /* Mixing Control Pair 3 */
1570 0x00000000, /* Vol Control A3 */
1571 0x00000000, /* Vol Control B3 */
1572 0x00000024, /* Mixing Control Pair 4 */
1573 0x00000000, /* Vol Control A4 */
1574 0x00000000 /* Vol Control B4 */
1575 };
1576
1577 /* Set DAC reset bit as output */
1578 data = hw_read_20kx(hw, GPIO_CTRL);
1579 data |= 0x02;
1580 hw_write_20kx(hw, GPIO_CTRL, data);
1581
1582 err = hw20k2_i2c_init(hw, 0x18, 1, 1);
1583 if (err < 0)
1584 goto End;
1585
1586 for (i = 0; i < 2; i++) {
1587 /* Reset DAC twice just in-case the chip
1588 * didn't initialized properly */
1589 data = hw_read_20kx(hw, GPIO_DATA);
1590 /* GPIO data bit 1 */
1591 data &= 0xFFFFFFFD;
1592 hw_write_20kx(hw, GPIO_DATA, data);
1593 mdelay(10);
1594 data |= 0x2;
1595 hw_write_20kx(hw, GPIO_DATA, data);
1596 mdelay(50);
1597
1598 /* Reset the 2nd time */
1599 data &= 0xFFFFFFFD;
1600 hw_write_20kx(hw, GPIO_DATA, data);
1601 mdelay(10);
1602 data |= 0x2;
1603 hw_write_20kx(hw, GPIO_DATA, data);
1604 mdelay(50);
1605
1606 if (hw20k2_i2c_read(hw, CS4382_MC1, &cs_read.mode_control_1))
1607 continue;
1608
1609 if (hw20k2_i2c_read(hw, CS4382_MC2, &cs_read.mode_control_2))
1610 continue;
1611
1612 if (hw20k2_i2c_read(hw, CS4382_MC3, &cs_read.mode_control_3))
1613 continue;
1614
1615 if (hw20k2_i2c_read(hw, CS4382_FC, &cs_read.filter_control))
1616 continue;
1617
1618 if (hw20k2_i2c_read(hw, CS4382_IC, &cs_read.invert_control))
1619 continue;
1620
1621 if (hw20k2_i2c_read(hw, CS4382_XC1, &cs_read.mix_control_P1))
1622 continue;
1623
1624 if (hw20k2_i2c_read(hw, CS4382_VCA1, &cs_read.vol_control_A1))
1625 continue;
1626
1627 if (hw20k2_i2c_read(hw, CS4382_VCB1, &cs_read.vol_control_B1))
1628 continue;
1629
1630 if (hw20k2_i2c_read(hw, CS4382_XC2, &cs_read.mix_control_P2))
1631 continue;
1632
1633 if (hw20k2_i2c_read(hw, CS4382_VCA2, &cs_read.vol_control_A2))
1634 continue;
1635
1636 if (hw20k2_i2c_read(hw, CS4382_VCB2, &cs_read.vol_control_B2))
1637 continue;
1638
1639 if (hw20k2_i2c_read(hw, CS4382_XC3, &cs_read.mix_control_P3))
1640 continue;
1641
1642 if (hw20k2_i2c_read(hw, CS4382_VCA3, &cs_read.vol_control_A3))
1643 continue;
1644
1645 if (hw20k2_i2c_read(hw, CS4382_VCB3, &cs_read.vol_control_B3))
1646 continue;
1647
1648 if (hw20k2_i2c_read(hw, CS4382_XC4, &cs_read.mix_control_P4))
1649 continue;
1650
1651 if (hw20k2_i2c_read(hw, CS4382_VCA4, &cs_read.vol_control_A4))
1652 continue;
1653
1654 if (hw20k2_i2c_read(hw, CS4382_VCB4, &cs_read.vol_control_B4))
1655 continue;
1656
1657 if (memcmp(&cs_read, &cs_def, sizeof(cs_read)))
1658 continue;
1659 else
1660 break;
1661 }
1662
1663 if (i >= 2)
1664 goto End;
1665
1666 /* Note: Every I2C write must have some delay.
1667 * This is not a requirement but the delay works here... */
1668 hw20k2_i2c_write(hw, CS4382_MC1, 0x80);
1669 hw20k2_i2c_write(hw, CS4382_MC2, 0x10);
1670 if (1 == info->msr) {
1671 hw20k2_i2c_write(hw, CS4382_XC1, 0x24);
1672 hw20k2_i2c_write(hw, CS4382_XC2, 0x24);
1673 hw20k2_i2c_write(hw, CS4382_XC3, 0x24);
1674 hw20k2_i2c_write(hw, CS4382_XC4, 0x24);
1675 } else if (2 == info->msr) {
1676 hw20k2_i2c_write(hw, CS4382_XC1, 0x25);
1677 hw20k2_i2c_write(hw, CS4382_XC2, 0x25);
1678 hw20k2_i2c_write(hw, CS4382_XC3, 0x25);
1679 hw20k2_i2c_write(hw, CS4382_XC4, 0x25);
1680 } else {
1681 hw20k2_i2c_write(hw, CS4382_XC1, 0x26);
1682 hw20k2_i2c_write(hw, CS4382_XC2, 0x26);
1683 hw20k2_i2c_write(hw, CS4382_XC3, 0x26);
1684 hw20k2_i2c_write(hw, CS4382_XC4, 0x26);
1685 }
1686
1687 return 0;
1688End:
1689
1690 hw20k2_i2c_uninit(hw);
1691 return -1;
1692}
1693
1694/* ADC operations */
1695#define MAKE_WM8775_ADDR(addr, data) (u32)(((addr<<1)&0xFE)|((data>>8)&0x1))
1696#define MAKE_WM8775_DATA(data) (u32)(data&0xFF)
1697
1698#define WM8775_IC 0x0B
1699#define WM8775_MMC 0x0C
1700#define WM8775_AADCL 0x0E
1701#define WM8775_AADCR 0x0F
1702#define WM8775_ADCMC 0x15
1703#define WM8775_RESET 0x17
1704
1705static int hw_is_adc_input_selected(struct hw *hw, enum ADCSRC type)
1706{
1707 u32 data;
1708
1709 data = hw_read_20kx(hw, GPIO_DATA);
1710 switch (type) {
1711 case ADC_MICIN:
1712 data = (data & (0x1 << 14)) ? 1 : 0;
1713 break;
1714 case ADC_LINEIN:
1715 data = (data & (0x1 << 14)) ? 0 : 1;
1716 break;
1717 default:
1718 data = 0;
1719 }
1720 return data;
1721}
1722
1723static int hw_adc_input_select(struct hw *hw, enum ADCSRC type)
1724{
1725 u32 data;
1726
1727 data = hw_read_20kx(hw, GPIO_DATA);
1728 switch (type) {
1729 case ADC_MICIN:
1730 data |= (0x1 << 14);
1731 hw_write_20kx(hw, GPIO_DATA, data);
1732 hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_ADCMC, 0x101),
1733 MAKE_WM8775_DATA(0x101)); /* Mic-in */
1734 hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_AADCL, 0xE7),
1735 MAKE_WM8775_DATA(0xE7)); /* +12dB boost */
1736 hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_AADCR, 0xE7),
1737 MAKE_WM8775_DATA(0xE7)); /* +12dB boost */
1738 break;
1739 case ADC_LINEIN:
1740 data &= ~(0x1 << 14);
1741 hw_write_20kx(hw, GPIO_DATA, data);
1742 hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_ADCMC, 0x102),
1743 MAKE_WM8775_DATA(0x102)); /* Line-in */
1744 hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_AADCL, 0xCF),
1745 MAKE_WM8775_DATA(0xCF)); /* No boost */
1746 hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_AADCR, 0xCF),
1747 MAKE_WM8775_DATA(0xCF)); /* No boost */
1748 break;
1749 default:
1750 break;
1751 }
1752
1753 return 0;
1754}
1755
1756static int hw_adc_init(struct hw *hw, const struct adc_conf *info)
1757{
1758 int err;
1759 u32 mux = 2, data, ctl;
1760
1761 /* Set ADC reset bit as output */
1762 data = hw_read_20kx(hw, GPIO_CTRL);
1763 data |= (0x1 << 15);
1764 hw_write_20kx(hw, GPIO_CTRL, data);
1765
1766 /* Initialize I2C */
1767 err = hw20k2_i2c_init(hw, 0x1A, 1, 1);
1768 if (err < 0) {
1769 printk(KERN_ALERT "ctxfi: Failure to acquire I2C!!!\n");
1770 goto error;
1771 }
1772
1773 /* Make ADC in normal operation */
1774 data = hw_read_20kx(hw, GPIO_DATA);
1775 data &= ~(0x1 << 15);
1776 mdelay(10);
1777 data |= (0x1 << 15);
1778 hw_write_20kx(hw, GPIO_DATA, data);
1779 mdelay(50);
1780
1781 /* Set the master mode (256fs) */
1782 if (1 == info->msr) {
1783 hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_MMC, 0x02),
1784 MAKE_WM8775_DATA(0x02));
1785 } else if (2 == info->msr) {
1786 hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_MMC, 0x0A),
1787 MAKE_WM8775_DATA(0x0A));
1788 } else {
1789 printk(KERN_ALERT "ctxfi: Invalid master sampling "
1790 "rate (msr %d)!!!\n", info->msr);
1791 err = -EINVAL;
1792 goto error;
1793 }
1794
1795 /* Configure GPIO bit 14 change to line-in/mic-in */
1796 ctl = hw_read_20kx(hw, GPIO_CTRL);
1797 ctl |= 0x1 << 14;
1798 hw_write_20kx(hw, GPIO_CTRL, ctl);
1799
1800 /* Check using Mic-in or Line-in */
1801 data = hw_read_20kx(hw, GPIO_DATA);
1802
1803 if (mux == 1) {
1804 /* Configures GPIO data to select Mic-in */
1805 data |= 0x1 << 14;
1806 hw_write_20kx(hw, GPIO_DATA, data);
1807
1808 hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_ADCMC, 0x101),
1809 MAKE_WM8775_DATA(0x101)); /* Mic-in */
1810 hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_AADCL, 0xE7),
1811 MAKE_WM8775_DATA(0xE7)); /* +12dB boost */
1812 hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_AADCR, 0xE7),
1813 MAKE_WM8775_DATA(0xE7)); /* +12dB boost */
1814 } else if (mux == 2) {
1815 /* Configures GPIO data to select Line-in */
1816 data &= ~(0x1 << 14);
1817 hw_write_20kx(hw, GPIO_DATA, data);
1818
1819 /* Setup ADC */
1820 hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_ADCMC, 0x102),
1821 MAKE_WM8775_DATA(0x102)); /* Line-in */
1822 hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_AADCL, 0xCF),
1823 MAKE_WM8775_DATA(0xCF)); /* No boost */
1824 hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_AADCR, 0xCF),
1825 MAKE_WM8775_DATA(0xCF)); /* No boost */
1826 } else {
1827 printk(KERN_ALERT "ctxfi: ERROR!!! Invalid input mux!!!\n");
1828 err = -EINVAL;
1829 goto error;
1830 }
1831
1832 return 0;
1833
1834error:
1835 hw20k2_i2c_uninit(hw);
1836 return err;
1837}
1838
1839static int hw_have_digit_io_switch(struct hw *hw)
1840{
1841 return 0;
1842}
1843
1844static int hw_card_start(struct hw *hw)
1845{
1846 int err = 0;
1847 struct pci_dev *pci = hw->pci;
1848 unsigned int gctl;
1849
1850 err = pci_enable_device(pci);
1851 if (err < 0)
1852 return err;
1853
1854 /* Set DMA transfer mask */
1855 if (pci_set_dma_mask(pci, CT_XFI_DMA_MASK) < 0 ||
1856 pci_set_consistent_dma_mask(pci, CT_XFI_DMA_MASK) < 0) {
1857 printk(KERN_ERR "ctxfi: architecture does not support PCI "
1858 "busmaster DMA with mask 0x%llx\n", CT_XFI_DMA_MASK);
1859 err = -ENXIO;
1860 goto error1;
1861 }
1862
1863 err = pci_request_regions(pci, "XFi");
1864 if (err < 0)
1865 goto error1;
1866
1867 hw->io_base = pci_resource_start(hw->pci, 2);
1868 hw->mem_base = (unsigned long)ioremap(hw->io_base,
1869 pci_resource_len(hw->pci, 2));
1870 if (NULL == (void *)hw->mem_base) {
1871 err = -ENOENT;
1872 goto error2;
1873 }
1874
1875 /* Switch to 20k2 mode from UAA mode. */
1876 gctl = hw_read_20kx(hw, GLOBAL_CNTL_GCTL);
1877 set_field(&gctl, GCTL_UAA, 0);
1878 hw_write_20kx(hw, GLOBAL_CNTL_GCTL, gctl);
1879
1880 /*if ((err = request_irq(pci->irq, ct_atc_interrupt, IRQF_SHARED,
1881 atc->chip_details->nm_card, hw))) {
1882 goto error3;
1883 }
1884 hw->irq = pci->irq;
1885 */
1886
1887 pci_set_master(pci);
1888
1889 return 0;
1890
1891/*error3:
1892 iounmap((void *)hw->mem_base);
1893 hw->mem_base = (unsigned long)NULL;*/
1894error2:
1895 pci_release_regions(pci);
1896 hw->io_base = 0;
1897error1:
1898 pci_disable_device(pci);
1899 return err;
1900}
1901
1902static int hw_card_stop(struct hw *hw)
1903{
1904 /* TODO: Disable interrupt and so on... */
1905 return 0;
1906}
1907
1908static int hw_card_shutdown(struct hw *hw)
1909{
1910 if (hw->irq >= 0)
1911 free_irq(hw->irq, hw);
1912
1913 hw->irq = -1;
1914
1915 if (NULL != ((void *)hw->mem_base))
1916 iounmap((void *)hw->mem_base);
1917
1918 hw->mem_base = (unsigned long)NULL;
1919
1920 if (hw->io_base)
1921 pci_release_regions(hw->pci);
1922
1923 hw->io_base = 0;
1924
1925 pci_disable_device(hw->pci);
1926
1927 return 0;
1928}
1929
1930static int hw_card_init(struct hw *hw, struct card_conf *info)
1931{
1932 int err;
1933 unsigned int gctl;
1934 u32 data = 0;
1935 struct dac_conf dac_info = {0};
1936 struct adc_conf adc_info = {0};
1937 struct daio_conf daio_info = {0};
1938 struct trn_conf trn_info = {0};
1939
1940 /* Get PCI io port/memory base address and
1941 * do 20kx core switch if needed. */
1942 if (!hw->io_base) {
1943 err = hw_card_start(hw);
1944 if (err)
1945 return err;
1946 }
1947
1948 /* PLL init */
1949 err = hw_pll_init(hw, info->rsr);
1950 if (err < 0)
1951 return err;
1952
1953 /* kick off auto-init */
1954 err = hw_auto_init(hw);
1955 if (err < 0)
1956 return err;
1957
1958 gctl = hw_read_20kx(hw, GLOBAL_CNTL_GCTL);
1959 set_field(&gctl, GCTL_DBP, 1);
1960 set_field(&gctl, GCTL_TBP, 1);
1961 set_field(&gctl, GCTL_FBP, 1);
1962 set_field(&gctl, GCTL_DPC, 0);
1963 hw_write_20kx(hw, GLOBAL_CNTL_GCTL, gctl);
1964
1965 /* Reset all global pending interrupts */
1966 hw_write_20kx(hw, INTERRUPT_GIE, 0);
1967 /* Reset all SRC pending interrupts */
1968 hw_write_20kx(hw, SRC_IP, 0);
1969
1970 /* TODO: detect the card ID and configure GPIO accordingly. */
1971 /* Configures GPIO (0xD802 0x98028) */
1972 /*hw_write_20kx(hw, GPIO_CTRL, 0x7F07);*/
1973 /* Configures GPIO (SB0880) */
1974 /*hw_write_20kx(hw, GPIO_CTRL, 0xFF07);*/
1975 hw_write_20kx(hw, GPIO_CTRL, 0xD802);
1976
1977 /* Enable audio ring */
1978 hw_write_20kx(hw, MIXER_AR_ENABLE, 0x01);
1979
1980 trn_info.vm_pgt_phys = info->vm_pgt_phys;
1981 err = hw_trn_init(hw, &trn_info);
1982 if (err < 0)
1983 return err;
1984
1985 daio_info.msr = info->msr;
1986 err = hw_daio_init(hw, &daio_info);
1987 if (err < 0)
1988 return err;
1989
1990 dac_info.msr = info->msr;
1991 err = hw_dac_init(hw, &dac_info);
1992 if (err < 0)
1993 return err;
1994
1995 adc_info.msr = info->msr;
1996 adc_info.input = ADC_LINEIN;
1997 adc_info.mic20db = 0;
1998 err = hw_adc_init(hw, &adc_info);
1999 if (err < 0)
2000 return err;
2001
2002 data = hw_read_20kx(hw, SRC_MCTL);
2003 data |= 0x1; /* Enables input from the audio ring */
2004 hw_write_20kx(hw, SRC_MCTL, data);
2005
2006 return 0;
2007}
2008
2009static u32 hw_read_20kx(struct hw *hw, u32 reg)
2010{
2011 return readl((void *)(hw->mem_base + reg));
2012}
2013
2014static void hw_write_20kx(struct hw *hw, u32 reg, u32 data)
2015{
2016 writel(data, (void *)(hw->mem_base + reg));
2017}
2018
2019static struct hw ct20k2_preset __devinitdata = {
2020 .irq = -1,
2021
2022 .card_init = hw_card_init,
2023 .card_stop = hw_card_stop,
2024 .pll_init = hw_pll_init,
2025 .is_adc_source_selected = hw_is_adc_input_selected,
2026 .select_adc_source = hw_adc_input_select,
2027 .have_digit_io_switch = hw_have_digit_io_switch,
2028
2029 .src_rsc_get_ctrl_blk = src_get_rsc_ctrl_blk,
2030 .src_rsc_put_ctrl_blk = src_put_rsc_ctrl_blk,
2031 .src_mgr_get_ctrl_blk = src_mgr_get_ctrl_blk,
2032 .src_mgr_put_ctrl_blk = src_mgr_put_ctrl_blk,
2033 .src_set_state = src_set_state,
2034 .src_set_bm = src_set_bm,
2035 .src_set_rsr = src_set_rsr,
2036 .src_set_sf = src_set_sf,
2037 .src_set_wr = src_set_wr,
2038 .src_set_pm = src_set_pm,
2039 .src_set_rom = src_set_rom,
2040 .src_set_vo = src_set_vo,
2041 .src_set_st = src_set_st,
2042 .src_set_ie = src_set_ie,
2043 .src_set_ilsz = src_set_ilsz,
2044 .src_set_bp = src_set_bp,
2045 .src_set_cisz = src_set_cisz,
2046 .src_set_ca = src_set_ca,
2047 .src_set_sa = src_set_sa,
2048 .src_set_la = src_set_la,
2049 .src_set_pitch = src_set_pitch,
2050 .src_set_dirty = src_set_dirty,
2051 .src_set_clear_zbufs = src_set_clear_zbufs,
2052 .src_set_dirty_all = src_set_dirty_all,
2053 .src_commit_write = src_commit_write,
2054 .src_get_ca = src_get_ca,
2055 .src_get_dirty = src_get_dirty,
2056 .src_dirty_conj_mask = src_dirty_conj_mask,
2057 .src_mgr_enbs_src = src_mgr_enbs_src,
2058 .src_mgr_enb_src = src_mgr_enb_src,
2059 .src_mgr_dsb_src = src_mgr_dsb_src,
2060 .src_mgr_commit_write = src_mgr_commit_write,
2061
2062 .srcimp_mgr_get_ctrl_blk = srcimp_mgr_get_ctrl_blk,
2063 .srcimp_mgr_put_ctrl_blk = srcimp_mgr_put_ctrl_blk,
2064 .srcimp_mgr_set_imaparc = srcimp_mgr_set_imaparc,
2065 .srcimp_mgr_set_imapuser = srcimp_mgr_set_imapuser,
2066 .srcimp_mgr_set_imapnxt = srcimp_mgr_set_imapnxt,
2067 .srcimp_mgr_set_imapaddr = srcimp_mgr_set_imapaddr,
2068 .srcimp_mgr_commit_write = srcimp_mgr_commit_write,
2069
2070 .amixer_rsc_get_ctrl_blk = amixer_rsc_get_ctrl_blk,
2071 .amixer_rsc_put_ctrl_blk = amixer_rsc_put_ctrl_blk,
2072 .amixer_mgr_get_ctrl_blk = amixer_mgr_get_ctrl_blk,
2073 .amixer_mgr_put_ctrl_blk = amixer_mgr_put_ctrl_blk,
2074 .amixer_set_mode = amixer_set_mode,
2075 .amixer_set_iv = amixer_set_iv,
2076 .amixer_set_x = amixer_set_x,
2077 .amixer_set_y = amixer_set_y,
2078 .amixer_set_sadr = amixer_set_sadr,
2079 .amixer_set_se = amixer_set_se,
2080 .amixer_set_dirty = amixer_set_dirty,
2081 .amixer_set_dirty_all = amixer_set_dirty_all,
2082 .amixer_commit_write = amixer_commit_write,
2083 .amixer_get_y = amixer_get_y,
2084 .amixer_get_dirty = amixer_get_dirty,
2085
2086 .dai_get_ctrl_blk = dai_get_ctrl_blk,
2087 .dai_put_ctrl_blk = dai_put_ctrl_blk,
2088 .dai_srt_set_srco = dai_srt_set_srco,
2089 .dai_srt_set_srcm = dai_srt_set_srcm,
2090 .dai_srt_set_rsr = dai_srt_set_rsr,
2091 .dai_srt_set_drat = dai_srt_set_drat,
2092 .dai_srt_set_ec = dai_srt_set_ec,
2093 .dai_srt_set_et = dai_srt_set_et,
2094 .dai_commit_write = dai_commit_write,
2095
2096 .dao_get_ctrl_blk = dao_get_ctrl_blk,
2097 .dao_put_ctrl_blk = dao_put_ctrl_blk,
2098 .dao_set_spos = dao_set_spos,
2099 .dao_commit_write = dao_commit_write,
2100 .dao_get_spos = dao_get_spos,
2101
2102 .daio_mgr_get_ctrl_blk = daio_mgr_get_ctrl_blk,
2103 .daio_mgr_put_ctrl_blk = daio_mgr_put_ctrl_blk,
2104 .daio_mgr_enb_dai = daio_mgr_enb_dai,
2105 .daio_mgr_dsb_dai = daio_mgr_dsb_dai,
2106 .daio_mgr_enb_dao = daio_mgr_enb_dao,
2107 .daio_mgr_dsb_dao = daio_mgr_dsb_dao,
2108 .daio_mgr_dao_init = daio_mgr_dao_init,
2109 .daio_mgr_set_imaparc = daio_mgr_set_imaparc,
2110 .daio_mgr_set_imapnxt = daio_mgr_set_imapnxt,
2111 .daio_mgr_set_imapaddr = daio_mgr_set_imapaddr,
2112 .daio_mgr_commit_write = daio_mgr_commit_write,
2113};
2114
2115int __devinit create_20k2_hw_obj(struct hw **rhw)
2116{
2117 struct hw20k2 *hw20k2;
2118
2119 *rhw = NULL;
2120 hw20k2 = kzalloc(sizeof(*hw20k2), GFP_KERNEL);
2121 if (!hw20k2)
2122 return -ENOMEM;
2123
2124 hw20k2->hw = ct20k2_preset;
2125 *rhw = &hw20k2->hw;
2126
2127 return 0;
2128}
2129
2130int destroy_20k2_hw_obj(struct hw *hw)
2131{
2132 if (hw->io_base)
2133 hw_card_shutdown(hw);
2134
2135 kfree(hw);
2136 return 0;
2137}
diff --git a/sound/pci/ctxfi/cthw20k2.h b/sound/pci/ctxfi/cthw20k2.h
new file mode 100644
index 00000000000..d2b7daab681
--- /dev/null
+++ b/sound/pci/ctxfi/cthw20k2.h
@@ -0,0 +1,26 @@
1/**
2 * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
3 *
4 * This source file is released under GPL v2 license (no other versions).
5 * See the COPYING file included in the main directory of this source
6 * distribution for the license terms and conditions.
7 *
8 * @File cthw20k2.h
9 *
10 * @Brief
11 * This file contains the definition of hardware access methord.
12 *
13 * @Author Liu Chun
14 * @Date May 13 2008
15 *
16 */
17
18#ifndef CTHW20K2_H
19#define CTHW20K2_H
20
21#include "cthardware.h"
22
23int create_20k2_hw_obj(struct hw **rhw);
24int destroy_20k2_hw_obj(struct hw *hw);
25
26#endif /* CTHW20K2_H */
diff --git a/sound/pci/ctxfi/ctimap.c b/sound/pci/ctxfi/ctimap.c
new file mode 100644
index 00000000000..0b73368a4df
--- /dev/null
+++ b/sound/pci/ctxfi/ctimap.c
@@ -0,0 +1,112 @@
1/**
2 * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
3 *
4 * This source file is released under GPL v2 license (no other versions).
5 * See the COPYING file included in the main directory of this source
6 * distribution for the license terms and conditions.
7 *
8 * @File ctimap.c
9 *
10 * @Brief
11 * This file contains the implementation of generic input mapper operations
12 * for input mapper management.
13 *
14 * @Author Liu Chun
15 * @Date May 23 2008
16 *
17 */
18
19#include "ctimap.h"
20#include <linux/slab.h>
21
22int input_mapper_add(struct list_head *mappers, struct imapper *entry,
23 int (*map_op)(void *, struct imapper *), void *data)
24{
25 struct list_head *pos, *pre, *head;
26 struct imapper *pre_ent, *pos_ent;
27
28 head = mappers;
29
30 if (list_empty(head)) {
31 entry->next = entry->addr;
32 map_op(data, entry);
33 list_add(&entry->list, head);
34 return 0;
35 }
36
37 list_for_each(pos, head) {
38 pos_ent = list_entry(pos, struct imapper, list);
39 if (pos_ent->slot > entry->slot) {
40 /* found a position in list */
41 break;
42 }
43 }
44
45 if (pos != head) {
46 pre = pos->prev;
47 if (pre == head)
48 pre = head->prev;
49
50 __list_add(&entry->list, pos->prev, pos);
51 } else {
52 pre = head->prev;
53 pos = head->next;
54 list_add_tail(&entry->list, head);
55 }
56
57 pre_ent = list_entry(pre, struct imapper, list);
58 pos_ent = list_entry(pos, struct imapper, list);
59
60 entry->next = pos_ent->addr;
61 map_op(data, entry);
62 pre_ent->next = entry->addr;
63 map_op(data, pre_ent);
64
65 return 0;
66}
67
68int input_mapper_delete(struct list_head *mappers, struct imapper *entry,
69 int (*map_op)(void *, struct imapper *), void *data)
70{
71 struct list_head *next, *pre, *head;
72 struct imapper *pre_ent, *next_ent;
73
74 head = mappers;
75
76 if (list_empty(head))
77 return 0;
78
79 pre = (entry->list.prev == head) ? head->prev : entry->list.prev;
80 next = (entry->list.next == head) ? head->next : entry->list.next;
81
82 if (pre == &entry->list) {
83 /* entry is the only one node in mappers list */
84 entry->next = entry->addr = entry->user = entry->slot = 0;
85 map_op(data, entry);
86 list_del(&entry->list);
87 return 0;
88 }
89
90 pre_ent = list_entry(pre, struct imapper, list);
91 next_ent = list_entry(next, struct imapper, list);
92
93 pre_ent->next = next_ent->addr;
94 map_op(data, pre_ent);
95 list_del(&entry->list);
96
97 return 0;
98}
99
100void free_input_mapper_list(struct list_head *head)
101{
102 struct imapper *entry;
103 struct list_head *pos;
104
105 while (!list_empty(head)) {
106 pos = head->next;
107 list_del(pos);
108 entry = list_entry(pos, struct imapper, list);
109 kfree(entry);
110 }
111}
112
diff --git a/sound/pci/ctxfi/ctimap.h b/sound/pci/ctxfi/ctimap.h
new file mode 100644
index 00000000000..53ccf9be8b6
--- /dev/null
+++ b/sound/pci/ctxfi/ctimap.h
@@ -0,0 +1,40 @@
1/**
2 * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
3 *
4 * This source file is released under GPL v2 license (no other versions).
5 * See the COPYING file included in the main directory of this source
6 * distribution for the license terms and conditions.
7 *
8 * @File ctimap.h
9 *
10 * @Brief
11 * This file contains the definition of generic input mapper operations
12 * for input mapper management.
13 *
14 * @Author Liu Chun
15 * @Date May 23 2008
16 *
17 */
18
19#ifndef CTIMAP_H
20#define CTIMAP_H
21
22#include <linux/list.h>
23
24struct imapper {
25 unsigned short slot; /* the id of the slot containing input data */
26 unsigned short user; /* the id of the user resource consuming data */
27 unsigned short addr; /* the input mapper ram id */
28 unsigned short next; /* the next input mapper ram id */
29 struct list_head list;
30};
31
32int input_mapper_add(struct list_head *mappers, struct imapper *entry,
33 int (*map_op)(void *, struct imapper *), void *data);
34
35int input_mapper_delete(struct list_head *mappers, struct imapper *entry,
36 int (*map_op)(void *, struct imapper *), void *data);
37
38void free_input_mapper_list(struct list_head *mappers);
39
40#endif /* CTIMAP_H */
diff --git a/sound/pci/ctxfi/ctmixer.c b/sound/pci/ctxfi/ctmixer.c
new file mode 100644
index 00000000000..666722d9de4
--- /dev/null
+++ b/sound/pci/ctxfi/ctmixer.c
@@ -0,0 +1,1123 @@
1/**
2 * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
3 *
4 * This source file is released under GPL v2 license (no other versions).
5 * See the COPYING file included in the main directory of this source
6 * distribution for the license terms and conditions.
7 *
8 * @File ctmixer.c
9 *
10 * @Brief
11 * This file contains the implementation of alsa mixer device functions.
12 *
13 * @Author Liu Chun
14 * @Date May 28 2008
15 *
16 */
17
18
19#include "ctmixer.h"
20#include "ctamixer.h"
21#include <linux/slab.h>
22#include <sound/core.h>
23#include <sound/control.h>
24#include <sound/asoundef.h>
25#include <sound/pcm.h>
26#include <sound/tlv.h>
27
28enum CT_SUM_CTL {
29 SUM_IN_F,
30 SUM_IN_R,
31 SUM_IN_C,
32 SUM_IN_S,
33 SUM_IN_F_C,
34
35 NUM_CT_SUMS
36};
37
38enum CT_AMIXER_CTL {
39 /* volume control mixers */
40 AMIXER_MASTER_F,
41 AMIXER_MASTER_R,
42 AMIXER_MASTER_C,
43 AMIXER_MASTER_S,
44 AMIXER_PCM_F,
45 AMIXER_PCM_R,
46 AMIXER_PCM_C,
47 AMIXER_PCM_S,
48 AMIXER_SPDIFI,
49 AMIXER_LINEIN,
50 AMIXER_MIC,
51 AMIXER_SPDIFO,
52 AMIXER_WAVE_F,
53 AMIXER_WAVE_R,
54 AMIXER_WAVE_C,
55 AMIXER_WAVE_S,
56 AMIXER_MASTER_F_C,
57 AMIXER_PCM_F_C,
58 AMIXER_SPDIFI_C,
59 AMIXER_LINEIN_C,
60 AMIXER_MIC_C,
61
62 /* this should always be the last one */
63 NUM_CT_AMIXERS
64};
65
66enum CTALSA_MIXER_CTL {
67 /* volume control mixers */
68 MIXER_MASTER_P,
69 MIXER_PCM_P,
70 MIXER_LINEIN_P,
71 MIXER_MIC_P,
72 MIXER_SPDIFI_P,
73 MIXER_SPDIFO_P,
74 MIXER_WAVEF_P,
75 MIXER_WAVER_P,
76 MIXER_WAVEC_P,
77 MIXER_WAVES_P,
78 MIXER_MASTER_C,
79 MIXER_PCM_C,
80 MIXER_LINEIN_C,
81 MIXER_MIC_C,
82 MIXER_SPDIFI_C,
83
84 /* switch control mixers */
85 MIXER_PCM_C_S,
86 MIXER_LINEIN_C_S,
87 MIXER_MIC_C_S,
88 MIXER_SPDIFI_C_S,
89 MIXER_LINEIN_P_S,
90 MIXER_SPDIFO_P_S,
91 MIXER_SPDIFI_P_S,
92 MIXER_WAVEF_P_S,
93 MIXER_WAVER_P_S,
94 MIXER_WAVEC_P_S,
95 MIXER_WAVES_P_S,
96 MIXER_DIGITAL_IO_S,
97 MIXER_IEC958_MASK,
98 MIXER_IEC958_DEFAULT,
99 MIXER_IEC958_STREAM,
100
101 /* this should always be the last one */
102 NUM_CTALSA_MIXERS
103};
104
105#define VOL_MIXER_START MIXER_MASTER_P
106#define VOL_MIXER_END MIXER_SPDIFI_C
107#define VOL_MIXER_NUM (VOL_MIXER_END - VOL_MIXER_START + 1)
108#define SWH_MIXER_START MIXER_PCM_C_S
109#define SWH_MIXER_END MIXER_DIGITAL_IO_S
110#define SWH_CAPTURE_START MIXER_PCM_C_S
111#define SWH_CAPTURE_END MIXER_SPDIFI_C_S
112
113#define CHN_NUM 2
114
115struct ct_kcontrol_init {
116 unsigned char ctl;
117 char *name;
118};
119
120static struct ct_kcontrol_init
121ct_kcontrol_init_table[NUM_CTALSA_MIXERS] = {
122 [MIXER_MASTER_P] = {
123 .ctl = 1,
124 .name = "Master Playback Volume",
125 },
126 [MIXER_MASTER_C] = {
127 .ctl = 1,
128 .name = "Master Capture Volume",
129 },
130 [MIXER_PCM_P] = {
131 .ctl = 1,
132 .name = "PCM Playback Volume",
133 },
134 [MIXER_PCM_C] = {
135 .ctl = 1,
136 .name = "PCM Capture Volume",
137 },
138 [MIXER_LINEIN_P] = {
139 .ctl = 1,
140 .name = "Line-in Playback Volume",
141 },
142 [MIXER_LINEIN_C] = {
143 .ctl = 1,
144 .name = "Line-in Capture Volume",
145 },
146 [MIXER_MIC_P] = {
147 .ctl = 1,
148 .name = "Mic Playback Volume",
149 },
150 [MIXER_MIC_C] = {
151 .ctl = 1,
152 .name = "Mic Capture Volume",
153 },
154 [MIXER_SPDIFI_P] = {
155 .ctl = 1,
156 .name = "S/PDIF-in Playback Volume",
157 },
158 [MIXER_SPDIFI_C] = {
159 .ctl = 1,
160 .name = "S/PDIF-in Capture Volume",
161 },
162 [MIXER_SPDIFO_P] = {
163 .ctl = 1,
164 .name = "S/PDIF-out Playback Volume",
165 },
166 [MIXER_WAVEF_P] = {
167 .ctl = 1,
168 .name = "Front Playback Volume",
169 },
170 [MIXER_WAVES_P] = {
171 .ctl = 1,
172 .name = "Side Playback Volume",
173 },
174 [MIXER_WAVEC_P] = {
175 .ctl = 1,
176 .name = "Center/LFE Playback Volume",
177 },
178 [MIXER_WAVER_P] = {
179 .ctl = 1,
180 .name = "Surround Playback Volume",
181 },
182
183 [MIXER_PCM_C_S] = {
184 .ctl = 1,
185 .name = "PCM Capture Switch",
186 },
187 [MIXER_LINEIN_C_S] = {
188 .ctl = 1,
189 .name = "Line-in Capture Switch",
190 },
191 [MIXER_MIC_C_S] = {
192 .ctl = 1,
193 .name = "Mic Capture Switch",
194 },
195 [MIXER_SPDIFI_C_S] = {
196 .ctl = 1,
197 .name = "S/PDIF-in Capture Switch",
198 },
199 [MIXER_LINEIN_P_S] = {
200 .ctl = 1,
201 .name = "Line-in Playback Switch",
202 },
203 [MIXER_SPDIFO_P_S] = {
204 .ctl = 1,
205 .name = "S/PDIF-out Playback Switch",
206 },
207 [MIXER_SPDIFI_P_S] = {
208 .ctl = 1,
209 .name = "S/PDIF-in Playback Switch",
210 },
211 [MIXER_WAVEF_P_S] = {
212 .ctl = 1,
213 .name = "Front Playback Switch",
214 },
215 [MIXER_WAVES_P_S] = {
216 .ctl = 1,
217 .name = "Side Playback Switch",
218 },
219 [MIXER_WAVEC_P_S] = {
220 .ctl = 1,
221 .name = "Center/LFE Playback Switch",
222 },
223 [MIXER_WAVER_P_S] = {
224 .ctl = 1,
225 .name = "Surround Playback Switch",
226 },
227 [MIXER_DIGITAL_IO_S] = {
228 .ctl = 0,
229 .name = "Digit-IO Playback Switch",
230 },
231};
232
233static void
234ct_mixer_recording_select(struct ct_mixer *mixer, enum CT_AMIXER_CTL type);
235
236static void
237ct_mixer_recording_unselect(struct ct_mixer *mixer, enum CT_AMIXER_CTL type);
238
239static struct snd_kcontrol *kctls[2] = {NULL};
240
241static enum CT_AMIXER_CTL get_amixer_index(enum CTALSA_MIXER_CTL alsa_index)
242{
243 switch (alsa_index) {
244 case MIXER_MASTER_P: return AMIXER_MASTER_F;
245 case MIXER_MASTER_C: return AMIXER_MASTER_F_C;
246 case MIXER_PCM_P: return AMIXER_PCM_F;
247 case MIXER_PCM_C:
248 case MIXER_PCM_C_S: return AMIXER_PCM_F_C;
249 case MIXER_LINEIN_P: return AMIXER_LINEIN;
250 case MIXER_LINEIN_C:
251 case MIXER_LINEIN_C_S: return AMIXER_LINEIN_C;
252 case MIXER_MIC_P: return AMIXER_MIC;
253 case MIXER_MIC_C:
254 case MIXER_MIC_C_S: return AMIXER_MIC_C;
255 case MIXER_SPDIFI_P: return AMIXER_SPDIFI;
256 case MIXER_SPDIFI_C:
257 case MIXER_SPDIFI_C_S: return AMIXER_SPDIFI_C;
258 case MIXER_SPDIFO_P: return AMIXER_SPDIFO;
259 case MIXER_WAVEF_P: return AMIXER_WAVE_F;
260 case MIXER_WAVES_P: return AMIXER_WAVE_S;
261 case MIXER_WAVEC_P: return AMIXER_WAVE_C;
262 case MIXER_WAVER_P: return AMIXER_WAVE_R;
263 default: return NUM_CT_AMIXERS;
264 }
265}
266
267static enum CT_AMIXER_CTL get_recording_amixer(enum CT_AMIXER_CTL index)
268{
269 switch (index) {
270 case AMIXER_MASTER_F: return AMIXER_MASTER_F_C;
271 case AMIXER_PCM_F: return AMIXER_PCM_F_C;
272 case AMIXER_SPDIFI: return AMIXER_SPDIFI_C;
273 case AMIXER_LINEIN: return AMIXER_LINEIN_C;
274 case AMIXER_MIC: return AMIXER_MIC_C;
275 default: return NUM_CT_AMIXERS;
276 }
277}
278
279static unsigned char
280get_switch_state(struct ct_mixer *mixer, enum CTALSA_MIXER_CTL type)
281{
282 return (mixer->switch_state & (0x1 << (type - SWH_MIXER_START)))
283 ? 1 : 0;
284}
285
286static void
287set_switch_state(struct ct_mixer *mixer,
288 enum CTALSA_MIXER_CTL type, unsigned char state)
289{
290 if (state)
291 mixer->switch_state |= (0x1 << (type - SWH_MIXER_START));
292 else
293 mixer->switch_state &= ~(0x1 << (type - SWH_MIXER_START));
294}
295
296#if 0 /* not used */
297/* Map integer value ranging from 0 to 65535 to 14-bit float value ranging
298 * from 2^-6 to (1+1023/1024) */
299static unsigned int uint16_to_float14(unsigned int x)
300{
301 unsigned int i;
302
303 if (x < 17)
304 return 0;
305
306 x *= 2031;
307 x /= 65535;
308 x += 16;
309
310 /* i <= 6 */
311 for (i = 0; !(x & 0x400); i++)
312 x <<= 1;
313
314 x = (((7 - i) & 0x7) << 10) | (x & 0x3ff);
315
316 return x;
317}
318
319static unsigned int float14_to_uint16(unsigned int x)
320{
321 unsigned int e;
322
323 if (!x)
324 return x;
325
326 e = (x >> 10) & 0x7;
327 x &= 0x3ff;
328 x += 1024;
329 x >>= (7 - e);
330 x -= 16;
331 x *= 65535;
332 x /= 2031;
333
334 return x;
335}
336#endif /* not used */
337
338#define VOL_SCALE 0x1c
339#define VOL_MAX 0x100
340
341static const DECLARE_TLV_DB_SCALE(ct_vol_db_scale, -6400, 25, 1);
342
343static int ct_alsa_mix_volume_info(struct snd_kcontrol *kcontrol,
344 struct snd_ctl_elem_info *uinfo)
345{
346 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
347 uinfo->count = 2;
348 uinfo->value.integer.min = 0;
349 uinfo->value.integer.max = VOL_MAX;
350
351 return 0;
352}
353
354static int ct_alsa_mix_volume_get(struct snd_kcontrol *kcontrol,
355 struct snd_ctl_elem_value *ucontrol)
356{
357 struct ct_atc *atc = snd_kcontrol_chip(kcontrol);
358 enum CT_AMIXER_CTL type = get_amixer_index(kcontrol->private_value);
359 struct amixer *amixer;
360 int i, val;
361
362 for (i = 0; i < 2; i++) {
363 amixer = ((struct ct_mixer *)atc->mixer)->
364 amixers[type*CHN_NUM+i];
365 val = amixer->ops->get_scale(amixer) / VOL_SCALE;
366 if (val < 0)
367 val = 0;
368 else if (val > VOL_MAX)
369 val = VOL_MAX;
370 ucontrol->value.integer.value[i] = val;
371 }
372
373 return 0;
374}
375
376static int ct_alsa_mix_volume_put(struct snd_kcontrol *kcontrol,
377 struct snd_ctl_elem_value *ucontrol)
378{
379 struct ct_atc *atc = snd_kcontrol_chip(kcontrol);
380 struct ct_mixer *mixer = atc->mixer;
381 enum CT_AMIXER_CTL type = get_amixer_index(kcontrol->private_value);
382 struct amixer *amixer;
383 int i, j, val, oval, change = 0;
384
385 for (i = 0; i < 2; i++) {
386 val = ucontrol->value.integer.value[i];
387 if (val < 0)
388 val = 0;
389 else if (val > VOL_MAX)
390 val = VOL_MAX;
391 val *= VOL_SCALE;
392 amixer = mixer->amixers[type*CHN_NUM+i];
393 oval = amixer->ops->get_scale(amixer);
394 if (val != oval) {
395 amixer->ops->set_scale(amixer, val);
396 amixer->ops->commit_write(amixer);
397 change = 1;
398 /* Synchronize Master/PCM playback AMIXERs. */
399 if (AMIXER_MASTER_F == type || AMIXER_PCM_F == type) {
400 for (j = 1; j < 4; j++) {
401 amixer = mixer->
402 amixers[(type+j)*CHN_NUM+i];
403 amixer->ops->set_scale(amixer, val);
404 amixer->ops->commit_write(amixer);
405 }
406 }
407 }
408 }
409
410 return change;
411}
412
413static struct snd_kcontrol_new vol_ctl = {
414 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
415 SNDRV_CTL_ELEM_ACCESS_TLV_READ,
416 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
417 .info = ct_alsa_mix_volume_info,
418 .get = ct_alsa_mix_volume_get,
419 .put = ct_alsa_mix_volume_put,
420 .tlv = { .p = ct_vol_db_scale },
421};
422
423static void
424do_line_mic_switch(struct ct_atc *atc, enum CTALSA_MIXER_CTL type)
425{
426
427 if (MIXER_LINEIN_C_S == type) {
428 atc->select_line_in(atc);
429 set_switch_state(atc->mixer, MIXER_MIC_C_S, 0);
430 snd_ctl_notify(atc->card, SNDRV_CTL_EVENT_MASK_VALUE,
431 &kctls[1]->id);
432 } else if (MIXER_MIC_C_S == type) {
433 atc->select_mic_in(atc);
434 set_switch_state(atc->mixer, MIXER_LINEIN_C_S, 0);
435 snd_ctl_notify(atc->card, SNDRV_CTL_EVENT_MASK_VALUE,
436 &kctls[0]->id);
437 }
438}
439
440static void
441do_digit_io_switch(struct ct_atc *atc, int state)
442{
443 struct ct_mixer *mixer = atc->mixer;
444
445 if (state) {
446 atc->select_digit_io(atc);
447 atc->spdif_out_unmute(atc,
448 get_switch_state(mixer, MIXER_SPDIFO_P_S));
449 atc->spdif_in_unmute(atc, 1);
450 atc->line_in_unmute(atc, 0);
451 return;
452 }
453
454 if (get_switch_state(mixer, MIXER_LINEIN_C_S))
455 atc->select_line_in(atc);
456 else if (get_switch_state(mixer, MIXER_MIC_C_S))
457 atc->select_mic_in(atc);
458
459 atc->spdif_out_unmute(atc, 0);
460 atc->spdif_in_unmute(atc, 0);
461 atc->line_in_unmute(atc, 1);
462 return;
463}
464
465static int ct_alsa_mix_switch_info(struct snd_kcontrol *kcontrol,
466 struct snd_ctl_elem_info *uinfo)
467{
468 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
469 uinfo->count = 1;
470 uinfo->value.integer.min = 0;
471 uinfo->value.integer.max = 1;
472 uinfo->value.integer.step = 1;
473
474 return 0;
475}
476
477static int ct_alsa_mix_switch_get(struct snd_kcontrol *kcontrol,
478 struct snd_ctl_elem_value *ucontrol)
479{
480 struct ct_mixer *mixer =
481 ((struct ct_atc *)snd_kcontrol_chip(kcontrol))->mixer;
482 enum CTALSA_MIXER_CTL type = kcontrol->private_value;
483
484 ucontrol->value.integer.value[0] = get_switch_state(mixer, type);
485 return 0;
486}
487
488static int ct_alsa_mix_switch_put(struct snd_kcontrol *kcontrol,
489 struct snd_ctl_elem_value *ucontrol)
490{
491 struct ct_atc *atc = snd_kcontrol_chip(kcontrol);
492 struct ct_mixer *mixer = atc->mixer;
493 enum CTALSA_MIXER_CTL type = kcontrol->private_value;
494 int state;
495
496 state = ucontrol->value.integer.value[0];
497 if (get_switch_state(mixer, type) == state)
498 return 0;
499
500 set_switch_state(mixer, type, state);
501 /* Do changes in mixer. */
502 if ((SWH_CAPTURE_START <= type) && (SWH_CAPTURE_END >= type)) {
503 if (state) {
504 ct_mixer_recording_select(mixer,
505 get_amixer_index(type));
506 } else {
507 ct_mixer_recording_unselect(mixer,
508 get_amixer_index(type));
509 }
510 }
511 /* Do changes out of mixer. */
512 if (state && (MIXER_LINEIN_C_S == type || MIXER_MIC_C_S == type))
513 do_line_mic_switch(atc, type);
514 else if (MIXER_WAVEF_P_S == type)
515 atc->line_front_unmute(atc, state);
516 else if (MIXER_WAVES_P_S == type)
517 atc->line_surround_unmute(atc, state);
518 else if (MIXER_WAVEC_P_S == type)
519 atc->line_clfe_unmute(atc, state);
520 else if (MIXER_WAVER_P_S == type)
521 atc->line_rear_unmute(atc, state);
522 else if (MIXER_LINEIN_P_S == type)
523 atc->line_in_unmute(atc, state);
524 else if (MIXER_SPDIFO_P_S == type)
525 atc->spdif_out_unmute(atc, state);
526 else if (MIXER_SPDIFI_P_S == type)
527 atc->spdif_in_unmute(atc, state);
528 else if (MIXER_DIGITAL_IO_S == type)
529 do_digit_io_switch(atc, state);
530
531 return 1;
532}
533
534static struct snd_kcontrol_new swh_ctl = {
535 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
536 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
537 .info = ct_alsa_mix_switch_info,
538 .get = ct_alsa_mix_switch_get,
539 .put = ct_alsa_mix_switch_put
540};
541
542static int ct_spdif_info(struct snd_kcontrol *kcontrol,
543 struct snd_ctl_elem_info *uinfo)
544{
545 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
546 uinfo->count = 1;
547 return 0;
548}
549
550static int ct_spdif_get_mask(struct snd_kcontrol *kcontrol,
551 struct snd_ctl_elem_value *ucontrol)
552{
553 ucontrol->value.iec958.status[0] = 0xff;
554 ucontrol->value.iec958.status[1] = 0xff;
555 ucontrol->value.iec958.status[2] = 0xff;
556 ucontrol->value.iec958.status[3] = 0xff;
557 return 0;
558}
559
560static int ct_spdif_default_get(struct snd_kcontrol *kcontrol,
561 struct snd_ctl_elem_value *ucontrol)
562{
563 unsigned int status = SNDRV_PCM_DEFAULT_CON_SPDIF;
564
565 ucontrol->value.iec958.status[0] = (status >> 0) & 0xff;
566 ucontrol->value.iec958.status[1] = (status >> 8) & 0xff;
567 ucontrol->value.iec958.status[2] = (status >> 16) & 0xff;
568 ucontrol->value.iec958.status[3] = (status >> 24) & 0xff;
569
570 return 0;
571}
572
573static int ct_spdif_get(struct snd_kcontrol *kcontrol,
574 struct snd_ctl_elem_value *ucontrol)
575{
576 struct ct_atc *atc = snd_kcontrol_chip(kcontrol);
577 unsigned int status;
578
579 atc->spdif_out_get_status(atc, &status);
580 ucontrol->value.iec958.status[0] = (status >> 0) & 0xff;
581 ucontrol->value.iec958.status[1] = (status >> 8) & 0xff;
582 ucontrol->value.iec958.status[2] = (status >> 16) & 0xff;
583 ucontrol->value.iec958.status[3] = (status >> 24) & 0xff;
584
585 return 0;
586}
587
588static int ct_spdif_put(struct snd_kcontrol *kcontrol,
589 struct snd_ctl_elem_value *ucontrol)
590{
591 struct ct_atc *atc = snd_kcontrol_chip(kcontrol);
592 int change;
593 unsigned int status, old_status;
594
595 status = (ucontrol->value.iec958.status[0] << 0) |
596 (ucontrol->value.iec958.status[1] << 8) |
597 (ucontrol->value.iec958.status[2] << 16) |
598 (ucontrol->value.iec958.status[3] << 24);
599
600 atc->spdif_out_get_status(atc, &old_status);
601 change = (old_status != status);
602 if (change)
603 atc->spdif_out_set_status(atc, status);
604
605 return change;
606}
607
608static struct snd_kcontrol_new iec958_mask_ctl = {
609 .access = SNDRV_CTL_ELEM_ACCESS_READ,
610 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
611 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, MASK),
612 .count = 1,
613 .info = ct_spdif_info,
614 .get = ct_spdif_get_mask,
615 .private_value = MIXER_IEC958_MASK
616};
617
618static struct snd_kcontrol_new iec958_default_ctl = {
619 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
620 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT),
621 .count = 1,
622 .info = ct_spdif_info,
623 .get = ct_spdif_default_get,
624 .put = ct_spdif_put,
625 .private_value = MIXER_IEC958_DEFAULT
626};
627
628static struct snd_kcontrol_new iec958_ctl = {
629 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
630 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
631 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, PCM_STREAM),
632 .count = 1,
633 .info = ct_spdif_info,
634 .get = ct_spdif_get,
635 .put = ct_spdif_put,
636 .private_value = MIXER_IEC958_STREAM
637};
638
639#define NUM_IEC958_CTL 3
640
641static int
642ct_mixer_kcontrol_new(struct ct_mixer *mixer, struct snd_kcontrol_new *new)
643{
644 struct snd_kcontrol *kctl;
645 int err;
646
647 kctl = snd_ctl_new1(new, mixer->atc);
648 if (NULL == kctl)
649 return -ENOMEM;
650
651 if (SNDRV_CTL_ELEM_IFACE_PCM == kctl->id.iface)
652 kctl->id.device = IEC958;
653
654 err = snd_ctl_add(mixer->atc->card, kctl);
655 if (err)
656 return err;
657
658 switch (new->private_value) {
659 case MIXER_LINEIN_C_S:
660 kctls[0] = kctl; break;
661 case MIXER_MIC_C_S:
662 kctls[1] = kctl; break;
663 default:
664 break;
665 }
666
667 return 0;
668}
669
670static int ct_mixer_kcontrols_create(struct ct_mixer *mixer)
671{
672 enum CTALSA_MIXER_CTL type;
673 struct ct_atc *atc = mixer->atc;
674 int err;
675
676 /* Create snd kcontrol instances on demand */
677 for (type = VOL_MIXER_START; type <= VOL_MIXER_END; type++) {
678 if (ct_kcontrol_init_table[type].ctl) {
679 vol_ctl.name = ct_kcontrol_init_table[type].name;
680 vol_ctl.private_value = (unsigned long)type;
681 err = ct_mixer_kcontrol_new(mixer, &vol_ctl);
682 if (err)
683 return err;
684 }
685 }
686
687 ct_kcontrol_init_table[MIXER_DIGITAL_IO_S].ctl =
688 atc->have_digit_io_switch(atc);
689 for (type = SWH_MIXER_START; type <= SWH_MIXER_END; type++) {
690 if (ct_kcontrol_init_table[type].ctl) {
691 swh_ctl.name = ct_kcontrol_init_table[type].name;
692 swh_ctl.private_value = (unsigned long)type;
693 err = ct_mixer_kcontrol_new(mixer, &swh_ctl);
694 if (err)
695 return err;
696 }
697 }
698
699 err = ct_mixer_kcontrol_new(mixer, &iec958_mask_ctl);
700 if (err)
701 return err;
702
703 err = ct_mixer_kcontrol_new(mixer, &iec958_default_ctl);
704 if (err)
705 return err;
706
707 err = ct_mixer_kcontrol_new(mixer, &iec958_ctl);
708 if (err)
709 return err;
710
711 atc->line_front_unmute(atc, 1);
712 set_switch_state(mixer, MIXER_WAVEF_P_S, 1);
713 atc->line_surround_unmute(atc, 0);
714 set_switch_state(mixer, MIXER_WAVES_P_S, 0);
715 atc->line_clfe_unmute(atc, 0);
716 set_switch_state(mixer, MIXER_WAVEC_P_S, 0);
717 atc->line_rear_unmute(atc, 0);
718 set_switch_state(mixer, MIXER_WAVER_P_S, 0);
719 atc->spdif_out_unmute(atc, 0);
720 set_switch_state(mixer, MIXER_SPDIFO_P_S, 0);
721 atc->line_in_unmute(atc, 0);
722 set_switch_state(mixer, MIXER_LINEIN_P_S, 0);
723 atc->spdif_in_unmute(atc, 0);
724 set_switch_state(mixer, MIXER_SPDIFI_P_S, 0);
725
726 set_switch_state(mixer, MIXER_PCM_C_S, 1);
727 set_switch_state(mixer, MIXER_LINEIN_C_S, 1);
728 set_switch_state(mixer, MIXER_SPDIFI_C_S, 1);
729
730 return 0;
731}
732
733static void
734ct_mixer_recording_select(struct ct_mixer *mixer, enum CT_AMIXER_CTL type)
735{
736 struct amixer *amix_d;
737 struct sum *sum_c;
738 int i;
739
740 for (i = 0; i < 2; i++) {
741 amix_d = mixer->amixers[type*CHN_NUM+i];
742 sum_c = mixer->sums[SUM_IN_F_C*CHN_NUM+i];
743 amix_d->ops->set_sum(amix_d, sum_c);
744 amix_d->ops->commit_write(amix_d);
745 }
746}
747
748static void
749ct_mixer_recording_unselect(struct ct_mixer *mixer, enum CT_AMIXER_CTL type)
750{
751 struct amixer *amix_d;
752 int i;
753
754 for (i = 0; i < 2; i++) {
755 amix_d = mixer->amixers[type*CHN_NUM+i];
756 amix_d->ops->set_sum(amix_d, NULL);
757 amix_d->ops->commit_write(amix_d);
758 }
759}
760
761static int ct_mixer_get_resources(struct ct_mixer *mixer)
762{
763 struct sum_mgr *sum_mgr;
764 struct sum *sum;
765 struct sum_desc sum_desc = {0};
766 struct amixer_mgr *amixer_mgr;
767 struct amixer *amixer;
768 struct amixer_desc am_desc = {0};
769 int err;
770 int i;
771
772 /* Allocate sum resources for mixer obj */
773 sum_mgr = (struct sum_mgr *)mixer->atc->rsc_mgrs[SUM];
774 sum_desc.msr = mixer->atc->msr;
775 for (i = 0; i < (NUM_CT_SUMS * CHN_NUM); i++) {
776 err = sum_mgr->get_sum(sum_mgr, &sum_desc, &sum);
777 if (err) {
778 printk(KERN_ERR "ctxfi:Failed to get sum resources for "
779 "front output!\n");
780 break;
781 }
782 mixer->sums[i] = sum;
783 }
784 if (err)
785 goto error1;
786
787 /* Allocate amixer resources for mixer obj */
788 amixer_mgr = (struct amixer_mgr *)mixer->atc->rsc_mgrs[AMIXER];
789 am_desc.msr = mixer->atc->msr;
790 for (i = 0; i < (NUM_CT_AMIXERS * CHN_NUM); i++) {
791 err = amixer_mgr->get_amixer(amixer_mgr, &am_desc, &amixer);
792 if (err) {
793 printk(KERN_ERR "ctxfi:Failed to get amixer resources "
794 "for mixer obj!\n");
795 break;
796 }
797 mixer->amixers[i] = amixer;
798 }
799 if (err)
800 goto error2;
801
802 return 0;
803
804error2:
805 for (i = 0; i < (NUM_CT_AMIXERS * CHN_NUM); i++) {
806 if (NULL != mixer->amixers[i]) {
807 amixer = mixer->amixers[i];
808 amixer_mgr->put_amixer(amixer_mgr, amixer);
809 mixer->amixers[i] = NULL;
810 }
811 }
812error1:
813 for (i = 0; i < (NUM_CT_SUMS * CHN_NUM); i++) {
814 if (NULL != mixer->sums[i]) {
815 sum_mgr->put_sum(sum_mgr, (struct sum *)mixer->sums[i]);
816 mixer->sums[i] = NULL;
817 }
818 }
819
820 return err;
821}
822
823static int ct_mixer_get_mem(struct ct_mixer **rmixer)
824{
825 struct ct_mixer *mixer;
826 int err;
827
828 *rmixer = NULL;
829 /* Allocate mem for mixer obj */
830 mixer = kzalloc(sizeof(*mixer), GFP_KERNEL);
831 if (NULL == mixer)
832 return -ENOMEM;
833
834 mixer->amixers = kzalloc(sizeof(void *)*(NUM_CT_AMIXERS*CHN_NUM),
835 GFP_KERNEL);
836 if (NULL == mixer->amixers) {
837 err = -ENOMEM;
838 goto error1;
839 }
840 mixer->sums = kzalloc(sizeof(void *)*(NUM_CT_SUMS*CHN_NUM), GFP_KERNEL);
841 if (NULL == mixer->sums) {
842 err = -ENOMEM;
843 goto error2;
844 }
845
846 *rmixer = mixer;
847 return 0;
848
849error2:
850 kfree(mixer->amixers);
851error1:
852 kfree(mixer);
853 return err;
854}
855
856static int ct_mixer_topology_build(struct ct_mixer *mixer)
857{
858 struct sum *sum;
859 struct amixer *amix_d, *amix_s;
860 enum CT_AMIXER_CTL i, j;
861
862 /* Build topology from destination to source */
863
864 /* Set up Master mixer */
865 for (i = AMIXER_MASTER_F, j = SUM_IN_F;
866 i <= AMIXER_MASTER_S; i++, j++) {
867 amix_d = mixer->amixers[i*CHN_NUM];
868 sum = mixer->sums[j*CHN_NUM];
869 amix_d->ops->setup(amix_d, &sum->rsc, INIT_VOL, NULL);
870 amix_d = mixer->amixers[i*CHN_NUM+1];
871 sum = mixer->sums[j*CHN_NUM+1];
872 amix_d->ops->setup(amix_d, &sum->rsc, INIT_VOL, NULL);
873 }
874
875 /* Set up Wave-out mixer */
876 for (i = AMIXER_WAVE_F, j = AMIXER_MASTER_F;
877 i <= AMIXER_WAVE_S; i++, j++) {
878 amix_d = mixer->amixers[i*CHN_NUM];
879 amix_s = mixer->amixers[j*CHN_NUM];
880 amix_d->ops->setup(amix_d, &amix_s->rsc, INIT_VOL, NULL);
881 amix_d = mixer->amixers[i*CHN_NUM+1];
882 amix_s = mixer->amixers[j*CHN_NUM+1];
883 amix_d->ops->setup(amix_d, &amix_s->rsc, INIT_VOL, NULL);
884 }
885
886 /* Set up S/PDIF-out mixer */
887 amix_d = mixer->amixers[AMIXER_SPDIFO*CHN_NUM];
888 amix_s = mixer->amixers[AMIXER_MASTER_F*CHN_NUM];
889 amix_d->ops->setup(amix_d, &amix_s->rsc, INIT_VOL, NULL);
890 amix_d = mixer->amixers[AMIXER_SPDIFO*CHN_NUM+1];
891 amix_s = mixer->amixers[AMIXER_MASTER_F*CHN_NUM+1];
892 amix_d->ops->setup(amix_d, &amix_s->rsc, INIT_VOL, NULL);
893
894 /* Set up PCM-in mixer */
895 for (i = AMIXER_PCM_F, j = SUM_IN_F; i <= AMIXER_PCM_S; i++, j++) {
896 amix_d = mixer->amixers[i*CHN_NUM];
897 sum = mixer->sums[j*CHN_NUM];
898 amix_d->ops->setup(amix_d, NULL, INIT_VOL, sum);
899 amix_d = mixer->amixers[i*CHN_NUM+1];
900 sum = mixer->sums[j*CHN_NUM+1];
901 amix_d->ops->setup(amix_d, NULL, INIT_VOL, sum);
902 }
903
904 /* Set up Line-in mixer */
905 amix_d = mixer->amixers[AMIXER_LINEIN*CHN_NUM];
906 sum = mixer->sums[SUM_IN_F*CHN_NUM];
907 amix_d->ops->setup(amix_d, NULL, INIT_VOL, sum);
908 amix_d = mixer->amixers[AMIXER_LINEIN*CHN_NUM+1];
909 sum = mixer->sums[SUM_IN_F*CHN_NUM+1];
910 amix_d->ops->setup(amix_d, NULL, INIT_VOL, sum);
911
912 /* Set up Mic-in mixer */
913 amix_d = mixer->amixers[AMIXER_MIC*CHN_NUM];
914 sum = mixer->sums[SUM_IN_F*CHN_NUM];
915 amix_d->ops->setup(amix_d, NULL, INIT_VOL, sum);
916 amix_d = mixer->amixers[AMIXER_MIC*CHN_NUM+1];
917 sum = mixer->sums[SUM_IN_F*CHN_NUM+1];
918 amix_d->ops->setup(amix_d, NULL, INIT_VOL, sum);
919
920 /* Set up S/PDIF-in mixer */
921 amix_d = mixer->amixers[AMIXER_SPDIFI*CHN_NUM];
922 sum = mixer->sums[SUM_IN_F*CHN_NUM];
923 amix_d->ops->setup(amix_d, NULL, INIT_VOL, sum);
924 amix_d = mixer->amixers[AMIXER_SPDIFI*CHN_NUM+1];
925 sum = mixer->sums[SUM_IN_F*CHN_NUM+1];
926 amix_d->ops->setup(amix_d, NULL, INIT_VOL, sum);
927
928 /* Set up Master recording mixer */
929 amix_d = mixer->amixers[AMIXER_MASTER_F_C*CHN_NUM];
930 sum = mixer->sums[SUM_IN_F_C*CHN_NUM];
931 amix_d->ops->setup(amix_d, &sum->rsc, INIT_VOL, NULL);
932 amix_d = mixer->amixers[AMIXER_MASTER_F_C*CHN_NUM+1];
933 sum = mixer->sums[SUM_IN_F_C*CHN_NUM+1];
934 amix_d->ops->setup(amix_d, &sum->rsc, INIT_VOL, NULL);
935
936 /* Set up PCM-in recording mixer */
937 amix_d = mixer->amixers[AMIXER_PCM_F_C*CHN_NUM];
938 sum = mixer->sums[SUM_IN_F_C*CHN_NUM];
939 amix_d->ops->setup(amix_d, NULL, INIT_VOL, sum);
940 amix_d = mixer->amixers[AMIXER_PCM_F_C*CHN_NUM+1];
941 sum = mixer->sums[SUM_IN_F_C*CHN_NUM+1];
942 amix_d->ops->setup(amix_d, NULL, INIT_VOL, sum);
943
944 /* Set up Line-in recording mixer */
945 amix_d = mixer->amixers[AMIXER_LINEIN_C*CHN_NUM];
946 sum = mixer->sums[SUM_IN_F_C*CHN_NUM];
947 amix_d->ops->setup(amix_d, NULL, INIT_VOL, sum);
948 amix_d = mixer->amixers[AMIXER_LINEIN_C*CHN_NUM+1];
949 sum = mixer->sums[SUM_IN_F_C*CHN_NUM+1];
950 amix_d->ops->setup(amix_d, NULL, INIT_VOL, sum);
951
952 /* Set up Mic-in recording mixer */
953 amix_d = mixer->amixers[AMIXER_MIC_C*CHN_NUM];
954 sum = mixer->sums[SUM_IN_F_C*CHN_NUM];
955 amix_d->ops->setup(amix_d, NULL, INIT_VOL, sum);
956 amix_d = mixer->amixers[AMIXER_MIC_C*CHN_NUM+1];
957 sum = mixer->sums[SUM_IN_F_C*CHN_NUM+1];
958 amix_d->ops->setup(amix_d, NULL, INIT_VOL, sum);
959
960 /* Set up S/PDIF-in recording mixer */
961 amix_d = mixer->amixers[AMIXER_SPDIFI_C*CHN_NUM];
962 sum = mixer->sums[SUM_IN_F_C*CHN_NUM];
963 amix_d->ops->setup(amix_d, NULL, INIT_VOL, sum);
964 amix_d = mixer->amixers[AMIXER_SPDIFI_C*CHN_NUM+1];
965 sum = mixer->sums[SUM_IN_F_C*CHN_NUM+1];
966 amix_d->ops->setup(amix_d, NULL, INIT_VOL, sum);
967
968 return 0;
969}
970
971static int mixer_set_input_port(struct amixer *amixer, struct rsc *rsc)
972{
973 amixer->ops->set_input(amixer, rsc);
974 amixer->ops->commit_write(amixer);
975
976 return 0;
977}
978
979static enum CT_AMIXER_CTL port_to_amixer(enum MIXER_PORT_T type)
980{
981 switch (type) {
982 case MIX_WAVE_FRONT: return AMIXER_WAVE_F;
983 case MIX_WAVE_SURROUND: return AMIXER_WAVE_S;
984 case MIX_WAVE_CENTLFE: return AMIXER_WAVE_C;
985 case MIX_WAVE_REAR: return AMIXER_WAVE_R;
986 case MIX_PCMO_FRONT: return AMIXER_MASTER_F_C;
987 case MIX_SPDIF_OUT: return AMIXER_SPDIFO;
988 case MIX_LINE_IN: return AMIXER_LINEIN;
989 case MIX_MIC_IN: return AMIXER_MIC;
990 case MIX_SPDIF_IN: return AMIXER_SPDIFI;
991 case MIX_PCMI_FRONT: return AMIXER_PCM_F;
992 case MIX_PCMI_SURROUND: return AMIXER_PCM_S;
993 case MIX_PCMI_CENTLFE: return AMIXER_PCM_C;
994 case MIX_PCMI_REAR: return AMIXER_PCM_R;
995 default: return 0;
996 }
997}
998
999static int mixer_get_output_ports(struct ct_mixer *mixer,
1000 enum MIXER_PORT_T type,
1001 struct rsc **rleft, struct rsc **rright)
1002{
1003 enum CT_AMIXER_CTL amix = port_to_amixer(type);
1004
1005 if (NULL != rleft)
1006 *rleft = &((struct amixer *)mixer->amixers[amix*CHN_NUM])->rsc;
1007
1008 if (NULL != rright)
1009 *rright =
1010 &((struct amixer *)mixer->amixers[amix*CHN_NUM+1])->rsc;
1011
1012 return 0;
1013}
1014
1015static int mixer_set_input_left(struct ct_mixer *mixer,
1016 enum MIXER_PORT_T type, struct rsc *rsc)
1017{
1018 enum CT_AMIXER_CTL amix = port_to_amixer(type);
1019
1020 mixer_set_input_port(mixer->amixers[amix*CHN_NUM], rsc);
1021 amix = get_recording_amixer(amix);
1022 if (amix < NUM_CT_AMIXERS)
1023 mixer_set_input_port(mixer->amixers[amix*CHN_NUM], rsc);
1024
1025 return 0;
1026}
1027
1028static int
1029mixer_set_input_right(struct ct_mixer *mixer,
1030 enum MIXER_PORT_T type, struct rsc *rsc)
1031{
1032 enum CT_AMIXER_CTL amix = port_to_amixer(type);
1033
1034 mixer_set_input_port(mixer->amixers[amix*CHN_NUM+1], rsc);
1035 amix = get_recording_amixer(amix);
1036 if (amix < NUM_CT_AMIXERS)
1037 mixer_set_input_port(mixer->amixers[amix*CHN_NUM+1], rsc);
1038
1039 return 0;
1040}
1041
1042int ct_mixer_destroy(struct ct_mixer *mixer)
1043{
1044 struct sum_mgr *sum_mgr = (struct sum_mgr *)mixer->atc->rsc_mgrs[SUM];
1045 struct amixer_mgr *amixer_mgr =
1046 (struct amixer_mgr *)mixer->atc->rsc_mgrs[AMIXER];
1047 struct amixer *amixer;
1048 int i = 0;
1049
1050 /* Release amixer resources */
1051 for (i = 0; i < (NUM_CT_AMIXERS * CHN_NUM); i++) {
1052 if (NULL != mixer->amixers[i]) {
1053 amixer = mixer->amixers[i];
1054 amixer_mgr->put_amixer(amixer_mgr, amixer);
1055 }
1056 }
1057
1058 /* Release sum resources */
1059 for (i = 0; i < (NUM_CT_SUMS * CHN_NUM); i++) {
1060 if (NULL != mixer->sums[i])
1061 sum_mgr->put_sum(sum_mgr, (struct sum *)mixer->sums[i]);
1062 }
1063
1064 /* Release mem assigned to mixer object */
1065 kfree(mixer->sums);
1066 kfree(mixer->amixers);
1067 kfree(mixer);
1068
1069 return 0;
1070}
1071
1072int ct_mixer_create(struct ct_atc *atc, struct ct_mixer **rmixer)
1073{
1074 struct ct_mixer *mixer;
1075 int err;
1076
1077 *rmixer = NULL;
1078
1079 /* Allocate mem for mixer obj */
1080 err = ct_mixer_get_mem(&mixer);
1081 if (err)
1082 return err;
1083
1084 mixer->switch_state = 0;
1085 mixer->atc = atc;
1086 /* Set operations */
1087 mixer->get_output_ports = mixer_get_output_ports;
1088 mixer->set_input_left = mixer_set_input_left;
1089 mixer->set_input_right = mixer_set_input_right;
1090
1091 /* Allocate chip resources for mixer obj */
1092 err = ct_mixer_get_resources(mixer);
1093 if (err)
1094 goto error;
1095
1096 /* Build internal mixer topology */
1097 ct_mixer_topology_build(mixer);
1098
1099 *rmixer = mixer;
1100
1101 return 0;
1102
1103error:
1104 ct_mixer_destroy(mixer);
1105 return err;
1106}
1107
1108int ct_alsa_mix_create(struct ct_atc *atc,
1109 enum CTALSADEVS device,
1110 const char *device_name)
1111{
1112 int err;
1113
1114 /* Create snd kcontrol instances on demand */
1115 /* vol_ctl.device = swh_ctl.device = device; */ /* better w/ device 0 */
1116 err = ct_mixer_kcontrols_create((struct ct_mixer *)atc->mixer);
1117 if (err)
1118 return err;
1119
1120 strcpy(atc->card->mixername, device_name);
1121
1122 return 0;
1123}
diff --git a/sound/pci/ctxfi/ctmixer.h b/sound/pci/ctxfi/ctmixer.h
new file mode 100644
index 00000000000..e2d96ebde74
--- /dev/null
+++ b/sound/pci/ctxfi/ctmixer.h
@@ -0,0 +1,67 @@
1/**
2 * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
3 *
4 * This source file is released under GPL v2 license (no other versions).
5 * See the COPYING file included in the main directory of this source
6 * distribution for the license terms and conditions.
7 *
8 * @File ctmixer.h
9 *
10 * @Brief
11 * This file contains the definition of the mixer device functions.
12 *
13 * @Author Liu Chun
14 * @Date Mar 28 2008
15 *
16 */
17
18#ifndef CTMIXER_H
19#define CTMIXER_H
20
21#include "ctatc.h"
22#include "ctresource.h"
23
24#define INIT_VOL 0x1c00
25
26enum MIXER_PORT_T {
27 MIX_WAVE_FRONT,
28 MIX_WAVE_REAR,
29 MIX_WAVE_CENTLFE,
30 MIX_WAVE_SURROUND,
31 MIX_SPDIF_OUT,
32 MIX_PCMO_FRONT,
33 MIX_MIC_IN,
34 MIX_LINE_IN,
35 MIX_SPDIF_IN,
36 MIX_PCMI_FRONT,
37 MIX_PCMI_REAR,
38 MIX_PCMI_CENTLFE,
39 MIX_PCMI_SURROUND,
40
41 NUM_MIX_PORTS
42};
43
44/* alsa mixer descriptor */
45struct ct_mixer {
46 struct ct_atc *atc;
47
48 void **amixers; /* amixer resources for volume control */
49 void **sums; /* sum resources for signal collection */
50 unsigned int switch_state; /* A bit-map to indicate state of switches */
51
52 int (*get_output_ports)(struct ct_mixer *mixer, enum MIXER_PORT_T type,
53 struct rsc **rleft, struct rsc **rright);
54
55 int (*set_input_left)(struct ct_mixer *mixer,
56 enum MIXER_PORT_T type, struct rsc *rsc);
57 int (*set_input_right)(struct ct_mixer *mixer,
58 enum MIXER_PORT_T type, struct rsc *rsc);
59};
60
61int ct_alsa_mix_create(struct ct_atc *atc,
62 enum CTALSADEVS device,
63 const char *device_name);
64int ct_mixer_create(struct ct_atc *atc, struct ct_mixer **rmixer);
65int ct_mixer_destroy(struct ct_mixer *mixer);
66
67#endif /* CTMIXER_H */
diff --git a/sound/pci/ctxfi/ctpcm.c b/sound/pci/ctxfi/ctpcm.c
new file mode 100644
index 00000000000..9e5c0c4da72
--- /dev/null
+++ b/sound/pci/ctxfi/ctpcm.c
@@ -0,0 +1,426 @@
1/**
2 * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
3 *
4 * This source file is released under GPL v2 license (no other versions).
5 * See the COPYING file included in the main directory of this source
6 * distribution for the license terms and conditions.
7 *
8 * @File ctpcm.c
9 *
10 * @Brief
11 * This file contains the definition of the pcm device functions.
12 *
13 * @Author Liu Chun
14 * @Date Apr 2 2008
15 *
16 */
17
18#include "ctpcm.h"
19#include "cttimer.h"
20#include <sound/pcm.h>
21
22/* Hardware descriptions for playback */
23static struct snd_pcm_hardware ct_pcm_playback_hw = {
24 .info = (SNDRV_PCM_INFO_MMAP |
25 SNDRV_PCM_INFO_INTERLEAVED |
26 SNDRV_PCM_INFO_BLOCK_TRANSFER |
27 SNDRV_PCM_INFO_MMAP_VALID |
28 SNDRV_PCM_INFO_PAUSE),
29 .formats = (SNDRV_PCM_FMTBIT_U8 |
30 SNDRV_PCM_FMTBIT_S16_LE |
31 SNDRV_PCM_FMTBIT_S24_3LE |
32 SNDRV_PCM_FMTBIT_S32_LE |
33 SNDRV_PCM_FMTBIT_FLOAT_LE),
34 .rates = (SNDRV_PCM_RATE_CONTINUOUS |
35 SNDRV_PCM_RATE_8000_192000),
36 .rate_min = 8000,
37 .rate_max = 192000,
38 .channels_min = 1,
39 .channels_max = 2,
40 .buffer_bytes_max = (128*1024),
41 .period_bytes_min = (64),
42 .period_bytes_max = (128*1024),
43 .periods_min = 2,
44 .periods_max = 1024,
45 .fifo_size = 0,
46};
47
48static struct snd_pcm_hardware ct_spdif_passthru_playback_hw = {
49 .info = (SNDRV_PCM_INFO_MMAP |
50 SNDRV_PCM_INFO_INTERLEAVED |
51 SNDRV_PCM_INFO_BLOCK_TRANSFER |
52 SNDRV_PCM_INFO_MMAP_VALID |
53 SNDRV_PCM_INFO_PAUSE),
54 .formats = SNDRV_PCM_FMTBIT_S16_LE,
55 .rates = (SNDRV_PCM_RATE_48000 |
56 SNDRV_PCM_RATE_44100 |
57 SNDRV_PCM_RATE_32000),
58 .rate_min = 32000,
59 .rate_max = 48000,
60 .channels_min = 2,
61 .channels_max = 2,
62 .buffer_bytes_max = (128*1024),
63 .period_bytes_min = (64),
64 .period_bytes_max = (128*1024),
65 .periods_min = 2,
66 .periods_max = 1024,
67 .fifo_size = 0,
68};
69
70/* Hardware descriptions for capture */
71static struct snd_pcm_hardware ct_pcm_capture_hw = {
72 .info = (SNDRV_PCM_INFO_MMAP |
73 SNDRV_PCM_INFO_INTERLEAVED |
74 SNDRV_PCM_INFO_BLOCK_TRANSFER |
75 SNDRV_PCM_INFO_PAUSE |
76 SNDRV_PCM_INFO_MMAP_VALID),
77 .formats = (SNDRV_PCM_FMTBIT_U8 |
78 SNDRV_PCM_FMTBIT_S16_LE |
79 SNDRV_PCM_FMTBIT_S24_3LE |
80 SNDRV_PCM_FMTBIT_S32_LE |
81 SNDRV_PCM_FMTBIT_FLOAT_LE),
82 .rates = (SNDRV_PCM_RATE_CONTINUOUS |
83 SNDRV_PCM_RATE_8000_96000),
84 .rate_min = 8000,
85 .rate_max = 96000,
86 .channels_min = 1,
87 .channels_max = 2,
88 .buffer_bytes_max = (128*1024),
89 .period_bytes_min = (384),
90 .period_bytes_max = (64*1024),
91 .periods_min = 2,
92 .periods_max = 1024,
93 .fifo_size = 0,
94};
95
96static void ct_atc_pcm_interrupt(struct ct_atc_pcm *atc_pcm)
97{
98 struct ct_atc_pcm *apcm = atc_pcm;
99
100 if (NULL == apcm->substream)
101 return;
102
103 snd_pcm_period_elapsed(apcm->substream);
104}
105
106static void ct_atc_pcm_free_substream(struct snd_pcm_runtime *runtime)
107{
108 struct ct_atc_pcm *apcm = runtime->private_data;
109 struct ct_atc *atc = snd_pcm_substream_chip(apcm->substream);
110
111 atc->pcm_release_resources(atc, apcm);
112 ct_timer_instance_free(apcm->timer);
113 kfree(apcm);
114 runtime->private_data = NULL;
115}
116
117/* pcm playback operations */
118static int ct_pcm_playback_open(struct snd_pcm_substream *substream)
119{
120 struct ct_atc *atc = snd_pcm_substream_chip(substream);
121 struct snd_pcm_runtime *runtime = substream->runtime;
122 struct ct_atc_pcm *apcm;
123 int err;
124
125 apcm = kzalloc(sizeof(*apcm), GFP_KERNEL);
126 if (NULL == apcm)
127 return -ENOMEM;
128
129 apcm->substream = substream;
130 apcm->interrupt = ct_atc_pcm_interrupt;
131 runtime->private_data = apcm;
132 runtime->private_free = ct_atc_pcm_free_substream;
133 if (IEC958 == substream->pcm->device) {
134 runtime->hw = ct_spdif_passthru_playback_hw;
135 atc->spdif_out_passthru(atc, 1);
136 } else {
137 runtime->hw = ct_pcm_playback_hw;
138 if (FRONT == substream->pcm->device)
139 runtime->hw.channels_max = 8;
140 }
141
142 err = snd_pcm_hw_constraint_integer(runtime,
143 SNDRV_PCM_HW_PARAM_PERIODS);
144 if (err < 0) {
145 kfree(apcm);
146 return err;
147 }
148 err = snd_pcm_hw_constraint_minmax(runtime,
149 SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
150 1024, UINT_MAX);
151 if (err < 0) {
152 kfree(apcm);
153 return err;
154 }
155
156 apcm->timer = ct_timer_instance_new(atc->timer, apcm);
157 if (!apcm->timer)
158 return -ENOMEM;
159
160 return 0;
161}
162
163static int ct_pcm_playback_close(struct snd_pcm_substream *substream)
164{
165 struct ct_atc *atc = snd_pcm_substream_chip(substream);
166
167 /* TODO: Notify mixer inactive. */
168 if (IEC958 == substream->pcm->device)
169 atc->spdif_out_passthru(atc, 0);
170
171 /* The ct_atc_pcm object will be freed by runtime->private_free */
172
173 return 0;
174}
175
176static int ct_pcm_hw_params(struct snd_pcm_substream *substream,
177 struct snd_pcm_hw_params *hw_params)
178{
179 struct ct_atc *atc = snd_pcm_substream_chip(substream);
180 struct ct_atc_pcm *apcm = substream->runtime->private_data;
181 int err;
182
183 err = snd_pcm_lib_malloc_pages(substream,
184 params_buffer_bytes(hw_params));
185 if (err < 0)
186 return err;
187 /* clear previous resources */
188 atc->pcm_release_resources(atc, apcm);
189 return err;
190}
191
192static int ct_pcm_hw_free(struct snd_pcm_substream *substream)
193{
194 struct ct_atc *atc = snd_pcm_substream_chip(substream);
195 struct ct_atc_pcm *apcm = substream->runtime->private_data;
196
197 /* clear previous resources */
198 atc->pcm_release_resources(atc, apcm);
199 /* Free snd-allocated pages */
200 return snd_pcm_lib_free_pages(substream);
201}
202
203
204static int ct_pcm_playback_prepare(struct snd_pcm_substream *substream)
205{
206 int err;
207 struct ct_atc *atc = snd_pcm_substream_chip(substream);
208 struct snd_pcm_runtime *runtime = substream->runtime;
209 struct ct_atc_pcm *apcm = runtime->private_data;
210
211 if (IEC958 == substream->pcm->device)
212 err = atc->spdif_passthru_playback_prepare(atc, apcm);
213 else
214 err = atc->pcm_playback_prepare(atc, apcm);
215
216 if (err < 0) {
217 printk(KERN_ERR "ctxfi: Preparing pcm playback failed!!!\n");
218 return err;
219 }
220
221 return 0;
222}
223
224static int
225ct_pcm_playback_trigger(struct snd_pcm_substream *substream, int cmd)
226{
227 struct ct_atc *atc = snd_pcm_substream_chip(substream);
228 struct snd_pcm_runtime *runtime = substream->runtime;
229 struct ct_atc_pcm *apcm = runtime->private_data;
230
231 switch (cmd) {
232 case SNDRV_PCM_TRIGGER_START:
233 case SNDRV_PCM_TRIGGER_RESUME:
234 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
235 atc->pcm_playback_start(atc, apcm);
236 break;
237 case SNDRV_PCM_TRIGGER_STOP:
238 case SNDRV_PCM_TRIGGER_SUSPEND:
239 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
240 atc->pcm_playback_stop(atc, apcm);
241 break;
242 default:
243 break;
244 }
245
246 return 0;
247}
248
249static snd_pcm_uframes_t
250ct_pcm_playback_pointer(struct snd_pcm_substream *substream)
251{
252 unsigned long position;
253 struct ct_atc *atc = snd_pcm_substream_chip(substream);
254 struct snd_pcm_runtime *runtime = substream->runtime;
255 struct ct_atc_pcm *apcm = runtime->private_data;
256
257 /* Read out playback position */
258 position = atc->pcm_playback_position(atc, apcm);
259 position = bytes_to_frames(runtime, position);
260 if (position >= runtime->buffer_size)
261 position = 0;
262 return position;
263}
264
265/* pcm capture operations */
266static int ct_pcm_capture_open(struct snd_pcm_substream *substream)
267{
268 struct ct_atc *atc = snd_pcm_substream_chip(substream);
269 struct snd_pcm_runtime *runtime = substream->runtime;
270 struct ct_atc_pcm *apcm;
271 int err;
272
273 apcm = kzalloc(sizeof(*apcm), GFP_KERNEL);
274 if (NULL == apcm)
275 return -ENOMEM;
276
277 apcm->started = 0;
278 apcm->substream = substream;
279 apcm->interrupt = ct_atc_pcm_interrupt;
280 runtime->private_data = apcm;
281 runtime->private_free = ct_atc_pcm_free_substream;
282 runtime->hw = ct_pcm_capture_hw;
283 runtime->hw.rate_max = atc->rsr * atc->msr;
284
285 err = snd_pcm_hw_constraint_integer(runtime,
286 SNDRV_PCM_HW_PARAM_PERIODS);
287 if (err < 0) {
288 kfree(apcm);
289 return err;
290 }
291 err = snd_pcm_hw_constraint_minmax(runtime,
292 SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
293 1024, UINT_MAX);
294 if (err < 0) {
295 kfree(apcm);
296 return err;
297 }
298
299 apcm->timer = ct_timer_instance_new(atc->timer, apcm);
300 if (!apcm->timer)
301 return -ENOMEM;
302
303 return 0;
304}
305
306static int ct_pcm_capture_close(struct snd_pcm_substream *substream)
307{
308 /* The ct_atc_pcm object will be freed by runtime->private_free */
309 /* TODO: Notify mixer inactive. */
310 return 0;
311}
312
313static int ct_pcm_capture_prepare(struct snd_pcm_substream *substream)
314{
315 int err;
316 struct ct_atc *atc = snd_pcm_substream_chip(substream);
317 struct snd_pcm_runtime *runtime = substream->runtime;
318 struct ct_atc_pcm *apcm = runtime->private_data;
319
320 err = atc->pcm_capture_prepare(atc, apcm);
321 if (err < 0) {
322 printk(KERN_ERR "ctxfi: Preparing pcm capture failed!!!\n");
323 return err;
324 }
325
326 return 0;
327}
328
329static int
330ct_pcm_capture_trigger(struct snd_pcm_substream *substream, int cmd)
331{
332 struct ct_atc *atc = snd_pcm_substream_chip(substream);
333 struct snd_pcm_runtime *runtime = substream->runtime;
334 struct ct_atc_pcm *apcm = runtime->private_data;
335
336 switch (cmd) {
337 case SNDRV_PCM_TRIGGER_START:
338 atc->pcm_capture_start(atc, apcm);
339 break;
340 case SNDRV_PCM_TRIGGER_STOP:
341 atc->pcm_capture_stop(atc, apcm);
342 break;
343 default:
344 atc->pcm_capture_stop(atc, apcm);
345 break;
346 }
347
348 return 0;
349}
350
351static snd_pcm_uframes_t
352ct_pcm_capture_pointer(struct snd_pcm_substream *substream)
353{
354 unsigned long position;
355 struct ct_atc *atc = snd_pcm_substream_chip(substream);
356 struct snd_pcm_runtime *runtime = substream->runtime;
357 struct ct_atc_pcm *apcm = runtime->private_data;
358
359 /* Read out playback position */
360 position = atc->pcm_capture_position(atc, apcm);
361 position = bytes_to_frames(runtime, position);
362 if (position >= runtime->buffer_size)
363 position = 0;
364 return position;
365}
366
367/* PCM operators for playback */
368static struct snd_pcm_ops ct_pcm_playback_ops = {
369 .open = ct_pcm_playback_open,
370 .close = ct_pcm_playback_close,
371 .ioctl = snd_pcm_lib_ioctl,
372 .hw_params = ct_pcm_hw_params,
373 .hw_free = ct_pcm_hw_free,
374 .prepare = ct_pcm_playback_prepare,
375 .trigger = ct_pcm_playback_trigger,
376 .pointer = ct_pcm_playback_pointer,
377 .page = snd_pcm_sgbuf_ops_page,
378};
379
380/* PCM operators for capture */
381static struct snd_pcm_ops ct_pcm_capture_ops = {
382 .open = ct_pcm_capture_open,
383 .close = ct_pcm_capture_close,
384 .ioctl = snd_pcm_lib_ioctl,
385 .hw_params = ct_pcm_hw_params,
386 .hw_free = ct_pcm_hw_free,
387 .prepare = ct_pcm_capture_prepare,
388 .trigger = ct_pcm_capture_trigger,
389 .pointer = ct_pcm_capture_pointer,
390 .page = snd_pcm_sgbuf_ops_page,
391};
392
393/* Create ALSA pcm device */
394int ct_alsa_pcm_create(struct ct_atc *atc,
395 enum CTALSADEVS device,
396 const char *device_name)
397{
398 struct snd_pcm *pcm;
399 int err;
400 int playback_count, capture_count;
401
402 playback_count = (IEC958 == device) ? 1 : 8;
403 capture_count = (FRONT == device) ? 1 : 0;
404 err = snd_pcm_new(atc->card, "ctxfi", device,
405 playback_count, capture_count, &pcm);
406 if (err < 0) {
407 printk(KERN_ERR "ctxfi: snd_pcm_new failed!! Err=%d\n", err);
408 return err;
409 }
410
411 pcm->private_data = atc;
412 pcm->info_flags = 0;
413 pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX;
414 strlcpy(pcm->name, device_name, sizeof(pcm->name));
415
416 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &ct_pcm_playback_ops);
417
418 if (FRONT == device)
419 snd_pcm_set_ops(pcm,
420 SNDRV_PCM_STREAM_CAPTURE, &ct_pcm_capture_ops);
421
422 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
423 snd_dma_pci_data(atc->pci), 128*1024, 128*1024);
424
425 return 0;
426}
diff --git a/sound/pci/ctxfi/ctpcm.h b/sound/pci/ctxfi/ctpcm.h
new file mode 100644
index 00000000000..178da0dca64
--- /dev/null
+++ b/sound/pci/ctxfi/ctpcm.h
@@ -0,0 +1,27 @@
1/**
2 * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
3 *
4 * This source file is released under GPL v2 license (no other versions).
5 * See the COPYING file included in the main directory of this source
6 * distribution for the license terms and conditions.
7 *
8 * @File ctpcm.h
9 *
10 * @Brief
11 * This file contains the definition of the pcm device functions.
12 *
13 * @Author Liu Chun
14 * @Date Mar 28 2008
15 *
16 */
17
18#ifndef CTPCM_H
19#define CTPCM_H
20
21#include "ctatc.h"
22
23int ct_alsa_pcm_create(struct ct_atc *atc,
24 enum CTALSADEVS device,
25 const char *device_name);
26
27#endif /* CTPCM_H */
diff --git a/sound/pci/ctxfi/ctresource.c b/sound/pci/ctxfi/ctresource.c
new file mode 100644
index 00000000000..889c495bb7d
--- /dev/null
+++ b/sound/pci/ctxfi/ctresource.c
@@ -0,0 +1,301 @@
1/**
2 * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
3 *
4 * This source file is released under GPL v2 license (no other versions).
5 * See the COPYING file included in the main directory of this source
6 * distribution for the license terms and conditions.
7 *
8 * @File ctresource.c
9 *
10 * @Brief
11 * This file contains the implementation of some generic helper functions.
12 *
13 * @Author Liu Chun
14 * @Date May 15 2008
15 *
16 */
17
18#include "ctresource.h"
19#include "cthardware.h"
20#include <linux/err.h>
21#include <linux/slab.h>
22
23#define AUDIO_SLOT_BLOCK_NUM 256
24
25/* Resource allocation based on bit-map management mechanism */
26static int
27get_resource(u8 *rscs, unsigned int amount,
28 unsigned int multi, unsigned int *ridx)
29{
30 int i, j, k, n;
31
32 /* Check whether there are sufficient resources to meet request. */
33 for (i = 0, n = multi; i < amount; i++) {
34 j = i / 8;
35 k = i % 8;
36 if (rscs[j] & ((u8)1 << k)) {
37 n = multi;
38 continue;
39 }
40 if (!(--n))
41 break; /* found sufficient contiguous resources */
42 }
43
44 if (i >= amount) {
45 /* Can not find sufficient contiguous resources */
46 return -ENOENT;
47 }
48
49 /* Mark the contiguous bits in resource bit-map as used */
50 for (n = multi; n > 0; n--) {
51 j = i / 8;
52 k = i % 8;
53 rscs[j] |= ((u8)1 << k);
54 i--;
55 }
56
57 *ridx = i + 1;
58
59 return 0;
60}
61
62static int put_resource(u8 *rscs, unsigned int multi, unsigned int idx)
63{
64 unsigned int i, j, k, n;
65
66 /* Mark the contiguous bits in resource bit-map as used */
67 for (n = multi, i = idx; n > 0; n--) {
68 j = i / 8;
69 k = i % 8;
70 rscs[j] &= ~((u8)1 << k);
71 i++;
72 }
73
74 return 0;
75}
76
77int mgr_get_resource(struct rsc_mgr *mgr, unsigned int n, unsigned int *ridx)
78{
79 int err;
80
81 if (n > mgr->avail)
82 return -ENOENT;
83
84 err = get_resource(mgr->rscs, mgr->amount, n, ridx);
85 if (!err)
86 mgr->avail -= n;
87
88 return err;
89}
90
91int mgr_put_resource(struct rsc_mgr *mgr, unsigned int n, unsigned int idx)
92{
93 put_resource(mgr->rscs, n, idx);
94 mgr->avail += n;
95
96 return 0;
97}
98
99static unsigned char offset_in_audio_slot_block[NUM_RSCTYP] = {
100 /* SRC channel is at Audio Ring slot 1 every 16 slots. */
101 [SRC] = 0x1,
102 [AMIXER] = 0x4,
103 [SUM] = 0xc,
104};
105
106static int rsc_index(const struct rsc *rsc)
107{
108 return rsc->conj;
109}
110
111static int audio_ring_slot(const struct rsc *rsc)
112{
113 return (rsc->conj << 4) + offset_in_audio_slot_block[rsc->type];
114}
115
116static int rsc_next_conj(struct rsc *rsc)
117{
118 unsigned int i;
119 for (i = 0; (i < 8) && (!(rsc->msr & (0x1 << i))); )
120 i++;
121 rsc->conj += (AUDIO_SLOT_BLOCK_NUM >> i);
122 return rsc->conj;
123}
124
125static int rsc_master(struct rsc *rsc)
126{
127 return rsc->conj = rsc->idx;
128}
129
130static struct rsc_ops rsc_generic_ops = {
131 .index = rsc_index,
132 .output_slot = audio_ring_slot,
133 .master = rsc_master,
134 .next_conj = rsc_next_conj,
135};
136
137int rsc_init(struct rsc *rsc, u32 idx, enum RSCTYP type, u32 msr, void *hw)
138{
139 int err = 0;
140
141 rsc->idx = idx;
142 rsc->conj = idx;
143 rsc->type = type;
144 rsc->msr = msr;
145 rsc->hw = hw;
146 rsc->ops = &rsc_generic_ops;
147 if (NULL == hw) {
148 rsc->ctrl_blk = NULL;
149 return 0;
150 }
151
152 switch (type) {
153 case SRC:
154 err = ((struct hw *)hw)->src_rsc_get_ctrl_blk(&rsc->ctrl_blk);
155 break;
156 case AMIXER:
157 err = ((struct hw *)hw)->
158 amixer_rsc_get_ctrl_blk(&rsc->ctrl_blk);
159 break;
160 case SRCIMP:
161 case SUM:
162 case DAIO:
163 break;
164 default:
165 printk(KERN_ERR
166 "ctxfi: Invalid resource type value %d!\n", type);
167 return -EINVAL;
168 }
169
170 if (err) {
171 printk(KERN_ERR
172 "ctxfi: Failed to get resource control block!\n");
173 return err;
174 }
175
176 return 0;
177}
178
179int rsc_uninit(struct rsc *rsc)
180{
181 if ((NULL != rsc->hw) && (NULL != rsc->ctrl_blk)) {
182 switch (rsc->type) {
183 case SRC:
184 ((struct hw *)rsc->hw)->
185 src_rsc_put_ctrl_blk(rsc->ctrl_blk);
186 break;
187 case AMIXER:
188 ((struct hw *)rsc->hw)->
189 amixer_rsc_put_ctrl_blk(rsc->ctrl_blk);
190 break;
191 case SUM:
192 case DAIO:
193 break;
194 default:
195 printk(KERN_ERR "ctxfi: "
196 "Invalid resource type value %d!\n", rsc->type);
197 break;
198 }
199
200 rsc->hw = rsc->ctrl_blk = NULL;
201 }
202
203 rsc->idx = rsc->conj = 0;
204 rsc->type = NUM_RSCTYP;
205 rsc->msr = 0;
206
207 return 0;
208}
209
210int rsc_mgr_init(struct rsc_mgr *mgr, enum RSCTYP type,
211 unsigned int amount, void *hw_obj)
212{
213 int err = 0;
214 struct hw *hw = hw_obj;
215
216 mgr->type = NUM_RSCTYP;
217
218 mgr->rscs = kzalloc(((amount + 8 - 1) / 8), GFP_KERNEL);
219 if (NULL == mgr->rscs)
220 return -ENOMEM;
221
222 switch (type) {
223 case SRC:
224 err = hw->src_mgr_get_ctrl_blk(&mgr->ctrl_blk);
225 break;
226 case SRCIMP:
227 err = hw->srcimp_mgr_get_ctrl_blk(&mgr->ctrl_blk);
228 break;
229 case AMIXER:
230 err = hw->amixer_mgr_get_ctrl_blk(&mgr->ctrl_blk);
231 break;
232 case DAIO:
233 err = hw->daio_mgr_get_ctrl_blk(hw, &mgr->ctrl_blk);
234 break;
235 case SUM:
236 break;
237 default:
238 printk(KERN_ERR
239 "ctxfi: Invalid resource type value %d!\n", type);
240 err = -EINVAL;
241 goto error;
242 }
243
244 if (err) {
245 printk(KERN_ERR
246 "ctxfi: Failed to get manager control block!\n");
247 goto error;
248 }
249
250 mgr->type = type;
251 mgr->avail = mgr->amount = amount;
252 mgr->hw = hw;
253
254 return 0;
255
256error:
257 kfree(mgr->rscs);
258 return err;
259}
260
261int rsc_mgr_uninit(struct rsc_mgr *mgr)
262{
263 if (NULL != mgr->rscs) {
264 kfree(mgr->rscs);
265 mgr->rscs = NULL;
266 }
267
268 if ((NULL != mgr->hw) && (NULL != mgr->ctrl_blk)) {
269 switch (mgr->type) {
270 case SRC:
271 ((struct hw *)mgr->hw)->
272 src_mgr_put_ctrl_blk(mgr->ctrl_blk);
273 break;
274 case SRCIMP:
275 ((struct hw *)mgr->hw)->
276 srcimp_mgr_put_ctrl_blk(mgr->ctrl_blk);
277 break;
278 case AMIXER:
279 ((struct hw *)mgr->hw)->
280 amixer_mgr_put_ctrl_blk(mgr->ctrl_blk);
281 break;
282 case DAIO:
283 ((struct hw *)mgr->hw)->
284 daio_mgr_put_ctrl_blk(mgr->ctrl_blk);
285 break;
286 case SUM:
287 break;
288 default:
289 printk(KERN_ERR "ctxfi: "
290 "Invalid resource type value %d!\n", mgr->type);
291 break;
292 }
293
294 mgr->hw = mgr->ctrl_blk = NULL;
295 }
296
297 mgr->type = NUM_RSCTYP;
298 mgr->avail = mgr->amount = 0;
299
300 return 0;
301}
diff --git a/sound/pci/ctxfi/ctresource.h b/sound/pci/ctxfi/ctresource.h
new file mode 100644
index 00000000000..0838c2e84f8
--- /dev/null
+++ b/sound/pci/ctxfi/ctresource.h
@@ -0,0 +1,72 @@
1/**
2 * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
3 *
4 * This source file is released under GPL v2 license (no other versions).
5 * See the COPYING file included in the main directory of this source
6 * distribution for the license terms and conditions.
7 *
8 * @File ctresource.h
9 *
10 * @Brief
11 * This file contains the definition of generic hardware resources for
12 * resource management.
13 *
14 * @Author Liu Chun
15 * @Date May 13 2008
16 *
17 */
18
19#ifndef CTRESOURCE_H
20#define CTRESOURCE_H
21
22#include <linux/types.h>
23
24enum RSCTYP {
25 SRC,
26 SRCIMP,
27 AMIXER,
28 SUM,
29 DAIO,
30 NUM_RSCTYP /* This must be the last one and less than 16 */
31};
32
33struct rsc_ops;
34
35struct rsc {
36 u32 idx:12; /* The index of a resource */
37 u32 type:4; /* The type (RSCTYP) of a resource */
38 u32 conj:12; /* Current conjugate index */
39 u32 msr:4; /* The Master Sample Rate a resource working on */
40 void *ctrl_blk; /* Chip specific control info block for a resource */
41 void *hw; /* Chip specific object for hardware access means */
42 struct rsc_ops *ops; /* Generic resource operations */
43};
44
45struct rsc_ops {
46 int (*master)(struct rsc *rsc); /* Move to master resource */
47 int (*next_conj)(struct rsc *rsc); /* Move to next conjugate resource */
48 int (*index)(const struct rsc *rsc); /* Return the index of resource */
49 /* Return the output slot number */
50 int (*output_slot)(const struct rsc *rsc);
51};
52
53int rsc_init(struct rsc *rsc, u32 idx, enum RSCTYP type, u32 msr, void *hw);
54int rsc_uninit(struct rsc *rsc);
55
56struct rsc_mgr {
57 enum RSCTYP type; /* The type (RSCTYP) of resource to manage */
58 unsigned int amount; /* The total amount of a kind of resource */
59 unsigned int avail; /* The amount of currently available resources */
60 unsigned char *rscs; /* The bit-map for resource allocation */
61 void *ctrl_blk; /* Chip specific control info block */
62 void *hw; /* Chip specific object for hardware access */
63};
64
65/* Resource management is based on bit-map mechanism */
66int rsc_mgr_init(struct rsc_mgr *mgr, enum RSCTYP type,
67 unsigned int amount, void *hw);
68int rsc_mgr_uninit(struct rsc_mgr *mgr);
69int mgr_get_resource(struct rsc_mgr *mgr, unsigned int n, unsigned int *ridx);
70int mgr_put_resource(struct rsc_mgr *mgr, unsigned int n, unsigned int idx);
71
72#endif /* CTRESOURCE_H */
diff --git a/sound/pci/ctxfi/ctsrc.c b/sound/pci/ctxfi/ctsrc.c
new file mode 100644
index 00000000000..e1c145d8b70
--- /dev/null
+++ b/sound/pci/ctxfi/ctsrc.c
@@ -0,0 +1,886 @@
1/**
2 * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
3 *
4 * This source file is released under GPL v2 license (no other versions).
5 * See the COPYING file included in the main directory of this source
6 * distribution for the license terms and conditions.
7 *
8 * @File ctsrc.c
9 *
10 * @Brief
11 * This file contains the implementation of the Sample Rate Convertor
12 * resource management object.
13 *
14 * @Author Liu Chun
15 * @Date May 13 2008
16 *
17 */
18
19#include "ctsrc.h"
20#include "cthardware.h"
21#include <linux/slab.h>
22
23#define SRC_RESOURCE_NUM 64
24#define SRCIMP_RESOURCE_NUM 256
25
26static unsigned int conj_mask;
27
28static int src_default_config_memrd(struct src *src);
29static int src_default_config_memwr(struct src *src);
30static int src_default_config_arcrw(struct src *src);
31
32static int (*src_default_config[3])(struct src *) = {
33 [MEMRD] = src_default_config_memrd,
34 [MEMWR] = src_default_config_memwr,
35 [ARCRW] = src_default_config_arcrw
36};
37
38static int src_set_state(struct src *src, unsigned int state)
39{
40 struct hw *hw;
41
42 hw = src->rsc.hw;
43 hw->src_set_state(src->rsc.ctrl_blk, state);
44
45 return 0;
46}
47
48static int src_set_bm(struct src *src, unsigned int bm)
49{
50 struct hw *hw;
51
52 hw = src->rsc.hw;
53 hw->src_set_bm(src->rsc.ctrl_blk, bm);
54
55 return 0;
56}
57
58static int src_set_sf(struct src *src, unsigned int sf)
59{
60 struct hw *hw;
61
62 hw = src->rsc.hw;
63 hw->src_set_sf(src->rsc.ctrl_blk, sf);
64
65 return 0;
66}
67
68static int src_set_pm(struct src *src, unsigned int pm)
69{
70 struct hw *hw;
71
72 hw = src->rsc.hw;
73 hw->src_set_pm(src->rsc.ctrl_blk, pm);
74
75 return 0;
76}
77
78static int src_set_rom(struct src *src, unsigned int rom)
79{
80 struct hw *hw;
81
82 hw = src->rsc.hw;
83 hw->src_set_rom(src->rsc.ctrl_blk, rom);
84
85 return 0;
86}
87
88static int src_set_vo(struct src *src, unsigned int vo)
89{
90 struct hw *hw;
91
92 hw = src->rsc.hw;
93 hw->src_set_vo(src->rsc.ctrl_blk, vo);
94
95 return 0;
96}
97
98static int src_set_st(struct src *src, unsigned int st)
99{
100 struct hw *hw;
101
102 hw = src->rsc.hw;
103 hw->src_set_st(src->rsc.ctrl_blk, st);
104
105 return 0;
106}
107
108static int src_set_bp(struct src *src, unsigned int bp)
109{
110 struct hw *hw;
111
112 hw = src->rsc.hw;
113 hw->src_set_bp(src->rsc.ctrl_blk, bp);
114
115 return 0;
116}
117
118static int src_set_cisz(struct src *src, unsigned int cisz)
119{
120 struct hw *hw;
121
122 hw = src->rsc.hw;
123 hw->src_set_cisz(src->rsc.ctrl_blk, cisz);
124
125 return 0;
126}
127
128static int src_set_ca(struct src *src, unsigned int ca)
129{
130 struct hw *hw;
131
132 hw = src->rsc.hw;
133 hw->src_set_ca(src->rsc.ctrl_blk, ca);
134
135 return 0;
136}
137
138static int src_set_sa(struct src *src, unsigned int sa)
139{
140 struct hw *hw;
141
142 hw = src->rsc.hw;
143 hw->src_set_sa(src->rsc.ctrl_blk, sa);
144
145 return 0;
146}
147
148static int src_set_la(struct src *src, unsigned int la)
149{
150 struct hw *hw;
151
152 hw = src->rsc.hw;
153 hw->src_set_la(src->rsc.ctrl_blk, la);
154
155 return 0;
156}
157
158static int src_set_pitch(struct src *src, unsigned int pitch)
159{
160 struct hw *hw;
161
162 hw = src->rsc.hw;
163 hw->src_set_pitch(src->rsc.ctrl_blk, pitch);
164
165 return 0;
166}
167
168static int src_set_clear_zbufs(struct src *src)
169{
170 struct hw *hw;
171
172 hw = src->rsc.hw;
173 hw->src_set_clear_zbufs(src->rsc.ctrl_blk, 1);
174
175 return 0;
176}
177
178static int src_commit_write(struct src *src)
179{
180 struct hw *hw;
181 int i;
182 unsigned int dirty = 0;
183
184 hw = src->rsc.hw;
185 src->rsc.ops->master(&src->rsc);
186 if (src->rsc.msr > 1) {
187 /* Save dirty flags for conjugate resource programming */
188 dirty = hw->src_get_dirty(src->rsc.ctrl_blk) & conj_mask;
189 }
190 hw->src_commit_write(hw, src->rsc.ops->index(&src->rsc),
191 src->rsc.ctrl_blk);
192
193 /* Program conjugate parameter mixer resources */
194 if (MEMWR == src->mode)
195 return 0;
196
197 for (i = 1; i < src->rsc.msr; i++) {
198 src->rsc.ops->next_conj(&src->rsc);
199 hw->src_set_dirty(src->rsc.ctrl_blk, dirty);
200 hw->src_commit_write(hw, src->rsc.ops->index(&src->rsc),
201 src->rsc.ctrl_blk);
202 }
203 src->rsc.ops->master(&src->rsc);
204
205 return 0;
206}
207
208static int src_get_ca(struct src *src)
209{
210 struct hw *hw;
211
212 hw = src->rsc.hw;
213 return hw->src_get_ca(hw, src->rsc.ops->index(&src->rsc),
214 src->rsc.ctrl_blk);
215}
216
217static int src_init(struct src *src)
218{
219 src_default_config[src->mode](src);
220
221 return 0;
222}
223
224static struct src *src_next_interleave(struct src *src)
225{
226 return src->intlv;
227}
228
229static int src_default_config_memrd(struct src *src)
230{
231 struct hw *hw = src->rsc.hw;
232 unsigned int rsr, msr;
233
234 hw->src_set_state(src->rsc.ctrl_blk, SRC_STATE_OFF);
235 hw->src_set_bm(src->rsc.ctrl_blk, 1);
236 for (rsr = 0, msr = src->rsc.msr; msr > 1; msr >>= 1)
237 rsr++;
238
239 hw->src_set_rsr(src->rsc.ctrl_blk, rsr);
240 hw->src_set_sf(src->rsc.ctrl_blk, SRC_SF_S16);
241 hw->src_set_wr(src->rsc.ctrl_blk, 0);
242 hw->src_set_pm(src->rsc.ctrl_blk, 0);
243 hw->src_set_rom(src->rsc.ctrl_blk, 0);
244 hw->src_set_vo(src->rsc.ctrl_blk, 0);
245 hw->src_set_st(src->rsc.ctrl_blk, 0);
246 hw->src_set_ilsz(src->rsc.ctrl_blk, src->multi - 1);
247 hw->src_set_cisz(src->rsc.ctrl_blk, 0x80);
248 hw->src_set_sa(src->rsc.ctrl_blk, 0x0);
249 hw->src_set_la(src->rsc.ctrl_blk, 0x1000);
250 hw->src_set_ca(src->rsc.ctrl_blk, 0x80);
251 hw->src_set_pitch(src->rsc.ctrl_blk, 0x1000000);
252 hw->src_set_clear_zbufs(src->rsc.ctrl_blk, 1);
253
254 src->rsc.ops->master(&src->rsc);
255 hw->src_commit_write(hw, src->rsc.ops->index(&src->rsc),
256 src->rsc.ctrl_blk);
257
258 for (msr = 1; msr < src->rsc.msr; msr++) {
259 src->rsc.ops->next_conj(&src->rsc);
260 hw->src_set_pitch(src->rsc.ctrl_blk, 0x1000000);
261 hw->src_commit_write(hw, src->rsc.ops->index(&src->rsc),
262 src->rsc.ctrl_blk);
263 }
264 src->rsc.ops->master(&src->rsc);
265
266 return 0;
267}
268
269static int src_default_config_memwr(struct src *src)
270{
271 struct hw *hw = src->rsc.hw;
272
273 hw->src_set_state(src->rsc.ctrl_blk, SRC_STATE_OFF);
274 hw->src_set_bm(src->rsc.ctrl_blk, 1);
275 hw->src_set_rsr(src->rsc.ctrl_blk, 0);
276 hw->src_set_sf(src->rsc.ctrl_blk, SRC_SF_S16);
277 hw->src_set_wr(src->rsc.ctrl_blk, 1);
278 hw->src_set_pm(src->rsc.ctrl_blk, 0);
279 hw->src_set_rom(src->rsc.ctrl_blk, 0);
280 hw->src_set_vo(src->rsc.ctrl_blk, 0);
281 hw->src_set_st(src->rsc.ctrl_blk, 0);
282 hw->src_set_ilsz(src->rsc.ctrl_blk, 0);
283 hw->src_set_cisz(src->rsc.ctrl_blk, 0x80);
284 hw->src_set_sa(src->rsc.ctrl_blk, 0x0);
285 hw->src_set_la(src->rsc.ctrl_blk, 0x1000);
286 hw->src_set_ca(src->rsc.ctrl_blk, 0x80);
287 hw->src_set_pitch(src->rsc.ctrl_blk, 0x1000000);
288 hw->src_set_clear_zbufs(src->rsc.ctrl_blk, 1);
289
290 src->rsc.ops->master(&src->rsc);
291 hw->src_commit_write(hw, src->rsc.ops->index(&src->rsc),
292 src->rsc.ctrl_blk);
293
294 return 0;
295}
296
297static int src_default_config_arcrw(struct src *src)
298{
299 struct hw *hw = src->rsc.hw;
300 unsigned int rsr, msr;
301 unsigned int dirty;
302
303 hw->src_set_state(src->rsc.ctrl_blk, SRC_STATE_OFF);
304 hw->src_set_bm(src->rsc.ctrl_blk, 0);
305 for (rsr = 0, msr = src->rsc.msr; msr > 1; msr >>= 1)
306 rsr++;
307
308 hw->src_set_rsr(src->rsc.ctrl_blk, rsr);
309 hw->src_set_sf(src->rsc.ctrl_blk, SRC_SF_F32);
310 hw->src_set_wr(src->rsc.ctrl_blk, 0);
311 hw->src_set_pm(src->rsc.ctrl_blk, 0);
312 hw->src_set_rom(src->rsc.ctrl_blk, 0);
313 hw->src_set_vo(src->rsc.ctrl_blk, 0);
314 hw->src_set_st(src->rsc.ctrl_blk, 0);
315 hw->src_set_ilsz(src->rsc.ctrl_blk, 0);
316 hw->src_set_cisz(src->rsc.ctrl_blk, 0x80);
317 hw->src_set_sa(src->rsc.ctrl_blk, 0x0);
318 /*hw->src_set_sa(src->rsc.ctrl_blk, 0x100);*/
319 hw->src_set_la(src->rsc.ctrl_blk, 0x1000);
320 /*hw->src_set_la(src->rsc.ctrl_blk, 0x03ffffe0);*/
321 hw->src_set_ca(src->rsc.ctrl_blk, 0x80);
322 hw->src_set_pitch(src->rsc.ctrl_blk, 0x1000000);
323 hw->src_set_clear_zbufs(src->rsc.ctrl_blk, 1);
324
325 dirty = hw->src_get_dirty(src->rsc.ctrl_blk);
326 src->rsc.ops->master(&src->rsc);
327 for (msr = 0; msr < src->rsc.msr; msr++) {
328 hw->src_set_dirty(src->rsc.ctrl_blk, dirty);
329 hw->src_commit_write(hw, src->rsc.ops->index(&src->rsc),
330 src->rsc.ctrl_blk);
331 src->rsc.ops->next_conj(&src->rsc);
332 }
333 src->rsc.ops->master(&src->rsc);
334
335 return 0;
336}
337
338static struct src_rsc_ops src_rsc_ops = {
339 .set_state = src_set_state,
340 .set_bm = src_set_bm,
341 .set_sf = src_set_sf,
342 .set_pm = src_set_pm,
343 .set_rom = src_set_rom,
344 .set_vo = src_set_vo,
345 .set_st = src_set_st,
346 .set_bp = src_set_bp,
347 .set_cisz = src_set_cisz,
348 .set_ca = src_set_ca,
349 .set_sa = src_set_sa,
350 .set_la = src_set_la,
351 .set_pitch = src_set_pitch,
352 .set_clr_zbufs = src_set_clear_zbufs,
353 .commit_write = src_commit_write,
354 .get_ca = src_get_ca,
355 .init = src_init,
356 .next_interleave = src_next_interleave,
357};
358
359static int
360src_rsc_init(struct src *src, u32 idx,
361 const struct src_desc *desc, struct src_mgr *mgr)
362{
363 int err;
364 int i, n;
365 struct src *p;
366
367 n = (MEMRD == desc->mode) ? desc->multi : 1;
368 for (i = 0, p = src; i < n; i++, p++) {
369 err = rsc_init(&p->rsc, idx + i, SRC, desc->msr, mgr->mgr.hw);
370 if (err)
371 goto error1;
372
373 /* Initialize src specific rsc operations */
374 p->ops = &src_rsc_ops;
375 p->multi = (0 == i) ? desc->multi : 1;
376 p->mode = desc->mode;
377 src_default_config[desc->mode](p);
378 mgr->src_enable(mgr, p);
379 p->intlv = p + 1;
380 }
381 (--p)->intlv = NULL; /* Set @intlv of the last SRC to NULL */
382
383 mgr->commit_write(mgr);
384
385 return 0;
386
387error1:
388 for (i--, p--; i >= 0; i--, p--) {
389 mgr->src_disable(mgr, p);
390 rsc_uninit(&p->rsc);
391 }
392 mgr->commit_write(mgr);
393 return err;
394}
395
396static int src_rsc_uninit(struct src *src, struct src_mgr *mgr)
397{
398 int i, n;
399 struct src *p;
400
401 n = (MEMRD == src->mode) ? src->multi : 1;
402 for (i = 0, p = src; i < n; i++, p++) {
403 mgr->src_disable(mgr, p);
404 rsc_uninit(&p->rsc);
405 p->multi = 0;
406 p->ops = NULL;
407 p->mode = NUM_SRCMODES;
408 p->intlv = NULL;
409 }
410 mgr->commit_write(mgr);
411
412 return 0;
413}
414
415static int
416get_src_rsc(struct src_mgr *mgr, const struct src_desc *desc, struct src **rsrc)
417{
418 unsigned int idx = SRC_RESOURCE_NUM;
419 int err;
420 struct src *src;
421 unsigned long flags;
422
423 *rsrc = NULL;
424
425 /* Check whether there are sufficient src resources to meet request. */
426 spin_lock_irqsave(&mgr->mgr_lock, flags);
427 if (MEMRD == desc->mode)
428 err = mgr_get_resource(&mgr->mgr, desc->multi, &idx);
429 else
430 err = mgr_get_resource(&mgr->mgr, 1, &idx);
431
432 spin_unlock_irqrestore(&mgr->mgr_lock, flags);
433 if (err) {
434 printk(KERN_ERR "ctxfi: Can't meet SRC resource request!\n");
435 return err;
436 }
437
438 /* Allocate mem for master src resource */
439 if (MEMRD == desc->mode)
440 src = kzalloc(sizeof(*src)*desc->multi, GFP_KERNEL);
441 else
442 src = kzalloc(sizeof(*src), GFP_KERNEL);
443
444 if (NULL == src) {
445 err = -ENOMEM;
446 goto error1;
447 }
448
449 err = src_rsc_init(src, idx, desc, mgr);
450 if (err)
451 goto error2;
452
453 *rsrc = src;
454
455 return 0;
456
457error2:
458 kfree(src);
459error1:
460 spin_lock_irqsave(&mgr->mgr_lock, flags);
461 if (MEMRD == desc->mode)
462 mgr_put_resource(&mgr->mgr, desc->multi, idx);
463 else
464 mgr_put_resource(&mgr->mgr, 1, idx);
465
466 spin_unlock_irqrestore(&mgr->mgr_lock, flags);
467 return err;
468}
469
470static int put_src_rsc(struct src_mgr *mgr, struct src *src)
471{
472 unsigned long flags;
473
474 spin_lock_irqsave(&mgr->mgr_lock, flags);
475 src->rsc.ops->master(&src->rsc);
476 if (MEMRD == src->mode)
477 mgr_put_resource(&mgr->mgr, src->multi,
478 src->rsc.ops->index(&src->rsc));
479 else
480 mgr_put_resource(&mgr->mgr, 1, src->rsc.ops->index(&src->rsc));
481
482 spin_unlock_irqrestore(&mgr->mgr_lock, flags);
483 src_rsc_uninit(src, mgr);
484 kfree(src);
485
486 return 0;
487}
488
489static int src_enable_s(struct src_mgr *mgr, struct src *src)
490{
491 struct hw *hw = mgr->mgr.hw;
492 int i;
493
494 src->rsc.ops->master(&src->rsc);
495 for (i = 0; i < src->rsc.msr; i++) {
496 hw->src_mgr_enbs_src(mgr->mgr.ctrl_blk,
497 src->rsc.ops->index(&src->rsc));
498 src->rsc.ops->next_conj(&src->rsc);
499 }
500 src->rsc.ops->master(&src->rsc);
501
502 return 0;
503}
504
505static int src_enable(struct src_mgr *mgr, struct src *src)
506{
507 struct hw *hw = mgr->mgr.hw;
508 int i;
509
510 src->rsc.ops->master(&src->rsc);
511 for (i = 0; i < src->rsc.msr; i++) {
512 hw->src_mgr_enb_src(mgr->mgr.ctrl_blk,
513 src->rsc.ops->index(&src->rsc));
514 src->rsc.ops->next_conj(&src->rsc);
515 }
516 src->rsc.ops->master(&src->rsc);
517
518 return 0;
519}
520
521static int src_disable(struct src_mgr *mgr, struct src *src)
522{
523 struct hw *hw = mgr->mgr.hw;
524 int i;
525
526 src->rsc.ops->master(&src->rsc);
527 for (i = 0; i < src->rsc.msr; i++) {
528 hw->src_mgr_dsb_src(mgr->mgr.ctrl_blk,
529 src->rsc.ops->index(&src->rsc));
530 src->rsc.ops->next_conj(&src->rsc);
531 }
532 src->rsc.ops->master(&src->rsc);
533
534 return 0;
535}
536
537static int src_mgr_commit_write(struct src_mgr *mgr)
538{
539 struct hw *hw = mgr->mgr.hw;
540
541 hw->src_mgr_commit_write(hw, mgr->mgr.ctrl_blk);
542
543 return 0;
544}
545
546int src_mgr_create(void *hw, struct src_mgr **rsrc_mgr)
547{
548 int err, i;
549 struct src_mgr *src_mgr;
550
551 *rsrc_mgr = NULL;
552 src_mgr = kzalloc(sizeof(*src_mgr), GFP_KERNEL);
553 if (NULL == src_mgr)
554 return -ENOMEM;
555
556 err = rsc_mgr_init(&src_mgr->mgr, SRC, SRC_RESOURCE_NUM, hw);
557 if (err)
558 goto error1;
559
560 spin_lock_init(&src_mgr->mgr_lock);
561 conj_mask = ((struct hw *)hw)->src_dirty_conj_mask();
562
563 src_mgr->get_src = get_src_rsc;
564 src_mgr->put_src = put_src_rsc;
565 src_mgr->src_enable_s = src_enable_s;
566 src_mgr->src_enable = src_enable;
567 src_mgr->src_disable = src_disable;
568 src_mgr->commit_write = src_mgr_commit_write;
569
570 /* Disable all SRC resources. */
571 for (i = 0; i < 256; i++)
572 ((struct hw *)hw)->src_mgr_dsb_src(src_mgr->mgr.ctrl_blk, i);
573
574 ((struct hw *)hw)->src_mgr_commit_write(hw, src_mgr->mgr.ctrl_blk);
575
576 *rsrc_mgr = src_mgr;
577
578 return 0;
579
580error1:
581 kfree(src_mgr);
582 return err;
583}
584
585int src_mgr_destroy(struct src_mgr *src_mgr)
586{
587 rsc_mgr_uninit(&src_mgr->mgr);
588 kfree(src_mgr);
589
590 return 0;
591}
592
593/* SRCIMP resource manager operations */
594
595static int srcimp_master(struct rsc *rsc)
596{
597 rsc->conj = 0;
598 return rsc->idx = container_of(rsc, struct srcimp, rsc)->idx[0];
599}
600
601static int srcimp_next_conj(struct rsc *rsc)
602{
603 rsc->conj++;
604 return container_of(rsc, struct srcimp, rsc)->idx[rsc->conj];
605}
606
607static int srcimp_index(const struct rsc *rsc)
608{
609 return container_of(rsc, struct srcimp, rsc)->idx[rsc->conj];
610}
611
612static struct rsc_ops srcimp_basic_rsc_ops = {
613 .master = srcimp_master,
614 .next_conj = srcimp_next_conj,
615 .index = srcimp_index,
616 .output_slot = NULL,
617};
618
619static int srcimp_map(struct srcimp *srcimp, struct src *src, struct rsc *input)
620{
621 struct imapper *entry;
622 int i;
623
624 srcimp->rsc.ops->master(&srcimp->rsc);
625 src->rsc.ops->master(&src->rsc);
626 input->ops->master(input);
627
628 /* Program master and conjugate resources */
629 for (i = 0; i < srcimp->rsc.msr; i++) {
630 entry = &srcimp->imappers[i];
631 entry->slot = input->ops->output_slot(input);
632 entry->user = src->rsc.ops->index(&src->rsc);
633 entry->addr = srcimp->rsc.ops->index(&srcimp->rsc);
634 srcimp->mgr->imap_add(srcimp->mgr, entry);
635 srcimp->mapped |= (0x1 << i);
636
637 srcimp->rsc.ops->next_conj(&srcimp->rsc);
638 input->ops->next_conj(input);
639 }
640
641 srcimp->rsc.ops->master(&srcimp->rsc);
642 input->ops->master(input);
643
644 return 0;
645}
646
647static int srcimp_unmap(struct srcimp *srcimp)
648{
649 int i;
650
651 /* Program master and conjugate resources */
652 for (i = 0; i < srcimp->rsc.msr; i++) {
653 if (srcimp->mapped & (0x1 << i)) {
654 srcimp->mgr->imap_delete(srcimp->mgr,
655 &srcimp->imappers[i]);
656 srcimp->mapped &= ~(0x1 << i);
657 }
658 }
659
660 return 0;
661}
662
663static struct srcimp_rsc_ops srcimp_ops = {
664 .map = srcimp_map,
665 .unmap = srcimp_unmap
666};
667
668static int srcimp_rsc_init(struct srcimp *srcimp,
669 const struct srcimp_desc *desc,
670 struct srcimp_mgr *mgr)
671{
672 int err;
673
674 err = rsc_init(&srcimp->rsc, srcimp->idx[0],
675 SRCIMP, desc->msr, mgr->mgr.hw);
676 if (err)
677 return err;
678
679 /* Reserve memory for imapper nodes */
680 srcimp->imappers = kzalloc(sizeof(struct imapper)*desc->msr,
681 GFP_KERNEL);
682 if (NULL == srcimp->imappers) {
683 err = -ENOMEM;
684 goto error1;
685 }
686
687 /* Set srcimp specific operations */
688 srcimp->rsc.ops = &srcimp_basic_rsc_ops;
689 srcimp->ops = &srcimp_ops;
690 srcimp->mgr = mgr;
691
692 srcimp->rsc.ops->master(&srcimp->rsc);
693
694 return 0;
695
696error1:
697 rsc_uninit(&srcimp->rsc);
698 return err;
699}
700
701static int srcimp_rsc_uninit(struct srcimp *srcimp)
702{
703 if (NULL != srcimp->imappers) {
704 kfree(srcimp->imappers);
705 srcimp->imappers = NULL;
706 }
707 srcimp->ops = NULL;
708 srcimp->mgr = NULL;
709 rsc_uninit(&srcimp->rsc);
710
711 return 0;
712}
713
714static int get_srcimp_rsc(struct srcimp_mgr *mgr,
715 const struct srcimp_desc *desc,
716 struct srcimp **rsrcimp)
717{
718 int err, i;
719 unsigned int idx;
720 struct srcimp *srcimp;
721 unsigned long flags;
722
723 *rsrcimp = NULL;
724
725 /* Allocate mem for SRCIMP resource */
726 srcimp = kzalloc(sizeof(*srcimp), GFP_KERNEL);
727 if (NULL == srcimp) {
728 err = -ENOMEM;
729 return err;
730 }
731
732 /* Check whether there are sufficient SRCIMP resources. */
733 spin_lock_irqsave(&mgr->mgr_lock, flags);
734 for (i = 0; i < desc->msr; i++) {
735 err = mgr_get_resource(&mgr->mgr, 1, &idx);
736 if (err)
737 break;
738
739 srcimp->idx[i] = idx;
740 }
741 spin_unlock_irqrestore(&mgr->mgr_lock, flags);
742 if (err) {
743 printk(KERN_ERR "ctxfi: Can't meet SRCIMP resource request!\n");
744 goto error1;
745 }
746
747 err = srcimp_rsc_init(srcimp, desc, mgr);
748 if (err)
749 goto error1;
750
751 *rsrcimp = srcimp;
752
753 return 0;
754
755error1:
756 spin_lock_irqsave(&mgr->mgr_lock, flags);
757 for (i--; i >= 0; i--)
758 mgr_put_resource(&mgr->mgr, 1, srcimp->idx[i]);
759
760 spin_unlock_irqrestore(&mgr->mgr_lock, flags);
761 kfree(srcimp);
762 return err;
763}
764
765static int put_srcimp_rsc(struct srcimp_mgr *mgr, struct srcimp *srcimp)
766{
767 unsigned long flags;
768 int i;
769
770 spin_lock_irqsave(&mgr->mgr_lock, flags);
771 for (i = 0; i < srcimp->rsc.msr; i++)
772 mgr_put_resource(&mgr->mgr, 1, srcimp->idx[i]);
773
774 spin_unlock_irqrestore(&mgr->mgr_lock, flags);
775 srcimp_rsc_uninit(srcimp);
776 kfree(srcimp);
777
778 return 0;
779}
780
781static int srcimp_map_op(void *data, struct imapper *entry)
782{
783 struct rsc_mgr *mgr = &((struct srcimp_mgr *)data)->mgr;
784 struct hw *hw = mgr->hw;
785
786 hw->srcimp_mgr_set_imaparc(mgr->ctrl_blk, entry->slot);
787 hw->srcimp_mgr_set_imapuser(mgr->ctrl_blk, entry->user);
788 hw->srcimp_mgr_set_imapnxt(mgr->ctrl_blk, entry->next);
789 hw->srcimp_mgr_set_imapaddr(mgr->ctrl_blk, entry->addr);
790 hw->srcimp_mgr_commit_write(mgr->hw, mgr->ctrl_blk);
791
792 return 0;
793}
794
795static int srcimp_imap_add(struct srcimp_mgr *mgr, struct imapper *entry)
796{
797 unsigned long flags;
798 int err;
799
800 spin_lock_irqsave(&mgr->imap_lock, flags);
801 if ((0 == entry->addr) && (mgr->init_imap_added)) {
802 input_mapper_delete(&mgr->imappers,
803 mgr->init_imap, srcimp_map_op, mgr);
804 mgr->init_imap_added = 0;
805 }
806 err = input_mapper_add(&mgr->imappers, entry, srcimp_map_op, mgr);
807 spin_unlock_irqrestore(&mgr->imap_lock, flags);
808
809 return err;
810}
811
812static int srcimp_imap_delete(struct srcimp_mgr *mgr, struct imapper *entry)
813{
814 unsigned long flags;
815 int err;
816
817 spin_lock_irqsave(&mgr->imap_lock, flags);
818 err = input_mapper_delete(&mgr->imappers, entry, srcimp_map_op, mgr);
819 if (list_empty(&mgr->imappers)) {
820 input_mapper_add(&mgr->imappers, mgr->init_imap,
821 srcimp_map_op, mgr);
822 mgr->init_imap_added = 1;
823 }
824 spin_unlock_irqrestore(&mgr->imap_lock, flags);
825
826 return err;
827}
828
829int srcimp_mgr_create(void *hw, struct srcimp_mgr **rsrcimp_mgr)
830{
831 int err;
832 struct srcimp_mgr *srcimp_mgr;
833 struct imapper *entry;
834
835 *rsrcimp_mgr = NULL;
836 srcimp_mgr = kzalloc(sizeof(*srcimp_mgr), GFP_KERNEL);
837 if (NULL == srcimp_mgr)
838 return -ENOMEM;
839
840 err = rsc_mgr_init(&srcimp_mgr->mgr, SRCIMP, SRCIMP_RESOURCE_NUM, hw);
841 if (err)
842 goto error1;
843
844 spin_lock_init(&srcimp_mgr->mgr_lock);
845 spin_lock_init(&srcimp_mgr->imap_lock);
846 INIT_LIST_HEAD(&srcimp_mgr->imappers);
847 entry = kzalloc(sizeof(*entry), GFP_KERNEL);
848 if (NULL == entry) {
849 err = -ENOMEM;
850 goto error2;
851 }
852 entry->slot = entry->addr = entry->next = entry->user = 0;
853 list_add(&entry->list, &srcimp_mgr->imappers);
854 srcimp_mgr->init_imap = entry;
855 srcimp_mgr->init_imap_added = 1;
856
857 srcimp_mgr->get_srcimp = get_srcimp_rsc;
858 srcimp_mgr->put_srcimp = put_srcimp_rsc;
859 srcimp_mgr->imap_add = srcimp_imap_add;
860 srcimp_mgr->imap_delete = srcimp_imap_delete;
861
862 *rsrcimp_mgr = srcimp_mgr;
863
864 return 0;
865
866error2:
867 rsc_mgr_uninit(&srcimp_mgr->mgr);
868error1:
869 kfree(srcimp_mgr);
870 return err;
871}
872
873int srcimp_mgr_destroy(struct srcimp_mgr *srcimp_mgr)
874{
875 unsigned long flags;
876
877 /* free src input mapper list */
878 spin_lock_irqsave(&srcimp_mgr->imap_lock, flags);
879 free_input_mapper_list(&srcimp_mgr->imappers);
880 spin_unlock_irqrestore(&srcimp_mgr->imap_lock, flags);
881
882 rsc_mgr_uninit(&srcimp_mgr->mgr);
883 kfree(srcimp_mgr);
884
885 return 0;
886}
diff --git a/sound/pci/ctxfi/ctsrc.h b/sound/pci/ctxfi/ctsrc.h
new file mode 100644
index 00000000000..259366aabca
--- /dev/null
+++ b/sound/pci/ctxfi/ctsrc.h
@@ -0,0 +1,149 @@
1/**
2 * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
3 *
4 * This source file is released under GPL v2 license (no other versions).
5 * See the COPYING file included in the main directory of this source
6 * distribution for the license terms and conditions.
7 *
8 * @File ctsrc.h
9 *
10 * @Brief
11 * This file contains the definition of the Sample Rate Convertor
12 * resource management object.
13 *
14 * @Author Liu Chun
15 * @Date May 13 2008
16 *
17 */
18
19#ifndef CTSRC_H
20#define CTSRC_H
21
22#include "ctresource.h"
23#include "ctimap.h"
24#include <linux/spinlock.h>
25#include <linux/list.h>
26
27#define SRC_STATE_OFF 0x0
28#define SRC_STATE_INIT 0x4
29#define SRC_STATE_RUN 0x5
30
31#define SRC_SF_U8 0x0
32#define SRC_SF_S16 0x1
33#define SRC_SF_S24 0x2
34#define SRC_SF_S32 0x3
35#define SRC_SF_F32 0x4
36
37/* Define the descriptor of a src resource */
38enum SRCMODE {
39 MEMRD, /* Read data from host memory */
40 MEMWR, /* Write data to host memory */
41 ARCRW, /* Read from and write to audio ring channel */
42 NUM_SRCMODES
43};
44
45struct src_rsc_ops;
46
47struct src {
48 struct rsc rsc; /* Basic resource info */
49 struct src *intlv; /* Pointer to next interleaved SRC in a series */
50 struct src_rsc_ops *ops; /* SRC specific operations */
51 /* Number of contiguous srcs for interleaved usage */
52 unsigned char multi;
53 unsigned char mode; /* Working mode of this SRC resource */
54};
55
56struct src_rsc_ops {
57 int (*set_state)(struct src *src, unsigned int state);
58 int (*set_bm)(struct src *src, unsigned int bm);
59 int (*set_sf)(struct src *src, unsigned int sf);
60 int (*set_pm)(struct src *src, unsigned int pm);
61 int (*set_rom)(struct src *src, unsigned int rom);
62 int (*set_vo)(struct src *src, unsigned int vo);
63 int (*set_st)(struct src *src, unsigned int st);
64 int (*set_bp)(struct src *src, unsigned int bp);
65 int (*set_cisz)(struct src *src, unsigned int cisz);
66 int (*set_ca)(struct src *src, unsigned int ca);
67 int (*set_sa)(struct src *src, unsigned int sa);
68 int (*set_la)(struct src *src, unsigned int la);
69 int (*set_pitch)(struct src *src, unsigned int pitch);
70 int (*set_clr_zbufs)(struct src *src);
71 int (*commit_write)(struct src *src);
72 int (*get_ca)(struct src *src);
73 int (*init)(struct src *src);
74 struct src* (*next_interleave)(struct src *src);
75};
76
77/* Define src resource request description info */
78struct src_desc {
79 /* Number of contiguous master srcs for interleaved usage */
80 unsigned char multi;
81 unsigned char msr;
82 unsigned char mode; /* Working mode of the requested srcs */
83};
84
85/* Define src manager object */
86struct src_mgr {
87 struct rsc_mgr mgr; /* Basic resource manager info */
88 spinlock_t mgr_lock;
89
90 /* request src resource */
91 int (*get_src)(struct src_mgr *mgr,
92 const struct src_desc *desc, struct src **rsrc);
93 /* return src resource */
94 int (*put_src)(struct src_mgr *mgr, struct src *src);
95 int (*src_enable_s)(struct src_mgr *mgr, struct src *src);
96 int (*src_enable)(struct src_mgr *mgr, struct src *src);
97 int (*src_disable)(struct src_mgr *mgr, struct src *src);
98 int (*commit_write)(struct src_mgr *mgr);
99};
100
101/* Define the descriptor of a SRC Input Mapper resource */
102struct srcimp_mgr;
103struct srcimp_rsc_ops;
104
105struct srcimp {
106 struct rsc rsc;
107 unsigned char idx[8];
108 struct imapper *imappers;
109 unsigned int mapped; /* A bit-map indicating which conj rsc is mapped */
110 struct srcimp_mgr *mgr;
111 struct srcimp_rsc_ops *ops;
112};
113
114struct srcimp_rsc_ops {
115 int (*map)(struct srcimp *srcimp, struct src *user, struct rsc *input);
116 int (*unmap)(struct srcimp *srcimp);
117};
118
119/* Define SRCIMP resource request description info */
120struct srcimp_desc {
121 unsigned int msr;
122};
123
124struct srcimp_mgr {
125 struct rsc_mgr mgr; /* Basic resource manager info */
126 spinlock_t mgr_lock;
127 spinlock_t imap_lock;
128 struct list_head imappers;
129 struct imapper *init_imap;
130 unsigned int init_imap_added;
131
132 /* request srcimp resource */
133 int (*get_srcimp)(struct srcimp_mgr *mgr,
134 const struct srcimp_desc *desc,
135 struct srcimp **rsrcimp);
136 /* return srcimp resource */
137 int (*put_srcimp)(struct srcimp_mgr *mgr, struct srcimp *srcimp);
138 int (*imap_add)(struct srcimp_mgr *mgr, struct imapper *entry);
139 int (*imap_delete)(struct srcimp_mgr *mgr, struct imapper *entry);
140};
141
142/* Constructor and destructor of SRC resource manager */
143int src_mgr_create(void *hw, struct src_mgr **rsrc_mgr);
144int src_mgr_destroy(struct src_mgr *src_mgr);
145/* Constructor and destructor of SRCIMP resource manager */
146int srcimp_mgr_create(void *hw, struct srcimp_mgr **rsrc_mgr);
147int srcimp_mgr_destroy(struct srcimp_mgr *srcimp_mgr);
148
149#endif /* CTSRC_H */
diff --git a/sound/pci/ctxfi/cttimer.c b/sound/pci/ctxfi/cttimer.c
new file mode 100644
index 00000000000..779c6c3591a
--- /dev/null
+++ b/sound/pci/ctxfi/cttimer.c
@@ -0,0 +1,441 @@
1/*
2 * PCM timer handling on ctxfi
3 *
4 * This source file is released under GPL v2 license (no other versions).
5 * See the COPYING file included in the main directory of this source
6 * distribution for the license terms and conditions.
7 */
8
9#include <linux/slab.h>
10#include <linux/math64.h>
11#include <linux/moduleparam.h>
12#include <sound/core.h>
13#include <sound/pcm.h>
14#include "ctatc.h"
15#include "cthardware.h"
16#include "cttimer.h"
17
18static int use_system_timer;
19MODULE_PARM_DESC(use_system_timer, "Foce to use system-timer");
20module_param(use_system_timer, bool, S_IRUGO);
21
22struct ct_timer_ops {
23 void (*init)(struct ct_timer_instance *);
24 void (*prepare)(struct ct_timer_instance *);
25 void (*start)(struct ct_timer_instance *);
26 void (*stop)(struct ct_timer_instance *);
27 void (*free_instance)(struct ct_timer_instance *);
28 void (*interrupt)(struct ct_timer *);
29 void (*free_global)(struct ct_timer *);
30};
31
32/* timer instance -- assigned to each PCM stream */
33struct ct_timer_instance {
34 spinlock_t lock;
35 struct ct_timer *timer_base;
36 struct ct_atc_pcm *apcm;
37 struct snd_pcm_substream *substream;
38 struct timer_list timer;
39 struct list_head instance_list;
40 struct list_head running_list;
41 unsigned int position;
42 unsigned int frag_count;
43 unsigned int running:1;
44 unsigned int need_update:1;
45};
46
47/* timer instance manager */
48struct ct_timer {
49 spinlock_t lock; /* global timer lock (for xfitimer) */
50 spinlock_t list_lock; /* lock for instance list */
51 struct ct_atc *atc;
52 struct ct_timer_ops *ops;
53 struct list_head instance_head;
54 struct list_head running_head;
55 unsigned int wc; /* current wallclock */
56 unsigned int irq_handling:1; /* in IRQ handling */
57 unsigned int reprogram:1; /* need to reprogram the internval */
58 unsigned int running:1; /* global timer running */
59};
60
61
62/*
63 * system-timer-based updates
64 */
65
66static void ct_systimer_callback(unsigned long data)
67{
68 struct ct_timer_instance *ti = (struct ct_timer_instance *)data;
69 struct snd_pcm_substream *substream = ti->substream;
70 struct snd_pcm_runtime *runtime = substream->runtime;
71 struct ct_atc_pcm *apcm = ti->apcm;
72 unsigned int period_size = runtime->period_size;
73 unsigned int buffer_size = runtime->buffer_size;
74 unsigned long flags;
75 unsigned int position, dist, interval;
76
77 position = substream->ops->pointer(substream);
78 dist = (position + buffer_size - ti->position) % buffer_size;
79 if (dist >= period_size ||
80 position / period_size != ti->position / period_size) {
81 apcm->interrupt(apcm);
82 ti->position = position;
83 }
84 /* Add extra HZ*5/1000 to avoid overrun issue when recording
85 * at 8kHz in 8-bit format or at 88kHz in 24-bit format. */
86 interval = ((period_size - (position % period_size))
87 * HZ + (runtime->rate - 1)) / runtime->rate + HZ * 5 / 1000;
88 spin_lock_irqsave(&ti->lock, flags);
89 if (ti->running)
90 mod_timer(&ti->timer, jiffies + interval);
91 spin_unlock_irqrestore(&ti->lock, flags);
92}
93
94static void ct_systimer_init(struct ct_timer_instance *ti)
95{
96 setup_timer(&ti->timer, ct_systimer_callback,
97 (unsigned long)ti);
98}
99
100static void ct_systimer_start(struct ct_timer_instance *ti)
101{
102 struct snd_pcm_runtime *runtime = ti->substream->runtime;
103 unsigned long flags;
104
105 spin_lock_irqsave(&ti->lock, flags);
106 ti->running = 1;
107 mod_timer(&ti->timer,
108 jiffies + (runtime->period_size * HZ +
109 (runtime->rate - 1)) / runtime->rate);
110 spin_unlock_irqrestore(&ti->lock, flags);
111}
112
113static void ct_systimer_stop(struct ct_timer_instance *ti)
114{
115 unsigned long flags;
116
117 spin_lock_irqsave(&ti->lock, flags);
118 ti->running = 0;
119 del_timer(&ti->timer);
120 spin_unlock_irqrestore(&ti->lock, flags);
121}
122
123static void ct_systimer_prepare(struct ct_timer_instance *ti)
124{
125 ct_systimer_stop(ti);
126 try_to_del_timer_sync(&ti->timer);
127}
128
129#define ct_systimer_free ct_systimer_prepare
130
131static struct ct_timer_ops ct_systimer_ops = {
132 .init = ct_systimer_init,
133 .free_instance = ct_systimer_free,
134 .prepare = ct_systimer_prepare,
135 .start = ct_systimer_start,
136 .stop = ct_systimer_stop,
137};
138
139
140/*
141 * Handling multiple streams using a global emu20k1 timer irq
142 */
143
144#define CT_TIMER_FREQ 48000
145#define MIN_TICKS 1
146#define MAX_TICKS ((1 << 13) - 1)
147
148static void ct_xfitimer_irq_rearm(struct ct_timer *atimer, int ticks)
149{
150 struct hw *hw = atimer->atc->hw;
151 if (ticks > MAX_TICKS)
152 ticks = MAX_TICKS;
153 hw->set_timer_tick(hw, ticks);
154 if (!atimer->running)
155 hw->set_timer_irq(hw, 1);
156 atimer->running = 1;
157}
158
159static void ct_xfitimer_irq_stop(struct ct_timer *atimer)
160{
161 if (atimer->running) {
162 struct hw *hw = atimer->atc->hw;
163 hw->set_timer_irq(hw, 0);
164 hw->set_timer_tick(hw, 0);
165 atimer->running = 0;
166 }
167}
168
169static inline unsigned int ct_xfitimer_get_wc(struct ct_timer *atimer)
170{
171 struct hw *hw = atimer->atc->hw;
172 return hw->get_wc(hw);
173}
174
175/*
176 * reprogram the timer interval;
177 * checks the running instance list and determines the next timer interval.
178 * also updates the each stream position, returns the number of streams
179 * to call snd_pcm_period_elapsed() appropriately
180 *
181 * call this inside the lock and irq disabled
182 */
183static int ct_xfitimer_reprogram(struct ct_timer *atimer)
184{
185 struct ct_timer_instance *ti;
186 unsigned int min_intr = (unsigned int)-1;
187 int updates = 0;
188 unsigned int wc, diff;
189
190 if (list_empty(&atimer->running_head)) {
191 ct_xfitimer_irq_stop(atimer);
192 atimer->reprogram = 0; /* clear flag */
193 return 0;
194 }
195
196 wc = ct_xfitimer_get_wc(atimer);
197 diff = wc - atimer->wc;
198 atimer->wc = wc;
199 list_for_each_entry(ti, &atimer->running_head, running_list) {
200 if (ti->frag_count > diff)
201 ti->frag_count -= diff;
202 else {
203 unsigned int pos;
204 unsigned int period_size, rate;
205
206 period_size = ti->substream->runtime->period_size;
207 rate = ti->substream->runtime->rate;
208 pos = ti->substream->ops->pointer(ti->substream);
209 if (pos / period_size != ti->position / period_size) {
210 ti->need_update = 1;
211 ti->position = pos;
212 updates++;
213 }
214 pos %= period_size;
215 pos = period_size - pos;
216 ti->frag_count = div_u64((u64)pos * CT_TIMER_FREQ +
217 rate - 1, rate);
218 }
219 if (ti->frag_count < min_intr)
220 min_intr = ti->frag_count;
221 }
222
223 if (min_intr < MIN_TICKS)
224 min_intr = MIN_TICKS;
225 ct_xfitimer_irq_rearm(atimer, min_intr);
226 atimer->reprogram = 0; /* clear flag */
227 return updates;
228}
229
230/* look through the instance list and call period_elapsed if needed */
231static void ct_xfitimer_check_period(struct ct_timer *atimer)
232{
233 struct ct_timer_instance *ti;
234 unsigned long flags;
235
236 spin_lock_irqsave(&atimer->list_lock, flags);
237 list_for_each_entry(ti, &atimer->instance_head, instance_list) {
238 if (ti->need_update) {
239 ti->need_update = 0;
240 ti->apcm->interrupt(ti->apcm);
241 }
242 }
243 spin_unlock_irqrestore(&atimer->list_lock, flags);
244}
245
246/* Handle timer-interrupt */
247static void ct_xfitimer_callback(struct ct_timer *atimer)
248{
249 int update;
250 unsigned long flags;
251
252 spin_lock_irqsave(&atimer->lock, flags);
253 atimer->irq_handling = 1;
254 do {
255 update = ct_xfitimer_reprogram(atimer);
256 spin_unlock(&atimer->lock);
257 if (update)
258 ct_xfitimer_check_period(atimer);
259 spin_lock(&atimer->lock);
260 } while (atimer->reprogram);
261 atimer->irq_handling = 0;
262 spin_unlock_irqrestore(&atimer->lock, flags);
263}
264
265static void ct_xfitimer_prepare(struct ct_timer_instance *ti)
266{
267 ti->frag_count = ti->substream->runtime->period_size;
268 ti->need_update = 0;
269}
270
271
272/* start/stop the timer */
273static void ct_xfitimer_update(struct ct_timer *atimer)
274{
275 unsigned long flags;
276 int update;
277
278 spin_lock_irqsave(&atimer->lock, flags);
279 if (atimer->irq_handling) {
280 /* reached from IRQ handler; let it handle later */
281 atimer->reprogram = 1;
282 spin_unlock_irqrestore(&atimer->lock, flags);
283 return;
284 }
285
286 ct_xfitimer_irq_stop(atimer);
287 update = ct_xfitimer_reprogram(atimer);
288 spin_unlock_irqrestore(&atimer->lock, flags);
289 if (update)
290 ct_xfitimer_check_period(atimer);
291}
292
293static void ct_xfitimer_start(struct ct_timer_instance *ti)
294{
295 struct ct_timer *atimer = ti->timer_base;
296 unsigned long flags;
297
298 spin_lock_irqsave(&atimer->lock, flags);
299 if (list_empty(&ti->running_list))
300 atimer->wc = ct_xfitimer_get_wc(atimer);
301 list_add(&ti->running_list, &atimer->running_head);
302 spin_unlock_irqrestore(&atimer->lock, flags);
303 ct_xfitimer_update(atimer);
304}
305
306static void ct_xfitimer_stop(struct ct_timer_instance *ti)
307{
308 struct ct_timer *atimer = ti->timer_base;
309 unsigned long flags;
310
311 spin_lock_irqsave(&atimer->lock, flags);
312 list_del_init(&ti->running_list);
313 ti->need_update = 0;
314 spin_unlock_irqrestore(&atimer->lock, flags);
315 ct_xfitimer_update(atimer);
316}
317
318static void ct_xfitimer_free_global(struct ct_timer *atimer)
319{
320 ct_xfitimer_irq_stop(atimer);
321}
322
323static struct ct_timer_ops ct_xfitimer_ops = {
324 .prepare = ct_xfitimer_prepare,
325 .start = ct_xfitimer_start,
326 .stop = ct_xfitimer_stop,
327 .interrupt = ct_xfitimer_callback,
328 .free_global = ct_xfitimer_free_global,
329};
330
331/*
332 * timer instance
333 */
334
335struct ct_timer_instance *
336ct_timer_instance_new(struct ct_timer *atimer, struct ct_atc_pcm *apcm)
337{
338 struct ct_timer_instance *ti;
339
340 ti = kzalloc(sizeof(*ti), GFP_KERNEL);
341 if (!ti)
342 return NULL;
343 spin_lock_init(&ti->lock);
344 INIT_LIST_HEAD(&ti->instance_list);
345 INIT_LIST_HEAD(&ti->running_list);
346 ti->timer_base = atimer;
347 ti->apcm = apcm;
348 ti->substream = apcm->substream;
349 if (atimer->ops->init)
350 atimer->ops->init(ti);
351
352 spin_lock_irq(&atimer->list_lock);
353 list_add(&ti->instance_list, &atimer->instance_head);
354 spin_unlock_irq(&atimer->list_lock);
355
356 return ti;
357}
358
359void ct_timer_prepare(struct ct_timer_instance *ti)
360{
361 if (ti->timer_base->ops->prepare)
362 ti->timer_base->ops->prepare(ti);
363 ti->position = 0;
364 ti->running = 0;
365}
366
367void ct_timer_start(struct ct_timer_instance *ti)
368{
369 struct ct_timer *atimer = ti->timer_base;
370 atimer->ops->start(ti);
371}
372
373void ct_timer_stop(struct ct_timer_instance *ti)
374{
375 struct ct_timer *atimer = ti->timer_base;
376 atimer->ops->stop(ti);
377}
378
379void ct_timer_instance_free(struct ct_timer_instance *ti)
380{
381 struct ct_timer *atimer = ti->timer_base;
382
383 atimer->ops->stop(ti); /* to be sure */
384 if (atimer->ops->free_instance)
385 atimer->ops->free_instance(ti);
386
387 spin_lock_irq(&atimer->list_lock);
388 list_del(&ti->instance_list);
389 spin_unlock_irq(&atimer->list_lock);
390
391 kfree(ti);
392}
393
394/*
395 * timer manager
396 */
397
398static void ct_timer_interrupt(void *data, unsigned int status)
399{
400 struct ct_timer *timer = data;
401
402 /* Interval timer interrupt */
403 if ((status & IT_INT) && timer->ops->interrupt)
404 timer->ops->interrupt(timer);
405}
406
407struct ct_timer *ct_timer_new(struct ct_atc *atc)
408{
409 struct ct_timer *atimer;
410 struct hw *hw;
411
412 atimer = kzalloc(sizeof(*atimer), GFP_KERNEL);
413 if (!atimer)
414 return NULL;
415 spin_lock_init(&atimer->lock);
416 spin_lock_init(&atimer->list_lock);
417 INIT_LIST_HEAD(&atimer->instance_head);
418 INIT_LIST_HEAD(&atimer->running_head);
419 atimer->atc = atc;
420 hw = atc->hw;
421 if (!use_system_timer && hw->set_timer_irq) {
422 snd_printd(KERN_INFO "ctxfi: Use xfi-native timer\n");
423 atimer->ops = &ct_xfitimer_ops;
424 hw->irq_callback_data = atimer;
425 hw->irq_callback = ct_timer_interrupt;
426 } else {
427 snd_printd(KERN_INFO "ctxfi: Use system timer\n");
428 atimer->ops = &ct_systimer_ops;
429 }
430 return atimer;
431}
432
433void ct_timer_free(struct ct_timer *atimer)
434{
435 struct hw *hw = atimer->atc->hw;
436 hw->irq_callback = NULL;
437 if (atimer->ops->free_global)
438 atimer->ops->free_global(atimer);
439 kfree(atimer);
440}
441
diff --git a/sound/pci/ctxfi/cttimer.h b/sound/pci/ctxfi/cttimer.h
new file mode 100644
index 00000000000..97934822929
--- /dev/null
+++ b/sound/pci/ctxfi/cttimer.h
@@ -0,0 +1,29 @@
1/*
2 * Timer handling
3 */
4
5#ifndef __CTTIMER_H
6#define __CTTIMER_H
7
8#include <linux/spinlock.h>
9#include <linux/timer.h>
10#include <linux/list.h>
11
12struct snd_pcm_substream;
13struct ct_atc;
14struct ct_atc_pcm;
15
16struct ct_timer;
17struct ct_timer_instance;
18
19struct ct_timer *ct_timer_new(struct ct_atc *atc);
20void ct_timer_free(struct ct_timer *atimer);
21
22struct ct_timer_instance *
23ct_timer_instance_new(struct ct_timer *atimer, struct ct_atc_pcm *apcm);
24void ct_timer_instance_free(struct ct_timer_instance *ti);
25void ct_timer_start(struct ct_timer_instance *ti);
26void ct_timer_stop(struct ct_timer_instance *ti);
27void ct_timer_prepare(struct ct_timer_instance *ti);
28
29#endif /* __CTTIMER_H */
diff --git a/sound/pci/ctxfi/ctvmem.c b/sound/pci/ctxfi/ctvmem.c
new file mode 100644
index 00000000000..67665a7e43c
--- /dev/null
+++ b/sound/pci/ctxfi/ctvmem.c
@@ -0,0 +1,250 @@
1/**
2 * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
3 *
4 * This source file is released under GPL v2 license (no other versions).
5 * See the COPYING file included in the main directory of this source
6 * distribution for the license terms and conditions.
7 *
8 * @File ctvmem.c
9 *
10 * @Brief
11 * This file contains the implementation of virtual memory management object
12 * for card device.
13 *
14 * @Author Liu Chun
15 * @Date Apr 1 2008
16 */
17
18#include "ctvmem.h"
19#include <linux/slab.h>
20#include <linux/mm.h>
21#include <linux/io.h>
22#include <sound/pcm.h>
23
24#define CT_PTES_PER_PAGE (CT_PAGE_SIZE / sizeof(void *))
25#define CT_ADDRS_PER_PAGE (CT_PTES_PER_PAGE * CT_PAGE_SIZE)
26
27/* *
28 * Find or create vm block based on requested @size.
29 * @size must be page aligned.
30 * */
31static struct ct_vm_block *
32get_vm_block(struct ct_vm *vm, unsigned int size)
33{
34 struct ct_vm_block *block = NULL, *entry;
35 struct list_head *pos;
36
37 size = CT_PAGE_ALIGN(size);
38 if (size > vm->size) {
39 printk(KERN_ERR "ctxfi: Fail! No sufficient device virtural "
40 "memory space available!\n");
41 return NULL;
42 }
43
44 mutex_lock(&vm->lock);
45 list_for_each(pos, &vm->unused) {
46 entry = list_entry(pos, struct ct_vm_block, list);
47 if (entry->size >= size)
48 break; /* found a block that is big enough */
49 }
50 if (pos == &vm->unused)
51 goto out;
52
53 if (entry->size == size) {
54 /* Move the vm node from unused list to used list directly */
55 list_del(&entry->list);
56 list_add(&entry->list, &vm->used);
57 vm->size -= size;
58 block = entry;
59 goto out;
60 }
61
62 block = kzalloc(sizeof(*block), GFP_KERNEL);
63 if (NULL == block)
64 goto out;
65
66 block->addr = entry->addr;
67 block->size = size;
68 list_add(&block->list, &vm->used);
69 entry->addr += size;
70 entry->size -= size;
71 vm->size -= size;
72
73 out:
74 mutex_unlock(&vm->lock);
75 return block;
76}
77
78static void put_vm_block(struct ct_vm *vm, struct ct_vm_block *block)
79{
80 struct ct_vm_block *entry, *pre_ent;
81 struct list_head *pos, *pre;
82
83 block->size = CT_PAGE_ALIGN(block->size);
84
85 mutex_lock(&vm->lock);
86 list_del(&block->list);
87 vm->size += block->size;
88
89 list_for_each(pos, &vm->unused) {
90 entry = list_entry(pos, struct ct_vm_block, list);
91 if (entry->addr >= (block->addr + block->size))
92 break; /* found a position */
93 }
94 if (pos == &vm->unused) {
95 list_add_tail(&block->list, &vm->unused);
96 entry = block;
97 } else {
98 if ((block->addr + block->size) == entry->addr) {
99 entry->addr = block->addr;
100 entry->size += block->size;
101 kfree(block);
102 } else {
103 __list_add(&block->list, pos->prev, pos);
104 entry = block;
105 }
106 }
107
108 pos = &entry->list;
109 pre = pos->prev;
110 while (pre != &vm->unused) {
111 entry = list_entry(pos, struct ct_vm_block, list);
112 pre_ent = list_entry(pre, struct ct_vm_block, list);
113 if ((pre_ent->addr + pre_ent->size) > entry->addr)
114 break;
115
116 pre_ent->size += entry->size;
117 list_del(pos);
118 kfree(entry);
119 pos = pre;
120 pre = pos->prev;
121 }
122 mutex_unlock(&vm->lock);
123}
124
125/* Map host addr (kmalloced/vmalloced) to device logical addr. */
126static struct ct_vm_block *
127ct_vm_map(struct ct_vm *vm, struct snd_pcm_substream *substream, int size)
128{
129 struct ct_vm_block *block;
130 unsigned int pte_start;
131 unsigned i, pages;
132 unsigned long *ptp;
133
134 block = get_vm_block(vm, size);
135 if (block == NULL) {
136 printk(KERN_ERR "ctxfi: No virtual memory block that is big "
137 "enough to allocate!\n");
138 return NULL;
139 }
140
141 ptp = vm->ptp[0];
142 pte_start = (block->addr >> CT_PAGE_SHIFT);
143 pages = block->size >> CT_PAGE_SHIFT;
144 for (i = 0; i < pages; i++) {
145 unsigned long addr;
146 addr = snd_pcm_sgbuf_get_addr(substream, i << CT_PAGE_SHIFT);
147 ptp[pte_start + i] = addr;
148 }
149
150 block->size = size;
151 return block;
152}
153
154static void ct_vm_unmap(struct ct_vm *vm, struct ct_vm_block *block)
155{
156 /* do unmapping */
157 put_vm_block(vm, block);
158}
159
160/* *
161 * return the host (kmalloced) addr of the @index-th device
162 * page talbe page on success, or NULL on failure.
163 * The first returned NULL indicates the termination.
164 * */
165static void *
166ct_get_ptp_virt(struct ct_vm *vm, int index)
167{
168 void *addr;
169
170 addr = (index >= CT_PTP_NUM) ? NULL : vm->ptp[index];
171
172 return addr;
173}
174
175int ct_vm_create(struct ct_vm **rvm)
176{
177 struct ct_vm *vm;
178 struct ct_vm_block *block;
179 int i;
180
181 *rvm = NULL;
182
183 vm = kzalloc(sizeof(*vm), GFP_KERNEL);
184 if (NULL == vm)
185 return -ENOMEM;
186
187 mutex_init(&vm->lock);
188
189 /* Allocate page table pages */
190 for (i = 0; i < CT_PTP_NUM; i++) {
191 vm->ptp[i] = kmalloc(PAGE_SIZE, GFP_KERNEL);
192 if (NULL == vm->ptp[i])
193 break;
194 }
195 if (!i) {
196 /* no page table pages are allocated */
197 kfree(vm);
198 return -ENOMEM;
199 }
200 vm->size = CT_ADDRS_PER_PAGE * i;
201 /* Initialise remaining ptps */
202 for (; i < CT_PTP_NUM; i++)
203 vm->ptp[i] = NULL;
204
205 vm->map = ct_vm_map;
206 vm->unmap = ct_vm_unmap;
207 vm->get_ptp_virt = ct_get_ptp_virt;
208 INIT_LIST_HEAD(&vm->unused);
209 INIT_LIST_HEAD(&vm->used);
210 block = kzalloc(sizeof(*block), GFP_KERNEL);
211 if (NULL != block) {
212 block->addr = 0;
213 block->size = vm->size;
214 list_add(&block->list, &vm->unused);
215 }
216
217 *rvm = vm;
218 return 0;
219}
220
221/* The caller must ensure no mapping pages are being used
222 * by hardware before calling this function */
223void ct_vm_destroy(struct ct_vm *vm)
224{
225 int i;
226 struct list_head *pos;
227 struct ct_vm_block *entry;
228
229 /* free used and unused list nodes */
230 while (!list_empty(&vm->used)) {
231 pos = vm->used.next;
232 list_del(pos);
233 entry = list_entry(pos, struct ct_vm_block, list);
234 kfree(entry);
235 }
236 while (!list_empty(&vm->unused)) {
237 pos = vm->unused.next;
238 list_del(pos);
239 entry = list_entry(pos, struct ct_vm_block, list);
240 kfree(entry);
241 }
242
243 /* free allocated page table pages */
244 for (i = 0; i < CT_PTP_NUM; i++)
245 kfree(vm->ptp[i]);
246
247 vm->size = 0;
248
249 kfree(vm);
250}
diff --git a/sound/pci/ctxfi/ctvmem.h b/sound/pci/ctxfi/ctvmem.h
new file mode 100644
index 00000000000..01e4fd0386a
--- /dev/null
+++ b/sound/pci/ctxfi/ctvmem.h
@@ -0,0 +1,61 @@
1/**
2 * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
3 *
4 * This source file is released under GPL v2 license (no other versions).
5 * See the COPYING file included in the main directory of this source
6 * distribution for the license terms and conditions.
7 *
8 * @File ctvmem.h
9 *
10 * @Brief
11 * This file contains the definition of virtual memory management object
12 * for card device.
13 *
14 * @Author Liu Chun
15 * @Date Mar 28 2008
16 */
17
18#ifndef CTVMEM_H
19#define CTVMEM_H
20
21#define CT_PTP_NUM 1 /* num of device page table pages */
22
23#include <linux/mutex.h>
24#include <linux/list.h>
25
26/* The chip can handle the page table of 4k pages
27 * (emu20k1 can handle even 8k pages, but we don't use it right now)
28 */
29#define CT_PAGE_SIZE 4096
30#define CT_PAGE_SHIFT 12
31#define CT_PAGE_MASK (~(PAGE_SIZE - 1))
32#define CT_PAGE_ALIGN(addr) ALIGN(addr, CT_PAGE_SIZE)
33
34struct ct_vm_block {
35 unsigned int addr; /* starting logical addr of this block */
36 unsigned int size; /* size of this device virtual mem block */
37 struct list_head list;
38};
39
40struct snd_pcm_substream;
41
42/* Virtual memory management object for card device */
43struct ct_vm {
44 void *ptp[CT_PTP_NUM]; /* Device page table pages */
45 unsigned int size; /* Available addr space in bytes */
46 struct list_head unused; /* List of unused blocks */
47 struct list_head used; /* List of used blocks */
48 struct mutex lock;
49
50 /* Map host addr (kmalloced/vmalloced) to device logical addr. */
51 struct ct_vm_block *(*map)(struct ct_vm *, struct snd_pcm_substream *,
52 int size);
53 /* Unmap device logical addr area. */
54 void (*unmap)(struct ct_vm *, struct ct_vm_block *block);
55 void *(*get_ptp_virt)(struct ct_vm *vm, int index);
56};
57
58int ct_vm_create(struct ct_vm **rvm);
59void ct_vm_destroy(struct ct_vm *vm);
60
61#endif /* CTVMEM_H */
diff --git a/sound/pci/ctxfi/xfi.c b/sound/pci/ctxfi/xfi.c
new file mode 100644
index 00000000000..2d3dd89af15
--- /dev/null
+++ b/sound/pci/ctxfi/xfi.c
@@ -0,0 +1,142 @@
1/*
2 * xfi linux driver.
3 *
4 * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
5 *
6 * This source file is released under GPL v2 license (no other versions).
7 * See the COPYING file included in the main directory of this source
8 * distribution for the license terms and conditions.
9 */
10
11#include <linux/init.h>
12#include <linux/pci.h>
13#include <linux/moduleparam.h>
14#include <linux/pci_ids.h>
15#include <sound/core.h>
16#include <sound/initval.h>
17#include "ctatc.h"
18#include "cthardware.h"
19
20MODULE_AUTHOR("Creative Technology Ltd");
21MODULE_DESCRIPTION("X-Fi driver version 1.03");
22MODULE_LICENSE("GPL v2");
23MODULE_SUPPORTED_DEVICE("{{Creative Labs, Sound Blaster X-Fi}");
24
25static unsigned int reference_rate = 48000;
26static unsigned int multiple = 2;
27MODULE_PARM_DESC(reference_rate, "Reference rate (default=48000)");
28module_param(reference_rate, uint, S_IRUGO);
29MODULE_PARM_DESC(multiple, "Rate multiplier (default=2)");
30module_param(multiple, uint, S_IRUGO);
31
32static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
33static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
34static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
35
36module_param_array(index, int, NULL, 0444);
37MODULE_PARM_DESC(index, "Index value for Creative X-Fi driver");
38module_param_array(id, charp, NULL, 0444);
39MODULE_PARM_DESC(id, "ID string for Creative X-Fi driver");
40module_param_array(enable, bool, NULL, 0444);
41MODULE_PARM_DESC(enable, "Enable Creative X-Fi driver");
42
43static struct pci_device_id ct_pci_dev_ids[] = {
44 /* only X-Fi is supported, so... */
45 { PCI_DEVICE(PCI_VENDOR_ID_CREATIVE, PCI_DEVICE_ID_CREATIVE_20K1),
46 .driver_data = ATC20K1,
47 },
48 { PCI_DEVICE(PCI_VENDOR_ID_CREATIVE, PCI_DEVICE_ID_CREATIVE_20K2),
49 .driver_data = ATC20K2,
50 },
51 { 0, }
52};
53MODULE_DEVICE_TABLE(pci, ct_pci_dev_ids);
54
55static int __devinit
56ct_card_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
57{
58 static int dev;
59 struct snd_card *card;
60 struct ct_atc *atc;
61 int err;
62
63 if (dev >= SNDRV_CARDS)
64 return -ENODEV;
65
66 if (!enable[dev]) {
67 dev++;
68 return -ENOENT;
69 }
70 err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
71 if (err)
72 return err;
73 if ((reference_rate != 48000) && (reference_rate != 44100)) {
74 printk(KERN_ERR "ctxfi: Invalid reference_rate value %u!!!\n",
75 reference_rate);
76 printk(KERN_ERR "ctxfi: The valid values for reference_rate "
77 "are 48000 and 44100, Value 48000 is assumed.\n");
78 reference_rate = 48000;
79 }
80 if ((multiple != 1) && (multiple != 2)) {
81 printk(KERN_ERR "ctxfi: Invalid multiple value %u!!!\n",
82 multiple);
83 printk(KERN_ERR "ctxfi: The valid values for multiple are "
84 "1 and 2, Value 2 is assumed.\n");
85 multiple = 2;
86 }
87 err = ct_atc_create(card, pci, reference_rate, multiple,
88 pci_id->driver_data, &atc);
89 if (err < 0)
90 goto error;
91
92 card->private_data = atc;
93
94 /* Create alsa devices supported by this card */
95 err = ct_atc_create_alsa_devs(atc);
96 if (err < 0)
97 goto error;
98
99 strcpy(card->driver, "SB-XFi");
100 strcpy(card->shortname, "Creative X-Fi");
101 snprintf(card->longname, sizeof(card->longname), "%s %s %s",
102 card->shortname, atc->chip_name, atc->model_name);
103
104 err = snd_card_register(card);
105 if (err < 0)
106 goto error;
107
108 pci_set_drvdata(pci, card);
109 dev++;
110
111 return 0;
112
113error:
114 snd_card_free(card);
115 return err;
116}
117
118static void __devexit ct_card_remove(struct pci_dev *pci)
119{
120 snd_card_free(pci_get_drvdata(pci));
121 pci_set_drvdata(pci, NULL);
122}
123
124static struct pci_driver ct_driver = {
125 .name = "SB-XFi",
126 .id_table = ct_pci_dev_ids,
127 .probe = ct_card_probe,
128 .remove = __devexit_p(ct_card_remove),
129};
130
131static int __init ct_card_init(void)
132{
133 return pci_register_driver(&ct_driver);
134}
135
136static void __exit ct_card_exit(void)
137{
138 pci_unregister_driver(&ct_driver);
139}
140
141module_init(ct_card_init)
142module_exit(ct_card_exit)
diff --git a/sound/pci/emu10k1/emupcm.c b/sound/pci/emu10k1/emupcm.c
index 78f62fd404c..55b83ef73c6 100644
--- a/sound/pci/emu10k1/emupcm.c
+++ b/sound/pci/emu10k1/emupcm.c
@@ -1736,7 +1736,7 @@ static struct snd_pcm_hardware snd_emu10k1_fx8010_playback =
1736 .buffer_bytes_max = (128*1024), 1736 .buffer_bytes_max = (128*1024),
1737 .period_bytes_min = 1024, 1737 .period_bytes_min = 1024,
1738 .period_bytes_max = (128*1024), 1738 .period_bytes_max = (128*1024),
1739 .periods_min = 1, 1739 .periods_min = 2,
1740 .periods_max = 1024, 1740 .periods_max = 1024,
1741 .fifo_size = 0, 1741 .fifo_size = 0,
1742}; 1742};
diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig
index eb2a19b894a..c710150d506 100644
--- a/sound/pci/hda/Kconfig
+++ b/sound/pci/hda/Kconfig
@@ -139,6 +139,19 @@ config SND_HDA_CODEC_CONEXANT
139 snd-hda-codec-conexant. 139 snd-hda-codec-conexant.
140 This module is automatically loaded at probing. 140 This module is automatically loaded at probing.
141 141
142config SND_HDA_CODEC_CA0110
143 bool "Build Creative CA0110-IBG codec support"
144 depends on SND_HDA_INTEL
145 default y
146 help
147 Say Y here to include Creative CA0110-IBG codec support in
148 snd-hda-intel driver, found on some Creative X-Fi cards.
149
150 When the HD-audio driver is built as a module, the codec
151 support code is also built as another module,
152 snd-hda-codec-ca0110.
153 This module is automatically loaded at probing.
154
142config SND_HDA_CODEC_CMEDIA 155config SND_HDA_CODEC_CMEDIA
143 bool "Build C-Media HD-audio codec support" 156 bool "Build C-Media HD-audio codec support"
144 default y 157 default y
diff --git a/sound/pci/hda/Makefile b/sound/pci/hda/Makefile
index 50f9d096725..e3081d4586c 100644
--- a/sound/pci/hda/Makefile
+++ b/sound/pci/hda/Makefile
@@ -13,6 +13,7 @@ snd-hda-codec-analog-objs := patch_analog.o
13snd-hda-codec-idt-objs := patch_sigmatel.o 13snd-hda-codec-idt-objs := patch_sigmatel.o
14snd-hda-codec-si3054-objs := patch_si3054.o 14snd-hda-codec-si3054-objs := patch_si3054.o
15snd-hda-codec-atihdmi-objs := patch_atihdmi.o 15snd-hda-codec-atihdmi-objs := patch_atihdmi.o
16snd-hda-codec-ca0110-objs := patch_ca0110.o
16snd-hda-codec-conexant-objs := patch_conexant.o 17snd-hda-codec-conexant-objs := patch_conexant.o
17snd-hda-codec-via-objs := patch_via.o 18snd-hda-codec-via-objs := patch_via.o
18snd-hda-codec-nvhdmi-objs := patch_nvhdmi.o 19snd-hda-codec-nvhdmi-objs := patch_nvhdmi.o
@@ -40,6 +41,9 @@ endif
40ifdef CONFIG_SND_HDA_CODEC_ATIHDMI 41ifdef CONFIG_SND_HDA_CODEC_ATIHDMI
41obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-atihdmi.o 42obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-atihdmi.o
42endif 43endif
44ifdef CONFIG_SND_HDA_CODEC_CA0110
45obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-ca0110.o
46endif
43ifdef CONFIG_SND_HDA_CODEC_CONEXANT 47ifdef CONFIG_SND_HDA_CODEC_CONEXANT
44obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-conexant.o 48obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-conexant.o
45endif 49endif
diff --git a/sound/pci/hda/hda_beep.c b/sound/pci/hda/hda_beep.c
index 4de5bacd392..29272f2e95a 100644
--- a/sound/pci/hda/hda_beep.c
+++ b/sound/pci/hda/hda_beep.c
@@ -45,6 +45,46 @@ static void snd_hda_generate_beep(struct work_struct *work)
45 AC_VERB_SET_BEEP_CONTROL, beep->tone); 45 AC_VERB_SET_BEEP_CONTROL, beep->tone);
46} 46}
47 47
48/* (non-standard) Linear beep tone calculation for IDT/STAC codecs
49 *
50 * The tone frequency of beep generator on IDT/STAC codecs is
51 * defined from the 8bit tone parameter, in Hz,
52 * freq = 48000 * (257 - tone) / 1024
53 * that is from 12kHz to 93.75kHz in step of 46.875 hz
54 */
55static int beep_linear_tone(struct hda_beep *beep, int hz)
56{
57 hz *= 1000; /* fixed point */
58 hz = hz - DIGBEEP_HZ_MIN;
59 if (hz < 0)
60 hz = 0; /* turn off PC beep*/
61 else if (hz >= (DIGBEEP_HZ_MAX - DIGBEEP_HZ_MIN))
62 hz = 0xff;
63 else {
64 hz /= DIGBEEP_HZ_STEP;
65 hz++;
66 }
67 return hz;
68}
69
70/* HD-audio standard beep tone parameter calculation
71 *
72 * The tone frequency in Hz is calculated as
73 * freq = 48000 / (tone * 4)
74 * from 47Hz to 12kHz
75 */
76static int beep_standard_tone(struct hda_beep *beep, int hz)
77{
78 if (hz <= 0)
79 return 0; /* disabled */
80 hz = 12000 / hz;
81 if (hz > 0xff)
82 return 0xff;
83 if (hz <= 0)
84 return 1;
85 return hz;
86}
87
48static int snd_hda_beep_event(struct input_dev *dev, unsigned int type, 88static int snd_hda_beep_event(struct input_dev *dev, unsigned int type,
49 unsigned int code, int hz) 89 unsigned int code, int hz)
50{ 90{
@@ -55,21 +95,14 @@ static int snd_hda_beep_event(struct input_dev *dev, unsigned int type,
55 if (hz) 95 if (hz)
56 hz = 1000; 96 hz = 1000;
57 case SND_TONE: 97 case SND_TONE:
58 hz *= 1000; /* fixed point */ 98 if (beep->linear_tone)
59 hz = hz - DIGBEEP_HZ_MIN; 99 beep->tone = beep_linear_tone(beep, hz);
60 if (hz < 0) 100 else
61 hz = 0; /* turn off PC beep*/ 101 beep->tone = beep_standard_tone(beep, hz);
62 else if (hz >= (DIGBEEP_HZ_MAX - DIGBEEP_HZ_MIN))
63 hz = 0xff;
64 else {
65 hz /= DIGBEEP_HZ_STEP;
66 hz++;
67 }
68 break; 102 break;
69 default: 103 default:
70 return -1; 104 return -1;
71 } 105 }
72 beep->tone = hz;
73 106
74 /* schedule beep event */ 107 /* schedule beep event */
75 schedule_work(&beep->beep_work); 108 schedule_work(&beep->beep_work);
diff --git a/sound/pci/hda/hda_beep.h b/sound/pci/hda/hda_beep.h
index 51bf6a5daf3..0c3de787c71 100644
--- a/sound/pci/hda/hda_beep.h
+++ b/sound/pci/hda/hda_beep.h
@@ -30,8 +30,9 @@ struct hda_beep {
30 struct hda_codec *codec; 30 struct hda_codec *codec;
31 char phys[32]; 31 char phys[32];
32 int tone; 32 int tone;
33 int nid; 33 hda_nid_t nid;
34 int enabled; 34 unsigned int enabled:1;
35 unsigned int linear_tone:1; /* linear tone for IDT/STAC codec */
35 struct work_struct beep_work; /* scheduled task for beep event */ 36 struct work_struct beep_work; /* scheduled task for beep event */
36}; 37};
37 38
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 8820faf6c9d..562403a2348 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -48,6 +48,7 @@ static struct hda_vendor_id hda_vendor_ids[] = {
48 { 0x1095, "Silicon Image" }, 48 { 0x1095, "Silicon Image" },
49 { 0x10de, "Nvidia" }, 49 { 0x10de, "Nvidia" },
50 { 0x10ec, "Realtek" }, 50 { 0x10ec, "Realtek" },
51 { 0x1102, "Creative" },
51 { 0x1106, "VIA" }, 52 { 0x1106, "VIA" },
52 { 0x111d, "IDT" }, 53 { 0x111d, "IDT" },
53 { 0x11c1, "LSI" }, 54 { 0x11c1, "LSI" },
@@ -157,6 +158,39 @@ make_codec_cmd(struct hda_codec *codec, hda_nid_t nid, int direct,
157 return val; 158 return val;
158} 159}
159 160
161/*
162 * Send and receive a verb
163 */
164static int codec_exec_verb(struct hda_codec *codec, unsigned int cmd,
165 unsigned int *res)
166{
167 struct hda_bus *bus = codec->bus;
168 int err;
169
170 if (res)
171 *res = -1;
172 again:
173 snd_hda_power_up(codec);
174 mutex_lock(&bus->cmd_mutex);
175 err = bus->ops.command(bus, cmd);
176 if (!err && res)
177 *res = bus->ops.get_response(bus);
178 mutex_unlock(&bus->cmd_mutex);
179 snd_hda_power_down(codec);
180 if (res && *res == -1 && bus->rirb_error) {
181 if (bus->response_reset) {
182 snd_printd("hda_codec: resetting BUS due to "
183 "fatal communication error\n");
184 bus->ops.bus_reset(bus);
185 }
186 goto again;
187 }
188 /* clear reset-flag when the communication gets recovered */
189 if (!err)
190 bus->response_reset = 0;
191 return err;
192}
193
160/** 194/**
161 * snd_hda_codec_read - send a command and get the response 195 * snd_hda_codec_read - send a command and get the response
162 * @codec: the HDA codec 196 * @codec: the HDA codec
@@ -173,18 +207,9 @@ unsigned int snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid,
173 int direct, 207 int direct,
174 unsigned int verb, unsigned int parm) 208 unsigned int verb, unsigned int parm)
175{ 209{
176 struct hda_bus *bus = codec->bus; 210 unsigned cmd = make_codec_cmd(codec, nid, direct, verb, parm);
177 unsigned int res; 211 unsigned int res;
178 212 codec_exec_verb(codec, cmd, &res);
179 res = make_codec_cmd(codec, nid, direct, verb, parm);
180 snd_hda_power_up(codec);
181 mutex_lock(&bus->cmd_mutex);
182 if (!bus->ops.command(bus, res))
183 res = bus->ops.get_response(bus);
184 else
185 res = (unsigned int)-1;
186 mutex_unlock(&bus->cmd_mutex);
187 snd_hda_power_down(codec);
188 return res; 213 return res;
189} 214}
190EXPORT_SYMBOL_HDA(snd_hda_codec_read); 215EXPORT_SYMBOL_HDA(snd_hda_codec_read);
@@ -204,17 +229,10 @@ EXPORT_SYMBOL_HDA(snd_hda_codec_read);
204int snd_hda_codec_write(struct hda_codec *codec, hda_nid_t nid, int direct, 229int snd_hda_codec_write(struct hda_codec *codec, hda_nid_t nid, int direct,
205 unsigned int verb, unsigned int parm) 230 unsigned int verb, unsigned int parm)
206{ 231{
207 struct hda_bus *bus = codec->bus; 232 unsigned int cmd = make_codec_cmd(codec, nid, direct, verb, parm);
208 unsigned int res; 233 unsigned int res;
209 int err; 234 return codec_exec_verb(codec, cmd,
210 235 codec->bus->sync_write ? &res : NULL);
211 res = make_codec_cmd(codec, nid, direct, verb, parm);
212 snd_hda_power_up(codec);
213 mutex_lock(&bus->cmd_mutex);
214 err = bus->ops.command(bus, res);
215 mutex_unlock(&bus->cmd_mutex);
216 snd_hda_power_down(codec);
217 return err;
218} 236}
219EXPORT_SYMBOL_HDA(snd_hda_codec_write); 237EXPORT_SYMBOL_HDA(snd_hda_codec_write);
220 238
@@ -613,7 +631,10 @@ static int get_codec_name(struct hda_codec *codec)
613 const struct hda_vendor_id *c; 631 const struct hda_vendor_id *c;
614 const char *vendor = NULL; 632 const char *vendor = NULL;
615 u16 vendor_id = codec->vendor_id >> 16; 633 u16 vendor_id = codec->vendor_id >> 16;
616 char tmp[16], name[32]; 634 char tmp[16];
635
636 if (codec->vendor_name)
637 goto get_chip_name;
617 638
618 for (c = hda_vendor_ids; c->id; c++) { 639 for (c = hda_vendor_ids; c->id; c++) {
619 if (c->id == vendor_id) { 640 if (c->id == vendor_id) {
@@ -625,14 +646,21 @@ static int get_codec_name(struct hda_codec *codec)
625 sprintf(tmp, "Generic %04x", vendor_id); 646 sprintf(tmp, "Generic %04x", vendor_id);
626 vendor = tmp; 647 vendor = tmp;
627 } 648 }
649 codec->vendor_name = kstrdup(vendor, GFP_KERNEL);
650 if (!codec->vendor_name)
651 return -ENOMEM;
652
653 get_chip_name:
654 if (codec->chip_name)
655 return 0;
656
628 if (codec->preset && codec->preset->name) 657 if (codec->preset && codec->preset->name)
629 snprintf(name, sizeof(name), "%s %s", vendor, 658 codec->chip_name = kstrdup(codec->preset->name, GFP_KERNEL);
630 codec->preset->name); 659 else {
631 else 660 sprintf(tmp, "ID %x", codec->vendor_id & 0xffff);
632 snprintf(name, sizeof(name), "%s ID %x", vendor, 661 codec->chip_name = kstrdup(tmp, GFP_KERNEL);
633 codec->vendor_id & 0xffff); 662 }
634 codec->name = kstrdup(name, GFP_KERNEL); 663 if (!codec->chip_name)
635 if (!codec->name)
636 return -ENOMEM; 664 return -ENOMEM;
637 return 0; 665 return 0;
638} 666}
@@ -838,7 +866,8 @@ static void snd_hda_codec_free(struct hda_codec *codec)
838 module_put(codec->owner); 866 module_put(codec->owner);
839 free_hda_cache(&codec->amp_cache); 867 free_hda_cache(&codec->amp_cache);
840 free_hda_cache(&codec->cmd_cache); 868 free_hda_cache(&codec->cmd_cache);
841 kfree(codec->name); 869 kfree(codec->vendor_name);
870 kfree(codec->chip_name);
842 kfree(codec->modelname); 871 kfree(codec->modelname);
843 kfree(codec->wcaps); 872 kfree(codec->wcaps);
844 kfree(codec); 873 kfree(codec);
@@ -979,15 +1008,16 @@ int snd_hda_codec_configure(struct hda_codec *codec)
979 int err; 1008 int err;
980 1009
981 codec->preset = find_codec_preset(codec); 1010 codec->preset = find_codec_preset(codec);
982 if (!codec->name) { 1011 if (!codec->vendor_name || !codec->chip_name) {
983 err = get_codec_name(codec); 1012 err = get_codec_name(codec);
984 if (err < 0) 1013 if (err < 0)
985 return err; 1014 return err;
986 } 1015 }
987 /* audio codec should override the mixer name */ 1016 /* audio codec should override the mixer name */
988 if (codec->afg || !*codec->bus->card->mixername) 1017 if (codec->afg || !*codec->bus->card->mixername)
989 strlcpy(codec->bus->card->mixername, codec->name, 1018 snprintf(codec->bus->card->mixername,
990 sizeof(codec->bus->card->mixername)); 1019 sizeof(codec->bus->card->mixername),
1020 "%s %s", codec->vendor_name, codec->chip_name);
991 1021
992 if (is_generic_config(codec)) { 1022 if (is_generic_config(codec)) {
993 err = snd_hda_parse_generic_codec(codec); 1023 err = snd_hda_parse_generic_codec(codec);
@@ -1055,6 +1085,8 @@ EXPORT_SYMBOL_HDA(snd_hda_codec_cleanup_stream);
1055/* FIXME: more better hash key? */ 1085/* FIXME: more better hash key? */
1056#define HDA_HASH_KEY(nid,dir,idx) (u32)((nid) + ((idx) << 16) + ((dir) << 24)) 1086#define HDA_HASH_KEY(nid,dir,idx) (u32)((nid) + ((idx) << 16) + ((dir) << 24))
1057#define HDA_HASH_PINCAP_KEY(nid) (u32)((nid) + (0x02 << 24)) 1087#define HDA_HASH_PINCAP_KEY(nid) (u32)((nid) + (0x02 << 24))
1088#define HDA_HASH_PARPCM_KEY(nid) (u32)((nid) + (0x03 << 24))
1089#define HDA_HASH_PARSTR_KEY(nid) (u32)((nid) + (0x04 << 24))
1058#define INFO_AMP_CAPS (1<<0) 1090#define INFO_AMP_CAPS (1<<0)
1059#define INFO_AMP_VOL(ch) (1 << (1 + (ch))) 1091#define INFO_AMP_VOL(ch) (1 << (1 + (ch)))
1060 1092
@@ -1145,19 +1177,32 @@ int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir,
1145} 1177}
1146EXPORT_SYMBOL_HDA(snd_hda_override_amp_caps); 1178EXPORT_SYMBOL_HDA(snd_hda_override_amp_caps);
1147 1179
1148u32 snd_hda_query_pin_caps(struct hda_codec *codec, hda_nid_t nid) 1180static unsigned int
1181query_caps_hash(struct hda_codec *codec, hda_nid_t nid, u32 key,
1182 unsigned int (*func)(struct hda_codec *, hda_nid_t))
1149{ 1183{
1150 struct hda_amp_info *info; 1184 struct hda_amp_info *info;
1151 1185
1152 info = get_alloc_amp_hash(codec, HDA_HASH_PINCAP_KEY(nid)); 1186 info = get_alloc_amp_hash(codec, key);
1153 if (!info) 1187 if (!info)
1154 return 0; 1188 return 0;
1155 if (!info->head.val) { 1189 if (!info->head.val) {
1156 info->amp_caps = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP);
1157 info->head.val |= INFO_AMP_CAPS; 1190 info->head.val |= INFO_AMP_CAPS;
1191 info->amp_caps = func(codec, nid);
1158 } 1192 }
1159 return info->amp_caps; 1193 return info->amp_caps;
1160} 1194}
1195
1196static unsigned int read_pin_cap(struct hda_codec *codec, hda_nid_t nid)
1197{
1198 return snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP);
1199}
1200
1201u32 snd_hda_query_pin_caps(struct hda_codec *codec, hda_nid_t nid)
1202{
1203 return query_caps_hash(codec, nid, HDA_HASH_PINCAP_KEY(nid),
1204 read_pin_cap);
1205}
1161EXPORT_SYMBOL_HDA(snd_hda_query_pin_caps); 1206EXPORT_SYMBOL_HDA(snd_hda_query_pin_caps);
1162 1207
1163/* 1208/*
@@ -1432,6 +1477,8 @@ _snd_hda_find_mixer_ctl(struct hda_codec *codec,
1432 memset(&id, 0, sizeof(id)); 1477 memset(&id, 0, sizeof(id));
1433 id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; 1478 id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1434 id.index = idx; 1479 id.index = idx;
1480 if (snd_BUG_ON(strlen(name) >= sizeof(id.name)))
1481 return NULL;
1435 strcpy(id.name, name); 1482 strcpy(id.name, name);
1436 return snd_ctl_find_id(codec->bus->card, &id); 1483 return snd_ctl_find_id(codec->bus->card, &id);
1437} 1484}
@@ -2242,28 +2289,22 @@ EXPORT_SYMBOL_HDA(snd_hda_create_spdif_in_ctls);
2242int snd_hda_codec_write_cache(struct hda_codec *codec, hda_nid_t nid, 2289int snd_hda_codec_write_cache(struct hda_codec *codec, hda_nid_t nid,
2243 int direct, unsigned int verb, unsigned int parm) 2290 int direct, unsigned int verb, unsigned int parm)
2244{ 2291{
2245 struct hda_bus *bus = codec->bus; 2292 int err = snd_hda_codec_write(codec, nid, direct, verb, parm);
2246 unsigned int res; 2293 struct hda_cache_head *c;
2247 int err; 2294 u32 key;
2248 2295
2249 res = make_codec_cmd(codec, nid, direct, verb, parm); 2296 if (err < 0)
2250 snd_hda_power_up(codec); 2297 return err;
2251 mutex_lock(&bus->cmd_mutex); 2298 /* parm may contain the verb stuff for get/set amp */
2252 err = bus->ops.command(bus, res); 2299 verb = verb | (parm >> 8);
2253 if (!err) { 2300 parm &= 0xff;
2254 struct hda_cache_head *c; 2301 key = build_cmd_cache_key(nid, verb);
2255 u32 key; 2302 mutex_lock(&codec->bus->cmd_mutex);
2256 /* parm may contain the verb stuff for get/set amp */ 2303 c = get_alloc_hash(&codec->cmd_cache, key);
2257 verb = verb | (parm >> 8); 2304 if (c)
2258 parm &= 0xff; 2305 c->val = parm;
2259 key = build_cmd_cache_key(nid, verb); 2306 mutex_unlock(&codec->bus->cmd_mutex);
2260 c = get_alloc_hash(&codec->cmd_cache, key); 2307 return 0;
2261 if (c)
2262 c->val = parm;
2263 }
2264 mutex_unlock(&bus->cmd_mutex);
2265 snd_hda_power_down(codec);
2266 return err;
2267} 2308}
2268EXPORT_SYMBOL_HDA(snd_hda_codec_write_cache); 2309EXPORT_SYMBOL_HDA(snd_hda_codec_write_cache);
2269 2310
@@ -2321,7 +2362,8 @@ static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
2321 if (wcaps & AC_WCAP_POWER) { 2362 if (wcaps & AC_WCAP_POWER) {
2322 unsigned int wid_type = (wcaps & AC_WCAP_TYPE) >> 2363 unsigned int wid_type = (wcaps & AC_WCAP_TYPE) >>
2323 AC_WCAP_TYPE_SHIFT; 2364 AC_WCAP_TYPE_SHIFT;
2324 if (wid_type == AC_WID_PIN) { 2365 if (power_state == AC_PWRST_D3 &&
2366 wid_type == AC_WID_PIN) {
2325 unsigned int pincap; 2367 unsigned int pincap;
2326 /* 2368 /*
2327 * don't power down the widget if it controls 2369 * don't power down the widget if it controls
@@ -2333,7 +2375,7 @@ static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
2333 nid, 0, 2375 nid, 0,
2334 AC_VERB_GET_EAPD_BTLENABLE, 0); 2376 AC_VERB_GET_EAPD_BTLENABLE, 0);
2335 eapd &= 0x02; 2377 eapd &= 0x02;
2336 if (power_state == AC_PWRST_D3 && eapd) 2378 if (eapd)
2337 continue; 2379 continue;
2338 } 2380 }
2339 } 2381 }
@@ -2544,6 +2586,41 @@ unsigned int snd_hda_calc_stream_format(unsigned int rate,
2544} 2586}
2545EXPORT_SYMBOL_HDA(snd_hda_calc_stream_format); 2587EXPORT_SYMBOL_HDA(snd_hda_calc_stream_format);
2546 2588
2589static unsigned int get_pcm_param(struct hda_codec *codec, hda_nid_t nid)
2590{
2591 unsigned int val = 0;
2592 if (nid != codec->afg &&
2593 (get_wcaps(codec, nid) & AC_WCAP_FORMAT_OVRD))
2594 val = snd_hda_param_read(codec, nid, AC_PAR_PCM);
2595 if (!val || val == -1)
2596 val = snd_hda_param_read(codec, codec->afg, AC_PAR_PCM);
2597 if (!val || val == -1)
2598 return 0;
2599 return val;
2600}
2601
2602static unsigned int query_pcm_param(struct hda_codec *codec, hda_nid_t nid)
2603{
2604 return query_caps_hash(codec, nid, HDA_HASH_PARPCM_KEY(nid),
2605 get_pcm_param);
2606}
2607
2608static unsigned int get_stream_param(struct hda_codec *codec, hda_nid_t nid)
2609{
2610 unsigned int streams = snd_hda_param_read(codec, nid, AC_PAR_STREAM);
2611 if (!streams || streams == -1)
2612 streams = snd_hda_param_read(codec, codec->afg, AC_PAR_STREAM);
2613 if (!streams || streams == -1)
2614 return 0;
2615 return streams;
2616}
2617
2618static unsigned int query_stream_param(struct hda_codec *codec, hda_nid_t nid)
2619{
2620 return query_caps_hash(codec, nid, HDA_HASH_PARSTR_KEY(nid),
2621 get_stream_param);
2622}
2623
2547/** 2624/**
2548 * snd_hda_query_supported_pcm - query the supported PCM rates and formats 2625 * snd_hda_query_supported_pcm - query the supported PCM rates and formats
2549 * @codec: the HDA codec 2626 * @codec: the HDA codec
@@ -2562,15 +2639,8 @@ static int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid,
2562{ 2639{
2563 unsigned int i, val, wcaps; 2640 unsigned int i, val, wcaps;
2564 2641
2565 val = 0;
2566 wcaps = get_wcaps(codec, nid); 2642 wcaps = get_wcaps(codec, nid);
2567 if (nid != codec->afg && (wcaps & AC_WCAP_FORMAT_OVRD)) { 2643 val = query_pcm_param(codec, nid);
2568 val = snd_hda_param_read(codec, nid, AC_PAR_PCM);
2569 if (val == -1)
2570 return -EIO;
2571 }
2572 if (!val)
2573 val = snd_hda_param_read(codec, codec->afg, AC_PAR_PCM);
2574 2644
2575 if (ratesp) { 2645 if (ratesp) {
2576 u32 rates = 0; 2646 u32 rates = 0;
@@ -2592,15 +2662,9 @@ static int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid,
2592 u64 formats = 0; 2662 u64 formats = 0;
2593 unsigned int streams, bps; 2663 unsigned int streams, bps;
2594 2664
2595 streams = snd_hda_param_read(codec, nid, AC_PAR_STREAM); 2665 streams = query_stream_param(codec, nid);
2596 if (streams == -1) 2666 if (!streams)
2597 return -EIO; 2667 return -EIO;
2598 if (!streams) {
2599 streams = snd_hda_param_read(codec, codec->afg,
2600 AC_PAR_STREAM);
2601 if (streams == -1)
2602 return -EIO;
2603 }
2604 2668
2605 bps = 0; 2669 bps = 0;
2606 if (streams & AC_SUPFMT_PCM) { 2670 if (streams & AC_SUPFMT_PCM) {
@@ -2674,17 +2738,9 @@ int snd_hda_is_supported_format(struct hda_codec *codec, hda_nid_t nid,
2674 int i; 2738 int i;
2675 unsigned int val = 0, rate, stream; 2739 unsigned int val = 0, rate, stream;
2676 2740
2677 if (nid != codec->afg && 2741 val = query_pcm_param(codec, nid);
2678 (get_wcaps(codec, nid) & AC_WCAP_FORMAT_OVRD)) { 2742 if (!val)
2679 val = snd_hda_param_read(codec, nid, AC_PAR_PCM); 2743 return 0;
2680 if (val == -1)
2681 return 0;
2682 }
2683 if (!val) {
2684 val = snd_hda_param_read(codec, codec->afg, AC_PAR_PCM);
2685 if (val == -1)
2686 return 0;
2687 }
2688 2744
2689 rate = format & 0xff00; 2745 rate = format & 0xff00;
2690 for (i = 0; i < AC_PAR_PCM_RATE_BITS; i++) 2746 for (i = 0; i < AC_PAR_PCM_RATE_BITS; i++)
@@ -2696,12 +2752,8 @@ int snd_hda_is_supported_format(struct hda_codec *codec, hda_nid_t nid,
2696 if (i >= AC_PAR_PCM_RATE_BITS) 2752 if (i >= AC_PAR_PCM_RATE_BITS)
2697 return 0; 2753 return 0;
2698 2754
2699 stream = snd_hda_param_read(codec, nid, AC_PAR_STREAM); 2755 stream = query_stream_param(codec, nid);
2700 if (stream == -1) 2756 if (!stream)
2701 return 0;
2702 if (!stream && nid != codec->afg)
2703 stream = snd_hda_param_read(codec, codec->afg, AC_PAR_STREAM);
2704 if (!stream || stream == -1)
2705 return 0; 2757 return 0;
2706 2758
2707 if (stream & AC_SUPFMT_PCM) { 2759 if (stream & AC_SUPFMT_PCM) {
@@ -3835,11 +3887,10 @@ EXPORT_SYMBOL_HDA(auto_pin_cfg_labels);
3835/** 3887/**
3836 * snd_hda_suspend - suspend the codecs 3888 * snd_hda_suspend - suspend the codecs
3837 * @bus: the HDA bus 3889 * @bus: the HDA bus
3838 * @state: suspsend state
3839 * 3890 *
3840 * Returns 0 if successful. 3891 * Returns 0 if successful.
3841 */ 3892 */
3842int snd_hda_suspend(struct hda_bus *bus, pm_message_t state) 3893int snd_hda_suspend(struct hda_bus *bus)
3843{ 3894{
3844 struct hda_codec *codec; 3895 struct hda_codec *codec;
3845 3896
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index 2fdecf4b0eb..cad79efaabc 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -574,6 +574,8 @@ struct hda_bus_ops {
574 /* attach a PCM stream */ 574 /* attach a PCM stream */
575 int (*attach_pcm)(struct hda_bus *bus, struct hda_codec *codec, 575 int (*attach_pcm)(struct hda_bus *bus, struct hda_codec *codec,
576 struct hda_pcm *pcm); 576 struct hda_pcm *pcm);
577 /* reset bus for retry verb */
578 void (*bus_reset)(struct hda_bus *bus);
577#ifdef CONFIG_SND_HDA_POWER_SAVE 579#ifdef CONFIG_SND_HDA_POWER_SAVE
578 /* notify power-up/down from codec to controller */ 580 /* notify power-up/down from codec to controller */
579 void (*pm_notify)(struct hda_bus *bus); 581 void (*pm_notify)(struct hda_bus *bus);
@@ -622,7 +624,13 @@ struct hda_bus {
622 624
623 /* misc op flags */ 625 /* misc op flags */
624 unsigned int needs_damn_long_delay :1; 626 unsigned int needs_damn_long_delay :1;
627 unsigned int allow_bus_reset:1; /* allow bus reset at fatal error */
628 unsigned int sync_write:1; /* sync after verb write */
629 /* status for codec/controller */
625 unsigned int shutdown :1; /* being unloaded */ 630 unsigned int shutdown :1; /* being unloaded */
631 unsigned int rirb_error:1; /* error in codec communication */
632 unsigned int response_reset:1; /* controller was reset */
633 unsigned int in_reset:1; /* during reset operation */
626}; 634};
627 635
628/* 636/*
@@ -747,7 +755,8 @@ struct hda_codec {
747 /* detected preset */ 755 /* detected preset */
748 const struct hda_codec_preset *preset; 756 const struct hda_codec_preset *preset;
749 struct module *owner; 757 struct module *owner;
750 const char *name; /* codec name */ 758 const char *vendor_name; /* codec vendor name */
759 const char *chip_name; /* codec chip name */
751 const char *modelname; /* model name for preset */ 760 const char *modelname; /* model name for preset */
752 761
753 /* set by patch */ 762 /* set by patch */
@@ -905,7 +914,7 @@ void snd_hda_get_codec_name(struct hda_codec *codec, char *name, int namelen);
905 * power management 914 * power management
906 */ 915 */
907#ifdef CONFIG_PM 916#ifdef CONFIG_PM
908int snd_hda_suspend(struct hda_bus *bus, pm_message_t state); 917int snd_hda_suspend(struct hda_bus *bus);
909int snd_hda_resume(struct hda_bus *bus); 918int snd_hda_resume(struct hda_bus *bus);
910#endif 919#endif
911 920
diff --git a/sound/pci/hda/hda_hwdep.c b/sound/pci/hda/hda_hwdep.c
index 1c57505c287..6812fbe80fa 100644
--- a/sound/pci/hda/hda_hwdep.c
+++ b/sound/pci/hda/hda_hwdep.c
@@ -242,7 +242,8 @@ CODEC_INFO_SHOW(subsystem_id);
242CODEC_INFO_SHOW(revision_id); 242CODEC_INFO_SHOW(revision_id);
243CODEC_INFO_SHOW(afg); 243CODEC_INFO_SHOW(afg);
244CODEC_INFO_SHOW(mfg); 244CODEC_INFO_SHOW(mfg);
245CODEC_INFO_STR_SHOW(name); 245CODEC_INFO_STR_SHOW(vendor_name);
246CODEC_INFO_STR_SHOW(chip_name);
246CODEC_INFO_STR_SHOW(modelname); 247CODEC_INFO_STR_SHOW(modelname);
247 248
248#define CODEC_INFO_STORE(type) \ 249#define CODEC_INFO_STORE(type) \
@@ -275,7 +276,8 @@ static ssize_t type##_store(struct device *dev, \
275CODEC_INFO_STORE(vendor_id); 276CODEC_INFO_STORE(vendor_id);
276CODEC_INFO_STORE(subsystem_id); 277CODEC_INFO_STORE(subsystem_id);
277CODEC_INFO_STORE(revision_id); 278CODEC_INFO_STORE(revision_id);
278CODEC_INFO_STR_STORE(name); 279CODEC_INFO_STR_STORE(vendor_name);
280CODEC_INFO_STR_STORE(chip_name);
279CODEC_INFO_STR_STORE(modelname); 281CODEC_INFO_STR_STORE(modelname);
280 282
281#define CODEC_ACTION_STORE(type) \ 283#define CODEC_ACTION_STORE(type) \
@@ -499,7 +501,8 @@ static struct device_attribute codec_attrs[] = {
499 CODEC_ATTR_RW(revision_id), 501 CODEC_ATTR_RW(revision_id),
500 CODEC_ATTR_RO(afg), 502 CODEC_ATTR_RO(afg),
501 CODEC_ATTR_RO(mfg), 503 CODEC_ATTR_RO(mfg),
502 CODEC_ATTR_RW(name), 504 CODEC_ATTR_RW(vendor_name),
505 CODEC_ATTR_RW(chip_name),
503 CODEC_ATTR_RW(modelname), 506 CODEC_ATTR_RW(modelname),
504 CODEC_ATTR_RW(init_verbs), 507 CODEC_ATTR_RW(init_verbs),
505 CODEC_ATTR_RW(hints), 508 CODEC_ATTR_RW(hints),
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 21e99cfa8c4..4e9ea708027 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -128,21 +128,33 @@ MODULE_SUPPORTED_DEVICE("{{Intel, ICH6},"
128 "{ULI, M5461}}"); 128 "{ULI, M5461}}");
129MODULE_DESCRIPTION("Intel HDA driver"); 129MODULE_DESCRIPTION("Intel HDA driver");
130 130
131#ifdef CONFIG_SND_VERBOSE_PRINTK
132#define SFX /* nop */
133#else
131#define SFX "hda-intel: " 134#define SFX "hda-intel: "
132 135#endif
133 136
134/* 137/*
135 * registers 138 * registers
136 */ 139 */
137#define ICH6_REG_GCAP 0x00 140#define ICH6_REG_GCAP 0x00
141#define ICH6_GCAP_64OK (1 << 0) /* 64bit address support */
142#define ICH6_GCAP_NSDO (3 << 1) /* # of serial data out signals */
143#define ICH6_GCAP_BSS (31 << 3) /* # of bidirectional streams */
144#define ICH6_GCAP_ISS (15 << 8) /* # of input streams */
145#define ICH6_GCAP_OSS (15 << 12) /* # of output streams */
138#define ICH6_REG_VMIN 0x02 146#define ICH6_REG_VMIN 0x02
139#define ICH6_REG_VMAJ 0x03 147#define ICH6_REG_VMAJ 0x03
140#define ICH6_REG_OUTPAY 0x04 148#define ICH6_REG_OUTPAY 0x04
141#define ICH6_REG_INPAY 0x06 149#define ICH6_REG_INPAY 0x06
142#define ICH6_REG_GCTL 0x08 150#define ICH6_REG_GCTL 0x08
151#define ICH6_GCTL_RESET (1 << 0) /* controller reset */
152#define ICH6_GCTL_FCNTRL (1 << 1) /* flush control */
153#define ICH6_GCTL_UNSOL (1 << 8) /* accept unsol. response enable */
143#define ICH6_REG_WAKEEN 0x0c 154#define ICH6_REG_WAKEEN 0x0c
144#define ICH6_REG_STATESTS 0x0e 155#define ICH6_REG_STATESTS 0x0e
145#define ICH6_REG_GSTS 0x10 156#define ICH6_REG_GSTS 0x10
157#define ICH6_GSTS_FSTS (1 << 1) /* flush status */
146#define ICH6_REG_INTCTL 0x20 158#define ICH6_REG_INTCTL 0x20
147#define ICH6_REG_INTSTS 0x24 159#define ICH6_REG_INTSTS 0x24
148#define ICH6_REG_WALCLK 0x30 160#define ICH6_REG_WALCLK 0x30
@@ -150,17 +162,27 @@ MODULE_DESCRIPTION("Intel HDA driver");
150#define ICH6_REG_CORBLBASE 0x40 162#define ICH6_REG_CORBLBASE 0x40
151#define ICH6_REG_CORBUBASE 0x44 163#define ICH6_REG_CORBUBASE 0x44
152#define ICH6_REG_CORBWP 0x48 164#define ICH6_REG_CORBWP 0x48
153#define ICH6_REG_CORBRP 0x4A 165#define ICH6_REG_CORBRP 0x4a
166#define ICH6_CORBRP_RST (1 << 15) /* read pointer reset */
154#define ICH6_REG_CORBCTL 0x4c 167#define ICH6_REG_CORBCTL 0x4c
168#define ICH6_CORBCTL_RUN (1 << 1) /* enable DMA */
169#define ICH6_CORBCTL_CMEIE (1 << 0) /* enable memory error irq */
155#define ICH6_REG_CORBSTS 0x4d 170#define ICH6_REG_CORBSTS 0x4d
171#define ICH6_CORBSTS_CMEI (1 << 0) /* memory error indication */
156#define ICH6_REG_CORBSIZE 0x4e 172#define ICH6_REG_CORBSIZE 0x4e
157 173
158#define ICH6_REG_RIRBLBASE 0x50 174#define ICH6_REG_RIRBLBASE 0x50
159#define ICH6_REG_RIRBUBASE 0x54 175#define ICH6_REG_RIRBUBASE 0x54
160#define ICH6_REG_RIRBWP 0x58 176#define ICH6_REG_RIRBWP 0x58
177#define ICH6_RIRBWP_RST (1 << 15) /* write pointer reset */
161#define ICH6_REG_RINTCNT 0x5a 178#define ICH6_REG_RINTCNT 0x5a
162#define ICH6_REG_RIRBCTL 0x5c 179#define ICH6_REG_RIRBCTL 0x5c
180#define ICH6_RBCTL_IRQ_EN (1 << 0) /* enable IRQ */
181#define ICH6_RBCTL_DMA_EN (1 << 1) /* enable DMA */
182#define ICH6_RBCTL_OVERRUN_EN (1 << 2) /* enable overrun irq */
163#define ICH6_REG_RIRBSTS 0x5d 183#define ICH6_REG_RIRBSTS 0x5d
184#define ICH6_RBSTS_IRQ (1 << 0) /* response irq */
185#define ICH6_RBSTS_OVERRUN (1 << 2) /* overrun irq */
164#define ICH6_REG_RIRBSIZE 0x5e 186#define ICH6_REG_RIRBSIZE 0x5e
165 187
166#define ICH6_REG_IC 0x60 188#define ICH6_REG_IC 0x60
@@ -257,16 +279,6 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 };
257#define ICH6_INT_CTRL_EN 0x40000000 /* controller interrupt enable bit */ 279#define ICH6_INT_CTRL_EN 0x40000000 /* controller interrupt enable bit */
258#define ICH6_INT_GLOBAL_EN 0x80000000 /* global interrupt enable bit */ 280#define ICH6_INT_GLOBAL_EN 0x80000000 /* global interrupt enable bit */
259 281
260/* GCTL unsolicited response enable bit */
261#define ICH6_GCTL_UREN (1<<8)
262
263/* GCTL reset bit */
264#define ICH6_GCTL_RESET (1<<0)
265
266/* CORB/RIRB control, read/write pointer */
267#define ICH6_RBCTL_DMA_EN 0x02 /* enable DMA */
268#define ICH6_RBCTL_IRQ_EN 0x01 /* enable IRQ */
269#define ICH6_RBRWP_CLR 0x8000 /* read/write pointer clear */
270/* below are so far hardcoded - should read registers in future */ 282/* below are so far hardcoded - should read registers in future */
271#define ICH6_MAX_CORB_ENTRIES 256 283#define ICH6_MAX_CORB_ENTRIES 256
272#define ICH6_MAX_RIRB_ENTRIES 256 284#define ICH6_MAX_RIRB_ENTRIES 256
@@ -512,25 +524,25 @@ static void azx_init_cmd_io(struct azx *chip)
512 /* set the corb write pointer to 0 */ 524 /* set the corb write pointer to 0 */
513 azx_writew(chip, CORBWP, 0); 525 azx_writew(chip, CORBWP, 0);
514 /* reset the corb hw read pointer */ 526 /* reset the corb hw read pointer */
515 azx_writew(chip, CORBRP, ICH6_RBRWP_CLR); 527 azx_writew(chip, CORBRP, ICH6_CORBRP_RST);
516 /* enable corb dma */ 528 /* enable corb dma */
517 azx_writeb(chip, CORBCTL, ICH6_RBCTL_DMA_EN); 529 azx_writeb(chip, CORBCTL, ICH6_CORBCTL_RUN);
518 530
519 /* RIRB set up */ 531 /* RIRB set up */
520 chip->rirb.addr = chip->rb.addr + 2048; 532 chip->rirb.addr = chip->rb.addr + 2048;
521 chip->rirb.buf = (u32 *)(chip->rb.area + 2048); 533 chip->rirb.buf = (u32 *)(chip->rb.area + 2048);
534 chip->rirb.wp = chip->rirb.rp = chip->rirb.cmds = 0;
522 azx_writel(chip, RIRBLBASE, (u32)chip->rirb.addr); 535 azx_writel(chip, RIRBLBASE, (u32)chip->rirb.addr);
523 azx_writel(chip, RIRBUBASE, upper_32_bits(chip->rirb.addr)); 536 azx_writel(chip, RIRBUBASE, upper_32_bits(chip->rirb.addr));
524 537
525 /* set the rirb size to 256 entries (ULI requires explicitly) */ 538 /* set the rirb size to 256 entries (ULI requires explicitly) */
526 azx_writeb(chip, RIRBSIZE, 0x02); 539 azx_writeb(chip, RIRBSIZE, 0x02);
527 /* reset the rirb hw write pointer */ 540 /* reset the rirb hw write pointer */
528 azx_writew(chip, RIRBWP, ICH6_RBRWP_CLR); 541 azx_writew(chip, RIRBWP, ICH6_RIRBWP_RST);
529 /* set N=1, get RIRB response interrupt for new entry */ 542 /* set N=1, get RIRB response interrupt for new entry */
530 azx_writew(chip, RINTCNT, 1); 543 azx_writew(chip, RINTCNT, 1);
531 /* enable rirb dma and response irq */ 544 /* enable rirb dma and response irq */
532 azx_writeb(chip, RIRBCTL, ICH6_RBCTL_DMA_EN | ICH6_RBCTL_IRQ_EN); 545 azx_writeb(chip, RIRBCTL, ICH6_RBCTL_DMA_EN | ICH6_RBCTL_IRQ_EN);
533 chip->rirb.rp = chip->rirb.cmds = 0;
534} 546}
535 547
536static void azx_free_cmd_io(struct azx *chip) 548static void azx_free_cmd_io(struct azx *chip)
@@ -606,6 +618,7 @@ static unsigned int azx_rirb_get_response(struct hda_bus *bus)
606 } 618 }
607 if (!chip->rirb.cmds) { 619 if (!chip->rirb.cmds) {
608 smp_rmb(); 620 smp_rmb();
621 bus->rirb_error = 0;
609 return chip->rirb.res; /* the last value */ 622 return chip->rirb.res; /* the last value */
610 } 623 }
611 if (time_after(jiffies, timeout)) 624 if (time_after(jiffies, timeout))
@@ -619,19 +632,21 @@ static unsigned int azx_rirb_get_response(struct hda_bus *bus)
619 } 632 }
620 633
621 if (chip->msi) { 634 if (chip->msi) {
622 snd_printk(KERN_WARNING "hda_intel: No response from codec, " 635 snd_printk(KERN_WARNING SFX "No response from codec, "
623 "disabling MSI: last cmd=0x%08x\n", chip->last_cmd); 636 "disabling MSI: last cmd=0x%08x\n", chip->last_cmd);
624 free_irq(chip->irq, chip); 637 free_irq(chip->irq, chip);
625 chip->irq = -1; 638 chip->irq = -1;
626 pci_disable_msi(chip->pci); 639 pci_disable_msi(chip->pci);
627 chip->msi = 0; 640 chip->msi = 0;
628 if (azx_acquire_irq(chip, 1) < 0) 641 if (azx_acquire_irq(chip, 1) < 0) {
642 bus->rirb_error = 1;
629 return -1; 643 return -1;
644 }
630 goto again; 645 goto again;
631 } 646 }
632 647
633 if (!chip->polling_mode) { 648 if (!chip->polling_mode) {
634 snd_printk(KERN_WARNING "hda_intel: azx_get_response timeout, " 649 snd_printk(KERN_WARNING SFX "azx_get_response timeout, "
635 "switching to polling mode: last cmd=0x%08x\n", 650 "switching to polling mode: last cmd=0x%08x\n",
636 chip->last_cmd); 651 chip->last_cmd);
637 chip->polling_mode = 1; 652 chip->polling_mode = 1;
@@ -646,14 +661,23 @@ static unsigned int azx_rirb_get_response(struct hda_bus *bus)
646 return -1; 661 return -1;
647 } 662 }
648 663
664 /* a fatal communication error; need either to reset or to fallback
665 * to the single_cmd mode
666 */
667 bus->rirb_error = 1;
668 if (bus->allow_bus_reset && !bus->response_reset && !bus->in_reset) {
669 bus->response_reset = 1;
670 return -1; /* give a chance to retry */
671 }
672
649 snd_printk(KERN_ERR "hda_intel: azx_get_response timeout, " 673 snd_printk(KERN_ERR "hda_intel: azx_get_response timeout, "
650 "switching to single_cmd mode: last cmd=0x%08x\n", 674 "switching to single_cmd mode: last cmd=0x%08x\n",
651 chip->last_cmd); 675 chip->last_cmd);
652 chip->rirb.rp = azx_readb(chip, RIRBWP);
653 chip->rirb.cmds = 0;
654 /* switch to single_cmd mode */
655 chip->single_cmd = 1; 676 chip->single_cmd = 1;
677 bus->response_reset = 0;
678 /* re-initialize CORB/RIRB */
656 azx_free_cmd_io(chip); 679 azx_free_cmd_io(chip);
680 azx_init_cmd_io(chip);
657 return -1; 681 return -1;
658} 682}
659 683
@@ -667,12 +691,34 @@ static unsigned int azx_rirb_get_response(struct hda_bus *bus)
667 * I left the codes, however, for debugging/testing purposes. 691 * I left the codes, however, for debugging/testing purposes.
668 */ 692 */
669 693
694/* receive a response */
695static int azx_single_wait_for_response(struct azx *chip)
696{
697 int timeout = 50;
698
699 while (timeout--) {
700 /* check IRV busy bit */
701 if (azx_readw(chip, IRS) & ICH6_IRS_VALID) {
702 /* reuse rirb.res as the response return value */
703 chip->rirb.res = azx_readl(chip, IR);
704 return 0;
705 }
706 udelay(1);
707 }
708 if (printk_ratelimit())
709 snd_printd(SFX "get_response timeout: IRS=0x%x\n",
710 azx_readw(chip, IRS));
711 chip->rirb.res = -1;
712 return -EIO;
713}
714
670/* send a command */ 715/* send a command */
671static int azx_single_send_cmd(struct hda_bus *bus, u32 val) 716static int azx_single_send_cmd(struct hda_bus *bus, u32 val)
672{ 717{
673 struct azx *chip = bus->private_data; 718 struct azx *chip = bus->private_data;
674 int timeout = 50; 719 int timeout = 50;
675 720
721 bus->rirb_error = 0;
676 while (timeout--) { 722 while (timeout--) {
677 /* check ICB busy bit */ 723 /* check ICB busy bit */
678 if (!((azx_readw(chip, IRS) & ICH6_IRS_BUSY))) { 724 if (!((azx_readw(chip, IRS) & ICH6_IRS_BUSY))) {
@@ -682,7 +728,7 @@ static int azx_single_send_cmd(struct hda_bus *bus, u32 val)
682 azx_writel(chip, IC, val); 728 azx_writel(chip, IC, val);
683 azx_writew(chip, IRS, azx_readw(chip, IRS) | 729 azx_writew(chip, IRS, azx_readw(chip, IRS) |
684 ICH6_IRS_BUSY); 730 ICH6_IRS_BUSY);
685 return 0; 731 return azx_single_wait_for_response(chip);
686 } 732 }
687 udelay(1); 733 udelay(1);
688 } 734 }
@@ -696,18 +742,7 @@ static int azx_single_send_cmd(struct hda_bus *bus, u32 val)
696static unsigned int azx_single_get_response(struct hda_bus *bus) 742static unsigned int azx_single_get_response(struct hda_bus *bus)
697{ 743{
698 struct azx *chip = bus->private_data; 744 struct azx *chip = bus->private_data;
699 int timeout = 50; 745 return chip->rirb.res;
700
701 while (timeout--) {
702 /* check IRV busy bit */
703 if (azx_readw(chip, IRS) & ICH6_IRS_VALID)
704 return azx_readl(chip, IR);
705 udelay(1);
706 }
707 if (printk_ratelimit())
708 snd_printd(SFX "get_response timeout: IRS=0x%x\n",
709 azx_readw(chip, IRS));
710 return (unsigned int)-1;
711} 746}
712 747
713/* 748/*
@@ -775,17 +810,17 @@ static int azx_reset(struct azx *chip)
775 810
776 /* check to see if controller is ready */ 811 /* check to see if controller is ready */
777 if (!azx_readb(chip, GCTL)) { 812 if (!azx_readb(chip, GCTL)) {
778 snd_printd("azx_reset: controller not ready!\n"); 813 snd_printd(SFX "azx_reset: controller not ready!\n");
779 return -EBUSY; 814 return -EBUSY;
780 } 815 }
781 816
782 /* Accept unsolicited responses */ 817 /* Accept unsolicited responses */
783 azx_writel(chip, GCTL, azx_readl(chip, GCTL) | ICH6_GCTL_UREN); 818 azx_writel(chip, GCTL, azx_readl(chip, GCTL) | ICH6_GCTL_UNSOL);
784 819
785 /* detect codecs */ 820 /* detect codecs */
786 if (!chip->codec_mask) { 821 if (!chip->codec_mask) {
787 chip->codec_mask = azx_readw(chip, STATESTS); 822 chip->codec_mask = azx_readw(chip, STATESTS);
788 snd_printdd("codec_mask = 0x%x\n", chip->codec_mask); 823 snd_printdd(SFX "codec_mask = 0x%x\n", chip->codec_mask);
789 } 824 }
790 825
791 return 0; 826 return 0;
@@ -895,8 +930,7 @@ static void azx_init_chip(struct azx *chip)
895 azx_int_enable(chip); 930 azx_int_enable(chip);
896 931
897 /* initialize the codec command I/O */ 932 /* initialize the codec command I/O */
898 if (!chip->single_cmd) 933 azx_init_cmd_io(chip);
899 azx_init_cmd_io(chip);
900 934
901 /* program the position buffer */ 935 /* program the position buffer */
902 azx_writel(chip, DPLBASE, (u32)chip->posbuf.addr); 936 azx_writel(chip, DPLBASE, (u32)chip->posbuf.addr);
@@ -953,12 +987,12 @@ static void azx_init_pci(struct azx *chip)
953 case AZX_DRIVER_SCH: 987 case AZX_DRIVER_SCH:
954 pci_read_config_word(chip->pci, INTEL_SCH_HDA_DEVC, &snoop); 988 pci_read_config_word(chip->pci, INTEL_SCH_HDA_DEVC, &snoop);
955 if (snoop & INTEL_SCH_HDA_DEVC_NOSNOOP) { 989 if (snoop & INTEL_SCH_HDA_DEVC_NOSNOOP) {
956 pci_write_config_word(chip->pci, INTEL_SCH_HDA_DEVC, \ 990 pci_write_config_word(chip->pci, INTEL_SCH_HDA_DEVC,
957 snoop & (~INTEL_SCH_HDA_DEVC_NOSNOOP)); 991 snoop & (~INTEL_SCH_HDA_DEVC_NOSNOOP));
958 pci_read_config_word(chip->pci, 992 pci_read_config_word(chip->pci,
959 INTEL_SCH_HDA_DEVC, &snoop); 993 INTEL_SCH_HDA_DEVC, &snoop);
960 snd_printdd("HDA snoop disabled, enabling ... %s\n",\ 994 snd_printdd(SFX "HDA snoop disabled, enabling ... %s\n",
961 (snoop & INTEL_SCH_HDA_DEVC_NOSNOOP) \ 995 (snoop & INTEL_SCH_HDA_DEVC_NOSNOOP)
962 ? "Failed" : "OK"); 996 ? "Failed" : "OK");
963 } 997 }
964 break; 998 break;
@@ -1012,7 +1046,7 @@ static irqreturn_t azx_interrupt(int irq, void *dev_id)
1012 /* clear rirb int */ 1046 /* clear rirb int */
1013 status = azx_readb(chip, RIRBSTS); 1047 status = azx_readb(chip, RIRBSTS);
1014 if (status & RIRB_INT_MASK) { 1048 if (status & RIRB_INT_MASK) {
1015 if (!chip->single_cmd && (status & RIRB_INT_RESPONSE)) 1049 if (status & RIRB_INT_RESPONSE)
1016 azx_update_rirb(chip); 1050 azx_update_rirb(chip);
1017 azx_writeb(chip, RIRBSTS, RIRB_INT_MASK); 1051 azx_writeb(chip, RIRBSTS, RIRB_INT_MASK);
1018 } 1052 }
@@ -1098,7 +1132,7 @@ static int azx_setup_periods(struct azx *chip,
1098 pos_align; 1132 pos_align;
1099 pos_adj = frames_to_bytes(runtime, pos_adj); 1133 pos_adj = frames_to_bytes(runtime, pos_adj);
1100 if (pos_adj >= period_bytes) { 1134 if (pos_adj >= period_bytes) {
1101 snd_printk(KERN_WARNING "Too big adjustment %d\n", 1135 snd_printk(KERN_WARNING SFX "Too big adjustment %d\n",
1102 bdl_pos_adj[chip->dev_index]); 1136 bdl_pos_adj[chip->dev_index]);
1103 pos_adj = 0; 1137 pos_adj = 0;
1104 } else { 1138 } else {
@@ -1122,7 +1156,7 @@ static int azx_setup_periods(struct azx *chip,
1122 return 0; 1156 return 0;
1123 1157
1124 error: 1158 error:
1125 snd_printk(KERN_ERR "Too many BDL entries: buffer=%d, period=%d\n", 1159 snd_printk(KERN_ERR SFX "Too many BDL entries: buffer=%d, period=%d\n",
1126 azx_dev->bufsize, period_bytes); 1160 azx_dev->bufsize, period_bytes);
1127 return -EINVAL; 1161 return -EINVAL;
1128} 1162}
@@ -1215,7 +1249,7 @@ static int probe_codec(struct azx *chip, int addr)
1215 chip->probing = 0; 1249 chip->probing = 0;
1216 if (res == -1) 1250 if (res == -1)
1217 return -EIO; 1251 return -EIO;
1218 snd_printdd("hda_intel: codec #%d probed OK\n", addr); 1252 snd_printdd(SFX "codec #%d probed OK\n", addr);
1219 return 0; 1253 return 0;
1220} 1254}
1221 1255
@@ -1223,6 +1257,26 @@ static int azx_attach_pcm_stream(struct hda_bus *bus, struct hda_codec *codec,
1223 struct hda_pcm *cpcm); 1257 struct hda_pcm *cpcm);
1224static void azx_stop_chip(struct azx *chip); 1258static void azx_stop_chip(struct azx *chip);
1225 1259
1260static void azx_bus_reset(struct hda_bus *bus)
1261{
1262 struct azx *chip = bus->private_data;
1263
1264 bus->in_reset = 1;
1265 azx_stop_chip(chip);
1266 azx_init_chip(chip);
1267#ifdef CONFIG_PM
1268 if (chip->initialized) {
1269 int i;
1270
1271 for (i = 0; i < AZX_MAX_PCMS; i++)
1272 snd_pcm_suspend_all(chip->pcm[i]);
1273 snd_hda_suspend(chip->bus);
1274 snd_hda_resume(chip->bus);
1275 }
1276#endif
1277 bus->in_reset = 0;
1278}
1279
1226/* 1280/*
1227 * Codec initialization 1281 * Codec initialization
1228 */ 1282 */
@@ -1246,6 +1300,7 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model,
1246 bus_temp.ops.command = azx_send_cmd; 1300 bus_temp.ops.command = azx_send_cmd;
1247 bus_temp.ops.get_response = azx_get_response; 1301 bus_temp.ops.get_response = azx_get_response;
1248 bus_temp.ops.attach_pcm = azx_attach_pcm_stream; 1302 bus_temp.ops.attach_pcm = azx_attach_pcm_stream;
1303 bus_temp.ops.bus_reset = azx_bus_reset;
1249#ifdef CONFIG_SND_HDA_POWER_SAVE 1304#ifdef CONFIG_SND_HDA_POWER_SAVE
1250 bus_temp.power_save = &power_save; 1305 bus_temp.power_save = &power_save;
1251 bus_temp.ops.pm_notify = azx_power_notify; 1306 bus_temp.ops.pm_notify = azx_power_notify;
@@ -1270,8 +1325,8 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model,
1270 /* Some BIOSen give you wrong codec addresses 1325 /* Some BIOSen give you wrong codec addresses
1271 * that don't exist 1326 * that don't exist
1272 */ 1327 */
1273 snd_printk(KERN_WARNING 1328 snd_printk(KERN_WARNING SFX
1274 "hda_intel: Codec #%d probe error; " 1329 "Codec #%d probe error; "
1275 "disabling it...\n", c); 1330 "disabling it...\n", c);
1276 chip->codec_mask &= ~(1 << c); 1331 chip->codec_mask &= ~(1 << c);
1277 /* More badly, accessing to a non-existing 1332 /* More badly, accessing to a non-existing
@@ -1487,7 +1542,7 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream)
1487 bufsize = snd_pcm_lib_buffer_bytes(substream); 1542 bufsize = snd_pcm_lib_buffer_bytes(substream);
1488 period_bytes = snd_pcm_lib_period_bytes(substream); 1543 period_bytes = snd_pcm_lib_period_bytes(substream);
1489 1544
1490 snd_printdd("azx_pcm_prepare: bufsize=0x%x, format=0x%x\n", 1545 snd_printdd(SFX "azx_pcm_prepare: bufsize=0x%x, format=0x%x\n",
1491 bufsize, format_val); 1546 bufsize, format_val);
1492 1547
1493 if (bufsize != azx_dev->bufsize || 1548 if (bufsize != azx_dev->bufsize ||
@@ -1830,7 +1885,7 @@ azx_attach_pcm_stream(struct hda_bus *bus, struct hda_codec *codec,
1830 &pcm); 1885 &pcm);
1831 if (err < 0) 1886 if (err < 0)
1832 return err; 1887 return err;
1833 strcpy(pcm->name, cpcm->name); 1888 strlcpy(pcm->name, cpcm->name, sizeof(pcm->name));
1834 apcm = kzalloc(sizeof(*apcm), GFP_KERNEL); 1889 apcm = kzalloc(sizeof(*apcm), GFP_KERNEL);
1835 if (apcm == NULL) 1890 if (apcm == NULL)
1836 return -ENOMEM; 1891 return -ENOMEM;
@@ -1973,7 +2028,7 @@ static int azx_suspend(struct pci_dev *pci, pm_message_t state)
1973 for (i = 0; i < AZX_MAX_PCMS; i++) 2028 for (i = 0; i < AZX_MAX_PCMS; i++)
1974 snd_pcm_suspend_all(chip->pcm[i]); 2029 snd_pcm_suspend_all(chip->pcm[i]);
1975 if (chip->initialized) 2030 if (chip->initialized)
1976 snd_hda_suspend(chip->bus, state); 2031 snd_hda_suspend(chip->bus);
1977 azx_stop_chip(chip); 2032 azx_stop_chip(chip);
1978 if (chip->irq >= 0) { 2033 if (chip->irq >= 0) {
1979 free_irq(chip->irq, chip); 2034 free_irq(chip->irq, chip);
@@ -2141,6 +2196,7 @@ static struct snd_pci_quirk probe_mask_list[] __devinitdata = {
2141 /* including bogus ALC268 in slot#2 that conflicts with ALC888 */ 2196 /* including bogus ALC268 in slot#2 that conflicts with ALC888 */
2142 SND_PCI_QUIRK(0x17c0, 0x4085, "Medion MD96630", 0x01), 2197 SND_PCI_QUIRK(0x17c0, 0x4085, "Medion MD96630", 0x01),
2143 /* forced codec slots */ 2198 /* forced codec slots */
2199 SND_PCI_QUIRK(0x1043, 0x1262, "ASUS W5Fm", 0x103),
2144 SND_PCI_QUIRK(0x1046, 0x1262, "ASUS W5F", 0x103), 2200 SND_PCI_QUIRK(0x1046, 0x1262, "ASUS W5F", 0x103),
2145 {} 2201 {}
2146}; 2202};
@@ -2264,14 +2320,14 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
2264 synchronize_irq(chip->irq); 2320 synchronize_irq(chip->irq);
2265 2321
2266 gcap = azx_readw(chip, GCAP); 2322 gcap = azx_readw(chip, GCAP);
2267 snd_printdd("chipset global capabilities = 0x%x\n", gcap); 2323 snd_printdd(SFX "chipset global capabilities = 0x%x\n", gcap);
2268 2324
2269 /* ATI chips seems buggy about 64bit DMA addresses */ 2325 /* ATI chips seems buggy about 64bit DMA addresses */
2270 if (chip->driver_type == AZX_DRIVER_ATI) 2326 if (chip->driver_type == AZX_DRIVER_ATI)
2271 gcap &= ~0x01; 2327 gcap &= ~ICH6_GCAP_64OK;
2272 2328
2273 /* allow 64bit DMA address if supported by H/W */ 2329 /* allow 64bit DMA address if supported by H/W */
2274 if ((gcap & 0x01) && !pci_set_dma_mask(pci, DMA_BIT_MASK(64))) 2330 if ((gcap & ICH6_GCAP_64OK) && !pci_set_dma_mask(pci, DMA_BIT_MASK(64)))
2275 pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(64)); 2331 pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(64));
2276 else { 2332 else {
2277 pci_set_dma_mask(pci, DMA_BIT_MASK(32)); 2333 pci_set_dma_mask(pci, DMA_BIT_MASK(32));
@@ -2308,7 +2364,7 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
2308 chip->azx_dev = kcalloc(chip->num_streams, sizeof(*chip->azx_dev), 2364 chip->azx_dev = kcalloc(chip->num_streams, sizeof(*chip->azx_dev),
2309 GFP_KERNEL); 2365 GFP_KERNEL);
2310 if (!chip->azx_dev) { 2366 if (!chip->azx_dev) {
2311 snd_printk(KERN_ERR "cannot malloc azx_dev\n"); 2367 snd_printk(KERN_ERR SFX "cannot malloc azx_dev\n");
2312 goto errout; 2368 goto errout;
2313 } 2369 }
2314 2370
@@ -2331,11 +2387,9 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
2331 goto errout; 2387 goto errout;
2332 } 2388 }
2333 /* allocate CORB/RIRB */ 2389 /* allocate CORB/RIRB */
2334 if (!chip->single_cmd) { 2390 err = azx_alloc_cmd_io(chip);
2335 err = azx_alloc_cmd_io(chip); 2391 if (err < 0)
2336 if (err < 0) 2392 goto errout;
2337 goto errout;
2338 }
2339 2393
2340 /* initialize streams */ 2394 /* initialize streams */
2341 azx_init_stream(chip); 2395 azx_init_stream(chip);
@@ -2358,9 +2412,11 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
2358 } 2412 }
2359 2413
2360 strcpy(card->driver, "HDA-Intel"); 2414 strcpy(card->driver, "HDA-Intel");
2361 strcpy(card->shortname, driver_short_names[chip->driver_type]); 2415 strlcpy(card->shortname, driver_short_names[chip->driver_type],
2362 sprintf(card->longname, "%s at 0x%lx irq %i", 2416 sizeof(card->shortname));
2363 card->shortname, chip->addr, chip->irq); 2417 snprintf(card->longname, sizeof(card->longname),
2418 "%s at 0x%lx irq %i",
2419 card->shortname, chip->addr, chip->irq);
2364 2420
2365 *rchip = chip; 2421 *rchip = chip;
2366 return 0; 2422 return 0;
@@ -2513,6 +2569,20 @@ static struct pci_device_id azx_ids[] = {
2513 { PCI_DEVICE(0x10de, 0x0d97), .driver_data = AZX_DRIVER_NVIDIA }, 2569 { PCI_DEVICE(0x10de, 0x0d97), .driver_data = AZX_DRIVER_NVIDIA },
2514 /* Teradici */ 2570 /* Teradici */
2515 { PCI_DEVICE(0x6549, 0x1200), .driver_data = AZX_DRIVER_TERA }, 2571 { PCI_DEVICE(0x6549, 0x1200), .driver_data = AZX_DRIVER_TERA },
2572 /* Creative X-Fi (CA0110-IBG) */
2573#if !defined(CONFIG_SND_CTXFI) && !defined(CONFIG_SND_CTXFI_MODULE)
2574 /* the following entry conflicts with snd-ctxfi driver,
2575 * as ctxfi driver mutates from HD-audio to native mode with
2576 * a special command sequence.
2577 */
2578 { PCI_DEVICE(PCI_VENDOR_ID_CREATIVE, PCI_ANY_ID),
2579 .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8,
2580 .class_mask = 0xffffff,
2581 .driver_data = AZX_DRIVER_GENERIC },
2582#else
2583 /* this entry seems still valid -- i.e. without emu20kx chip */
2584 { PCI_DEVICE(0x1102, 0x0009), .driver_data = AZX_DRIVER_GENERIC },
2585#endif
2516 /* AMD Generic, PCI class code and Vendor ID for HD Audio */ 2586 /* AMD Generic, PCI class code and Vendor ID for HD Audio */
2517 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_ANY_ID), 2587 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_ANY_ID),
2518 .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8, 2588 .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8,
diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c
index 93d7499350c..418c5d1bada 100644
--- a/sound/pci/hda/hda_proc.c
+++ b/sound/pci/hda/hda_proc.c
@@ -466,8 +466,12 @@ static void print_codec_info(struct snd_info_entry *entry,
466 hda_nid_t nid; 466 hda_nid_t nid;
467 int i, nodes; 467 int i, nodes;
468 468
469 snd_iprintf(buffer, "Codec: %s\n", 469 snd_iprintf(buffer, "Codec: ");
470 codec->name ? codec->name : "Not Set"); 470 if (codec->vendor_name && codec->chip_name)
471 snd_iprintf(buffer, "%s %s\n",
472 codec->vendor_name, codec->chip_name);
473 else
474 snd_iprintf(buffer, "Not Set\n");
471 snd_iprintf(buffer, "Address: %d\n", codec->addr); 475 snd_iprintf(buffer, "Address: %d\n", codec->addr);
472 snd_iprintf(buffer, "Function Id: 0x%x\n", codec->function_id); 476 snd_iprintf(buffer, "Function Id: 0x%x\n", codec->function_id);
473 snd_iprintf(buffer, "Vendor Id: 0x%08x\n", codec->vendor_id); 477 snd_iprintf(buffer, "Vendor Id: 0x%08x\n", codec->vendor_id);
diff --git a/sound/pci/hda/patch_ca0110.c b/sound/pci/hda/patch_ca0110.c
new file mode 100644
index 00000000000..392d108c355
--- /dev/null
+++ b/sound/pci/hda/patch_ca0110.c
@@ -0,0 +1,573 @@
1/*
2 * HD audio interface patch for Creative X-Fi CA0110-IBG chip
3 *
4 * Copyright (c) 2008 Takashi Iwai <tiwai@suse.de>
5 *
6 * 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 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This driver 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/delay.h>
23#include <linux/slab.h>
24#include <linux/pci.h>
25#include <sound/core.h>
26#include "hda_codec.h"
27#include "hda_local.h"
28
29/*
30 */
31
32struct ca0110_spec {
33 struct auto_pin_cfg autocfg;
34 struct hda_multi_out multiout;
35 hda_nid_t out_pins[AUTO_CFG_MAX_OUTS];
36 hda_nid_t dacs[AUTO_CFG_MAX_OUTS];
37 hda_nid_t hp_dac;
38 hda_nid_t input_pins[AUTO_PIN_LAST];
39 hda_nid_t adcs[AUTO_PIN_LAST];
40 hda_nid_t dig_out;
41 hda_nid_t dig_in;
42 unsigned int num_inputs;
43 const char *input_labels[AUTO_PIN_LAST];
44 struct hda_pcm pcm_rec[2]; /* PCM information */
45};
46
47/*
48 * PCM callbacks
49 */
50static int ca0110_playback_pcm_open(struct hda_pcm_stream *hinfo,
51 struct hda_codec *codec,
52 struct snd_pcm_substream *substream)
53{
54 struct ca0110_spec *spec = codec->spec;
55 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
56 hinfo);
57}
58
59static int ca0110_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
60 struct hda_codec *codec,
61 unsigned int stream_tag,
62 unsigned int format,
63 struct snd_pcm_substream *substream)
64{
65 struct ca0110_spec *spec = codec->spec;
66 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
67 stream_tag, format, substream);
68}
69
70static int ca0110_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
71 struct hda_codec *codec,
72 struct snd_pcm_substream *substream)
73{
74 struct ca0110_spec *spec = codec->spec;
75 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
76}
77
78/*
79 * Digital out
80 */
81static int ca0110_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
82 struct hda_codec *codec,
83 struct snd_pcm_substream *substream)
84{
85 struct ca0110_spec *spec = codec->spec;
86 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
87}
88
89static int ca0110_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
90 struct hda_codec *codec,
91 struct snd_pcm_substream *substream)
92{
93 struct ca0110_spec *spec = codec->spec;
94 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
95}
96
97static int ca0110_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
98 struct hda_codec *codec,
99 unsigned int stream_tag,
100 unsigned int format,
101 struct snd_pcm_substream *substream)
102{
103 struct ca0110_spec *spec = codec->spec;
104 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag,
105 format, substream);
106}
107
108/*
109 * Analog capture
110 */
111static int ca0110_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
112 struct hda_codec *codec,
113 unsigned int stream_tag,
114 unsigned int format,
115 struct snd_pcm_substream *substream)
116{
117 struct ca0110_spec *spec = codec->spec;
118
119 snd_hda_codec_setup_stream(codec, spec->adcs[substream->number],
120 stream_tag, 0, format);
121 return 0;
122}
123
124static int ca0110_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
125 struct hda_codec *codec,
126 struct snd_pcm_substream *substream)
127{
128 struct ca0110_spec *spec = codec->spec;
129
130 snd_hda_codec_cleanup_stream(codec, spec->adcs[substream->number]);
131 return 0;
132}
133
134/*
135 */
136
137static char *dirstr[2] = { "Playback", "Capture" };
138
139static int _add_switch(struct hda_codec *codec, hda_nid_t nid, const char *pfx,
140 int chan, int dir)
141{
142 char namestr[44];
143 int type = dir ? HDA_INPUT : HDA_OUTPUT;
144 struct snd_kcontrol_new knew =
145 HDA_CODEC_MUTE_MONO(namestr, nid, chan, 0, type);
146 sprintf(namestr, "%s %s Switch", pfx, dirstr[dir]);
147 return snd_hda_ctl_add(codec, snd_ctl_new1(&knew, codec));
148}
149
150static int _add_volume(struct hda_codec *codec, hda_nid_t nid, const char *pfx,
151 int chan, int dir)
152{
153 char namestr[44];
154 int type = dir ? HDA_INPUT : HDA_OUTPUT;
155 struct snd_kcontrol_new knew =
156 HDA_CODEC_VOLUME_MONO(namestr, nid, chan, 0, type);
157 sprintf(namestr, "%s %s Volume", pfx, dirstr[dir]);
158 return snd_hda_ctl_add(codec, snd_ctl_new1(&knew, codec));
159}
160
161#define add_out_switch(codec, nid, pfx) _add_switch(codec, nid, pfx, 3, 0)
162#define add_out_volume(codec, nid, pfx) _add_volume(codec, nid, pfx, 3, 0)
163#define add_in_switch(codec, nid, pfx) _add_switch(codec, nid, pfx, 3, 1)
164#define add_in_volume(codec, nid, pfx) _add_volume(codec, nid, pfx, 3, 1)
165#define add_mono_switch(codec, nid, pfx, chan) \
166 _add_switch(codec, nid, pfx, chan, 0)
167#define add_mono_volume(codec, nid, pfx, chan) \
168 _add_volume(codec, nid, pfx, chan, 0)
169
170static int ca0110_build_controls(struct hda_codec *codec)
171{
172 struct ca0110_spec *spec = codec->spec;
173 struct auto_pin_cfg *cfg = &spec->autocfg;
174 static char *prefix[AUTO_CFG_MAX_OUTS] = {
175 "Front", "Surround", NULL, "Side", "Multi"
176 };
177 hda_nid_t mutenid;
178 int i, err;
179
180 for (i = 0; i < spec->multiout.num_dacs; i++) {
181 if (get_wcaps(codec, spec->out_pins[i]) & AC_WCAP_OUT_AMP)
182 mutenid = spec->out_pins[i];
183 else
184 mutenid = spec->multiout.dac_nids[i];
185 if (!prefix[i]) {
186 err = add_mono_switch(codec, mutenid,
187 "Center", 1);
188 if (err < 0)
189 return err;
190 err = add_mono_switch(codec, mutenid,
191 "LFE", 1);
192 if (err < 0)
193 return err;
194 err = add_mono_volume(codec, spec->multiout.dac_nids[i],
195 "Center", 1);
196 if (err < 0)
197 return err;
198 err = add_mono_volume(codec, spec->multiout.dac_nids[i],
199 "LFE", 1);
200 if (err < 0)
201 return err;
202 } else {
203 err = add_out_switch(codec, mutenid,
204 prefix[i]);
205 if (err < 0)
206 return err;
207 err = add_out_volume(codec, spec->multiout.dac_nids[i],
208 prefix[i]);
209 if (err < 0)
210 return err;
211 }
212 }
213 if (cfg->hp_outs) {
214 if (get_wcaps(codec, cfg->hp_pins[0]) & AC_WCAP_OUT_AMP)
215 mutenid = cfg->hp_pins[0];
216 else
217 mutenid = spec->multiout.dac_nids[i];
218
219 err = add_out_switch(codec, mutenid, "Headphone");
220 if (err < 0)
221 return err;
222 if (spec->hp_dac) {
223 err = add_out_volume(codec, spec->hp_dac, "Headphone");
224 if (err < 0)
225 return err;
226 }
227 }
228 for (i = 0; i < spec->num_inputs; i++) {
229 const char *label = spec->input_labels[i];
230 if (get_wcaps(codec, spec->input_pins[i]) & AC_WCAP_IN_AMP)
231 mutenid = spec->input_pins[i];
232 else
233 mutenid = spec->adcs[i];
234 err = add_in_switch(codec, mutenid, label);
235 if (err < 0)
236 return err;
237 err = add_in_volume(codec, spec->adcs[i], label);
238 if (err < 0)
239 return err;
240 }
241
242 if (spec->dig_out) {
243 err = snd_hda_create_spdif_out_ctls(codec, spec->dig_out);
244 if (err < 0)
245 return err;
246 err = snd_hda_create_spdif_share_sw(codec, &spec->multiout);
247 if (err < 0)
248 return err;
249 spec->multiout.share_spdif = 1;
250 }
251 if (spec->dig_in) {
252 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in);
253 if (err < 0)
254 return err;
255 err = add_in_volume(codec, spec->dig_in, "IEC958");
256 }
257 return 0;
258}
259
260/*
261 */
262static struct hda_pcm_stream ca0110_pcm_analog_playback = {
263 .substreams = 1,
264 .channels_min = 2,
265 .channels_max = 8,
266 .ops = {
267 .open = ca0110_playback_pcm_open,
268 .prepare = ca0110_playback_pcm_prepare,
269 .cleanup = ca0110_playback_pcm_cleanup
270 },
271};
272
273static struct hda_pcm_stream ca0110_pcm_analog_capture = {
274 .substreams = 1,
275 .channels_min = 2,
276 .channels_max = 2,
277 .ops = {
278 .prepare = ca0110_capture_pcm_prepare,
279 .cleanup = ca0110_capture_pcm_cleanup
280 },
281};
282
283static struct hda_pcm_stream ca0110_pcm_digital_playback = {
284 .substreams = 1,
285 .channels_min = 2,
286 .channels_max = 2,
287 .ops = {
288 .open = ca0110_dig_playback_pcm_open,
289 .close = ca0110_dig_playback_pcm_close,
290 .prepare = ca0110_dig_playback_pcm_prepare
291 },
292};
293
294static struct hda_pcm_stream ca0110_pcm_digital_capture = {
295 .substreams = 1,
296 .channels_min = 2,
297 .channels_max = 2,
298};
299
300static int ca0110_build_pcms(struct hda_codec *codec)
301{
302 struct ca0110_spec *spec = codec->spec;
303 struct hda_pcm *info = spec->pcm_rec;
304
305 codec->pcm_info = info;
306 codec->num_pcms = 0;
307
308 info->name = "CA0110 Analog";
309 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ca0110_pcm_analog_playback;
310 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->dacs[0];
311 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max =
312 spec->multiout.max_channels;
313 info->stream[SNDRV_PCM_STREAM_CAPTURE] = ca0110_pcm_analog_capture;
314 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = spec->num_inputs;
315 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adcs[0];
316 codec->num_pcms++;
317
318 if (!spec->dig_out && !spec->dig_in)
319 return 0;
320
321 info++;
322 info->name = "CA0110 Digital";
323 info->pcm_type = HDA_PCM_TYPE_SPDIF;
324 if (spec->dig_out) {
325 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
326 ca0110_pcm_digital_playback;
327 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->dig_out;
328 }
329 if (spec->dig_in) {
330 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
331 ca0110_pcm_digital_capture;
332 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in;
333 }
334 codec->num_pcms++;
335
336 return 0;
337}
338
339static void init_output(struct hda_codec *codec, hda_nid_t pin, hda_nid_t dac)
340{
341 if (pin) {
342 snd_hda_codec_write(codec, pin, 0,
343 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP);
344 if (get_wcaps(codec, pin) & AC_WCAP_OUT_AMP)
345 snd_hda_codec_write(codec, pin, 0,
346 AC_VERB_SET_AMP_GAIN_MUTE,
347 AMP_OUT_UNMUTE);
348 }
349 if (dac)
350 snd_hda_codec_write(codec, dac, 0,
351 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO);
352}
353
354static void init_input(struct hda_codec *codec, hda_nid_t pin, hda_nid_t adc)
355{
356 if (pin) {
357 snd_hda_codec_write(codec, pin, 0,
358 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80);
359 if (get_wcaps(codec, pin) & AC_WCAP_IN_AMP)
360 snd_hda_codec_write(codec, pin, 0,
361 AC_VERB_SET_AMP_GAIN_MUTE,
362 AMP_IN_UNMUTE(0));
363 }
364 if (adc)
365 snd_hda_codec_write(codec, adc, 0, AC_VERB_SET_AMP_GAIN_MUTE,
366 AMP_IN_UNMUTE(0));
367}
368
369static int ca0110_init(struct hda_codec *codec)
370{
371 struct ca0110_spec *spec = codec->spec;
372 struct auto_pin_cfg *cfg = &spec->autocfg;
373 int i;
374
375 for (i = 0; i < spec->multiout.num_dacs; i++)
376 init_output(codec, spec->out_pins[i],
377 spec->multiout.dac_nids[i]);
378 init_output(codec, cfg->hp_pins[0], spec->hp_dac);
379 init_output(codec, cfg->dig_out_pins[0], spec->dig_out);
380
381 for (i = 0; i < spec->num_inputs; i++)
382 init_input(codec, spec->input_pins[i], spec->adcs[i]);
383 init_input(codec, cfg->dig_in_pin, spec->dig_in);
384 return 0;
385}
386
387static void ca0110_free(struct hda_codec *codec)
388{
389 kfree(codec->spec);
390}
391
392static struct hda_codec_ops ca0110_patch_ops = {
393 .build_controls = ca0110_build_controls,
394 .build_pcms = ca0110_build_pcms,
395 .init = ca0110_init,
396 .free = ca0110_free,
397};
398
399
400static void parse_line_outs(struct hda_codec *codec)
401{
402 struct ca0110_spec *spec = codec->spec;
403 struct auto_pin_cfg *cfg = &spec->autocfg;
404 int i, n;
405 unsigned int def_conf;
406 hda_nid_t nid;
407
408 n = 0;
409 for (i = 0; i < cfg->line_outs; i++) {
410 nid = cfg->line_out_pins[i];
411 def_conf = snd_hda_codec_get_pincfg(codec, nid);
412 if (!def_conf)
413 continue; /* invalid pin */
414 if (snd_hda_get_connections(codec, nid, &spec->dacs[i], 1) != 1)
415 continue;
416 spec->out_pins[n++] = nid;
417 }
418 spec->multiout.dac_nids = spec->dacs;
419 spec->multiout.num_dacs = n;
420 spec->multiout.max_channels = n * 2;
421}
422
423static void parse_hp_out(struct hda_codec *codec)
424{
425 struct ca0110_spec *spec = codec->spec;
426 struct auto_pin_cfg *cfg = &spec->autocfg;
427 int i;
428 unsigned int def_conf;
429 hda_nid_t nid, dac;
430
431 if (!cfg->hp_outs)
432 return;
433 nid = cfg->hp_pins[0];
434 def_conf = snd_hda_codec_get_pincfg(codec, nid);
435 if (!def_conf) {
436 cfg->hp_outs = 0;
437 return;
438 }
439 if (snd_hda_get_connections(codec, nid, &dac, 1) != 1)
440 return;
441
442 for (i = 0; i < cfg->line_outs; i++)
443 if (dac == spec->dacs[i])
444 break;
445 if (i >= cfg->line_outs) {
446 spec->hp_dac = dac;
447 spec->multiout.hp_nid = dac;
448 }
449}
450
451static void parse_input(struct hda_codec *codec)
452{
453 struct ca0110_spec *spec = codec->spec;
454 struct auto_pin_cfg *cfg = &spec->autocfg;
455 hda_nid_t nid, pin;
456 int n, i, j;
457
458 n = 0;
459 nid = codec->start_nid;
460 for (i = 0; i < codec->num_nodes; i++, nid++) {
461 unsigned int wcaps = get_wcaps(codec, nid);
462 unsigned int type = (wcaps & AC_WCAP_TYPE) >>
463 AC_WCAP_TYPE_SHIFT;
464 if (type != AC_WID_AUD_IN)
465 continue;
466 if (snd_hda_get_connections(codec, nid, &pin, 1) != 1)
467 continue;
468 if (pin == cfg->dig_in_pin) {
469 spec->dig_in = nid;
470 continue;
471 }
472 for (j = 0; j < AUTO_PIN_LAST; j++)
473 if (cfg->input_pins[j] == pin)
474 break;
475 if (j >= AUTO_PIN_LAST)
476 continue;
477 spec->input_pins[n] = pin;
478 spec->input_labels[n] = auto_pin_cfg_labels[j];
479 spec->adcs[n] = nid;
480 n++;
481 }
482 spec->num_inputs = n;
483}
484
485static void parse_digital(struct hda_codec *codec)
486{
487 struct ca0110_spec *spec = codec->spec;
488 struct auto_pin_cfg *cfg = &spec->autocfg;
489
490 if (cfg->dig_outs &&
491 snd_hda_get_connections(codec, cfg->dig_out_pins[0],
492 &spec->dig_out, 1) == 1)
493 spec->multiout.dig_out_nid = cfg->dig_out_pins[0];
494}
495
496static int ca0110_parse_auto_config(struct hda_codec *codec)
497{
498 struct ca0110_spec *spec = codec->spec;
499 int err;
500
501 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
502 if (err < 0)
503 return err;
504
505 parse_line_outs(codec);
506 parse_hp_out(codec);
507 parse_digital(codec);
508 parse_input(codec);
509 return 0;
510}
511
512
513int patch_ca0110(struct hda_codec *codec)
514{
515 struct ca0110_spec *spec;
516 int err;
517
518 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
519 if (!spec)
520 return -ENOMEM;
521 codec->spec = spec;
522
523 codec->bus->needs_damn_long_delay = 1;
524
525 err = ca0110_parse_auto_config(codec);
526 if (err < 0)
527 goto error;
528
529 codec->patch_ops = ca0110_patch_ops;
530
531 return 0;
532
533 error:
534 kfree(codec->spec);
535 codec->spec = NULL;
536 return err;
537}
538
539
540/*
541 * patch entries
542 */
543static struct hda_codec_preset snd_hda_preset_ca0110[] = {
544 { .id = 0x1102000a, .name = "CA0110-IBG", .patch = patch_ca0110 },
545 { .id = 0x1102000b, .name = "CA0110-IBG", .patch = patch_ca0110 },
546 { .id = 0x1102000d, .name = "SB0880 X-Fi", .patch = patch_ca0110 },
547 {} /* terminator */
548};
549
550MODULE_ALIAS("snd-hda-codec-id:1102000a");
551MODULE_ALIAS("snd-hda-codec-id:1102000b");
552MODULE_ALIAS("snd-hda-codec-id:1102000d");
553
554MODULE_LICENSE("GPL");
555MODULE_DESCRIPTION("Creative CA0110-IBG HD-audio codec");
556
557static struct hda_codec_preset_list ca0110_list = {
558 .preset = snd_hda_preset_ca0110,
559 .owner = THIS_MODULE,
560};
561
562static int __init patch_ca0110_init(void)
563{
564 return snd_hda_add_codec_preset(&ca0110_list);
565}
566
567static void __exit patch_ca0110_exit(void)
568{
569 snd_hda_delete_codec_preset(&ca0110_list);
570}
571
572module_init(patch_ca0110_init)
573module_exit(patch_ca0110_exit)
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index 56ce19e68cb..4fcbe21829a 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -1848,6 +1848,7 @@ static const char *cxt5051_models[CXT5051_MODELS] = {
1848 1848
1849static struct snd_pci_quirk cxt5051_cfg_tbl[] = { 1849static struct snd_pci_quirk cxt5051_cfg_tbl[] = {
1850 SND_PCI_QUIRK(0x103c, 0x30cf, "HP DV6736", CXT5051_HP_DV6736), 1850 SND_PCI_QUIRK(0x103c, 0x30cf, "HP DV6736", CXT5051_HP_DV6736),
1851 SND_PCI_QUIRK(0x103c, 0x360b, "Compaq Presario CQ60", CXT5051_HP),
1851 SND_PCI_QUIRK(0x14f1, 0x0101, "Conexant Reference board", 1852 SND_PCI_QUIRK(0x14f1, 0x0101, "Conexant Reference board",
1852 CXT5051_LAPTOP), 1853 CXT5051_LAPTOP),
1853 SND_PCI_QUIRK(0x14f1, 0x5051, "HP Spartan 1.1", CXT5051_HP), 1854 SND_PCI_QUIRK(0x14f1, 0x5051, "HP Spartan 1.1", CXT5051_HP),
diff --git a/sound/pci/hda/patch_nvhdmi.c b/sound/pci/hda/patch_nvhdmi.c
index d57d8132a06..f5792e2eea8 100644
--- a/sound/pci/hda/patch_nvhdmi.c
+++ b/sound/pci/hda/patch_nvhdmi.c
@@ -35,9 +35,28 @@ struct nvhdmi_spec {
35 struct hda_pcm pcm_rec; 35 struct hda_pcm pcm_rec;
36}; 36};
37 37
38#define Nv_VERB_SET_Channel_Allocation 0xF79
39#define Nv_VERB_SET_Info_Frame_Checksum 0xF7A
40#define Nv_VERB_SET_Audio_Protection_On 0xF98
41#define Nv_VERB_SET_Audio_Protection_Off 0xF99
42
43#define Nv_Master_Convert_nid 0x04
44#define Nv_Master_Pin_nid 0x05
45
46static hda_nid_t nvhdmi_convert_nids[4] = {
47 /*front, rear, clfe, rear_surr */
48 0x6, 0x8, 0xa, 0xc,
49};
50
38static struct hda_verb nvhdmi_basic_init[] = { 51static struct hda_verb nvhdmi_basic_init[] = {
52 /* set audio protect on */
53 { 0x1, Nv_VERB_SET_Audio_Protection_On, 0x1},
39 /* enable digital output on pin widget */ 54 /* enable digital output on pin widget */
40 { 0x05, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 55 { 0x5, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x5 },
56 { 0x7, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x5 },
57 { 0x9, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x5 },
58 { 0xb, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x5 },
59 { 0xd, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x5 },
41 {} /* terminator */ 60 {} /* terminator */
42}; 61};
43 62
@@ -66,48 +85,205 @@ static int nvhdmi_init(struct hda_codec *codec)
66 * Digital out 85 * Digital out
67 */ 86 */
68static int nvhdmi_dig_playback_pcm_open(struct hda_pcm_stream *hinfo, 87static int nvhdmi_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
69 struct hda_codec *codec, 88 struct hda_codec *codec,
70 struct snd_pcm_substream *substream) 89 struct snd_pcm_substream *substream)
71{ 90{
72 struct nvhdmi_spec *spec = codec->spec; 91 struct nvhdmi_spec *spec = codec->spec;
73 return snd_hda_multi_out_dig_open(codec, &spec->multiout); 92 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
74} 93}
75 94
76static int nvhdmi_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, 95static int nvhdmi_dig_playback_pcm_close_8ch(struct hda_pcm_stream *hinfo,
77 struct hda_codec *codec, 96 struct hda_codec *codec,
78 struct snd_pcm_substream *substream) 97 struct snd_pcm_substream *substream)
79{ 98{
80 struct nvhdmi_spec *spec = codec->spec; 99 struct nvhdmi_spec *spec = codec->spec;
100 int i;
101
102 snd_hda_codec_write(codec, Nv_Master_Convert_nid,
103 0, AC_VERB_SET_CHANNEL_STREAMID, 0);
104 for (i = 0; i < 4; i++) {
105 /* set the stream id */
106 snd_hda_codec_write(codec, nvhdmi_convert_nids[i], 0,
107 AC_VERB_SET_CHANNEL_STREAMID, 0);
108 /* set the stream format */
109 snd_hda_codec_write(codec, nvhdmi_convert_nids[i], 0,
110 AC_VERB_SET_STREAM_FORMAT, 0);
111 }
112
81 return snd_hda_multi_out_dig_close(codec, &spec->multiout); 113 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
82} 114}
83 115
84static int nvhdmi_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, 116static int nvhdmi_dig_playback_pcm_close_2ch(struct hda_pcm_stream *hinfo,
85 struct hda_codec *codec, 117 struct hda_codec *codec,
86 unsigned int stream_tag, 118 struct snd_pcm_substream *substream)
87 unsigned int format, 119{
88 struct snd_pcm_substream *substream) 120 struct nvhdmi_spec *spec = codec->spec;
121 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
122}
123
124static int nvhdmi_dig_playback_pcm_prepare_8ch(struct hda_pcm_stream *hinfo,
125 struct hda_codec *codec,
126 unsigned int stream_tag,
127 unsigned int format,
128 struct snd_pcm_substream *substream)
129{
130 int chs;
131 unsigned int dataDCC1, dataDCC2, chan, chanmask, channel_id;
132 int i;
133
134 mutex_lock(&codec->spdif_mutex);
135
136 chs = substream->runtime->channels;
137 chan = chs ? (chs - 1) : 1;
138
139 switch (chs) {
140 default:
141 case 0:
142 case 2:
143 chanmask = 0x00;
144 break;
145 case 4:
146 chanmask = 0x08;
147 break;
148 case 6:
149 chanmask = 0x0b;
150 break;
151 case 8:
152 chanmask = 0x13;
153 break;
154 }
155 dataDCC1 = AC_DIG1_ENABLE | AC_DIG1_COPYRIGHT;
156 dataDCC2 = 0x2;
157
158 /* set the Audio InforFrame Channel Allocation */
159 snd_hda_codec_write(codec, 0x1, 0,
160 Nv_VERB_SET_Channel_Allocation, chanmask);
161
162 /* turn off SPDIF once; otherwise the IEC958 bits won't be updated */
163 if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE))
164 snd_hda_codec_write(codec,
165 Nv_Master_Convert_nid,
166 0,
167 AC_VERB_SET_DIGI_CONVERT_1,
168 codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff);
169
170 /* set the stream id */
171 snd_hda_codec_write(codec, Nv_Master_Convert_nid, 0,
172 AC_VERB_SET_CHANNEL_STREAMID, (stream_tag << 4) | 0x0);
173
174 /* set the stream format */
175 snd_hda_codec_write(codec, Nv_Master_Convert_nid, 0,
176 AC_VERB_SET_STREAM_FORMAT, format);
177
178 /* turn on again (if needed) */
179 /* enable and set the channel status audio/data flag */
180 if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE)) {
181 snd_hda_codec_write(codec,
182 Nv_Master_Convert_nid,
183 0,
184 AC_VERB_SET_DIGI_CONVERT_1,
185 codec->spdif_ctls & 0xff);
186 snd_hda_codec_write(codec,
187 Nv_Master_Convert_nid,
188 0,
189 AC_VERB_SET_DIGI_CONVERT_2, dataDCC2);
190 }
191
192 for (i = 0; i < 4; i++) {
193 if (chs == 2)
194 channel_id = 0;
195 else
196 channel_id = i * 2;
197
198 /* turn off SPDIF once;
199 *otherwise the IEC958 bits won't be updated
200 */
201 if (codec->spdif_status_reset &&
202 (codec->spdif_ctls & AC_DIG1_ENABLE))
203 snd_hda_codec_write(codec,
204 nvhdmi_convert_nids[i],
205 0,
206 AC_VERB_SET_DIGI_CONVERT_1,
207 codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff);
208 /* set the stream id */
209 snd_hda_codec_write(codec,
210 nvhdmi_convert_nids[i],
211 0,
212 AC_VERB_SET_CHANNEL_STREAMID,
213 (stream_tag << 4) | channel_id);
214 /* set the stream format */
215 snd_hda_codec_write(codec,
216 nvhdmi_convert_nids[i],
217 0,
218 AC_VERB_SET_STREAM_FORMAT,
219 format);
220 /* turn on again (if needed) */
221 /* enable and set the channel status audio/data flag */
222 if (codec->spdif_status_reset &&
223 (codec->spdif_ctls & AC_DIG1_ENABLE)) {
224 snd_hda_codec_write(codec,
225 nvhdmi_convert_nids[i],
226 0,
227 AC_VERB_SET_DIGI_CONVERT_1,
228 codec->spdif_ctls & 0xff);
229 snd_hda_codec_write(codec,
230 nvhdmi_convert_nids[i],
231 0,
232 AC_VERB_SET_DIGI_CONVERT_2, dataDCC2);
233 }
234 }
235
236 /* set the Audio Info Frame Checksum */
237 snd_hda_codec_write(codec, 0x1, 0,
238 Nv_VERB_SET_Info_Frame_Checksum,
239 (0x71 - chan - chanmask));
240
241 mutex_unlock(&codec->spdif_mutex);
242 return 0;
243}
244
245static int nvhdmi_dig_playback_pcm_prepare_2ch(struct hda_pcm_stream *hinfo,
246 struct hda_codec *codec,
247 unsigned int stream_tag,
248 unsigned int format,
249 struct snd_pcm_substream *substream)
89{ 250{
90 struct nvhdmi_spec *spec = codec->spec; 251 struct nvhdmi_spec *spec = codec->spec;
91 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag, 252 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag,
92 format, substream); 253 format, substream);
93} 254}
94 255
95static struct hda_pcm_stream nvhdmi_pcm_digital_playback = { 256static struct hda_pcm_stream nvhdmi_pcm_digital_playback_8ch = {
257 .substreams = 1,
258 .channels_min = 2,
259 .channels_max = 8,
260 .nid = Nv_Master_Convert_nid,
261 .rates = SNDRV_PCM_RATE_48000,
262 .maxbps = 16,
263 .formats = SNDRV_PCM_FMTBIT_S16_LE,
264 .ops = {
265 .open = nvhdmi_dig_playback_pcm_open,
266 .close = nvhdmi_dig_playback_pcm_close_8ch,
267 .prepare = nvhdmi_dig_playback_pcm_prepare_8ch
268 },
269};
270
271static struct hda_pcm_stream nvhdmi_pcm_digital_playback_2ch = {
96 .substreams = 1, 272 .substreams = 1,
97 .channels_min = 2, 273 .channels_min = 2,
98 .channels_max = 2, 274 .channels_max = 2,
99 .nid = 0x4, /* NID to query formats and rates and setup streams */ 275 .nid = Nv_Master_Convert_nid,
100 .rates = SNDRV_PCM_RATE_48000, 276 .rates = SNDRV_PCM_RATE_48000,
101 .maxbps = 16, 277 .maxbps = 16,
102 .formats = SNDRV_PCM_FMTBIT_S16_LE, 278 .formats = SNDRV_PCM_FMTBIT_S16_LE,
103 .ops = { 279 .ops = {
104 .open = nvhdmi_dig_playback_pcm_open, 280 .open = nvhdmi_dig_playback_pcm_open,
105 .close = nvhdmi_dig_playback_pcm_close, 281 .close = nvhdmi_dig_playback_pcm_close_2ch,
106 .prepare = nvhdmi_dig_playback_pcm_prepare 282 .prepare = nvhdmi_dig_playback_pcm_prepare_2ch
107 }, 283 },
108}; 284};
109 285
110static int nvhdmi_build_pcms(struct hda_codec *codec) 286static int nvhdmi_build_pcms_8ch(struct hda_codec *codec)
111{ 287{
112 struct nvhdmi_spec *spec = codec->spec; 288 struct nvhdmi_spec *spec = codec->spec;
113 struct hda_pcm *info = &spec->pcm_rec; 289 struct hda_pcm *info = &spec->pcm_rec;
@@ -117,7 +293,24 @@ static int nvhdmi_build_pcms(struct hda_codec *codec)
117 293
118 info->name = "NVIDIA HDMI"; 294 info->name = "NVIDIA HDMI";
119 info->pcm_type = HDA_PCM_TYPE_HDMI; 295 info->pcm_type = HDA_PCM_TYPE_HDMI;
120 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = nvhdmi_pcm_digital_playback; 296 info->stream[SNDRV_PCM_STREAM_PLAYBACK]
297 = nvhdmi_pcm_digital_playback_8ch;
298
299 return 0;
300}
301
302static int nvhdmi_build_pcms_2ch(struct hda_codec *codec)
303{
304 struct nvhdmi_spec *spec = codec->spec;
305 struct hda_pcm *info = &spec->pcm_rec;
306
307 codec->num_pcms = 1;
308 codec->pcm_info = info;
309
310 info->name = "NVIDIA HDMI";
311 info->pcm_type = HDA_PCM_TYPE_HDMI;
312 info->stream[SNDRV_PCM_STREAM_PLAYBACK]
313 = nvhdmi_pcm_digital_playback_2ch;
121 314
122 return 0; 315 return 0;
123} 316}
@@ -127,14 +320,40 @@ static void nvhdmi_free(struct hda_codec *codec)
127 kfree(codec->spec); 320 kfree(codec->spec);
128} 321}
129 322
130static struct hda_codec_ops nvhdmi_patch_ops = { 323static struct hda_codec_ops nvhdmi_patch_ops_8ch = {
324 .build_controls = nvhdmi_build_controls,
325 .build_pcms = nvhdmi_build_pcms_8ch,
326 .init = nvhdmi_init,
327 .free = nvhdmi_free,
328};
329
330static struct hda_codec_ops nvhdmi_patch_ops_2ch = {
131 .build_controls = nvhdmi_build_controls, 331 .build_controls = nvhdmi_build_controls,
132 .build_pcms = nvhdmi_build_pcms, 332 .build_pcms = nvhdmi_build_pcms_2ch,
133 .init = nvhdmi_init, 333 .init = nvhdmi_init,
134 .free = nvhdmi_free, 334 .free = nvhdmi_free,
135}; 335};
136 336
137static int patch_nvhdmi(struct hda_codec *codec) 337static int patch_nvhdmi_8ch(struct hda_codec *codec)
338{
339 struct nvhdmi_spec *spec;
340
341 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
342 if (spec == NULL)
343 return -ENOMEM;
344
345 codec->spec = spec;
346
347 spec->multiout.num_dacs = 0; /* no analog */
348 spec->multiout.max_channels = 8;
349 spec->multiout.dig_out_nid = Nv_Master_Convert_nid;
350
351 codec->patch_ops = nvhdmi_patch_ops_8ch;
352
353 return 0;
354}
355
356static int patch_nvhdmi_2ch(struct hda_codec *codec)
138{ 357{
139 struct nvhdmi_spec *spec; 358 struct nvhdmi_spec *spec;
140 359
@@ -144,13 +363,11 @@ static int patch_nvhdmi(struct hda_codec *codec)
144 363
145 codec->spec = spec; 364 codec->spec = spec;
146 365
147 spec->multiout.num_dacs = 0; /* no analog */ 366 spec->multiout.num_dacs = 0; /* no analog */
148 spec->multiout.max_channels = 2; 367 spec->multiout.max_channels = 2;
149 spec->multiout.dig_out_nid = 0x4; /* NID for copying analog to digital, 368 spec->multiout.dig_out_nid = Nv_Master_Convert_nid;
150 * seems to be unused in pure-digital
151 * case. */
152 369
153 codec->patch_ops = nvhdmi_patch_ops; 370 codec->patch_ops = nvhdmi_patch_ops_2ch;
154 371
155 return 0; 372 return 0;
156} 373}
@@ -159,11 +376,11 @@ static int patch_nvhdmi(struct hda_codec *codec)
159 * patch entries 376 * patch entries
160 */ 377 */
161static struct hda_codec_preset snd_hda_preset_nvhdmi[] = { 378static struct hda_codec_preset snd_hda_preset_nvhdmi[] = {
162 { .id = 0x10de0002, .name = "MCP78 HDMI", .patch = patch_nvhdmi }, 379 { .id = 0x10de0002, .name = "MCP78 HDMI", .patch = patch_nvhdmi_8ch },
163 { .id = 0x10de0006, .name = "MCP78 HDMI", .patch = patch_nvhdmi }, 380 { .id = 0x10de0006, .name = "MCP78 HDMI", .patch = patch_nvhdmi_8ch },
164 { .id = 0x10de0007, .name = "MCP7A HDMI", .patch = patch_nvhdmi }, 381 { .id = 0x10de0007, .name = "MCP7A HDMI", .patch = patch_nvhdmi_8ch },
165 { .id = 0x10de0067, .name = "MCP67 HDMI", .patch = patch_nvhdmi }, 382 { .id = 0x10de0067, .name = "MCP67 HDMI", .patch = patch_nvhdmi_2ch },
166 { .id = 0x10de8001, .name = "MCP73 HDMI", .patch = patch_nvhdmi }, 383 { .id = 0x10de8001, .name = "MCP73 HDMI", .patch = patch_nvhdmi_2ch },
167 {} /* terminator */ 384 {} /* terminator */
168}; 385};
169 386
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index b8a0d3e7927..337d2a59c67 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -190,6 +190,7 @@ enum {
190 ALC663_ASUS_MODE6, 190 ALC663_ASUS_MODE6,
191 ALC272_DELL, 191 ALC272_DELL,
192 ALC272_DELL_ZM1, 192 ALC272_DELL_ZM1,
193 ALC272_SAMSUNG_NC10,
193 ALC662_AUTO, 194 ALC662_AUTO,
194 ALC662_MODEL_LAST, 195 ALC662_MODEL_LAST,
195}; 196};
@@ -205,6 +206,7 @@ enum {
205 ALC882_ASUS_A7M, 206 ALC882_ASUS_A7M,
206 ALC885_MACPRO, 207 ALC885_MACPRO,
207 ALC885_MBP3, 208 ALC885_MBP3,
209 ALC885_MB5,
208 ALC885_IMAC24, 210 ALC885_IMAC24,
209 ALC882_AUTO, 211 ALC882_AUTO,
210 ALC882_MODEL_LAST, 212 ALC882_MODEL_LAST,
@@ -218,9 +220,11 @@ enum {
218 ALC883_6ST_DIG, 220 ALC883_6ST_DIG,
219 ALC883_TARGA_DIG, 221 ALC883_TARGA_DIG,
220 ALC883_TARGA_2ch_DIG, 222 ALC883_TARGA_2ch_DIG,
223 ALC883_TARGA_8ch_DIG,
221 ALC883_ACER, 224 ALC883_ACER,
222 ALC883_ACER_ASPIRE, 225 ALC883_ACER_ASPIRE,
223 ALC888_ACER_ASPIRE_4930G, 226 ALC888_ACER_ASPIRE_4930G,
227 ALC888_ACER_ASPIRE_8930G,
224 ALC883_MEDION, 228 ALC883_MEDION,
225 ALC883_MEDION_MD2, 229 ALC883_MEDION_MD2,
226 ALC883_LAPTOP_EAPD, 230 ALC883_LAPTOP_EAPD,
@@ -238,7 +242,9 @@ enum {
238 ALC883_3ST_6ch_INTEL, 242 ALC883_3ST_6ch_INTEL,
239 ALC888_ASUS_M90V, 243 ALC888_ASUS_M90V,
240 ALC888_ASUS_EEE1601, 244 ALC888_ASUS_EEE1601,
245 ALC889A_MB31,
241 ALC1200_ASUS_P5Q, 246 ALC1200_ASUS_P5Q,
247 ALC883_SONY_VAIO_TT,
242 ALC883_AUTO, 248 ALC883_AUTO,
243 ALC883_MODEL_LAST, 249 ALC883_MODEL_LAST,
244}; 250};
@@ -253,6 +259,15 @@ enum {
253/* for GPIO Poll */ 259/* for GPIO Poll */
254#define GPIO_MASK 0x03 260#define GPIO_MASK 0x03
255 261
262/* extra amp-initialization sequence types */
263enum {
264 ALC_INIT_NONE,
265 ALC_INIT_DEFAULT,
266 ALC_INIT_GPIO1,
267 ALC_INIT_GPIO2,
268 ALC_INIT_GPIO3,
269};
270
256struct alc_spec { 271struct alc_spec {
257 /* codec parameterization */ 272 /* codec parameterization */
258 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */ 273 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
@@ -266,13 +281,13 @@ struct alc_spec {
266 */ 281 */
267 unsigned int num_init_verbs; 282 unsigned int num_init_verbs;
268 283
269 char *stream_name_analog; /* analog PCM stream */ 284 char stream_name_analog[16]; /* analog PCM stream */
270 struct hda_pcm_stream *stream_analog_playback; 285 struct hda_pcm_stream *stream_analog_playback;
271 struct hda_pcm_stream *stream_analog_capture; 286 struct hda_pcm_stream *stream_analog_capture;
272 struct hda_pcm_stream *stream_analog_alt_playback; 287 struct hda_pcm_stream *stream_analog_alt_playback;
273 struct hda_pcm_stream *stream_analog_alt_capture; 288 struct hda_pcm_stream *stream_analog_alt_capture;
274 289
275 char *stream_name_digital; /* digital PCM stream */ 290 char stream_name_digital[16]; /* digital PCM stream */
276 struct hda_pcm_stream *stream_digital_playback; 291 struct hda_pcm_stream *stream_digital_playback;
277 struct hda_pcm_stream *stream_digital_capture; 292 struct hda_pcm_stream *stream_digital_capture;
278 293
@@ -301,6 +316,8 @@ struct alc_spec {
301 const struct hda_channel_mode *channel_mode; 316 const struct hda_channel_mode *channel_mode;
302 int num_channel_mode; 317 int num_channel_mode;
303 int need_dac_fix; 318 int need_dac_fix;
319 int const_channel_count;
320 int ext_channel_count;
304 321
305 /* PCM information */ 322 /* PCM information */
306 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */ 323 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
@@ -322,6 +339,7 @@ struct alc_spec {
322 339
323 /* other flags */ 340 /* other flags */
324 unsigned int no_analog :1; /* digital I/O only */ 341 unsigned int no_analog :1; /* digital I/O only */
342 int init_amp;
325 343
326 /* for virtual master */ 344 /* for virtual master */
327 hda_nid_t vmaster_nid; 345 hda_nid_t vmaster_nid;
@@ -355,6 +373,7 @@ struct alc_config_preset {
355 unsigned int num_channel_mode; 373 unsigned int num_channel_mode;
356 const struct hda_channel_mode *channel_mode; 374 const struct hda_channel_mode *channel_mode;
357 int need_dac_fix; 375 int need_dac_fix;
376 int const_channel_count;
358 unsigned int num_mux_defs; 377 unsigned int num_mux_defs;
359 const struct hda_input_mux *input_mux; 378 const struct hda_input_mux *input_mux;
360 void (*unsol_event)(struct hda_codec *, unsigned int); 379 void (*unsol_event)(struct hda_codec *, unsigned int);
@@ -449,7 +468,7 @@ static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
449 struct alc_spec *spec = codec->spec; 468 struct alc_spec *spec = codec->spec;
450 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode, 469 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
451 spec->num_channel_mode, 470 spec->num_channel_mode,
452 spec->multiout.max_channels); 471 spec->ext_channel_count);
453} 472}
454 473
455static int alc_ch_mode_put(struct snd_kcontrol *kcontrol, 474static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
@@ -459,9 +478,12 @@ static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
459 struct alc_spec *spec = codec->spec; 478 struct alc_spec *spec = codec->spec;
460 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode, 479 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
461 spec->num_channel_mode, 480 spec->num_channel_mode,
462 &spec->multiout.max_channels); 481 &spec->ext_channel_count);
463 if (err >= 0 && spec->need_dac_fix) 482 if (err >= 0 && !spec->const_channel_count) {
464 spec->multiout.num_dacs = spec->multiout.max_channels / 2; 483 spec->multiout.max_channels = spec->ext_channel_count;
484 if (spec->need_dac_fix)
485 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
486 }
465 return err; 487 return err;
466} 488}
467 489
@@ -776,6 +798,12 @@ static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid,
776 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT; 798 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
777 if (pincap & AC_PINCAP_VREF_80) 799 if (pincap & AC_PINCAP_VREF_80)
778 val = PIN_VREF80; 800 val = PIN_VREF80;
801 else if (pincap & AC_PINCAP_VREF_50)
802 val = PIN_VREF50;
803 else if (pincap & AC_PINCAP_VREF_100)
804 val = PIN_VREF100;
805 else if (pincap & AC_PINCAP_VREF_GRD)
806 val = PIN_VREFGRD;
779 } 807 }
780 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val); 808 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val);
781} 809}
@@ -835,8 +863,13 @@ static void setup_preset(struct alc_spec *spec,
835 spec->channel_mode = preset->channel_mode; 863 spec->channel_mode = preset->channel_mode;
836 spec->num_channel_mode = preset->num_channel_mode; 864 spec->num_channel_mode = preset->num_channel_mode;
837 spec->need_dac_fix = preset->need_dac_fix; 865 spec->need_dac_fix = preset->need_dac_fix;
866 spec->const_channel_count = preset->const_channel_count;
838 867
839 spec->multiout.max_channels = spec->channel_mode[0].channels; 868 if (preset->const_channel_count)
869 spec->multiout.max_channels = preset->const_channel_count;
870 else
871 spec->multiout.max_channels = spec->channel_mode[0].channels;
872 spec->ext_channel_count = spec->channel_mode[0].channels;
840 873
841 spec->multiout.num_dacs = preset->num_dacs; 874 spec->multiout.num_dacs = preset->num_dacs;
842 spec->multiout.dac_nids = preset->dac_nids; 875 spec->multiout.dac_nids = preset->dac_nids;
@@ -915,20 +948,26 @@ static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
915 alc_fix_pll(codec); 948 alc_fix_pll(codec);
916} 949}
917 950
918static void alc_sku_automute(struct hda_codec *codec) 951static void alc_automute_pin(struct hda_codec *codec)
919{ 952{
920 struct alc_spec *spec = codec->spec; 953 struct alc_spec *spec = codec->spec;
921 unsigned int present; 954 unsigned int present;
922 unsigned int hp_nid = spec->autocfg.hp_pins[0]; 955 unsigned int nid = spec->autocfg.hp_pins[0];
923 unsigned int sp_nid = spec->autocfg.speaker_pins[0]; 956 int i;
924 957
925 /* need to execute and sync at first */ 958 /* need to execute and sync at first */
926 snd_hda_codec_read(codec, hp_nid, 0, AC_VERB_SET_PIN_SENSE, 0); 959 snd_hda_codec_read(codec, nid, 0, AC_VERB_SET_PIN_SENSE, 0);
927 present = snd_hda_codec_read(codec, hp_nid, 0, 960 present = snd_hda_codec_read(codec, nid, 0,
928 AC_VERB_GET_PIN_SENSE, 0); 961 AC_VERB_GET_PIN_SENSE, 0);
929 spec->jack_present = (present & 0x80000000) != 0; 962 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
930 snd_hda_codec_write(codec, sp_nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 963 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
931 spec->jack_present ? 0 : PIN_OUT); 964 nid = spec->autocfg.speaker_pins[i];
965 if (!nid)
966 break;
967 snd_hda_codec_write(codec, nid, 0,
968 AC_VERB_SET_PIN_WIDGET_CONTROL,
969 spec->jack_present ? 0 : PIN_OUT);
970 }
932} 971}
933 972
934#if 0 /* it's broken in some acses -- temporarily disabled */ 973#if 0 /* it's broken in some acses -- temporarily disabled */
@@ -963,16 +1002,19 @@ static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
963 res >>= 28; 1002 res >>= 28;
964 else 1003 else
965 res >>= 26; 1004 res >>= 26;
966 if (res == ALC880_HP_EVENT) 1005 switch (res) {
967 alc_sku_automute(codec); 1006 case ALC880_HP_EVENT:
968 1007 alc_automute_pin(codec);
969 if (res == ALC880_MIC_EVENT) 1008 break;
1009 case ALC880_MIC_EVENT:
970 alc_mic_automute(codec); 1010 alc_mic_automute(codec);
1011 break;
1012 }
971} 1013}
972 1014
973static void alc_inithook(struct hda_codec *codec) 1015static void alc_inithook(struct hda_codec *codec)
974{ 1016{
975 alc_sku_automute(codec); 1017 alc_automute_pin(codec);
976 alc_mic_automute(codec); 1018 alc_mic_automute(codec);
977} 1019}
978 1020
@@ -994,69 +1036,21 @@ static void alc888_coef_init(struct hda_codec *codec)
994 AC_VERB_SET_PROC_COEF, 0x3030); 1036 AC_VERB_SET_PROC_COEF, 0x3030);
995} 1037}
996 1038
997/* 32-bit subsystem ID for BIOS loading in HD Audio codec. 1039static void alc_auto_init_amp(struct hda_codec *codec, int type)
998 * 31 ~ 16 : Manufacture ID
999 * 15 ~ 8 : SKU ID
1000 * 7 ~ 0 : Assembly ID
1001 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
1002 */
1003static void alc_subsystem_id(struct hda_codec *codec,
1004 unsigned int porta, unsigned int porte,
1005 unsigned int portd)
1006{ 1040{
1007 unsigned int ass, tmp, i; 1041 unsigned int tmp;
1008 unsigned nid;
1009 struct alc_spec *spec = codec->spec;
1010
1011 ass = codec->subsystem_id & 0xffff;
1012 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
1013 goto do_sku;
1014
1015 /*
1016 * 31~30 : port conetcivity
1017 * 29~21 : reserve
1018 * 20 : PCBEEP input
1019 * 19~16 : Check sum (15:1)
1020 * 15~1 : Custom
1021 * 0 : override
1022 */
1023 nid = 0x1d;
1024 if (codec->vendor_id == 0x10ec0260)
1025 nid = 0x17;
1026 ass = snd_hda_codec_get_pincfg(codec, nid);
1027 if (!(ass & 1) && !(ass & 0x100000))
1028 return;
1029 if ((ass >> 30) != 1) /* no physical connection */
1030 return;
1031 1042
1032 /* check sum */ 1043 switch (type) {
1033 tmp = 0; 1044 case ALC_INIT_GPIO1:
1034 for (i = 1; i < 16; i++) {
1035 if ((ass >> i) & 1)
1036 tmp++;
1037 }
1038 if (((ass >> 16) & 0xf) != tmp)
1039 return;
1040do_sku:
1041 /*
1042 * 0 : override
1043 * 1 : Swap Jack
1044 * 2 : 0 --> Desktop, 1 --> Laptop
1045 * 3~5 : External Amplifier control
1046 * 7~6 : Reserved
1047 */
1048 tmp = (ass & 0x38) >> 3; /* external Amp control */
1049 switch (tmp) {
1050 case 1:
1051 snd_hda_sequence_write(codec, alc_gpio1_init_verbs); 1045 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
1052 break; 1046 break;
1053 case 3: 1047 case ALC_INIT_GPIO2:
1054 snd_hda_sequence_write(codec, alc_gpio2_init_verbs); 1048 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
1055 break; 1049 break;
1056 case 7: 1050 case ALC_INIT_GPIO3:
1057 snd_hda_sequence_write(codec, alc_gpio3_init_verbs); 1051 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
1058 break; 1052 break;
1059 case 5: /* set EAPD output high */ 1053 case ALC_INIT_DEFAULT:
1060 switch (codec->vendor_id) { 1054 switch (codec->vendor_id) {
1061 case 0x10ec0260: 1055 case 0x10ec0260:
1062 snd_hda_codec_write(codec, 0x0f, 0, 1056 snd_hda_codec_write(codec, 0x0f, 0,
@@ -1110,7 +1104,7 @@ do_sku:
1110 tmp | 0x2010); 1104 tmp | 0x2010);
1111 break; 1105 break;
1112 case 0x10ec0888: 1106 case 0x10ec0888:
1113 /*alc888_coef_init(codec);*/ /* called in alc_init() */ 1107 alc888_coef_init(codec);
1114 break; 1108 break;
1115 case 0x10ec0267: 1109 case 0x10ec0267:
1116 case 0x10ec0268: 1110 case 0x10ec0268:
@@ -1125,7 +1119,107 @@ do_sku:
1125 tmp | 0x3000); 1119 tmp | 0x3000);
1126 break; 1120 break;
1127 } 1121 }
1128 default: 1122 break;
1123 }
1124}
1125
1126static void alc_init_auto_hp(struct hda_codec *codec)
1127{
1128 struct alc_spec *spec = codec->spec;
1129
1130 if (!spec->autocfg.hp_pins[0])
1131 return;
1132
1133 if (!spec->autocfg.speaker_pins[0]) {
1134 if (spec->autocfg.line_out_pins[0] &&
1135 spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT)
1136 spec->autocfg.speaker_pins[0] =
1137 spec->autocfg.line_out_pins[0];
1138 else
1139 return;
1140 }
1141
1142 snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n",
1143 spec->autocfg.hp_pins[0]);
1144 snd_hda_codec_write_cache(codec, spec->autocfg.hp_pins[0], 0,
1145 AC_VERB_SET_UNSOLICITED_ENABLE,
1146 AC_USRSP_EN | ALC880_HP_EVENT);
1147 spec->unsol_event = alc_sku_unsol_event;
1148}
1149
1150/* check subsystem ID and set up device-specific initialization;
1151 * return 1 if initialized, 0 if invalid SSID
1152 */
1153/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
1154 * 31 ~ 16 : Manufacture ID
1155 * 15 ~ 8 : SKU ID
1156 * 7 ~ 0 : Assembly ID
1157 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
1158 */
1159static int alc_subsystem_id(struct hda_codec *codec,
1160 hda_nid_t porta, hda_nid_t porte,
1161 hda_nid_t portd)
1162{
1163 unsigned int ass, tmp, i;
1164 unsigned nid;
1165 struct alc_spec *spec = codec->spec;
1166
1167 ass = codec->subsystem_id & 0xffff;
1168 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
1169 goto do_sku;
1170
1171 /* invalid SSID, check the special NID pin defcfg instead */
1172 /*
1173 * 31~30 : port conetcivity
1174 * 29~21 : reserve
1175 * 20 : PCBEEP input
1176 * 19~16 : Check sum (15:1)
1177 * 15~1 : Custom
1178 * 0 : override
1179 */
1180 nid = 0x1d;
1181 if (codec->vendor_id == 0x10ec0260)
1182 nid = 0x17;
1183 ass = snd_hda_codec_get_pincfg(codec, nid);
1184 snd_printd("realtek: No valid SSID, "
1185 "checking pincfg 0x%08x for NID 0x%x\n",
1186 ass, nid);
1187 if (!(ass & 1) && !(ass & 0x100000))
1188 return 0;
1189 if ((ass >> 30) != 1) /* no physical connection */
1190 return 0;
1191
1192 /* check sum */
1193 tmp = 0;
1194 for (i = 1; i < 16; i++) {
1195 if ((ass >> i) & 1)
1196 tmp++;
1197 }
1198 if (((ass >> 16) & 0xf) != tmp)
1199 return 0;
1200do_sku:
1201 snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
1202 ass & 0xffff, codec->vendor_id);
1203 /*
1204 * 0 : override
1205 * 1 : Swap Jack
1206 * 2 : 0 --> Desktop, 1 --> Laptop
1207 * 3~5 : External Amplifier control
1208 * 7~6 : Reserved
1209 */
1210 tmp = (ass & 0x38) >> 3; /* external Amp control */
1211 switch (tmp) {
1212 case 1:
1213 spec->init_amp = ALC_INIT_GPIO1;
1214 break;
1215 case 3:
1216 spec->init_amp = ALC_INIT_GPIO2;
1217 break;
1218 case 7:
1219 spec->init_amp = ALC_INIT_GPIO3;
1220 break;
1221 case 5:
1222 spec->init_amp = ALC_INIT_DEFAULT;
1129 break; 1223 break;
1130 } 1224 }
1131 1225
@@ -1133,7 +1227,7 @@ do_sku:
1133 * when the external headphone out jack is plugged" 1227 * when the external headphone out jack is plugged"
1134 */ 1228 */
1135 if (!(ass & 0x8000)) 1229 if (!(ass & 0x8000))
1136 return; 1230 return 1;
1137 /* 1231 /*
1138 * 10~8 : Jack location 1232 * 10~8 : Jack location
1139 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered 1233 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
@@ -1141,14 +1235,6 @@ do_sku:
1141 * 15 : 1 --> enable the function "Mute internal speaker 1235 * 15 : 1 --> enable the function "Mute internal speaker
1142 * when the external headphone out jack is plugged" 1236 * when the external headphone out jack is plugged"
1143 */ 1237 */
1144 if (!spec->autocfg.speaker_pins[0]) {
1145 if (spec->autocfg.line_out_pins[0])
1146 spec->autocfg.speaker_pins[0] =
1147 spec->autocfg.line_out_pins[0];
1148 else
1149 return;
1150 }
1151
1152 if (!spec->autocfg.hp_pins[0]) { 1238 if (!spec->autocfg.hp_pins[0]) {
1153 tmp = (ass >> 11) & 0x3; /* HP to chassis */ 1239 tmp = (ass >> 11) & 0x3; /* HP to chassis */
1154 if (tmp == 0) 1240 if (tmp == 0)
@@ -1158,23 +1244,23 @@ do_sku:
1158 else if (tmp == 2) 1244 else if (tmp == 2)
1159 spec->autocfg.hp_pins[0] = portd; 1245 spec->autocfg.hp_pins[0] = portd;
1160 else 1246 else
1161 return; 1247 return 1;
1162 } 1248 }
1163 if (spec->autocfg.hp_pins[0])
1164 snd_hda_codec_write(codec, spec->autocfg.hp_pins[0], 0,
1165 AC_VERB_SET_UNSOLICITED_ENABLE,
1166 AC_USRSP_EN | ALC880_HP_EVENT);
1167 1249
1168#if 0 /* it's broken in some acses -- temporarily disabled */ 1250 alc_init_auto_hp(codec);
1169 if (spec->autocfg.input_pins[AUTO_PIN_MIC] && 1251 return 1;
1170 spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC]) 1252}
1171 snd_hda_codec_write(codec,
1172 spec->autocfg.input_pins[AUTO_PIN_MIC], 0,
1173 AC_VERB_SET_UNSOLICITED_ENABLE,
1174 AC_USRSP_EN | ALC880_MIC_EVENT);
1175#endif /* disabled */
1176 1253
1177 spec->unsol_event = alc_sku_unsol_event; 1254static void alc_ssid_check(struct hda_codec *codec,
1255 hda_nid_t porta, hda_nid_t porte, hda_nid_t portd)
1256{
1257 if (!alc_subsystem_id(codec, porta, porte, portd)) {
1258 struct alc_spec *spec = codec->spec;
1259 snd_printd("realtek: "
1260 "Enable default setup for auto mode as fallback\n");
1261 spec->init_amp = ALC_INIT_DEFAULT;
1262 alc_init_auto_hp(codec);
1263 }
1178} 1264}
1179 1265
1180/* 1266/*
@@ -1309,32 +1395,58 @@ static struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
1309 {} 1395 {}
1310}; 1396};
1311 1397
1312static void alc888_fujitsu_xa3530_automute(struct hda_codec *codec) 1398static void alc_automute_amp(struct hda_codec *codec)
1313{ 1399{
1314 unsigned int present; 1400 struct alc_spec *spec = codec->spec;
1315 unsigned int bits; 1401 unsigned int val, mute;
1316 /* Line out presence */ 1402 hda_nid_t nid;
1317 present = snd_hda_codec_read(codec, 0x17, 0, 1403 int i;
1318 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 1404
1319 /* HP out presence */ 1405 spec->jack_present = 0;
1320 present = present || snd_hda_codec_read(codec, 0x1b, 0, 1406 for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) {
1321 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 1407 nid = spec->autocfg.hp_pins[i];
1322 bits = present ? HDA_AMP_MUTE : 0; 1408 if (!nid)
1409 break;
1410 val = snd_hda_codec_read(codec, nid, 0,
1411 AC_VERB_GET_PIN_SENSE, 0);
1412 if (val & AC_PINSENSE_PRESENCE) {
1413 spec->jack_present = 1;
1414 break;
1415 }
1416 }
1417
1418 mute = spec->jack_present ? HDA_AMP_MUTE : 0;
1323 /* Toggle internal speakers muting */ 1419 /* Toggle internal speakers muting */
1324 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 1420 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
1325 HDA_AMP_MUTE, bits); 1421 nid = spec->autocfg.speaker_pins[i];
1326 /* Toggle internal bass muting */ 1422 if (!nid)
1327 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 1423 break;
1328 HDA_AMP_MUTE, bits); 1424 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
1425 HDA_AMP_MUTE, mute);
1426 }
1329} 1427}
1330 1428
1331static void alc888_fujitsu_xa3530_unsol_event(struct hda_codec *codec, 1429static void alc_automute_amp_unsol_event(struct hda_codec *codec,
1332 unsigned int res) 1430 unsigned int res)
1333{ 1431{
1334 if (res >> 26 == ALC880_HP_EVENT) 1432 if (codec->vendor_id == 0x10ec0880)
1335 alc888_fujitsu_xa3530_automute(codec); 1433 res >>= 28;
1434 else
1435 res >>= 26;
1436 if (res == ALC880_HP_EVENT)
1437 alc_automute_amp(codec);
1336} 1438}
1337 1439
1440static void alc888_fujitsu_xa3530_init_hook(struct hda_codec *codec)
1441{
1442 struct alc_spec *spec = codec->spec;
1443
1444 spec->autocfg.hp_pins[0] = 0x17; /* line-out */
1445 spec->autocfg.hp_pins[1] = 0x1b; /* hp */
1446 spec->autocfg.speaker_pins[0] = 0x14; /* speaker */
1447 spec->autocfg.speaker_pins[1] = 0x15; /* bass */
1448 alc_automute_amp(codec);
1449}
1338 1450
1339/* 1451/*
1340 * ALC888 Acer Aspire 4930G model 1452 * ALC888 Acer Aspire 4930G model
@@ -1358,6 +1470,59 @@ static struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
1358 { } 1470 { }
1359}; 1471};
1360 1472
1473/*
1474 * ALC889 Acer Aspire 8930G model
1475 */
1476
1477static struct hda_verb alc889_acer_aspire_8930g_verbs[] = {
1478/* Front Mic: set to PIN_IN (empty by default) */
1479 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1480/* Unselect Front Mic by default in input mixer 3 */
1481 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
1482/* Enable unsolicited event for HP jack */
1483 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1484/* Connect Internal Front to Front */
1485 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1486 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1487 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1488/* Connect Internal Rear to Rear */
1489 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1490 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1491 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
1492/* Connect Internal CLFE to CLFE */
1493 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1494 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1495 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
1496/* Connect HP out to Front */
1497 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
1498 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1499 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1500/* Enable all DACs */
1501/* DAC DISABLE/MUTE 1? */
1502/* setting bits 1-5 disables DAC nids 0x02-0x06 apparently. Init=0x38 */
1503 {0x20, AC_VERB_SET_COEF_INDEX, 0x03},
1504 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
1505/* DAC DISABLE/MUTE 2? */
1506/* some bit here disables the other DACs. Init=0x4900 */
1507 {0x20, AC_VERB_SET_COEF_INDEX, 0x08},
1508 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
1509/* Enable amplifiers */
1510 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
1511 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
1512/* DMIC fix
1513 * This laptop has a stereo digital microphone. The mics are only 1cm apart
1514 * which makes the stereo useless. However, either the mic or the ALC889
1515 * makes the signal become a difference/sum signal instead of standard
1516 * stereo, which is annoying. So instead we flip this bit which makes the
1517 * codec replicate the sum signal to both channels, turning it into a
1518 * normal mono mic.
1519 */
1520/* DMIC_CONTROL? Init value = 0x0001 */
1521 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
1522 {0x20, AC_VERB_SET_PROC_COEF, 0x0003},
1523 { }
1524};
1525
1361static struct hda_input_mux alc888_2_capture_sources[2] = { 1526static struct hda_input_mux alc888_2_capture_sources[2] = {
1362 /* Front mic only available on one ADC */ 1527 /* Front mic only available on one ADC */
1363 { 1528 {
@@ -1379,6 +1544,38 @@ static struct hda_input_mux alc888_2_capture_sources[2] = {
1379 } 1544 }
1380}; 1545};
1381 1546
1547static struct hda_input_mux alc889_capture_sources[3] = {
1548 /* Digital mic only available on first "ADC" */
1549 {
1550 .num_items = 5,
1551 .items = {
1552 { "Mic", 0x0 },
1553 { "Line", 0x2 },
1554 { "CD", 0x4 },
1555 { "Front Mic", 0xb },
1556 { "Input Mix", 0xa },
1557 },
1558 },
1559 {
1560 .num_items = 4,
1561 .items = {
1562 { "Mic", 0x0 },
1563 { "Line", 0x2 },
1564 { "CD", 0x4 },
1565 { "Input Mix", 0xa },
1566 },
1567 },
1568 {
1569 .num_items = 4,
1570 .items = {
1571 { "Mic", 0x0 },
1572 { "Line", 0x2 },
1573 { "CD", 0x4 },
1574 { "Input Mix", 0xa },
1575 },
1576 }
1577};
1578
1382static struct snd_kcontrol_new alc888_base_mixer[] = { 1579static struct snd_kcontrol_new alc888_base_mixer[] = {
1383 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 1580 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1384 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 1581 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
@@ -1401,22 +1598,24 @@ static struct snd_kcontrol_new alc888_base_mixer[] = {
1401 { } /* end */ 1598 { } /* end */
1402}; 1599};
1403 1600
1404static void alc888_acer_aspire_4930g_automute(struct hda_codec *codec) 1601static void alc888_acer_aspire_4930g_init_hook(struct hda_codec *codec)
1405{ 1602{
1406 unsigned int present; 1603 struct alc_spec *spec = codec->spec;
1407 unsigned int bits; 1604
1408 present = snd_hda_codec_read(codec, 0x15, 0, 1605 spec->autocfg.hp_pins[0] = 0x15;
1409 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 1606 spec->autocfg.speaker_pins[0] = 0x14;
1410 bits = present ? HDA_AMP_MUTE : 0; 1607 alc_automute_amp(codec);
1411 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
1412 HDA_AMP_MUTE, bits);
1413} 1608}
1414 1609
1415static void alc888_acer_aspire_4930g_unsol_event(struct hda_codec *codec, 1610static void alc889_acer_aspire_8930g_init_hook(struct hda_codec *codec)
1416 unsigned int res)
1417{ 1611{
1418 if (res >> 26 == ALC880_HP_EVENT) 1612 struct alc_spec *spec = codec->spec;
1419 alc888_acer_aspire_4930g_automute(codec); 1613
1614 spec->autocfg.hp_pins[0] = 0x15;
1615 spec->autocfg.speaker_pins[0] = 0x14;
1616 spec->autocfg.speaker_pins[1] = 0x16;
1617 spec->autocfg.speaker_pins[2] = 0x1b;
1618 alc_automute_amp(codec);
1420} 1619}
1421 1620
1422/* 1621/*
@@ -2384,21 +2583,6 @@ static struct hda_verb alc880_beep_init_verbs[] = {
2384 { } 2583 { }
2385}; 2584};
2386 2585
2387/* toggle speaker-output according to the hp-jack state */
2388static void alc880_uniwill_hp_automute(struct hda_codec *codec)
2389{
2390 unsigned int present;
2391 unsigned char bits;
2392
2393 present = snd_hda_codec_read(codec, 0x14, 0,
2394 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2395 bits = present ? HDA_AMP_MUTE : 0;
2396 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
2397 HDA_AMP_MUTE, bits);
2398 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
2399 HDA_AMP_MUTE, bits);
2400}
2401
2402/* auto-toggle front mic */ 2586/* auto-toggle front mic */
2403static void alc880_uniwill_mic_automute(struct hda_codec *codec) 2587static void alc880_uniwill_mic_automute(struct hda_codec *codec)
2404{ 2588{
@@ -2411,9 +2595,14 @@ static void alc880_uniwill_mic_automute(struct hda_codec *codec)
2411 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits); 2595 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
2412} 2596}
2413 2597
2414static void alc880_uniwill_automute(struct hda_codec *codec) 2598static void alc880_uniwill_init_hook(struct hda_codec *codec)
2415{ 2599{
2416 alc880_uniwill_hp_automute(codec); 2600 struct alc_spec *spec = codec->spec;
2601
2602 spec->autocfg.hp_pins[0] = 0x14;
2603 spec->autocfg.speaker_pins[0] = 0x15;
2604 spec->autocfg.speaker_pins[0] = 0x16;
2605 alc_automute_amp(codec);
2417 alc880_uniwill_mic_automute(codec); 2606 alc880_uniwill_mic_automute(codec);
2418} 2607}
2419 2608
@@ -2424,24 +2613,22 @@ static void alc880_uniwill_unsol_event(struct hda_codec *codec,
2424 * definition. 4bit tag is placed at 28 bit! 2613 * definition. 4bit tag is placed at 28 bit!
2425 */ 2614 */
2426 switch (res >> 28) { 2615 switch (res >> 28) {
2427 case ALC880_HP_EVENT:
2428 alc880_uniwill_hp_automute(codec);
2429 break;
2430 case ALC880_MIC_EVENT: 2616 case ALC880_MIC_EVENT:
2431 alc880_uniwill_mic_automute(codec); 2617 alc880_uniwill_mic_automute(codec);
2432 break; 2618 break;
2619 default:
2620 alc_automute_amp_unsol_event(codec, res);
2621 break;
2433 } 2622 }
2434} 2623}
2435 2624
2436static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec) 2625static void alc880_uniwill_p53_init_hook(struct hda_codec *codec)
2437{ 2626{
2438 unsigned int present; 2627 struct alc_spec *spec = codec->spec;
2439 unsigned char bits;
2440 2628
2441 present = snd_hda_codec_read(codec, 0x14, 0, 2629 spec->autocfg.hp_pins[0] = 0x14;
2442 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 2630 spec->autocfg.speaker_pins[0] = 0x15;
2443 bits = present ? HDA_AMP_MUTE : 0; 2631 alc_automute_amp(codec);
2444 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, HDA_AMP_MUTE, bits);
2445} 2632}
2446 2633
2447static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec) 2634static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
@@ -2463,10 +2650,10 @@ static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
2463 /* Looks like the unsol event is incompatible with the standard 2650 /* Looks like the unsol event is incompatible with the standard
2464 * definition. 4bit tag is placed at 28 bit! 2651 * definition. 4bit tag is placed at 28 bit!
2465 */ 2652 */
2466 if ((res >> 28) == ALC880_HP_EVENT)
2467 alc880_uniwill_p53_hp_automute(codec);
2468 if ((res >> 28) == ALC880_DCVOL_EVENT) 2653 if ((res >> 28) == ALC880_DCVOL_EVENT)
2469 alc880_uniwill_p53_dcvol_automute(codec); 2654 alc880_uniwill_p53_dcvol_automute(codec);
2655 else
2656 alc_automute_amp_unsol_event(codec, res);
2470} 2657}
2471 2658
2472/* 2659/*
@@ -2536,6 +2723,7 @@ static struct hda_verb alc880_pin_asus_init_verbs[] = {
2536/* Enable GPIO mask and set output */ 2723/* Enable GPIO mask and set output */
2537#define alc880_gpio1_init_verbs alc_gpio1_init_verbs 2724#define alc880_gpio1_init_verbs alc_gpio1_init_verbs
2538#define alc880_gpio2_init_verbs alc_gpio2_init_verbs 2725#define alc880_gpio2_init_verbs alc_gpio2_init_verbs
2726#define alc880_gpio3_init_verbs alc_gpio3_init_verbs
2539 2727
2540/* Clevo m520g init */ 2728/* Clevo m520g init */
2541static struct hda_verb alc880_pin_clevo_init_verbs[] = { 2729static struct hda_verb alc880_pin_clevo_init_verbs[] = {
@@ -2698,30 +2886,18 @@ static struct hda_verb alc880_lg_init_verbs[] = {
2698 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 2886 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2699 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2887 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2700 /* jack sense */ 2888 /* jack sense */
2701 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1}, 2889 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2702 { } 2890 { }
2703}; 2891};
2704 2892
2705/* toggle speaker-output according to the hp-jack state */ 2893/* toggle speaker-output according to the hp-jack state */
2706static void alc880_lg_automute(struct hda_codec *codec) 2894static void alc880_lg_init_hook(struct hda_codec *codec)
2707{ 2895{
2708 unsigned int present; 2896 struct alc_spec *spec = codec->spec;
2709 unsigned char bits;
2710
2711 present = snd_hda_codec_read(codec, 0x1b, 0,
2712 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2713 bits = present ? HDA_AMP_MUTE : 0;
2714 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
2715 HDA_AMP_MUTE, bits);
2716}
2717 2897
2718static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res) 2898 spec->autocfg.hp_pins[0] = 0x1b;
2719{ 2899 spec->autocfg.speaker_pins[0] = 0x17;
2720 /* Looks like the unsol event is incompatible with the standard 2900 alc_automute_amp(codec);
2721 * definition. 4bit tag is placed at 28 bit!
2722 */
2723 if ((res >> 28) == 0x01)
2724 alc880_lg_automute(codec);
2725} 2901}
2726 2902
2727/* 2903/*
@@ -2795,30 +2971,18 @@ static struct hda_verb alc880_lg_lw_init_verbs[] = {
2795 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2971 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2796 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2972 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2797 /* jack sense */ 2973 /* jack sense */
2798 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1}, 2974 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2799 { } 2975 { }
2800}; 2976};
2801 2977
2802/* toggle speaker-output according to the hp-jack state */ 2978/* toggle speaker-output according to the hp-jack state */
2803static void alc880_lg_lw_automute(struct hda_codec *codec) 2979static void alc880_lg_lw_init_hook(struct hda_codec *codec)
2804{ 2980{
2805 unsigned int present; 2981 struct alc_spec *spec = codec->spec;
2806 unsigned char bits;
2807 2982
2808 present = snd_hda_codec_read(codec, 0x1b, 0, 2983 spec->autocfg.hp_pins[0] = 0x1b;
2809 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 2984 spec->autocfg.speaker_pins[0] = 0x14;
2810 bits = present ? HDA_AMP_MUTE : 0; 2985 alc_automute_amp(codec);
2811 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
2812 HDA_AMP_MUTE, bits);
2813}
2814
2815static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res)
2816{
2817 /* Looks like the unsol event is incompatible with the standard
2818 * definition. 4bit tag is placed at 28 bit!
2819 */
2820 if ((res >> 28) == 0x01)
2821 alc880_lg_lw_automute(codec);
2822} 2986}
2823 2987
2824static struct snd_kcontrol_new alc880_medion_rim_mixer[] = { 2988static struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
@@ -2865,16 +3029,10 @@ static struct hda_verb alc880_medion_rim_init_verbs[] = {
2865/* toggle speaker-output according to the hp-jack state */ 3029/* toggle speaker-output according to the hp-jack state */
2866static void alc880_medion_rim_automute(struct hda_codec *codec) 3030static void alc880_medion_rim_automute(struct hda_codec *codec)
2867{ 3031{
2868 unsigned int present; 3032 struct alc_spec *spec = codec->spec;
2869 unsigned char bits; 3033 alc_automute_amp(codec);
2870 3034 /* toggle EAPD */
2871 present = snd_hda_codec_read(codec, 0x14, 0, 3035 if (spec->jack_present)
2872 AC_VERB_GET_PIN_SENSE, 0)
2873 & AC_PINSENSE_PRESENCE;
2874 bits = present ? HDA_AMP_MUTE : 0;
2875 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
2876 HDA_AMP_MUTE, bits);
2877 if (present)
2878 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0); 3036 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
2879 else 3037 else
2880 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2); 3038 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
@@ -2890,6 +3048,15 @@ static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
2890 alc880_medion_rim_automute(codec); 3048 alc880_medion_rim_automute(codec);
2891} 3049}
2892 3050
3051static void alc880_medion_rim_init_hook(struct hda_codec *codec)
3052{
3053 struct alc_spec *spec = codec->spec;
3054
3055 spec->autocfg.hp_pins[0] = 0x14;
3056 spec->autocfg.speaker_pins[0] = 0x1b;
3057 alc880_medion_rim_automute(codec);
3058}
3059
2893#ifdef CONFIG_SND_HDA_POWER_SAVE 3060#ifdef CONFIG_SND_HDA_POWER_SAVE
2894static struct hda_amp_list alc880_loopbacks[] = { 3061static struct hda_amp_list alc880_loopbacks[] = {
2895 { 0x0b, HDA_INPUT, 0 }, 3062 { 0x0b, HDA_INPUT, 0 },
@@ -2918,8 +3085,7 @@ static int alc_init(struct hda_codec *codec)
2918 unsigned int i; 3085 unsigned int i;
2919 3086
2920 alc_fix_pll(codec); 3087 alc_fix_pll(codec);
2921 if (codec->vendor_id == 0x10ec0888) 3088 alc_auto_init_amp(codec, spec->init_amp);
2922 alc888_coef_init(codec);
2923 3089
2924 for (i = 0; i < spec->num_init_verbs; i++) 3090 for (i = 0; i < spec->num_init_verbs; i++)
2925 snd_hda_sequence_write(codec, spec->init_verbs[i]); 3091 snd_hda_sequence_write(codec, spec->init_verbs[i]);
@@ -3121,7 +3287,10 @@ static int alc_build_pcms(struct hda_codec *codec)
3121 if (spec->no_analog) 3287 if (spec->no_analog)
3122 goto skip_analog; 3288 goto skip_analog;
3123 3289
3290 snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog),
3291 "%s Analog", codec->chip_name);
3124 info->name = spec->stream_name_analog; 3292 info->name = spec->stream_name_analog;
3293
3125 if (spec->stream_analog_playback) { 3294 if (spec->stream_analog_playback) {
3126 if (snd_BUG_ON(!spec->multiout.dac_nids)) 3295 if (snd_BUG_ON(!spec->multiout.dac_nids))
3127 return -EINVAL; 3296 return -EINVAL;
@@ -3147,6 +3316,9 @@ static int alc_build_pcms(struct hda_codec *codec)
3147 skip_analog: 3316 skip_analog:
3148 /* SPDIF for stream index #1 */ 3317 /* SPDIF for stream index #1 */
3149 if (spec->multiout.dig_out_nid || spec->dig_in_nid) { 3318 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
3319 snprintf(spec->stream_name_digital,
3320 sizeof(spec->stream_name_digital),
3321 "%s Digital", codec->chip_name);
3150 codec->num_pcms = 2; 3322 codec->num_pcms = 2;
3151 codec->slave_dig_outs = spec->multiout.slave_dig_outs; 3323 codec->slave_dig_outs = spec->multiout.slave_dig_outs;
3152 info = spec->pcm_rec + 1; 3324 info = spec->pcm_rec + 1;
@@ -3749,7 +3921,7 @@ static struct alc_config_preset alc880_presets[] = {
3749 .channel_mode = alc880_2_jack_modes, 3921 .channel_mode = alc880_2_jack_modes,
3750 .input_mux = &alc880_f1734_capture_source, 3922 .input_mux = &alc880_f1734_capture_source,
3751 .unsol_event = alc880_uniwill_p53_unsol_event, 3923 .unsol_event = alc880_uniwill_p53_unsol_event,
3752 .init_hook = alc880_uniwill_p53_hp_automute, 3924 .init_hook = alc880_uniwill_p53_init_hook,
3753 }, 3925 },
3754 [ALC880_ASUS] = { 3926 [ALC880_ASUS] = {
3755 .mixers = { alc880_asus_mixer }, 3927 .mixers = { alc880_asus_mixer },
@@ -3826,7 +3998,7 @@ static struct alc_config_preset alc880_presets[] = {
3826 .need_dac_fix = 1, 3998 .need_dac_fix = 1,
3827 .input_mux = &alc880_capture_source, 3999 .input_mux = &alc880_capture_source,
3828 .unsol_event = alc880_uniwill_unsol_event, 4000 .unsol_event = alc880_uniwill_unsol_event,
3829 .init_hook = alc880_uniwill_automute, 4001 .init_hook = alc880_uniwill_init_hook,
3830 }, 4002 },
3831 [ALC880_UNIWILL_P53] = { 4003 [ALC880_UNIWILL_P53] = {
3832 .mixers = { alc880_uniwill_p53_mixer }, 4004 .mixers = { alc880_uniwill_p53_mixer },
@@ -3838,7 +4010,7 @@ static struct alc_config_preset alc880_presets[] = {
3838 .channel_mode = alc880_threestack_modes, 4010 .channel_mode = alc880_threestack_modes,
3839 .input_mux = &alc880_capture_source, 4011 .input_mux = &alc880_capture_source,
3840 .unsol_event = alc880_uniwill_p53_unsol_event, 4012 .unsol_event = alc880_uniwill_p53_unsol_event,
3841 .init_hook = alc880_uniwill_p53_hp_automute, 4013 .init_hook = alc880_uniwill_p53_init_hook,
3842 }, 4014 },
3843 [ALC880_FUJITSU] = { 4015 [ALC880_FUJITSU] = {
3844 .mixers = { alc880_fujitsu_mixer }, 4016 .mixers = { alc880_fujitsu_mixer },
@@ -3852,7 +4024,7 @@ static struct alc_config_preset alc880_presets[] = {
3852 .channel_mode = alc880_2_jack_modes, 4024 .channel_mode = alc880_2_jack_modes,
3853 .input_mux = &alc880_capture_source, 4025 .input_mux = &alc880_capture_source,
3854 .unsol_event = alc880_uniwill_p53_unsol_event, 4026 .unsol_event = alc880_uniwill_p53_unsol_event,
3855 .init_hook = alc880_uniwill_p53_hp_automute, 4027 .init_hook = alc880_uniwill_p53_init_hook,
3856 }, 4028 },
3857 [ALC880_CLEVO] = { 4029 [ALC880_CLEVO] = {
3858 .mixers = { alc880_three_stack_mixer }, 4030 .mixers = { alc880_three_stack_mixer },
@@ -3877,8 +4049,8 @@ static struct alc_config_preset alc880_presets[] = {
3877 .channel_mode = alc880_lg_ch_modes, 4049 .channel_mode = alc880_lg_ch_modes,
3878 .need_dac_fix = 1, 4050 .need_dac_fix = 1,
3879 .input_mux = &alc880_lg_capture_source, 4051 .input_mux = &alc880_lg_capture_source,
3880 .unsol_event = alc880_lg_unsol_event, 4052 .unsol_event = alc_automute_amp_unsol_event,
3881 .init_hook = alc880_lg_automute, 4053 .init_hook = alc880_lg_init_hook,
3882#ifdef CONFIG_SND_HDA_POWER_SAVE 4054#ifdef CONFIG_SND_HDA_POWER_SAVE
3883 .loopbacks = alc880_lg_loopbacks, 4055 .loopbacks = alc880_lg_loopbacks,
3884#endif 4056#endif
@@ -3893,8 +4065,8 @@ static struct alc_config_preset alc880_presets[] = {
3893 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes), 4065 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
3894 .channel_mode = alc880_lg_lw_modes, 4066 .channel_mode = alc880_lg_lw_modes,
3895 .input_mux = &alc880_lg_lw_capture_source, 4067 .input_mux = &alc880_lg_lw_capture_source,
3896 .unsol_event = alc880_lg_lw_unsol_event, 4068 .unsol_event = alc_automute_amp_unsol_event,
3897 .init_hook = alc880_lg_lw_automute, 4069 .init_hook = alc880_lg_lw_init_hook,
3898 }, 4070 },
3899 [ALC880_MEDION_RIM] = { 4071 [ALC880_MEDION_RIM] = {
3900 .mixers = { alc880_medion_rim_mixer }, 4072 .mixers = { alc880_medion_rim_mixer },
@@ -3908,7 +4080,7 @@ static struct alc_config_preset alc880_presets[] = {
3908 .channel_mode = alc880_2_jack_modes, 4080 .channel_mode = alc880_2_jack_modes,
3909 .input_mux = &alc880_medion_rim_capture_source, 4081 .input_mux = &alc880_medion_rim_capture_source,
3910 .unsol_event = alc880_medion_rim_unsol_event, 4082 .unsol_event = alc880_medion_rim_unsol_event,
3911 .init_hook = alc880_medion_rim_automute, 4083 .init_hook = alc880_medion_rim_init_hook,
3912 }, 4084 },
3913#ifdef CONFIG_SND_DEBUG 4085#ifdef CONFIG_SND_DEBUG
3914 [ALC880_TEST] = { 4086 [ALC880_TEST] = {
@@ -4193,7 +4365,6 @@ static void alc880_auto_init_multi_out(struct hda_codec *codec)
4193 struct alc_spec *spec = codec->spec; 4365 struct alc_spec *spec = codec->spec;
4194 int i; 4366 int i;
4195 4367
4196 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
4197 for (i = 0; i < spec->autocfg.line_outs; i++) { 4368 for (i = 0; i < spec->autocfg.line_outs; i++) {
4198 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 4369 hda_nid_t nid = spec->autocfg.line_out_pins[i];
4199 int pin_type = get_pin_type(spec->autocfg.line_out_type); 4370 int pin_type = get_pin_type(spec->autocfg.line_out_type);
@@ -4298,6 +4469,8 @@ static int alc880_parse_auto_config(struct hda_codec *codec)
4298 spec->num_mux_defs = 1; 4469 spec->num_mux_defs = 1;
4299 spec->input_mux = &spec->private_imux[0]; 4470 spec->input_mux = &spec->private_imux[0];
4300 4471
4472 alc_ssid_check(codec, 0x15, 0x1b, 0x14);
4473
4301 return 1; 4474 return 1;
4302} 4475}
4303 4476
@@ -4355,8 +4528,8 @@ static int patch_alc880(struct hda_codec *codec)
4355 alc880_models, 4528 alc880_models,
4356 alc880_cfg_tbl); 4529 alc880_cfg_tbl);
4357 if (board_config < 0) { 4530 if (board_config < 0) {
4358 printk(KERN_INFO "hda_codec: Unknown model for ALC880, " 4531 printk(KERN_INFO "hda_codec: Unknown model for %s, "
4359 "trying auto-probe from BIOS...\n"); 4532 "trying auto-probe from BIOS...\n", codec->chip_name);
4360 board_config = ALC880_AUTO; 4533 board_config = ALC880_AUTO;
4361 } 4534 }
4362 4535
@@ -4383,12 +4556,10 @@ static int patch_alc880(struct hda_codec *codec)
4383 if (board_config != ALC880_AUTO) 4556 if (board_config != ALC880_AUTO)
4384 setup_preset(spec, &alc880_presets[board_config]); 4557 setup_preset(spec, &alc880_presets[board_config]);
4385 4558
4386 spec->stream_name_analog = "ALC880 Analog";
4387 spec->stream_analog_playback = &alc880_pcm_analog_playback; 4559 spec->stream_analog_playback = &alc880_pcm_analog_playback;
4388 spec->stream_analog_capture = &alc880_pcm_analog_capture; 4560 spec->stream_analog_capture = &alc880_pcm_analog_capture;
4389 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture; 4561 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
4390 4562
4391 spec->stream_name_digital = "ALC880 Digital";
4392 spec->stream_digital_playback = &alc880_pcm_digital_playback; 4563 spec->stream_digital_playback = &alc880_pcm_digital_playback;
4393 spec->stream_digital_capture = &alc880_pcm_digital_capture; 4564 spec->stream_digital_capture = &alc880_pcm_digital_capture;
4394 4565
@@ -5673,7 +5844,6 @@ static void alc260_auto_init_multi_out(struct hda_codec *codec)
5673 struct alc_spec *spec = codec->spec; 5844 struct alc_spec *spec = codec->spec;
5674 hda_nid_t nid; 5845 hda_nid_t nid;
5675 5846
5676 alc_subsystem_id(codec, 0x10, 0x15, 0x0f);
5677 nid = spec->autocfg.line_out_pins[0]; 5847 nid = spec->autocfg.line_out_pins[0];
5678 if (nid) { 5848 if (nid) {
5679 int pin_type = get_pin_type(spec->autocfg.line_out_type); 5849 int pin_type = get_pin_type(spec->autocfg.line_out_type);
@@ -5783,6 +5953,8 @@ static int alc260_parse_auto_config(struct hda_codec *codec)
5783 spec->num_mux_defs = 1; 5953 spec->num_mux_defs = 1;
5784 spec->input_mux = &spec->private_imux[0]; 5954 spec->input_mux = &spec->private_imux[0];
5785 5955
5956 alc_ssid_check(codec, 0x10, 0x15, 0x0f);
5957
5786 return 1; 5958 return 1;
5787} 5959}
5788 5960
@@ -6000,8 +6172,9 @@ static int patch_alc260(struct hda_codec *codec)
6000 alc260_models, 6172 alc260_models,
6001 alc260_cfg_tbl); 6173 alc260_cfg_tbl);
6002 if (board_config < 0) { 6174 if (board_config < 0) {
6003 snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260, " 6175 snd_printd(KERN_INFO "hda_codec: Unknown model for %s, "
6004 "trying auto-probe from BIOS...\n"); 6176 "trying auto-probe from BIOS...\n",
6177 codec->chip_name);
6005 board_config = ALC260_AUTO; 6178 board_config = ALC260_AUTO;
6006 } 6179 }
6007 6180
@@ -6028,11 +6201,9 @@ static int patch_alc260(struct hda_codec *codec)
6028 if (board_config != ALC260_AUTO) 6201 if (board_config != ALC260_AUTO)
6029 setup_preset(spec, &alc260_presets[board_config]); 6202 setup_preset(spec, &alc260_presets[board_config]);
6030 6203
6031 spec->stream_name_analog = "ALC260 Analog";
6032 spec->stream_analog_playback = &alc260_pcm_analog_playback; 6204 spec->stream_analog_playback = &alc260_pcm_analog_playback;
6033 spec->stream_analog_capture = &alc260_pcm_analog_capture; 6205 spec->stream_analog_capture = &alc260_pcm_analog_capture;
6034 6206
6035 spec->stream_name_digital = "ALC260 Digital";
6036 spec->stream_digital_playback = &alc260_pcm_digital_playback; 6207 spec->stream_digital_playback = &alc260_pcm_digital_playback;
6037 spec->stream_digital_capture = &alc260_pcm_digital_capture; 6208 spec->stream_digital_capture = &alc260_pcm_digital_capture;
6038 6209
@@ -6109,6 +6280,16 @@ static struct hda_input_mux alc882_capture_source = {
6109 { "CD", 0x4 }, 6280 { "CD", 0x4 },
6110 }, 6281 },
6111}; 6282};
6283
6284static struct hda_input_mux mb5_capture_source = {
6285 .num_items = 3,
6286 .items = {
6287 { "Mic", 0x1 },
6288 { "Line", 0x2 },
6289 { "CD", 0x4 },
6290 },
6291};
6292
6112/* 6293/*
6113 * 2ch mode 6294 * 2ch mode
6114 */ 6295 */
@@ -6196,6 +6377,34 @@ static struct hda_channel_mode alc885_mbp_6ch_modes[2] = {
6196 { 6, alc885_mbp_ch6_init }, 6377 { 6, alc885_mbp_ch6_init },
6197}; 6378};
6198 6379
6380/*
6381 * 2ch
6382 * Speakers/Woofer/HP = Front
6383 * LineIn = Input
6384 */
6385static struct hda_verb alc885_mb5_ch2_init[] = {
6386 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6387 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6388 { } /* end */
6389};
6390
6391/*
6392 * 6ch mode
6393 * Speakers/HP = Front
6394 * Woofer = LFE
6395 * LineIn = Surround
6396 */
6397static struct hda_verb alc885_mb5_ch6_init[] = {
6398 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6399 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6400 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6401 { } /* end */
6402};
6403
6404static struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
6405 { 2, alc885_mb5_ch2_init },
6406 { 6, alc885_mb5_ch6_init },
6407};
6199 6408
6200/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 6409/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
6201 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b 6410 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
@@ -6238,6 +6447,25 @@ static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
6238 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT), 6447 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
6239 { } /* end */ 6448 { } /* end */
6240}; 6449};
6450
6451static struct snd_kcontrol_new alc885_mb5_mixer[] = {
6452 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
6453 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
6454 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
6455 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
6456 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
6457 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
6458 HDA_CODEC_VOLUME("HP Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
6459 HDA_BIND_MUTE ("HP Playback Switch", 0x0f, 0x02, HDA_INPUT),
6460 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6461 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6462 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
6463 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
6464 HDA_CODEC_VOLUME("Line Boost", 0x15, 0x00, HDA_INPUT),
6465 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0x00, HDA_INPUT),
6466 { } /* end */
6467};
6468
6241static struct snd_kcontrol_new alc882_w2jc_mixer[] = { 6469static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
6242 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 6470 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6243 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 6471 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
@@ -6465,6 +6693,55 @@ static struct hda_verb alc882_macpro_init_verbs[] = {
6465 { } 6693 { }
6466}; 6694};
6467 6695
6696/* Macbook 5,1 */
6697static struct hda_verb alc885_mb5_init_verbs[] = {
6698 /* DACs */
6699 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6700 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6701 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6702 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6703 /* Front mixer */
6704 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6705 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6706 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6707 /* Surround mixer */
6708 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6709 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6710 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6711 /* LFE mixer */
6712 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6713 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6714 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6715 /* HP mixer */
6716 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6717 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6718 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6719 /* Front Pin (0x0c) */
6720 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
6721 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6722 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
6723 /* LFE Pin (0x0e) */
6724 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
6725 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6726 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
6727 /* HP Pin (0x0f) */
6728 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6729 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6730 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
6731 /* Front Mic pin: input vref at 80% */
6732 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6733 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6734 /* Line In pin */
6735 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6736 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6737
6738 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6739 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6740 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6741 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6742 { }
6743};
6744
6468/* Macbook Pro rev3 */ 6745/* Macbook Pro rev3 */
6469static struct hda_verb alc885_mbp3_init_verbs[] = { 6746static struct hda_verb alc885_mbp3_init_verbs[] = {
6470 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 6747 /* Front mixer: unmute input/output amp left and right (volume = 0) */
@@ -6554,45 +6831,23 @@ static struct hda_verb alc885_imac24_init_verbs[] = {
6554}; 6831};
6555 6832
6556/* Toggle speaker-output according to the hp-jack state */ 6833/* Toggle speaker-output according to the hp-jack state */
6557static void alc885_imac24_automute(struct hda_codec *codec) 6834static void alc885_imac24_automute_init_hook(struct hda_codec *codec)
6558{ 6835{
6559 unsigned int present; 6836 struct alc_spec *spec = codec->spec;
6560
6561 present = snd_hda_codec_read(codec, 0x14, 0,
6562 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6563 snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0,
6564 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6565 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
6566 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6567}
6568 6837
6569/* Processes unsolicited events. */ 6838 spec->autocfg.hp_pins[0] = 0x14;
6570static void alc885_imac24_unsol_event(struct hda_codec *codec, 6839 spec->autocfg.speaker_pins[0] = 0x18;
6571 unsigned int res) 6840 spec->autocfg.speaker_pins[1] = 0x1a;
6572{ 6841 alc_automute_amp(codec);
6573 /* Headphone insertion or removal. */
6574 if ((res >> 26) == ALC880_HP_EVENT)
6575 alc885_imac24_automute(codec);
6576} 6842}
6577 6843
6578static void alc885_mbp3_automute(struct hda_codec *codec) 6844static void alc885_mbp3_init_hook(struct hda_codec *codec)
6579{ 6845{
6580 unsigned int present; 6846 struct alc_spec *spec = codec->spec;
6581
6582 present = snd_hda_codec_read(codec, 0x15, 0,
6583 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6584 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
6585 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6586 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
6587 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
6588 6847
6589} 6848 spec->autocfg.hp_pins[0] = 0x15;
6590static void alc885_mbp3_unsol_event(struct hda_codec *codec, 6849 spec->autocfg.speaker_pins[0] = 0x14;
6591 unsigned int res) 6850 alc_automute_amp(codec);
6592{
6593 /* Headphone insertion or removal. */
6594 if ((res >> 26) == ALC880_HP_EVENT)
6595 alc885_mbp3_automute(codec);
6596} 6851}
6597 6852
6598 6853
@@ -6617,24 +6872,25 @@ static struct hda_verb alc882_targa_verbs[] = {
6617/* toggle speaker-output according to the hp-jack state */ 6872/* toggle speaker-output according to the hp-jack state */
6618static void alc882_targa_automute(struct hda_codec *codec) 6873static void alc882_targa_automute(struct hda_codec *codec)
6619{ 6874{
6620 unsigned int present; 6875 struct alc_spec *spec = codec->spec;
6621 6876 alc_automute_amp(codec);
6622 present = snd_hda_codec_read(codec, 0x14, 0,
6623 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6624 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
6625 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6626 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA, 6877 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
6627 present ? 1 : 3); 6878 spec->jack_present ? 1 : 3);
6879}
6880
6881static void alc882_targa_init_hook(struct hda_codec *codec)
6882{
6883 struct alc_spec *spec = codec->spec;
6884
6885 spec->autocfg.hp_pins[0] = 0x14;
6886 spec->autocfg.speaker_pins[0] = 0x1b;
6887 alc882_targa_automute(codec);
6628} 6888}
6629 6889
6630static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res) 6890static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
6631{ 6891{
6632 /* Looks like the unsol event is incompatible with the standard 6892 if ((res >> 26) == ALC880_HP_EVENT)
6633 * definition. 4bit tag is placed at 26 bit!
6634 */
6635 if (((res >> 26) == ALC880_HP_EVENT)) {
6636 alc882_targa_automute(codec); 6893 alc882_targa_automute(codec);
6637 }
6638} 6894}
6639 6895
6640static struct hda_verb alc882_asus_a7j_verbs[] = { 6896static struct hda_verb alc882_asus_a7j_verbs[] = {
@@ -6716,7 +6972,7 @@ static void alc885_macpro_init_hook(struct hda_codec *codec)
6716static void alc885_imac24_init_hook(struct hda_codec *codec) 6972static void alc885_imac24_init_hook(struct hda_codec *codec)
6717{ 6973{
6718 alc885_macpro_init_hook(codec); 6974 alc885_macpro_init_hook(codec);
6719 alc885_imac24_automute(codec); 6975 alc885_imac24_automute_init_hook(codec);
6720} 6976}
6721 6977
6722/* 6978/*
@@ -6809,6 +7065,7 @@ static const char *alc882_models[ALC882_MODEL_LAST] = {
6809 [ALC882_ASUS_A7J] = "asus-a7j", 7065 [ALC882_ASUS_A7J] = "asus-a7j",
6810 [ALC882_ASUS_A7M] = "asus-a7m", 7066 [ALC882_ASUS_A7M] = "asus-a7m",
6811 [ALC885_MACPRO] = "macpro", 7067 [ALC885_MACPRO] = "macpro",
7068 [ALC885_MB5] = "mb5",
6812 [ALC885_MBP3] = "mbp3", 7069 [ALC885_MBP3] = "mbp3",
6813 [ALC885_IMAC24] = "imac24", 7070 [ALC885_IMAC24] = "imac24",
6814 [ALC882_AUTO] = "auto", 7071 [ALC882_AUTO] = "auto",
@@ -6886,8 +7143,20 @@ static struct alc_config_preset alc882_presets[] = {
6886 .input_mux = &alc882_capture_source, 7143 .input_mux = &alc882_capture_source,
6887 .dig_out_nid = ALC882_DIGOUT_NID, 7144 .dig_out_nid = ALC882_DIGOUT_NID,
6888 .dig_in_nid = ALC882_DIGIN_NID, 7145 .dig_in_nid = ALC882_DIGIN_NID,
6889 .unsol_event = alc885_mbp3_unsol_event, 7146 .unsol_event = alc_automute_amp_unsol_event,
6890 .init_hook = alc885_mbp3_automute, 7147 .init_hook = alc885_mbp3_init_hook,
7148 },
7149 [ALC885_MB5] = {
7150 .mixers = { alc885_mb5_mixer, alc882_chmode_mixer },
7151 .init_verbs = { alc885_mb5_init_verbs,
7152 alc880_gpio1_init_verbs },
7153 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7154 .dac_nids = alc882_dac_nids,
7155 .channel_mode = alc885_mb5_6ch_modes,
7156 .num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes),
7157 .input_mux = &mb5_capture_source,
7158 .dig_out_nid = ALC882_DIGOUT_NID,
7159 .dig_in_nid = ALC882_DIGIN_NID,
6891 }, 7160 },
6892 [ALC885_MACPRO] = { 7161 [ALC885_MACPRO] = {
6893 .mixers = { alc882_macpro_mixer }, 7162 .mixers = { alc882_macpro_mixer },
@@ -6911,7 +7180,7 @@ static struct alc_config_preset alc882_presets[] = {
6911 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes), 7180 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6912 .channel_mode = alc882_ch_modes, 7181 .channel_mode = alc882_ch_modes,
6913 .input_mux = &alc882_capture_source, 7182 .input_mux = &alc882_capture_source,
6914 .unsol_event = alc885_imac24_unsol_event, 7183 .unsol_event = alc_automute_amp_unsol_event,
6915 .init_hook = alc885_imac24_init_hook, 7184 .init_hook = alc885_imac24_init_hook,
6916 }, 7185 },
6917 [ALC882_TARGA] = { 7186 [ALC882_TARGA] = {
@@ -6928,7 +7197,7 @@ static struct alc_config_preset alc882_presets[] = {
6928 .need_dac_fix = 1, 7197 .need_dac_fix = 1,
6929 .input_mux = &alc882_capture_source, 7198 .input_mux = &alc882_capture_source,
6930 .unsol_event = alc882_targa_unsol_event, 7199 .unsol_event = alc882_targa_unsol_event,
6931 .init_hook = alc882_targa_automute, 7200 .init_hook = alc882_targa_init_hook,
6932 }, 7201 },
6933 [ALC882_ASUS_A7J] = { 7202 [ALC882_ASUS_A7J] = {
6934 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer }, 7203 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
@@ -7008,7 +7277,6 @@ static void alc882_auto_init_multi_out(struct hda_codec *codec)
7008 struct alc_spec *spec = codec->spec; 7277 struct alc_spec *spec = codec->spec;
7009 int i; 7278 int i;
7010 7279
7011 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
7012 for (i = 0; i <= HDA_SIDE; i++) { 7280 for (i = 0; i <= HDA_SIDE; i++) {
7013 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 7281 hda_nid_t nid = spec->autocfg.line_out_pins[i];
7014 int pin_type = get_pin_type(spec->autocfg.line_out_type); 7282 int pin_type = get_pin_type(spec->autocfg.line_out_type);
@@ -7191,10 +7459,17 @@ static int patch_alc882(struct hda_codec *codec)
7191 case 0x106b00a1: /* Macbook (might be wrong - PCI SSID?) */ 7459 case 0x106b00a1: /* Macbook (might be wrong - PCI SSID?) */
7192 case 0x106b00a4: /* MacbookPro4,1 */ 7460 case 0x106b00a4: /* MacbookPro4,1 */
7193 case 0x106b2c00: /* Macbook Pro rev3 */ 7461 case 0x106b2c00: /* Macbook Pro rev3 */
7194 case 0x106b3600: /* Macbook 3.1 */ 7462 /* Macbook 3.1 (0x106b3600) is handled by patch_alc883() */
7195 case 0x106b3800: /* MacbookPro4,1 - latter revision */ 7463 case 0x106b3800: /* MacbookPro4,1 - latter revision */
7196 board_config = ALC885_MBP3; 7464 board_config = ALC885_MBP3;
7197 break; 7465 break;
7466 case 0x106b3f00: /* Macbook 5,1 */
7467 case 0x106b4000: /* Macbook Pro 5,1 - FIXME: HP jack sense
7468 * seems not working, so apparently
7469 * no perfect solution yet
7470 */
7471 board_config = ALC885_MB5;
7472 break;
7198 default: 7473 default:
7199 /* ALC889A is handled better as ALC888-compatible */ 7474 /* ALC889A is handled better as ALC888-compatible */
7200 if (codec->revision_id == 0x100101 || 7475 if (codec->revision_id == 0x100101 ||
@@ -7202,8 +7477,9 @@ static int patch_alc882(struct hda_codec *codec)
7202 alc_free(codec); 7477 alc_free(codec);
7203 return patch_alc883(codec); 7478 return patch_alc883(codec);
7204 } 7479 }
7205 printk(KERN_INFO "hda_codec: Unknown model for ALC882, " 7480 printk(KERN_INFO "hda_codec: Unknown model for %s, "
7206 "trying auto-probe from BIOS...\n"); 7481 "trying auto-probe from BIOS...\n",
7482 codec->chip_name);
7207 board_config = ALC882_AUTO; 7483 board_config = ALC882_AUTO;
7208 } 7484 }
7209 } 7485 }
@@ -7233,14 +7509,6 @@ static int patch_alc882(struct hda_codec *codec)
7233 if (board_config != ALC882_AUTO) 7509 if (board_config != ALC882_AUTO)
7234 setup_preset(spec, &alc882_presets[board_config]); 7510 setup_preset(spec, &alc882_presets[board_config]);
7235 7511
7236 if (codec->vendor_id == 0x10ec0885) {
7237 spec->stream_name_analog = "ALC885 Analog";
7238 spec->stream_name_digital = "ALC885 Digital";
7239 } else {
7240 spec->stream_name_analog = "ALC882 Analog";
7241 spec->stream_name_digital = "ALC882 Digital";
7242 }
7243
7244 spec->stream_analog_playback = &alc882_pcm_analog_playback; 7512 spec->stream_analog_playback = &alc882_pcm_analog_playback;
7245 spec->stream_analog_capture = &alc882_pcm_analog_capture; 7513 spec->stream_analog_capture = &alc882_pcm_analog_capture;
7246 /* FIXME: setup DAC5 */ 7514 /* FIXME: setup DAC5 */
@@ -7393,6 +7661,17 @@ static struct hda_input_mux alc883_asus_eee1601_capture_source = {
7393 }, 7661 },
7394}; 7662};
7395 7663
7664static struct hda_input_mux alc889A_mb31_capture_source = {
7665 .num_items = 2,
7666 .items = {
7667 { "Mic", 0x0 },
7668 /* Front Mic (0x01) unused */
7669 { "Line", 0x2 },
7670 /* Line 2 (0x03) unused */
7671 /* CD (0x04) unsused? */
7672 },
7673};
7674
7396/* 7675/*
7397 * 2ch mode 7676 * 2ch mode
7398 */ 7677 */
@@ -7442,6 +7721,73 @@ static struct hda_channel_mode alc883_3ST_6ch_modes[3] = {
7442 { 6, alc883_3ST_ch6_init }, 7721 { 6, alc883_3ST_ch6_init },
7443}; 7722};
7444 7723
7724
7725/*
7726 * 2ch mode
7727 */
7728static struct hda_verb alc883_4ST_ch2_init[] = {
7729 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7730 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7731 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7732 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7733 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7734 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7735 { } /* end */
7736};
7737
7738/*
7739 * 4ch mode
7740 */
7741static struct hda_verb alc883_4ST_ch4_init[] = {
7742 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7743 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7744 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7745 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7746 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7747 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7748 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7749 { } /* end */
7750};
7751
7752/*
7753 * 6ch mode
7754 */
7755static struct hda_verb alc883_4ST_ch6_init[] = {
7756 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7757 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7758 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7759 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7760 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7761 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7762 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7763 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7764 { } /* end */
7765};
7766
7767/*
7768 * 8ch mode
7769 */
7770static struct hda_verb alc883_4ST_ch8_init[] = {
7771 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7772 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7773 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7774 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7775 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7776 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7777 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7778 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7779 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7780 { } /* end */
7781};
7782
7783static struct hda_channel_mode alc883_4ST_8ch_modes[4] = {
7784 { 2, alc883_4ST_ch2_init },
7785 { 4, alc883_4ST_ch4_init },
7786 { 6, alc883_4ST_ch6_init },
7787 { 8, alc883_4ST_ch8_init },
7788};
7789
7790
7445/* 7791/*
7446 * 2ch mode 7792 * 2ch mode
7447 */ 7793 */
@@ -7511,6 +7857,49 @@ static struct hda_channel_mode alc883_sixstack_modes[2] = {
7511 { 8, alc883_sixstack_ch8_init }, 7857 { 8, alc883_sixstack_ch8_init },
7512}; 7858};
7513 7859
7860/* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */
7861static struct hda_verb alc889A_mb31_ch2_init[] = {
7862 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
7863 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
7864 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
7865 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
7866 { } /* end */
7867};
7868
7869/* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */
7870static struct hda_verb alc889A_mb31_ch4_init[] = {
7871 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
7872 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
7873 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
7874 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
7875 { } /* end */
7876};
7877
7878/* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */
7879static struct hda_verb alc889A_mb31_ch5_init[] = {
7880 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */
7881 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
7882 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
7883 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
7884 { } /* end */
7885};
7886
7887/* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */
7888static struct hda_verb alc889A_mb31_ch6_init[] = {
7889 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */
7890 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */
7891 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
7892 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
7893 { } /* end */
7894};
7895
7896static struct hda_channel_mode alc889A_mb31_6ch_modes[4] = {
7897 { 2, alc889A_mb31_ch2_init },
7898 { 4, alc889A_mb31_ch4_init },
7899 { 5, alc889A_mb31_ch5_init },
7900 { 6, alc889A_mb31_ch6_init },
7901};
7902
7514static struct hda_verb alc883_medion_eapd_verbs[] = { 7903static struct hda_verb alc883_medion_eapd_verbs[] = {
7515 /* eanable EAPD on medion laptop */ 7904 /* eanable EAPD on medion laptop */
7516 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 7905 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
@@ -7776,8 +8165,6 @@ static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
7776 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT), 8165 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
7777 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 8166 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7778 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 8167 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
7779 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7780 HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
7781 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 8168 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7782 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 8169 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7783 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8170 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
@@ -7791,6 +8178,42 @@ static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
7791 { } /* end */ 8178 { } /* end */
7792}; 8179};
7793 8180
8181static struct snd_kcontrol_new alc889A_mb31_mixer[] = {
8182 /* Output mixers */
8183 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8184 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
8185 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8186 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
8187 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00,
8188 HDA_OUTPUT),
8189 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT),
8190 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT),
8191 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT),
8192 /* Output switches */
8193 HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT),
8194 HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT),
8195 HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT),
8196 /* Boost mixers */
8197 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
8198 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
8199 /* Input mixers */
8200 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
8201 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
8202 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8203 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8204 { } /* end */
8205};
8206
8207static struct snd_kcontrol_new alc883_vaiott_mixer[] = {
8208 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8209 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8210 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8211 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8212 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
8213 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8214 { } /* end */
8215};
8216
7794static struct hda_bind_ctls alc883_bind_cap_vol = { 8217static struct hda_bind_ctls alc883_bind_cap_vol = {
7795 .ops = &snd_hda_bind_vol, 8218 .ops = &snd_hda_bind_vol,
7796 .values = { 8219 .values = {
@@ -7926,16 +8349,14 @@ static struct hda_verb alc883_init_verbs[] = {
7926}; 8349};
7927 8350
7928/* toggle speaker-output according to the hp-jack state */ 8351/* toggle speaker-output according to the hp-jack state */
7929static void alc883_mitac_hp_automute(struct hda_codec *codec) 8352static void alc883_mitac_init_hook(struct hda_codec *codec)
7930{ 8353{
7931 unsigned int present; 8354 struct alc_spec *spec = codec->spec;
7932 8355
7933 present = snd_hda_codec_read(codec, 0x15, 0, 8356 spec->autocfg.hp_pins[0] = 0x15;
7934 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 8357 spec->autocfg.speaker_pins[0] = 0x14;
7935 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 8358 spec->autocfg.speaker_pins[1] = 0x17;
7936 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 8359 alc_automute_amp(codec);
7937 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
7938 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7939} 8360}
7940 8361
7941/* auto-toggle front mic */ 8362/* auto-toggle front mic */
@@ -7952,25 +8373,6 @@ static void alc883_mitac_mic_automute(struct hda_codec *codec)
7952} 8373}
7953*/ 8374*/
7954 8375
7955static void alc883_mitac_automute(struct hda_codec *codec)
7956{
7957 alc883_mitac_hp_automute(codec);
7958 /* alc883_mitac_mic_automute(codec); */
7959}
7960
7961static void alc883_mitac_unsol_event(struct hda_codec *codec,
7962 unsigned int res)
7963{
7964 switch (res >> 26) {
7965 case ALC880_HP_EVENT:
7966 alc883_mitac_hp_automute(codec);
7967 break;
7968 case ALC880_MIC_EVENT:
7969 /* alc883_mitac_mic_automute(codec); */
7970 break;
7971 }
7972}
7973
7974static struct hda_verb alc883_mitac_verbs[] = { 8376static struct hda_verb alc883_mitac_verbs[] = {
7975 /* HP */ 8377 /* HP */
7976 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 8378 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
@@ -8022,14 +8424,24 @@ static struct hda_verb alc883_tagra_verbs[] = {
8022 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 8424 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8023 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8425 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8024 8426
8025 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ 8427/* Connect Line-Out side jack (SPDIF) to Side */
8026 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */ 8428 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8027 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 8429 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8430 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
8431/* Connect Mic jack to CLFE */
8432 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8433 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8434 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
8435/* Connect Line-in jack to Surround */
8436 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8437 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8438 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
8439/* Connect HP out jack to Front */
8440 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8441 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8442 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8028 8443
8029 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 8444 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8030 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
8031 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
8032 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
8033 8445
8034 { } /* end */ 8446 { } /* end */
8035}; 8447};
@@ -8088,29 +8500,26 @@ static struct hda_verb alc888_6st_dell_verbs[] = {
8088 { } 8500 { }
8089}; 8501};
8090 8502
8091static void alc888_3st_hp_front_automute(struct hda_codec *codec) 8503static struct hda_verb alc883_vaiott_verbs[] = {
8092{ 8504 /* HP */
8093 unsigned int present, bits; 8505 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8506 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8094 8507
8095 present = snd_hda_codec_read(codec, 0x1b, 0, 8508 /* enable unsolicited event */
8096 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 8509 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8097 bits = present ? HDA_AMP_MUTE : 0; 8510
8098 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 8511 { } /* end */
8099 HDA_AMP_MUTE, bits); 8512};
8100 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8101 HDA_AMP_MUTE, bits);
8102 snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0,
8103 HDA_AMP_MUTE, bits);
8104}
8105 8513
8106static void alc888_3st_hp_unsol_event(struct hda_codec *codec, 8514static void alc888_3st_hp_init_hook(struct hda_codec *codec)
8107 unsigned int res)
8108{ 8515{
8109 switch (res >> 26) { 8516 struct alc_spec *spec = codec->spec;
8110 case ALC880_HP_EVENT: 8517
8111 alc888_3st_hp_front_automute(codec); 8518 spec->autocfg.hp_pins[0] = 0x1b;
8112 break; 8519 spec->autocfg.speaker_pins[0] = 0x14;
8113 } 8520 spec->autocfg.speaker_pins[1] = 0x16;
8521 spec->autocfg.speaker_pins[2] = 0x18;
8522 alc_automute_amp(codec);
8114} 8523}
8115 8524
8116static struct hda_verb alc888_3st_hp_verbs[] = { 8525static struct hda_verb alc888_3st_hp_verbs[] = {
@@ -8207,56 +8616,18 @@ static struct hda_verb alc883_medion_md2_verbs[] = {
8207}; 8616};
8208 8617
8209/* toggle speaker-output according to the hp-jack state */ 8618/* toggle speaker-output according to the hp-jack state */
8210static void alc883_medion_md2_automute(struct hda_codec *codec) 8619static void alc883_medion_md2_init_hook(struct hda_codec *codec)
8211{ 8620{
8212 unsigned int present; 8621 struct alc_spec *spec = codec->spec;
8213
8214 present = snd_hda_codec_read(codec, 0x14, 0,
8215 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8216 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8217 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8218}
8219
8220static void alc883_medion_md2_unsol_event(struct hda_codec *codec,
8221 unsigned int res)
8222{
8223 if ((res >> 26) == ALC880_HP_EVENT)
8224 alc883_medion_md2_automute(codec);
8225}
8226
8227/* toggle speaker-output according to the hp-jack state */
8228static void alc883_tagra_automute(struct hda_codec *codec)
8229{
8230 unsigned int present;
8231 unsigned char bits;
8232
8233 present = snd_hda_codec_read(codec, 0x14, 0,
8234 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8235 bits = present ? HDA_AMP_MUTE : 0;
8236 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
8237 HDA_AMP_MUTE, bits);
8238 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
8239 present ? 1 : 3);
8240}
8241 8622
8242static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res) 8623 spec->autocfg.hp_pins[0] = 0x14;
8243{ 8624 spec->autocfg.speaker_pins[0] = 0x15;
8244 if ((res >> 26) == ALC880_HP_EVENT) 8625 alc_automute_amp(codec);
8245 alc883_tagra_automute(codec);
8246} 8626}
8247 8627
8248/* toggle speaker-output according to the hp-jack state */ 8628/* toggle speaker-output according to the hp-jack state */
8249static void alc883_clevo_m720_hp_automute(struct hda_codec *codec) 8629#define alc883_tagra_init_hook alc882_targa_init_hook
8250{ 8630#define alc883_tagra_unsol_event alc882_targa_unsol_event
8251 unsigned int present;
8252 unsigned char bits;
8253
8254 present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0)
8255 & AC_PINSENSE_PRESENCE;
8256 bits = present ? HDA_AMP_MUTE : 0;
8257 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8258 HDA_AMP_MUTE, bits);
8259}
8260 8631
8261static void alc883_clevo_m720_mic_automute(struct hda_codec *codec) 8632static void alc883_clevo_m720_mic_automute(struct hda_codec *codec)
8262{ 8633{
@@ -8268,9 +8639,13 @@ static void alc883_clevo_m720_mic_automute(struct hda_codec *codec)
8268 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 8639 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8269} 8640}
8270 8641
8271static void alc883_clevo_m720_automute(struct hda_codec *codec) 8642static void alc883_clevo_m720_init_hook(struct hda_codec *codec)
8272{ 8643{
8273 alc883_clevo_m720_hp_automute(codec); 8644 struct alc_spec *spec = codec->spec;
8645
8646 spec->autocfg.hp_pins[0] = 0x15;
8647 spec->autocfg.speaker_pins[0] = 0x14;
8648 alc_automute_amp(codec);
8274 alc883_clevo_m720_mic_automute(codec); 8649 alc883_clevo_m720_mic_automute(codec);
8275} 8650}
8276 8651
@@ -8278,52 +8653,32 @@ static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
8278 unsigned int res) 8653 unsigned int res)
8279{ 8654{
8280 switch (res >> 26) { 8655 switch (res >> 26) {
8281 case ALC880_HP_EVENT:
8282 alc883_clevo_m720_hp_automute(codec);
8283 break;
8284 case ALC880_MIC_EVENT: 8656 case ALC880_MIC_EVENT:
8285 alc883_clevo_m720_mic_automute(codec); 8657 alc883_clevo_m720_mic_automute(codec);
8286 break; 8658 break;
8659 default:
8660 alc_automute_amp_unsol_event(codec, res);
8661 break;
8287 } 8662 }
8288} 8663}
8289 8664
8290/* toggle speaker-output according to the hp-jack state */ 8665/* toggle speaker-output according to the hp-jack state */
8291static void alc883_2ch_fujitsu_pi2515_automute(struct hda_codec *codec) 8666static void alc883_2ch_fujitsu_pi2515_init_hook(struct hda_codec *codec)
8292{ 8667{
8293 unsigned int present; 8668 struct alc_spec *spec = codec->spec;
8294 unsigned char bits;
8295
8296 present = snd_hda_codec_read(codec, 0x14, 0, AC_VERB_GET_PIN_SENSE, 0)
8297 & AC_PINSENSE_PRESENCE;
8298 bits = present ? HDA_AMP_MUTE : 0;
8299 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8300 HDA_AMP_MUTE, bits);
8301}
8302 8669
8303static void alc883_2ch_fujitsu_pi2515_unsol_event(struct hda_codec *codec, 8670 spec->autocfg.hp_pins[0] = 0x14;
8304 unsigned int res) 8671 spec->autocfg.speaker_pins[0] = 0x15;
8305{ 8672 alc_automute_amp(codec);
8306 if ((res >> 26) == ALC880_HP_EVENT)
8307 alc883_2ch_fujitsu_pi2515_automute(codec);
8308} 8673}
8309 8674
8310static void alc883_haier_w66_automute(struct hda_codec *codec) 8675static void alc883_haier_w66_init_hook(struct hda_codec *codec)
8311{ 8676{
8312 unsigned int present; 8677 struct alc_spec *spec = codec->spec;
8313 unsigned char bits;
8314 8678
8315 present = snd_hda_codec_read(codec, 0x1b, 0, 8679 spec->autocfg.hp_pins[0] = 0x1b;
8316 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 8680 spec->autocfg.speaker_pins[0] = 0x14;
8317 bits = present ? 0x80 : 0; 8681 alc_automute_amp(codec);
8318 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8319 0x80, bits);
8320}
8321
8322static void alc883_haier_w66_unsol_event(struct hda_codec *codec,
8323 unsigned int res)
8324{
8325 if ((res >> 26) == ALC880_HP_EVENT)
8326 alc883_haier_w66_automute(codec);
8327} 8682}
8328 8683
8329static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec) 8684static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
@@ -8331,8 +8686,8 @@ static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
8331 unsigned int present; 8686 unsigned int present;
8332 unsigned char bits; 8687 unsigned char bits;
8333 8688
8334 present = snd_hda_codec_read(codec, 0x14, 0, 8689 present = snd_hda_codec_read(codec, 0x14, 0, AC_VERB_GET_PIN_SENSE, 0)
8335 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 8690 & AC_PINSENSE_PRESENCE;
8336 bits = present ? HDA_AMP_MUTE : 0; 8691 bits = present ? HDA_AMP_MUTE : 0;
8337 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 8692 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8338 HDA_AMP_MUTE, bits); 8693 HDA_AMP_MUTE, bits);
@@ -8362,23 +8717,14 @@ static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
8362} 8717}
8363 8718
8364/* toggle speaker-output according to the hp-jack state */ 8719/* toggle speaker-output according to the hp-jack state */
8365static void alc883_acer_aspire_automute(struct hda_codec *codec) 8720static void alc883_acer_aspire_init_hook(struct hda_codec *codec)
8366{ 8721{
8367 unsigned int present; 8722 struct alc_spec *spec = codec->spec;
8368
8369 present = snd_hda_codec_read(codec, 0x14, 0,
8370 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8371 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8372 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8373 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8374 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8375}
8376 8723
8377static void alc883_acer_aspire_unsol_event(struct hda_codec *codec, 8724 spec->autocfg.hp_pins[0] = 0x14;
8378 unsigned int res) 8725 spec->autocfg.speaker_pins[0] = 0x15;
8379{ 8726 spec->autocfg.speaker_pins[1] = 0x16;
8380 if ((res >> 26) == ALC880_HP_EVENT) 8727 alc_automute_amp(codec);
8381 alc883_acer_aspire_automute(codec);
8382} 8728}
8383 8729
8384static struct hda_verb alc883_acer_eapd_verbs[] = { 8730static struct hda_verb alc883_acer_eapd_verbs[] = {
@@ -8399,75 +8745,39 @@ static struct hda_verb alc883_acer_eapd_verbs[] = {
8399 { } 8745 { }
8400}; 8746};
8401 8747
8402static void alc888_6st_dell_front_automute(struct hda_codec *codec) 8748static void alc888_6st_dell_init_hook(struct hda_codec *codec)
8403{ 8749{
8404 unsigned int present; 8750 struct alc_spec *spec = codec->spec;
8405
8406 present = snd_hda_codec_read(codec, 0x1b, 0,
8407 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8408 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8409 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8410 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8411 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8412 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8413 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8414 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
8415 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8416}
8417 8751
8418static void alc888_6st_dell_unsol_event(struct hda_codec *codec, 8752 spec->autocfg.hp_pins[0] = 0x1b;
8419 unsigned int res) 8753 spec->autocfg.speaker_pins[0] = 0x14;
8420{ 8754 spec->autocfg.speaker_pins[1] = 0x15;
8421 switch (res >> 26) { 8755 spec->autocfg.speaker_pins[2] = 0x16;
8422 case ALC880_HP_EVENT: 8756 spec->autocfg.speaker_pins[3] = 0x17;
8423 /* printk(KERN_DEBUG "hp_event\n"); */ 8757 alc_automute_amp(codec);
8424 alc888_6st_dell_front_automute(codec);
8425 break;
8426 }
8427} 8758}
8428 8759
8429static void alc888_lenovo_sky_front_automute(struct hda_codec *codec) 8760static void alc888_lenovo_sky_init_hook(struct hda_codec *codec)
8430{ 8761{
8431 unsigned int mute; 8762 struct alc_spec *spec = codec->spec;
8432 unsigned int present;
8433 8763
8434 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0); 8764 spec->autocfg.hp_pins[0] = 0x1b;
8435 present = snd_hda_codec_read(codec, 0x1b, 0, 8765 spec->autocfg.speaker_pins[0] = 0x14;
8436 AC_VERB_GET_PIN_SENSE, 0); 8766 spec->autocfg.speaker_pins[1] = 0x15;
8437 present = (present & 0x80000000) != 0; 8767 spec->autocfg.speaker_pins[2] = 0x16;
8438 if (present) { 8768 spec->autocfg.speaker_pins[3] = 0x17;
8439 /* mute internal speaker */ 8769 spec->autocfg.speaker_pins[4] = 0x1a;
8440 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 8770 alc_automute_amp(codec);
8441 HDA_AMP_MUTE, HDA_AMP_MUTE);
8442 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8443 HDA_AMP_MUTE, HDA_AMP_MUTE);
8444 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8445 HDA_AMP_MUTE, HDA_AMP_MUTE);
8446 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
8447 HDA_AMP_MUTE, HDA_AMP_MUTE);
8448 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
8449 HDA_AMP_MUTE, HDA_AMP_MUTE);
8450 } else {
8451 /* unmute internal speaker if necessary */
8452 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
8453 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8454 HDA_AMP_MUTE, mute);
8455 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8456 HDA_AMP_MUTE, mute);
8457 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8458 HDA_AMP_MUTE, mute);
8459 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
8460 HDA_AMP_MUTE, mute);
8461 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
8462 HDA_AMP_MUTE, mute);
8463 }
8464} 8771}
8465 8772
8466static void alc883_lenovo_sky_unsol_event(struct hda_codec *codec, 8773static void alc883_vaiott_init_hook(struct hda_codec *codec)
8467 unsigned int res)
8468{ 8774{
8469 if ((res >> 26) == ALC880_HP_EVENT) 8775 struct alc_spec *spec = codec->spec;
8470 alc888_lenovo_sky_front_automute(codec); 8776
8777 spec->autocfg.hp_pins[0] = 0x15;
8778 spec->autocfg.speaker_pins[0] = 0x14;
8779 spec->autocfg.speaker_pins[1] = 0x17;
8780 alc_automute_amp(codec);
8471} 8781}
8472 8782
8473/* 8783/*
@@ -8555,39 +8865,33 @@ static void alc883_nb_mic_automute(struct hda_codec *codec)
8555 0x7000 | (0x01 << 8) | (present ? 0x80 : 0)); 8865 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
8556} 8866}
8557 8867
8558static void alc883_M90V_speaker_automute(struct hda_codec *codec) 8868static void alc883_M90V_init_hook(struct hda_codec *codec)
8559{ 8869{
8560 unsigned int present; 8870 struct alc_spec *spec = codec->spec;
8561 unsigned char bits;
8562 8871
8563 present = snd_hda_codec_read(codec, 0x1b, 0, 8872 spec->autocfg.hp_pins[0] = 0x1b;
8564 AC_VERB_GET_PIN_SENSE, 0) 8873 spec->autocfg.speaker_pins[0] = 0x14;
8565 & AC_PINSENSE_PRESENCE; 8874 spec->autocfg.speaker_pins[1] = 0x15;
8566 bits = present ? 0 : PIN_OUT; 8875 spec->autocfg.speaker_pins[2] = 0x16;
8567 snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 8876 alc_automute_pin(codec);
8568 bits);
8569 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8570 bits);
8571 snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8572 bits);
8573} 8877}
8574 8878
8575static void alc883_mode2_unsol_event(struct hda_codec *codec, 8879static void alc883_mode2_unsol_event(struct hda_codec *codec,
8576 unsigned int res) 8880 unsigned int res)
8577{ 8881{
8578 switch (res >> 26) { 8882 switch (res >> 26) {
8579 case ALC880_HP_EVENT:
8580 alc883_M90V_speaker_automute(codec);
8581 break;
8582 case ALC880_MIC_EVENT: 8883 case ALC880_MIC_EVENT:
8583 alc883_nb_mic_automute(codec); 8884 alc883_nb_mic_automute(codec);
8584 break; 8885 break;
8886 default:
8887 alc_sku_unsol_event(codec, res);
8888 break;
8585 } 8889 }
8586} 8890}
8587 8891
8588static void alc883_mode2_inithook(struct hda_codec *codec) 8892static void alc883_mode2_inithook(struct hda_codec *codec)
8589{ 8893{
8590 alc883_M90V_speaker_automute(codec); 8894 alc883_M90V_init_hook(codec);
8591 alc883_nb_mic_automute(codec); 8895 alc883_nb_mic_automute(codec);
8592} 8896}
8593 8897
@@ -8604,32 +8908,49 @@ static struct hda_verb alc888_asus_eee1601_verbs[] = {
8604 { } /* end */ 8908 { } /* end */
8605}; 8909};
8606 8910
8607static void alc883_eee1601_speaker_automute(struct hda_codec *codec) 8911static void alc883_eee1601_inithook(struct hda_codec *codec)
8608{ 8912{
8609 unsigned int present; 8913 struct alc_spec *spec = codec->spec;
8610 unsigned char bits;
8611 8914
8612 present = snd_hda_codec_read(codec, 0x14, 0, 8915 spec->autocfg.hp_pins[0] = 0x14;
8613 AC_VERB_GET_PIN_SENSE, 0) 8916 spec->autocfg.speaker_pins[0] = 0x1b;
8614 & AC_PINSENSE_PRESENCE; 8917 alc_automute_pin(codec);
8615 bits = present ? 0 : PIN_OUT;
8616 snd_hda_codec_write(codec, 0x1b, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8617 bits);
8618} 8918}
8619 8919
8620static void alc883_eee1601_unsol_event(struct hda_codec *codec, 8920static struct hda_verb alc889A_mb31_verbs[] = {
8621 unsigned int res) 8921 /* Init rear pin (used as headphone output) */
8922 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */
8923 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */
8924 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8925 /* Init line pin (used as output in 4ch and 6ch mode) */
8926 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Connect to CLFE */
8927 /* Init line 2 pin (used as headphone out by default) */
8928 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Use as input */
8929 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */
8930 { } /* end */
8931};
8932
8933/* Mute speakers according to the headphone jack state */
8934static void alc889A_mb31_automute(struct hda_codec *codec)
8622{ 8935{
8623 switch (res >> 26) { 8936 unsigned int present;
8624 case ALC880_HP_EVENT: 8937
8625 alc883_eee1601_speaker_automute(codec); 8938 /* Mute only in 2ch or 4ch mode */
8626 break; 8939 if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0)
8940 == 0x00) {
8941 present = snd_hda_codec_read(codec, 0x15, 0,
8942 AC_VERB_GET_PIN_SENSE, 0) & AC_PINSENSE_PRESENCE;
8943 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8944 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8945 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8946 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8627 } 8947 }
8628} 8948}
8629 8949
8630static void alc883_eee1601_inithook(struct hda_codec *codec) 8950static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res)
8631{ 8951{
8632 alc883_eee1601_speaker_automute(codec); 8952 if ((res >> 26) == ALC880_HP_EVENT)
8953 alc889A_mb31_automute(codec);
8633} 8954}
8634 8955
8635#ifdef CONFIG_SND_HDA_POWER_SAVE 8956#ifdef CONFIG_SND_HDA_POWER_SAVE
@@ -8653,9 +8974,11 @@ static const char *alc883_models[ALC883_MODEL_LAST] = {
8653 [ALC883_6ST_DIG] = "6stack-dig", 8974 [ALC883_6ST_DIG] = "6stack-dig",
8654 [ALC883_TARGA_DIG] = "targa-dig", 8975 [ALC883_TARGA_DIG] = "targa-dig",
8655 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig", 8976 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
8977 [ALC883_TARGA_8ch_DIG] = "targa-8ch-dig",
8656 [ALC883_ACER] = "acer", 8978 [ALC883_ACER] = "acer",
8657 [ALC883_ACER_ASPIRE] = "acer-aspire", 8979 [ALC883_ACER_ASPIRE] = "acer-aspire",
8658 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g", 8980 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g",
8981 [ALC888_ACER_ASPIRE_8930G] = "acer-aspire-8930g",
8659 [ALC883_MEDION] = "medion", 8982 [ALC883_MEDION] = "medion",
8660 [ALC883_MEDION_MD2] = "medion-md2", 8983 [ALC883_MEDION_MD2] = "medion-md2",
8661 [ALC883_LAPTOP_EAPD] = "laptop-eapd", 8984 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
@@ -8672,6 +8995,8 @@ static const char *alc883_models[ALC883_MODEL_LAST] = {
8672 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530", 8995 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
8673 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel", 8996 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
8674 [ALC1200_ASUS_P5Q] = "asus-p5q", 8997 [ALC1200_ASUS_P5Q] = "asus-p5q",
8998 [ALC889A_MB31] = "mb31",
8999 [ALC883_SONY_VAIO_TT] = "sony-vaio-tt",
8675 [ALC883_AUTO] = "auto", 9000 [ALC883_AUTO] = "auto",
8676}; 9001};
8677 9002
@@ -8687,14 +9012,18 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = {
8687 ALC888_ACER_ASPIRE_4930G), 9012 ALC888_ACER_ASPIRE_4930G),
8688 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G", 9013 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
8689 ALC888_ACER_ASPIRE_4930G), 9014 ALC888_ACER_ASPIRE_4930G),
9015 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
9016 ALC888_ACER_ASPIRE_8930G),
8690 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC883_AUTO), 9017 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC883_AUTO),
8691 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC883_AUTO), 9018 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC883_AUTO),
8692 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G", 9019 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
8693 ALC888_ACER_ASPIRE_4930G), 9020 ALC888_ACER_ASPIRE_4930G),
8694 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G", 9021 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
8695 ALC888_ACER_ASPIRE_4930G), 9022 ALC888_ACER_ASPIRE_4930G),
8696 /* default Acer */ 9023 /* default Acer -- disabled as it causes more problems.
8697 SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), 9024 * model=auto should work fine now
9025 */
9026 /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */
8698 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL), 9027 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
8699 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG), 9028 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
8700 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP), 9029 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
@@ -8730,6 +9059,7 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = {
8730 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG), 9059 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
8731 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG), 9060 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
8732 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG), 9061 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
9062 SND_PCI_QUIRK(0x1462, 0x6510, "MSI GX620", ALC883_TARGA_8ch_DIG),
8733 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG), 9063 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
8734 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG), 9064 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
8735 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG), 9065 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
@@ -8762,6 +9092,7 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = {
8762 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC), 9092 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
8763 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC883_3ST_6ch_INTEL), 9093 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC883_3ST_6ch_INTEL),
8764 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch), 9094 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
9095 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC883_SONY_VAIO_TT),
8765 {} 9096 {}
8766}; 9097};
8767 9098
@@ -8842,7 +9173,7 @@ static struct alc_config_preset alc883_presets[] = {
8842 .need_dac_fix = 1, 9173 .need_dac_fix = 1,
8843 .input_mux = &alc883_capture_source, 9174 .input_mux = &alc883_capture_source,
8844 .unsol_event = alc883_tagra_unsol_event, 9175 .unsol_event = alc883_tagra_unsol_event,
8845 .init_hook = alc883_tagra_automute, 9176 .init_hook = alc883_tagra_init_hook,
8846 }, 9177 },
8847 [ALC883_TARGA_2ch_DIG] = { 9178 [ALC883_TARGA_2ch_DIG] = {
8848 .mixers = { alc883_tagra_2ch_mixer}, 9179 .mixers = { alc883_tagra_2ch_mixer},
@@ -8856,7 +9187,25 @@ static struct alc_config_preset alc883_presets[] = {
8856 .channel_mode = alc883_3ST_2ch_modes, 9187 .channel_mode = alc883_3ST_2ch_modes,
8857 .input_mux = &alc883_capture_source, 9188 .input_mux = &alc883_capture_source,
8858 .unsol_event = alc883_tagra_unsol_event, 9189 .unsol_event = alc883_tagra_unsol_event,
8859 .init_hook = alc883_tagra_automute, 9190 .init_hook = alc883_tagra_init_hook,
9191 },
9192 [ALC883_TARGA_8ch_DIG] = {
9193 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
9194 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
9195 alc883_tagra_verbs },
9196 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9197 .dac_nids = alc883_dac_nids,
9198 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
9199 .adc_nids = alc883_adc_nids_rev,
9200 .capsrc_nids = alc883_capsrc_nids_rev,
9201 .dig_out_nid = ALC883_DIGOUT_NID,
9202 .dig_in_nid = ALC883_DIGIN_NID,
9203 .num_channel_mode = ARRAY_SIZE(alc883_4ST_8ch_modes),
9204 .channel_mode = alc883_4ST_8ch_modes,
9205 .need_dac_fix = 1,
9206 .input_mux = &alc883_capture_source,
9207 .unsol_event = alc883_tagra_unsol_event,
9208 .init_hook = alc883_tagra_init_hook,
8860 }, 9209 },
8861 [ALC883_ACER] = { 9210 [ALC883_ACER] = {
8862 .mixers = { alc883_base_mixer }, 9211 .mixers = { alc883_base_mixer },
@@ -8881,8 +9230,8 @@ static struct alc_config_preset alc883_presets[] = {
8881 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 9230 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8882 .channel_mode = alc883_3ST_2ch_modes, 9231 .channel_mode = alc883_3ST_2ch_modes,
8883 .input_mux = &alc883_capture_source, 9232 .input_mux = &alc883_capture_source,
8884 .unsol_event = alc883_acer_aspire_unsol_event, 9233 .unsol_event = alc_automute_amp_unsol_event,
8885 .init_hook = alc883_acer_aspire_automute, 9234 .init_hook = alc883_acer_aspire_init_hook,
8886 }, 9235 },
8887 [ALC888_ACER_ASPIRE_4930G] = { 9236 [ALC888_ACER_ASPIRE_4930G] = {
8888 .mixers = { alc888_base_mixer, 9237 .mixers = { alc888_base_mixer,
@@ -8901,8 +9250,29 @@ static struct alc_config_preset alc883_presets[] = {
8901 .num_mux_defs = 9250 .num_mux_defs =
8902 ARRAY_SIZE(alc888_2_capture_sources), 9251 ARRAY_SIZE(alc888_2_capture_sources),
8903 .input_mux = alc888_2_capture_sources, 9252 .input_mux = alc888_2_capture_sources,
8904 .unsol_event = alc888_acer_aspire_4930g_unsol_event, 9253 .unsol_event = alc_automute_amp_unsol_event,
8905 .init_hook = alc888_acer_aspire_4930g_automute, 9254 .init_hook = alc888_acer_aspire_4930g_init_hook,
9255 },
9256 [ALC888_ACER_ASPIRE_8930G] = {
9257 .mixers = { alc888_base_mixer,
9258 alc883_chmode_mixer },
9259 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
9260 alc889_acer_aspire_8930g_verbs },
9261 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9262 .dac_nids = alc883_dac_nids,
9263 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
9264 .adc_nids = alc889_adc_nids,
9265 .capsrc_nids = alc889_capsrc_nids,
9266 .dig_out_nid = ALC883_DIGOUT_NID,
9267 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9268 .channel_mode = alc883_3ST_6ch_modes,
9269 .need_dac_fix = 1,
9270 .const_channel_count = 6,
9271 .num_mux_defs =
9272 ARRAY_SIZE(alc889_capture_sources),
9273 .input_mux = alc889_capture_sources,
9274 .unsol_event = alc_automute_amp_unsol_event,
9275 .init_hook = alc889_acer_aspire_8930g_init_hook,
8906 }, 9276 },
8907 [ALC883_MEDION] = { 9277 [ALC883_MEDION] = {
8908 .mixers = { alc883_fivestack_mixer, 9278 .mixers = { alc883_fivestack_mixer,
@@ -8926,8 +9296,8 @@ static struct alc_config_preset alc883_presets[] = {
8926 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 9296 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8927 .channel_mode = alc883_3ST_2ch_modes, 9297 .channel_mode = alc883_3ST_2ch_modes,
8928 .input_mux = &alc883_capture_source, 9298 .input_mux = &alc883_capture_source,
8929 .unsol_event = alc883_medion_md2_unsol_event, 9299 .unsol_event = alc_automute_amp_unsol_event,
8930 .init_hook = alc883_medion_md2_automute, 9300 .init_hook = alc883_medion_md2_init_hook,
8931 }, 9301 },
8932 [ALC883_LAPTOP_EAPD] = { 9302 [ALC883_LAPTOP_EAPD] = {
8933 .mixers = { alc883_base_mixer }, 9303 .mixers = { alc883_base_mixer },
@@ -8948,7 +9318,7 @@ static struct alc_config_preset alc883_presets[] = {
8948 .channel_mode = alc883_3ST_2ch_modes, 9318 .channel_mode = alc883_3ST_2ch_modes,
8949 .input_mux = &alc883_capture_source, 9319 .input_mux = &alc883_capture_source,
8950 .unsol_event = alc883_clevo_m720_unsol_event, 9320 .unsol_event = alc883_clevo_m720_unsol_event,
8951 .init_hook = alc883_clevo_m720_automute, 9321 .init_hook = alc883_clevo_m720_init_hook,
8952 }, 9322 },
8953 [ALC883_LENOVO_101E_2ch] = { 9323 [ALC883_LENOVO_101E_2ch] = {
8954 .mixers = { alc883_lenovo_101e_2ch_mixer}, 9324 .mixers = { alc883_lenovo_101e_2ch_mixer},
@@ -8972,8 +9342,8 @@ static struct alc_config_preset alc883_presets[] = {
8972 .channel_mode = alc883_3ST_2ch_modes, 9342 .channel_mode = alc883_3ST_2ch_modes,
8973 .need_dac_fix = 1, 9343 .need_dac_fix = 1,
8974 .input_mux = &alc883_lenovo_nb0763_capture_source, 9344 .input_mux = &alc883_lenovo_nb0763_capture_source,
8975 .unsol_event = alc883_medion_md2_unsol_event, 9345 .unsol_event = alc_automute_amp_unsol_event,
8976 .init_hook = alc883_medion_md2_automute, 9346 .init_hook = alc883_medion_md2_init_hook,
8977 }, 9347 },
8978 [ALC888_LENOVO_MS7195_DIG] = { 9348 [ALC888_LENOVO_MS7195_DIG] = {
8979 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, 9349 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
@@ -8997,8 +9367,8 @@ static struct alc_config_preset alc883_presets[] = {
8997 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 9367 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8998 .channel_mode = alc883_3ST_2ch_modes, 9368 .channel_mode = alc883_3ST_2ch_modes,
8999 .input_mux = &alc883_capture_source, 9369 .input_mux = &alc883_capture_source,
9000 .unsol_event = alc883_haier_w66_unsol_event, 9370 .unsol_event = alc_automute_amp_unsol_event,
9001 .init_hook = alc883_haier_w66_automute, 9371 .init_hook = alc883_haier_w66_init_hook,
9002 }, 9372 },
9003 [ALC888_3ST_HP] = { 9373 [ALC888_3ST_HP] = {
9004 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, 9374 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
@@ -9009,8 +9379,8 @@ static struct alc_config_preset alc883_presets[] = {
9009 .channel_mode = alc888_3st_hp_modes, 9379 .channel_mode = alc888_3st_hp_modes,
9010 .need_dac_fix = 1, 9380 .need_dac_fix = 1,
9011 .input_mux = &alc883_capture_source, 9381 .input_mux = &alc883_capture_source,
9012 .unsol_event = alc888_3st_hp_unsol_event, 9382 .unsol_event = alc_automute_amp_unsol_event,
9013 .init_hook = alc888_3st_hp_front_automute, 9383 .init_hook = alc888_3st_hp_init_hook,
9014 }, 9384 },
9015 [ALC888_6ST_DELL] = { 9385 [ALC888_6ST_DELL] = {
9016 .mixers = { alc883_base_mixer, alc883_chmode_mixer }, 9386 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
@@ -9022,8 +9392,8 @@ static struct alc_config_preset alc883_presets[] = {
9022 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), 9392 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9023 .channel_mode = alc883_sixstack_modes, 9393 .channel_mode = alc883_sixstack_modes,
9024 .input_mux = &alc883_capture_source, 9394 .input_mux = &alc883_capture_source,
9025 .unsol_event = alc888_6st_dell_unsol_event, 9395 .unsol_event = alc_automute_amp_unsol_event,
9026 .init_hook = alc888_6st_dell_front_automute, 9396 .init_hook = alc888_6st_dell_init_hook,
9027 }, 9397 },
9028 [ALC883_MITAC] = { 9398 [ALC883_MITAC] = {
9029 .mixers = { alc883_mitac_mixer }, 9399 .mixers = { alc883_mitac_mixer },
@@ -9033,8 +9403,8 @@ static struct alc_config_preset alc883_presets[] = {
9033 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 9403 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9034 .channel_mode = alc883_3ST_2ch_modes, 9404 .channel_mode = alc883_3ST_2ch_modes,
9035 .input_mux = &alc883_capture_source, 9405 .input_mux = &alc883_capture_source,
9036 .unsol_event = alc883_mitac_unsol_event, 9406 .unsol_event = alc_automute_amp_unsol_event,
9037 .init_hook = alc883_mitac_automute, 9407 .init_hook = alc883_mitac_init_hook,
9038 }, 9408 },
9039 [ALC883_FUJITSU_PI2515] = { 9409 [ALC883_FUJITSU_PI2515] = {
9040 .mixers = { alc883_2ch_fujitsu_pi2515_mixer }, 9410 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
@@ -9046,8 +9416,8 @@ static struct alc_config_preset alc883_presets[] = {
9046 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 9416 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9047 .channel_mode = alc883_3ST_2ch_modes, 9417 .channel_mode = alc883_3ST_2ch_modes,
9048 .input_mux = &alc883_fujitsu_pi2515_capture_source, 9418 .input_mux = &alc883_fujitsu_pi2515_capture_source,
9049 .unsol_event = alc883_2ch_fujitsu_pi2515_unsol_event, 9419 .unsol_event = alc_automute_amp_unsol_event,
9050 .init_hook = alc883_2ch_fujitsu_pi2515_automute, 9420 .init_hook = alc883_2ch_fujitsu_pi2515_init_hook,
9051 }, 9421 },
9052 [ALC888_FUJITSU_XA3530] = { 9422 [ALC888_FUJITSU_XA3530] = {
9053 .mixers = { alc888_base_mixer, alc883_chmode_mixer }, 9423 .mixers = { alc888_base_mixer, alc883_chmode_mixer },
@@ -9064,8 +9434,8 @@ static struct alc_config_preset alc883_presets[] = {
9064 .num_mux_defs = 9434 .num_mux_defs =
9065 ARRAY_SIZE(alc888_2_capture_sources), 9435 ARRAY_SIZE(alc888_2_capture_sources),
9066 .input_mux = alc888_2_capture_sources, 9436 .input_mux = alc888_2_capture_sources,
9067 .unsol_event = alc888_fujitsu_xa3530_unsol_event, 9437 .unsol_event = alc_automute_amp_unsol_event,
9068 .init_hook = alc888_fujitsu_xa3530_automute, 9438 .init_hook = alc888_fujitsu_xa3530_init_hook,
9069 }, 9439 },
9070 [ALC888_LENOVO_SKY] = { 9440 [ALC888_LENOVO_SKY] = {
9071 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer }, 9441 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
@@ -9077,8 +9447,8 @@ static struct alc_config_preset alc883_presets[] = {
9077 .channel_mode = alc883_sixstack_modes, 9447 .channel_mode = alc883_sixstack_modes,
9078 .need_dac_fix = 1, 9448 .need_dac_fix = 1,
9079 .input_mux = &alc883_lenovo_sky_capture_source, 9449 .input_mux = &alc883_lenovo_sky_capture_source,
9080 .unsol_event = alc883_lenovo_sky_unsol_event, 9450 .unsol_event = alc_automute_amp_unsol_event,
9081 .init_hook = alc888_lenovo_sky_front_automute, 9451 .init_hook = alc888_lenovo_sky_init_hook,
9082 }, 9452 },
9083 [ALC888_ASUS_M90V] = { 9453 [ALC888_ASUS_M90V] = {
9084 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, 9454 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
@@ -9106,7 +9476,7 @@ static struct alc_config_preset alc883_presets[] = {
9106 .channel_mode = alc883_3ST_2ch_modes, 9476 .channel_mode = alc883_3ST_2ch_modes,
9107 .need_dac_fix = 1, 9477 .need_dac_fix = 1,
9108 .input_mux = &alc883_asus_eee1601_capture_source, 9478 .input_mux = &alc883_asus_eee1601_capture_source,
9109 .unsol_event = alc883_eee1601_unsol_event, 9479 .unsol_event = alc_sku_unsol_event,
9110 .init_hook = alc883_eee1601_inithook, 9480 .init_hook = alc883_eee1601_inithook,
9111 }, 9481 },
9112 [ALC1200_ASUS_P5Q] = { 9482 [ALC1200_ASUS_P5Q] = {
@@ -9121,6 +9491,32 @@ static struct alc_config_preset alc883_presets[] = {
9121 .channel_mode = alc883_sixstack_modes, 9491 .channel_mode = alc883_sixstack_modes,
9122 .input_mux = &alc883_capture_source, 9492 .input_mux = &alc883_capture_source,
9123 }, 9493 },
9494 [ALC889A_MB31] = {
9495 .mixers = { alc889A_mb31_mixer, alc883_chmode_mixer},
9496 .init_verbs = { alc883_init_verbs, alc889A_mb31_verbs,
9497 alc880_gpio1_init_verbs },
9498 .adc_nids = alc883_adc_nids,
9499 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
9500 .dac_nids = alc883_dac_nids,
9501 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9502 .channel_mode = alc889A_mb31_6ch_modes,
9503 .num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes),
9504 .input_mux = &alc889A_mb31_capture_source,
9505 .dig_out_nid = ALC883_DIGOUT_NID,
9506 .unsol_event = alc889A_mb31_unsol_event,
9507 .init_hook = alc889A_mb31_automute,
9508 },
9509 [ALC883_SONY_VAIO_TT] = {
9510 .mixers = { alc883_vaiott_mixer },
9511 .init_verbs = { alc883_init_verbs, alc883_vaiott_verbs },
9512 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9513 .dac_nids = alc883_dac_nids,
9514 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9515 .channel_mode = alc883_3ST_2ch_modes,
9516 .input_mux = &alc883_capture_source,
9517 .unsol_event = alc_automute_amp_unsol_event,
9518 .init_hook = alc883_vaiott_init_hook,
9519 },
9124}; 9520};
9125 9521
9126 9522
@@ -9149,7 +9545,6 @@ static void alc883_auto_init_multi_out(struct hda_codec *codec)
9149 struct alc_spec *spec = codec->spec; 9545 struct alc_spec *spec = codec->spec;
9150 int i; 9546 int i;
9151 9547
9152 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
9153 for (i = 0; i <= HDA_SIDE; i++) { 9548 for (i = 0; i <= HDA_SIDE; i++) {
9154 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 9549 hda_nid_t nid = spec->autocfg.line_out_pins[i];
9155 int pin_type = get_pin_type(spec->autocfg.line_out_type); 9550 int pin_type = get_pin_type(spec->autocfg.line_out_type);
@@ -9267,10 +9662,18 @@ static int patch_alc883(struct hda_codec *codec)
9267 board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST, 9662 board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST,
9268 alc883_models, 9663 alc883_models,
9269 alc883_cfg_tbl); 9664 alc883_cfg_tbl);
9270 if (board_config < 0) { 9665 if (board_config < 0 || board_config >= ALC883_MODEL_LAST) {
9271 printk(KERN_INFO "hda_codec: Unknown model for ALC883, " 9666 /* Pick up systems that don't supply PCI SSID */
9272 "trying auto-probe from BIOS...\n"); 9667 switch (codec->subsystem_id) {
9273 board_config = ALC883_AUTO; 9668 case 0x106b3600: /* Macbook 3.1 */
9669 board_config = ALC889A_MB31;
9670 break;
9671 default:
9672 printk(KERN_INFO
9673 "hda_codec: Unknown model for %s, trying "
9674 "auto-probe from BIOS...\n", codec->chip_name);
9675 board_config = ALC883_AUTO;
9676 }
9274 } 9677 }
9275 9678
9276 if (board_config == ALC883_AUTO) { 9679 if (board_config == ALC883_AUTO) {
@@ -9298,13 +9701,6 @@ static int patch_alc883(struct hda_codec *codec)
9298 9701
9299 switch (codec->vendor_id) { 9702 switch (codec->vendor_id) {
9300 case 0x10ec0888: 9703 case 0x10ec0888:
9301 if (codec->revision_id == 0x100101) {
9302 spec->stream_name_analog = "ALC1200 Analog";
9303 spec->stream_name_digital = "ALC1200 Digital";
9304 } else {
9305 spec->stream_name_analog = "ALC888 Analog";
9306 spec->stream_name_digital = "ALC888 Digital";
9307 }
9308 if (!spec->num_adc_nids) { 9704 if (!spec->num_adc_nids) {
9309 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids); 9705 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
9310 spec->adc_nids = alc883_adc_nids; 9706 spec->adc_nids = alc883_adc_nids;
@@ -9312,10 +9708,9 @@ static int patch_alc883(struct hda_codec *codec)
9312 if (!spec->capsrc_nids) 9708 if (!spec->capsrc_nids)
9313 spec->capsrc_nids = alc883_capsrc_nids; 9709 spec->capsrc_nids = alc883_capsrc_nids;
9314 spec->capture_style = CAPT_MIX; /* matrix-style capture */ 9710 spec->capture_style = CAPT_MIX; /* matrix-style capture */
9711 spec->init_amp = ALC_INIT_DEFAULT; /* always initialize */
9315 break; 9712 break;
9316 case 0x10ec0889: 9713 case 0x10ec0889:
9317 spec->stream_name_analog = "ALC889 Analog";
9318 spec->stream_name_digital = "ALC889 Digital";
9319 if (!spec->num_adc_nids) { 9714 if (!spec->num_adc_nids) {
9320 spec->num_adc_nids = ARRAY_SIZE(alc889_adc_nids); 9715 spec->num_adc_nids = ARRAY_SIZE(alc889_adc_nids);
9321 spec->adc_nids = alc889_adc_nids; 9716 spec->adc_nids = alc889_adc_nids;
@@ -9326,8 +9721,6 @@ static int patch_alc883(struct hda_codec *codec)
9326 capture */ 9721 capture */
9327 break; 9722 break;
9328 default: 9723 default:
9329 spec->stream_name_analog = "ALC883 Analog";
9330 spec->stream_name_digital = "ALC883 Digital";
9331 if (!spec->num_adc_nids) { 9724 if (!spec->num_adc_nids) {
9332 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids); 9725 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
9333 spec->adc_nids = alc883_adc_nids; 9726 spec->adc_nids = alc883_adc_nids;
@@ -9407,24 +9800,6 @@ static struct snd_kcontrol_new alc262_base_mixer[] = {
9407 { } /* end */ 9800 { } /* end */
9408}; 9801};
9409 9802
9410static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
9411 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9412 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9413 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9414 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9415 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9416 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9417 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9418 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9419 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9420 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9421 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9422 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9423 /*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/
9424 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9425 { } /* end */
9426};
9427
9428/* update HP, line and mono-out pins according to the master switch */ 9803/* update HP, line and mono-out pins according to the master switch */
9429static void alc262_hp_master_update(struct hda_codec *codec) 9804static void alc262_hp_master_update(struct hda_codec *codec)
9430{ 9805{
@@ -9480,14 +9855,7 @@ static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
9480 alc262_hp_wildwest_automute(codec); 9855 alc262_hp_wildwest_automute(codec);
9481} 9856}
9482 9857
9483static int alc262_hp_master_sw_get(struct snd_kcontrol *kcontrol, 9858#define alc262_hp_master_sw_get alc260_hp_master_sw_get
9484 struct snd_ctl_elem_value *ucontrol)
9485{
9486 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9487 struct alc_spec *spec = codec->spec;
9488 *ucontrol->value.integer.value = spec->master_sw;
9489 return 0;
9490}
9491 9859
9492static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol, 9860static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
9493 struct snd_ctl_elem_value *ucontrol) 9861 struct snd_ctl_elem_value *ucontrol)
@@ -9503,14 +9871,17 @@ static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
9503 return 1; 9871 return 1;
9504} 9872}
9505 9873
9874#define ALC262_HP_MASTER_SWITCH \
9875 { \
9876 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
9877 .name = "Master Playback Switch", \
9878 .info = snd_ctl_boolean_mono_info, \
9879 .get = alc262_hp_master_sw_get, \
9880 .put = alc262_hp_master_sw_put, \
9881 }
9882
9506static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = { 9883static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
9507 { 9884 ALC262_HP_MASTER_SWITCH,
9508 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9509 .name = "Master Playback Switch",
9510 .info = snd_ctl_boolean_mono_info,
9511 .get = alc262_hp_master_sw_get,
9512 .put = alc262_hp_master_sw_put,
9513 },
9514 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9885 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9515 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT), 9886 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9516 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 9887 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
@@ -9534,13 +9905,7 @@ static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
9534}; 9905};
9535 9906
9536static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = { 9907static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
9537 { 9908 ALC262_HP_MASTER_SWITCH,
9538 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9539 .name = "Master Playback Switch",
9540 .info = snd_ctl_boolean_mono_info,
9541 .get = alc262_hp_master_sw_get,
9542 .put = alc262_hp_master_sw_put,
9543 },
9544 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9909 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9545 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 9910 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9546 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 9911 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
@@ -9567,32 +9932,13 @@ static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
9567}; 9932};
9568 9933
9569/* mute/unmute internal speaker according to the hp jack and mute state */ 9934/* mute/unmute internal speaker according to the hp jack and mute state */
9570static void alc262_hp_t5735_automute(struct hda_codec *codec, int force) 9935static void alc262_hp_t5735_init_hook(struct hda_codec *codec)
9571{ 9936{
9572 struct alc_spec *spec = codec->spec; 9937 struct alc_spec *spec = codec->spec;
9573 9938
9574 if (force || !spec->sense_updated) { 9939 spec->autocfg.hp_pins[0] = 0x15;
9575 unsigned int present; 9940 spec->autocfg.speaker_pins[0] = 0x0c; /* HACK: not actually a pin */
9576 present = snd_hda_codec_read(codec, 0x15, 0, 9941 alc_automute_amp(codec);
9577 AC_VERB_GET_PIN_SENSE, 0);
9578 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
9579 spec->sense_updated = 1;
9580 }
9581 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0, HDA_AMP_MUTE,
9582 spec->jack_present ? HDA_AMP_MUTE : 0);
9583}
9584
9585static void alc262_hp_t5735_unsol_event(struct hda_codec *codec,
9586 unsigned int res)
9587{
9588 if ((res >> 26) != ALC880_HP_EVENT)
9589 return;
9590 alc262_hp_t5735_automute(codec, 1);
9591}
9592
9593static void alc262_hp_t5735_init_hook(struct hda_codec *codec)
9594{
9595 alc262_hp_t5735_automute(codec, 1);
9596} 9942}
9597 9943
9598static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = { 9944static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
@@ -9645,46 +9991,132 @@ static struct hda_input_mux alc262_hp_rp5700_capture_source = {
9645 }, 9991 },
9646}; 9992};
9647 9993
9648/* bind hp and internal speaker mute (with plug check) */ 9994/* bind hp and internal speaker mute (with plug check) as master switch */
9649static int alc262_sony_master_sw_put(struct snd_kcontrol *kcontrol, 9995static void alc262_hippo_master_update(struct hda_codec *codec)
9650 struct snd_ctl_elem_value *ucontrol)
9651{ 9996{
9652 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 9997 struct alc_spec *spec = codec->spec;
9653 long *valp = ucontrol->value.integer.value; 9998 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
9654 int change; 9999 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
10000 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
10001 unsigned int mute;
9655 10002
9656 /* change hp mute */ 10003 /* HP */
9657 change = snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0, 10004 mute = spec->master_sw ? 0 : HDA_AMP_MUTE;
9658 HDA_AMP_MUTE, 10005 snd_hda_codec_amp_stereo(codec, hp_nid, HDA_OUTPUT, 0,
9659 valp[0] ? 0 : HDA_AMP_MUTE); 10006 HDA_AMP_MUTE, mute);
9660 change |= snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0, 10007 /* mute internal speaker per jack sense */
9661 HDA_AMP_MUTE, 10008 if (spec->jack_present)
9662 valp[1] ? 0 : HDA_AMP_MUTE); 10009 mute = HDA_AMP_MUTE;
9663 if (change) { 10010 if (line_nid)
9664 /* change speaker according to HP jack state */ 10011 snd_hda_codec_amp_stereo(codec, line_nid, HDA_OUTPUT, 0,
9665 struct alc_spec *spec = codec->spec;
9666 unsigned int mute;
9667 if (spec->jack_present)
9668 mute = HDA_AMP_MUTE;
9669 else
9670 mute = snd_hda_codec_amp_read(codec, 0x15, 0,
9671 HDA_OUTPUT, 0);
9672 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9673 HDA_AMP_MUTE, mute); 10012 HDA_AMP_MUTE, mute);
10013 if (speaker_nid && speaker_nid != line_nid)
10014 snd_hda_codec_amp_stereo(codec, speaker_nid, HDA_OUTPUT, 0,
10015 HDA_AMP_MUTE, mute);
10016}
10017
10018#define alc262_hippo_master_sw_get alc262_hp_master_sw_get
10019
10020static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol,
10021 struct snd_ctl_elem_value *ucontrol)
10022{
10023 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10024 struct alc_spec *spec = codec->spec;
10025 int val = !!*ucontrol->value.integer.value;
10026
10027 if (val == spec->master_sw)
10028 return 0;
10029 spec->master_sw = val;
10030 alc262_hippo_master_update(codec);
10031 return 1;
10032}
10033
10034#define ALC262_HIPPO_MASTER_SWITCH \
10035 { \
10036 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
10037 .name = "Master Playback Switch", \
10038 .info = snd_ctl_boolean_mono_info, \
10039 .get = alc262_hippo_master_sw_get, \
10040 .put = alc262_hippo_master_sw_put, \
9674 } 10041 }
9675 return change; 10042
10043static struct snd_kcontrol_new alc262_hippo_mixer[] = {
10044 ALC262_HIPPO_MASTER_SWITCH,
10045 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10046 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10047 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10048 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10049 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10050 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10051 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10052 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10053 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10054 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10055 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10056 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
10057 { } /* end */
10058};
10059
10060static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
10061 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10062 ALC262_HIPPO_MASTER_SWITCH,
10063 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10064 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10065 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10066 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10067 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10068 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10069 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10070 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10071 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10072 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10073 { } /* end */
10074};
10075
10076/* mute/unmute internal speaker according to the hp jack and mute state */
10077static void alc262_hippo_automute(struct hda_codec *codec)
10078{
10079 struct alc_spec *spec = codec->spec;
10080 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
10081 unsigned int present;
10082
10083 /* need to execute and sync at first */
10084 snd_hda_codec_read(codec, hp_nid, 0, AC_VERB_SET_PIN_SENSE, 0);
10085 present = snd_hda_codec_read(codec, hp_nid, 0,
10086 AC_VERB_GET_PIN_SENSE, 0);
10087 spec->jack_present = (present & 0x80000000) != 0;
10088 alc262_hippo_master_update(codec);
10089}
10090
10091static void alc262_hippo_unsol_event(struct hda_codec *codec, unsigned int res)
10092{
10093 if ((res >> 26) != ALC880_HP_EVENT)
10094 return;
10095 alc262_hippo_automute(codec);
10096}
10097
10098static void alc262_hippo_init_hook(struct hda_codec *codec)
10099{
10100 struct alc_spec *spec = codec->spec;
10101
10102 spec->autocfg.hp_pins[0] = 0x15;
10103 spec->autocfg.speaker_pins[0] = 0x14;
10104 alc262_hippo_automute(codec);
10105}
10106
10107static void alc262_hippo1_init_hook(struct hda_codec *codec)
10108{
10109 struct alc_spec *spec = codec->spec;
10110
10111 spec->autocfg.hp_pins[0] = 0x1b;
10112 spec->autocfg.speaker_pins[0] = 0x14;
10113 alc262_hippo_automute(codec);
9676} 10114}
9677 10115
10116
9678static struct snd_kcontrol_new alc262_sony_mixer[] = { 10117static struct snd_kcontrol_new alc262_sony_mixer[] = {
9679 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 10118 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9680 { 10119 ALC262_HIPPO_MASTER_SWITCH,
9681 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9682 .name = "Master Playback Switch",
9683 .info = snd_hda_mixer_amp_switch_info,
9684 .get = snd_hda_mixer_amp_switch_get,
9685 .put = alc262_sony_master_sw_put,
9686 .private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
9687 },
9688 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 10120 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9689 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 10121 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9690 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 10122 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
@@ -9693,8 +10125,8 @@ static struct snd_kcontrol_new alc262_sony_mixer[] = {
9693}; 10125};
9694 10126
9695static struct snd_kcontrol_new alc262_benq_t31_mixer[] = { 10127static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
9696 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 10128 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9697 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 10129 ALC262_HIPPO_MASTER_SWITCH,
9698 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 10130 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9699 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 10131 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9700 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 10132 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
@@ -9735,34 +10167,15 @@ static struct hda_verb alc262_tyan_verbs[] = {
9735}; 10167};
9736 10168
9737/* unsolicited event for HP jack sensing */ 10169/* unsolicited event for HP jack sensing */
9738static void alc262_tyan_automute(struct hda_codec *codec) 10170static void alc262_tyan_init_hook(struct hda_codec *codec)
9739{ 10171{
9740 unsigned int mute; 10172 struct alc_spec *spec = codec->spec;
9741 unsigned int present;
9742 10173
9743 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0); 10174 spec->autocfg.hp_pins[0] = 0x1b;
9744 present = snd_hda_codec_read(codec, 0x1b, 0, 10175 spec->autocfg.speaker_pins[0] = 0x15;
9745 AC_VERB_GET_PIN_SENSE, 0); 10176 alc_automute_amp(codec);
9746 present = (present & 0x80000000) != 0;
9747 if (present) {
9748 /* mute line output on ATX panel */
9749 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9750 HDA_AMP_MUTE, HDA_AMP_MUTE);
9751 } else {
9752 /* unmute line output if necessary */
9753 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
9754 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9755 HDA_AMP_MUTE, mute);
9756 }
9757} 10177}
9758 10178
9759static void alc262_tyan_unsol_event(struct hda_codec *codec,
9760 unsigned int res)
9761{
9762 if ((res >> 26) != ALC880_HP_EVENT)
9763 return;
9764 alc262_tyan_automute(codec);
9765}
9766 10179
9767#define alc262_capture_mixer alc882_capture_mixer 10180#define alc262_capture_mixer alc882_capture_mixer
9768#define alc262_capture_alt_mixer alc882_capture_alt_mixer 10181#define alc262_capture_alt_mixer alc882_capture_alt_mixer
@@ -9917,99 +10330,25 @@ static void alc262_dmic_automute(struct hda_codec *codec)
9917 AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x09); 10330 AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x09);
9918} 10331}
9919 10332
9920/* toggle speaker-output according to the hp-jack state */
9921static void alc262_toshiba_s06_speaker_automute(struct hda_codec *codec)
9922{
9923 unsigned int present;
9924 unsigned char bits;
9925
9926 present = snd_hda_codec_read(codec, 0x15, 0,
9927 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
9928 bits = present ? 0 : PIN_OUT;
9929 snd_hda_codec_write(codec, 0x14, 0,
9930 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
9931}
9932
9933
9934 10333
9935/* unsolicited event for HP jack sensing */ 10334/* unsolicited event for HP jack sensing */
9936static void alc262_toshiba_s06_unsol_event(struct hda_codec *codec, 10335static void alc262_toshiba_s06_unsol_event(struct hda_codec *codec,
9937 unsigned int res) 10336 unsigned int res)
9938{ 10337{
9939 if ((res >> 26) == ALC880_HP_EVENT)
9940 alc262_toshiba_s06_speaker_automute(codec);
9941 if ((res >> 26) == ALC880_MIC_EVENT) 10338 if ((res >> 26) == ALC880_MIC_EVENT)
9942 alc262_dmic_automute(codec); 10339 alc262_dmic_automute(codec);
9943 10340 else
10341 alc_sku_unsol_event(codec, res);
9944} 10342}
9945 10343
9946static void alc262_toshiba_s06_init_hook(struct hda_codec *codec) 10344static void alc262_toshiba_s06_init_hook(struct hda_codec *codec)
9947{ 10345{
9948 alc262_toshiba_s06_speaker_automute(codec);
9949 alc262_dmic_automute(codec);
9950}
9951
9952/* mute/unmute internal speaker according to the hp jack and mute state */
9953static void alc262_hippo_automute(struct hda_codec *codec)
9954{
9955 struct alc_spec *spec = codec->spec; 10346 struct alc_spec *spec = codec->spec;
9956 unsigned int mute;
9957 unsigned int present;
9958
9959 /* need to execute and sync at first */
9960 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
9961 present = snd_hda_codec_read(codec, 0x15, 0,
9962 AC_VERB_GET_PIN_SENSE, 0);
9963 spec->jack_present = (present & 0x80000000) != 0;
9964 if (spec->jack_present) {
9965 /* mute internal speaker */
9966 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9967 HDA_AMP_MUTE, HDA_AMP_MUTE);
9968 } else {
9969 /* unmute internal speaker if necessary */
9970 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
9971 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9972 HDA_AMP_MUTE, mute);
9973 }
9974}
9975
9976/* unsolicited event for HP jack sensing */
9977static void alc262_hippo_unsol_event(struct hda_codec *codec,
9978 unsigned int res)
9979{
9980 if ((res >> 26) != ALC880_HP_EVENT)
9981 return;
9982 alc262_hippo_automute(codec);
9983}
9984
9985static void alc262_hippo1_automute(struct hda_codec *codec)
9986{
9987 unsigned int mute;
9988 unsigned int present;
9989 10347
9990 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0); 10348 spec->autocfg.hp_pins[0] = 0x15;
9991 present = snd_hda_codec_read(codec, 0x1b, 0, 10349 spec->autocfg.speaker_pins[0] = 0x14;
9992 AC_VERB_GET_PIN_SENSE, 0); 10350 alc_automute_pin(codec);
9993 present = (present & 0x80000000) != 0; 10351 alc262_dmic_automute(codec);
9994 if (present) {
9995 /* mute internal speaker */
9996 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9997 HDA_AMP_MUTE, HDA_AMP_MUTE);
9998 } else {
9999 /* unmute internal speaker if necessary */
10000 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
10001 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10002 HDA_AMP_MUTE, mute);
10003 }
10004}
10005
10006/* unsolicited event for HP jack sensing */
10007static void alc262_hippo1_unsol_event(struct hda_codec *codec,
10008 unsigned int res)
10009{
10010 if ((res >> 26) != ALC880_HP_EVENT)
10011 return;
10012 alc262_hippo1_automute(codec);
10013} 10352}
10014 10353
10015/* 10354/*
@@ -10279,14 +10618,7 @@ static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
10279 10618
10280static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = { 10619static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
10281 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol), 10620 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
10282 { 10621 ALC262_HIPPO_MASTER_SWITCH,
10283 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10284 .name = "Master Playback Switch",
10285 .info = snd_hda_mixer_amp_switch_info,
10286 .get = snd_hda_mixer_amp_switch_get,
10287 .put = alc262_sony_master_sw_put,
10288 .private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
10289 },
10290 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 10622 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10291 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 10623 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10292 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 10624 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
@@ -10633,31 +10965,46 @@ static struct hda_verb alc262_HP_BPC_init_verbs[] = {
10633 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 10965 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10634 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 10966 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10635 10967
10636 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, 10968 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10637 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 10969 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10638 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 10970 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10639 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, 10971 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10640 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 10972 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10641 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 10973 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10642 10974
10643 10975
10644 /* FIXME: use matrix-type input source selection */ 10976 /* FIXME: use matrix-type input source selection */
10645 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 10977 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 0b, 12 */
10646 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 10978 /* Input mixer1: only unmute Mic */
10647 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 10979 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10648 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, 10980 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
10649 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, 10981 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10650 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, 10982 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10983 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10984 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
10985 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
10986 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
10987 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
10651 /* Input mixer2 */ 10988 /* Input mixer2 */
10652 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 10989 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10653 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, 10990 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
10654 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, 10991 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10655 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, 10992 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10993 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10994 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
10995 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
10996 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
10997 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
10656 /* Input mixer3 */ 10998 /* Input mixer3 */
10657 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 10999 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10658 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, 11000 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
10659 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, 11001 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10660 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, 11002 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11003 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11004 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
11005 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
11006 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
11007 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
10661 11008
10662 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 11009 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10663 11010
@@ -10837,6 +11184,8 @@ static int alc262_parse_auto_config(struct hda_codec *codec)
10837 if (err < 0) 11184 if (err < 0)
10838 return err; 11185 return err;
10839 11186
11187 alc_ssid_check(codec, 0x15, 0x14, 0x1b);
11188
10840 return 1; 11189 return 1;
10841} 11190}
10842 11191
@@ -10939,7 +11288,7 @@ static struct alc_config_preset alc262_presets[] = {
10939 .input_mux = &alc262_capture_source, 11288 .input_mux = &alc262_capture_source,
10940 }, 11289 },
10941 [ALC262_HIPPO] = { 11290 [ALC262_HIPPO] = {
10942 .mixers = { alc262_base_mixer }, 11291 .mixers = { alc262_hippo_mixer },
10943 .init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs}, 11292 .init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs},
10944 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 11293 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10945 .dac_nids = alc262_dac_nids, 11294 .dac_nids = alc262_dac_nids,
@@ -10949,7 +11298,7 @@ static struct alc_config_preset alc262_presets[] = {
10949 .channel_mode = alc262_modes, 11298 .channel_mode = alc262_modes,
10950 .input_mux = &alc262_capture_source, 11299 .input_mux = &alc262_capture_source,
10951 .unsol_event = alc262_hippo_unsol_event, 11300 .unsol_event = alc262_hippo_unsol_event,
10952 .init_hook = alc262_hippo_automute, 11301 .init_hook = alc262_hippo_init_hook,
10953 }, 11302 },
10954 [ALC262_HIPPO_1] = { 11303 [ALC262_HIPPO_1] = {
10955 .mixers = { alc262_hippo1_mixer }, 11304 .mixers = { alc262_hippo1_mixer },
@@ -10961,8 +11310,8 @@ static struct alc_config_preset alc262_presets[] = {
10961 .num_channel_mode = ARRAY_SIZE(alc262_modes), 11310 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10962 .channel_mode = alc262_modes, 11311 .channel_mode = alc262_modes,
10963 .input_mux = &alc262_capture_source, 11312 .input_mux = &alc262_capture_source,
10964 .unsol_event = alc262_hippo1_unsol_event, 11313 .unsol_event = alc262_hippo_unsol_event,
10965 .init_hook = alc262_hippo1_automute, 11314 .init_hook = alc262_hippo1_init_hook,
10966 }, 11315 },
10967 [ALC262_FUJITSU] = { 11316 [ALC262_FUJITSU] = {
10968 .mixers = { alc262_fujitsu_mixer }, 11317 .mixers = { alc262_fujitsu_mixer },
@@ -11024,7 +11373,7 @@ static struct alc_config_preset alc262_presets[] = {
11024 .num_channel_mode = ARRAY_SIZE(alc262_modes), 11373 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11025 .channel_mode = alc262_modes, 11374 .channel_mode = alc262_modes,
11026 .input_mux = &alc262_capture_source, 11375 .input_mux = &alc262_capture_source,
11027 .unsol_event = alc262_hp_t5735_unsol_event, 11376 .unsol_event = alc_automute_amp_unsol_event,
11028 .init_hook = alc262_hp_t5735_init_hook, 11377 .init_hook = alc262_hp_t5735_init_hook,
11029 }, 11378 },
11030 [ALC262_HP_RP5700] = { 11379 [ALC262_HP_RP5700] = {
@@ -11056,7 +11405,7 @@ static struct alc_config_preset alc262_presets[] = {
11056 .channel_mode = alc262_modes, 11405 .channel_mode = alc262_modes,
11057 .input_mux = &alc262_capture_source, 11406 .input_mux = &alc262_capture_source,
11058 .unsol_event = alc262_hippo_unsol_event, 11407 .unsol_event = alc262_hippo_unsol_event,
11059 .init_hook = alc262_hippo_automute, 11408 .init_hook = alc262_hippo_init_hook,
11060 }, 11409 },
11061 [ALC262_BENQ_T31] = { 11410 [ALC262_BENQ_T31] = {
11062 .mixers = { alc262_benq_t31_mixer }, 11411 .mixers = { alc262_benq_t31_mixer },
@@ -11068,7 +11417,7 @@ static struct alc_config_preset alc262_presets[] = {
11068 .channel_mode = alc262_modes, 11417 .channel_mode = alc262_modes,
11069 .input_mux = &alc262_capture_source, 11418 .input_mux = &alc262_capture_source,
11070 .unsol_event = alc262_hippo_unsol_event, 11419 .unsol_event = alc262_hippo_unsol_event,
11071 .init_hook = alc262_hippo_automute, 11420 .init_hook = alc262_hippo_init_hook,
11072 }, 11421 },
11073 [ALC262_ULTRA] = { 11422 [ALC262_ULTRA] = {
11074 .mixers = { alc262_ultra_mixer }, 11423 .mixers = { alc262_ultra_mixer },
@@ -11133,7 +11482,7 @@ static struct alc_config_preset alc262_presets[] = {
11133 .channel_mode = alc262_modes, 11482 .channel_mode = alc262_modes,
11134 .input_mux = &alc262_capture_source, 11483 .input_mux = &alc262_capture_source,
11135 .unsol_event = alc262_hippo_unsol_event, 11484 .unsol_event = alc262_hippo_unsol_event,
11136 .init_hook = alc262_hippo_automute, 11485 .init_hook = alc262_hippo_init_hook,
11137 }, 11486 },
11138 [ALC262_TYAN] = { 11487 [ALC262_TYAN] = {
11139 .mixers = { alc262_tyan_mixer }, 11488 .mixers = { alc262_tyan_mixer },
@@ -11145,8 +11494,8 @@ static struct alc_config_preset alc262_presets[] = {
11145 .num_channel_mode = ARRAY_SIZE(alc262_modes), 11494 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11146 .channel_mode = alc262_modes, 11495 .channel_mode = alc262_modes,
11147 .input_mux = &alc262_capture_source, 11496 .input_mux = &alc262_capture_source,
11148 .unsol_event = alc262_tyan_unsol_event, 11497 .unsol_event = alc_automute_amp_unsol_event,
11149 .init_hook = alc262_tyan_automute, 11498 .init_hook = alc262_tyan_init_hook,
11150 }, 11499 },
11151}; 11500};
11152 11501
@@ -11181,8 +11530,8 @@ static int patch_alc262(struct hda_codec *codec)
11181 alc262_cfg_tbl); 11530 alc262_cfg_tbl);
11182 11531
11183 if (board_config < 0) { 11532 if (board_config < 0) {
11184 printk(KERN_INFO "hda_codec: Unknown model for ALC262, " 11533 printk(KERN_INFO "hda_codec: Unknown model for %s, "
11185 "trying auto-probe from BIOS...\n"); 11534 "trying auto-probe from BIOS...\n", codec->chip_name);
11186 board_config = ALC262_AUTO; 11535 board_config = ALC262_AUTO;
11187 } 11536 }
11188 11537
@@ -11211,11 +11560,9 @@ static int patch_alc262(struct hda_codec *codec)
11211 if (board_config != ALC262_AUTO) 11560 if (board_config != ALC262_AUTO)
11212 setup_preset(spec, &alc262_presets[board_config]); 11561 setup_preset(spec, &alc262_presets[board_config]);
11213 11562
11214 spec->stream_name_analog = "ALC262 Analog";
11215 spec->stream_analog_playback = &alc262_pcm_analog_playback; 11563 spec->stream_analog_playback = &alc262_pcm_analog_playback;
11216 spec->stream_analog_capture = &alc262_pcm_analog_capture; 11564 spec->stream_analog_capture = &alc262_pcm_analog_capture;
11217 11565
11218 spec->stream_name_digital = "ALC262 Digital";
11219 spec->stream_digital_playback = &alc262_pcm_digital_playback; 11566 spec->stream_digital_playback = &alc262_pcm_digital_playback;
11220 spec->stream_digital_capture = &alc262_pcm_digital_capture; 11567 spec->stream_digital_capture = &alc262_pcm_digital_capture;
11221 11568
@@ -11290,6 +11637,17 @@ static struct snd_kcontrol_new alc268_base_mixer[] = {
11290 { } 11637 { }
11291}; 11638};
11292 11639
11640static struct snd_kcontrol_new alc268_toshiba_mixer[] = {
11641 /* output mixer control */
11642 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
11643 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
11644 ALC262_HIPPO_MASTER_SWITCH,
11645 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11646 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11647 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
11648 { }
11649};
11650
11293/* bind Beep switches of both NID 0x0f and 0x10 */ 11651/* bind Beep switches of both NID 0x0f and 0x10 */
11294static struct hda_bind_ctls alc268_bind_beep_sw = { 11652static struct hda_bind_ctls alc268_bind_beep_sw = {
11295 .ops = &snd_hda_bind_sw, 11653 .ops = &snd_hda_bind_sw,
@@ -11313,8 +11671,6 @@ static struct hda_verb alc268_eapd_verbs[] = {
11313}; 11671};
11314 11672
11315/* Toshiba specific */ 11673/* Toshiba specific */
11316#define alc268_toshiba_automute alc262_hippo_automute
11317
11318static struct hda_verb alc268_toshiba_verbs[] = { 11674static struct hda_verb alc268_toshiba_verbs[] = {
11319 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 11675 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11320 { } /* end */ 11676 { } /* end */
@@ -11450,13 +11806,8 @@ static struct hda_verb alc268_acer_verbs[] = {
11450}; 11806};
11451 11807
11452/* unsolicited event for HP jack sensing */ 11808/* unsolicited event for HP jack sensing */
11453static void alc268_toshiba_unsol_event(struct hda_codec *codec, 11809#define alc268_toshiba_unsol_event alc262_hippo_unsol_event
11454 unsigned int res) 11810#define alc268_toshiba_init_hook alc262_hippo_init_hook
11455{
11456 if ((res >> 26) != ALC880_HP_EVENT)
11457 return;
11458 alc268_toshiba_automute(codec);
11459}
11460 11811
11461static void alc268_acer_unsol_event(struct hda_codec *codec, 11812static void alc268_acer_unsol_event(struct hda_codec *codec,
11462 unsigned int res) 11813 unsigned int res)
@@ -11531,30 +11882,15 @@ static struct hda_verb alc268_dell_verbs[] = {
11531}; 11882};
11532 11883
11533/* mute/unmute internal speaker according to the hp jack and mute state */ 11884/* mute/unmute internal speaker according to the hp jack and mute state */
11534static void alc268_dell_automute(struct hda_codec *codec) 11885static void alc268_dell_init_hook(struct hda_codec *codec)
11535{ 11886{
11536 unsigned int present; 11887 struct alc_spec *spec = codec->spec;
11537 unsigned int mute;
11538
11539 present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0);
11540 if (present & 0x80000000)
11541 mute = HDA_AMP_MUTE;
11542 else
11543 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
11544 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11545 HDA_AMP_MUTE, mute);
11546}
11547 11888
11548static void alc268_dell_unsol_event(struct hda_codec *codec, 11889 spec->autocfg.hp_pins[0] = 0x15;
11549 unsigned int res) 11890 spec->autocfg.speaker_pins[0] = 0x14;
11550{ 11891 alc_automute_pin(codec);
11551 if ((res >> 26) != ALC880_HP_EVENT)
11552 return;
11553 alc268_dell_automute(codec);
11554} 11892}
11555 11893
11556#define alc268_dell_init_hook alc268_dell_automute
11557
11558static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = { 11894static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
11559 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT), 11895 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
11560 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 11896 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
@@ -11573,16 +11909,6 @@ static struct hda_verb alc267_quanta_il1_verbs[] = {
11573 { } 11909 { }
11574}; 11910};
11575 11911
11576static void alc267_quanta_il1_hp_automute(struct hda_codec *codec)
11577{
11578 unsigned int present;
11579
11580 present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0)
11581 & AC_PINSENSE_PRESENCE;
11582 snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
11583 present ? 0 : PIN_OUT);
11584}
11585
11586static void alc267_quanta_il1_mic_automute(struct hda_codec *codec) 11912static void alc267_quanta_il1_mic_automute(struct hda_codec *codec)
11587{ 11913{
11588 unsigned int present; 11914 unsigned int present;
@@ -11594,9 +11920,13 @@ static void alc267_quanta_il1_mic_automute(struct hda_codec *codec)
11594 present ? 0x00 : 0x01); 11920 present ? 0x00 : 0x01);
11595} 11921}
11596 11922
11597static void alc267_quanta_il1_automute(struct hda_codec *codec) 11923static void alc267_quanta_il1_init_hook(struct hda_codec *codec)
11598{ 11924{
11599 alc267_quanta_il1_hp_automute(codec); 11925 struct alc_spec *spec = codec->spec;
11926
11927 spec->autocfg.hp_pins[0] = 0x15;
11928 spec->autocfg.speaker_pins[0] = 0x14;
11929 alc_automute_pin(codec);
11600 alc267_quanta_il1_mic_automute(codec); 11930 alc267_quanta_il1_mic_automute(codec);
11601} 11931}
11602 11932
@@ -11604,12 +11934,12 @@ static void alc267_quanta_il1_unsol_event(struct hda_codec *codec,
11604 unsigned int res) 11934 unsigned int res)
11605{ 11935{
11606 switch (res >> 26) { 11936 switch (res >> 26) {
11607 case ALC880_HP_EVENT:
11608 alc267_quanta_il1_hp_automute(codec);
11609 break;
11610 case ALC880_MIC_EVENT: 11937 case ALC880_MIC_EVENT:
11611 alc267_quanta_il1_mic_automute(codec); 11938 alc267_quanta_il1_mic_automute(codec);
11612 break; 11939 break;
11940 default:
11941 alc_sku_unsol_event(codec, res);
11942 break;
11613 } 11943 }
11614} 11944}
11615 11945
@@ -12057,15 +12387,16 @@ static struct snd_pci_quirk alc268_cfg_tbl[] = {
12057 ALC268_ACER_ASPIRE_ONE), 12387 ALC268_ACER_ASPIRE_ONE),
12058 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL), 12388 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
12059 SND_PCI_QUIRK(0x1028, 0x02b0, "Dell Inspiron Mini9", ALC268_DELL), 12389 SND_PCI_QUIRK(0x1028, 0x02b0, "Dell Inspiron Mini9", ALC268_DELL),
12060 SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA), 12390 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP TX25xx series",
12391 ALC268_TOSHIBA),
12061 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST), 12392 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
12062 SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA), 12393 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
12063 SND_PCI_QUIRK(0x1179, 0xff50, "TOSHIBA A305", ALC268_TOSHIBA), 12394 SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05",
12064 SND_PCI_QUIRK(0x1179, 0xff64, "TOSHIBA L305", ALC268_TOSHIBA), 12395 ALC268_TOSHIBA),
12065 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA), 12396 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
12066 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER), 12397 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
12067 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1), 12398 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
12068 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO), 12399 SND_PCI_QUIRK(0x1854, 0x1775, "LG R510", ALC268_DELL),
12069 {} 12400 {}
12070}; 12401};
12071 12402
@@ -12083,7 +12414,7 @@ static struct alc_config_preset alc268_presets[] = {
12083 .channel_mode = alc268_modes, 12414 .channel_mode = alc268_modes,
12084 .input_mux = &alc268_capture_source, 12415 .input_mux = &alc268_capture_source,
12085 .unsol_event = alc267_quanta_il1_unsol_event, 12416 .unsol_event = alc267_quanta_il1_unsol_event,
12086 .init_hook = alc267_quanta_il1_automute, 12417 .init_hook = alc267_quanta_il1_init_hook,
12087 }, 12418 },
12088 [ALC268_3ST] = { 12419 [ALC268_3ST] = {
12089 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer, 12420 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
@@ -12101,7 +12432,7 @@ static struct alc_config_preset alc268_presets[] = {
12101 .input_mux = &alc268_capture_source, 12432 .input_mux = &alc268_capture_source,
12102 }, 12433 },
12103 [ALC268_TOSHIBA] = { 12434 [ALC268_TOSHIBA] = {
12104 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer, 12435 .mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer,
12105 alc268_beep_mixer }, 12436 alc268_beep_mixer },
12106 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 12437 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12107 alc268_toshiba_verbs }, 12438 alc268_toshiba_verbs },
@@ -12115,7 +12446,7 @@ static struct alc_config_preset alc268_presets[] = {
12115 .channel_mode = alc268_modes, 12446 .channel_mode = alc268_modes,
12116 .input_mux = &alc268_capture_source, 12447 .input_mux = &alc268_capture_source,
12117 .unsol_event = alc268_toshiba_unsol_event, 12448 .unsol_event = alc268_toshiba_unsol_event,
12118 .init_hook = alc268_toshiba_automute, 12449 .init_hook = alc268_toshiba_init_hook,
12119 }, 12450 },
12120 [ALC268_ACER] = { 12451 [ALC268_ACER] = {
12121 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer, 12452 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
@@ -12178,7 +12509,7 @@ static struct alc_config_preset alc268_presets[] = {
12178 .hp_nid = 0x02, 12509 .hp_nid = 0x02,
12179 .num_channel_mode = ARRAY_SIZE(alc268_modes), 12510 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12180 .channel_mode = alc268_modes, 12511 .channel_mode = alc268_modes,
12181 .unsol_event = alc268_dell_unsol_event, 12512 .unsol_event = alc_sku_unsol_event,
12182 .init_hook = alc268_dell_init_hook, 12513 .init_hook = alc268_dell_init_hook,
12183 .input_mux = &alc268_capture_source, 12514 .input_mux = &alc268_capture_source,
12184 }, 12515 },
@@ -12198,7 +12529,7 @@ static struct alc_config_preset alc268_presets[] = {
12198 .channel_mode = alc268_modes, 12529 .channel_mode = alc268_modes,
12199 .input_mux = &alc268_capture_source, 12530 .input_mux = &alc268_capture_source,
12200 .unsol_event = alc268_toshiba_unsol_event, 12531 .unsol_event = alc268_toshiba_unsol_event,
12201 .init_hook = alc268_toshiba_automute 12532 .init_hook = alc268_toshiba_init_hook
12202 }, 12533 },
12203#ifdef CONFIG_SND_DEBUG 12534#ifdef CONFIG_SND_DEBUG
12204 [ALC268_TEST] = { 12535 [ALC268_TEST] = {
@@ -12236,8 +12567,8 @@ static int patch_alc268(struct hda_codec *codec)
12236 alc268_cfg_tbl); 12567 alc268_cfg_tbl);
12237 12568
12238 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) { 12569 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
12239 printk(KERN_INFO "hda_codec: Unknown model for ALC268, " 12570 printk(KERN_INFO "hda_codec: Unknown model for %s, "
12240 "trying auto-probe from BIOS...\n"); 12571 "trying auto-probe from BIOS...\n", codec->chip_name);
12241 board_config = ALC268_AUTO; 12572 board_config = ALC268_AUTO;
12242 } 12573 }
12243 12574
@@ -12258,14 +12589,6 @@ static int patch_alc268(struct hda_codec *codec)
12258 if (board_config != ALC268_AUTO) 12589 if (board_config != ALC268_AUTO)
12259 setup_preset(spec, &alc268_presets[board_config]); 12590 setup_preset(spec, &alc268_presets[board_config]);
12260 12591
12261 if (codec->vendor_id == 0x10ec0267) {
12262 spec->stream_name_analog = "ALC267 Analog";
12263 spec->stream_name_digital = "ALC267 Digital";
12264 } else {
12265 spec->stream_name_analog = "ALC268 Analog";
12266 spec->stream_name_digital = "ALC268 Digital";
12267 }
12268
12269 spec->stream_analog_playback = &alc268_pcm_analog_playback; 12592 spec->stream_analog_playback = &alc268_pcm_analog_playback;
12270 spec->stream_analog_capture = &alc268_pcm_analog_capture; 12593 spec->stream_analog_capture = &alc268_pcm_analog_capture;
12271 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture; 12594 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
@@ -13092,8 +13415,8 @@ static int patch_alc269(struct hda_codec *codec)
13092 alc269_cfg_tbl); 13415 alc269_cfg_tbl);
13093 13416
13094 if (board_config < 0) { 13417 if (board_config < 0) {
13095 printk(KERN_INFO "hda_codec: Unknown model for ALC269, " 13418 printk(KERN_INFO "hda_codec: Unknown model for %s, "
13096 "trying auto-probe from BIOS...\n"); 13419 "trying auto-probe from BIOS...\n", codec->chip_name);
13097 board_config = ALC269_AUTO; 13420 board_config = ALC269_AUTO;
13098 } 13421 }
13099 13422
@@ -13120,7 +13443,6 @@ static int patch_alc269(struct hda_codec *codec)
13120 if (board_config != ALC269_AUTO) 13443 if (board_config != ALC269_AUTO)
13121 setup_preset(spec, &alc269_presets[board_config]); 13444 setup_preset(spec, &alc269_presets[board_config]);
13122 13445
13123 spec->stream_name_analog = "ALC269 Analog";
13124 if (codec->subsystem_id == 0x17aa3bf8) { 13446 if (codec->subsystem_id == 0x17aa3bf8) {
13125 /* Due to a hardware problem on Lenovo Ideadpad, we need to 13447 /* Due to a hardware problem on Lenovo Ideadpad, we need to
13126 * fix the sample rate of analog I/O to 44.1kHz 13448 * fix the sample rate of analog I/O to 44.1kHz
@@ -13131,7 +13453,6 @@ static int patch_alc269(struct hda_codec *codec)
13131 spec->stream_analog_playback = &alc269_pcm_analog_playback; 13453 spec->stream_analog_playback = &alc269_pcm_analog_playback;
13132 spec->stream_analog_capture = &alc269_pcm_analog_capture; 13454 spec->stream_analog_capture = &alc269_pcm_analog_capture;
13133 } 13455 }
13134 spec->stream_name_digital = "ALC269 Digital";
13135 spec->stream_digital_playback = &alc269_pcm_digital_playback; 13456 spec->stream_digital_playback = &alc269_pcm_digital_playback;
13136 spec->stream_digital_capture = &alc269_pcm_digital_capture; 13457 spec->stream_digital_capture = &alc269_pcm_digital_capture;
13137 13458
@@ -13920,7 +14241,6 @@ static void alc861_auto_init_multi_out(struct hda_codec *codec)
13920 struct alc_spec *spec = codec->spec; 14241 struct alc_spec *spec = codec->spec;
13921 int i; 14242 int i;
13922 14243
13923 alc_subsystem_id(codec, 0x0e, 0x0f, 0x0b);
13924 for (i = 0; i < spec->autocfg.line_outs; i++) { 14244 for (i = 0; i < spec->autocfg.line_outs; i++) {
13925 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 14245 hda_nid_t nid = spec->autocfg.line_out_pins[i];
13926 int pin_type = get_pin_type(spec->autocfg.line_out_type); 14246 int pin_type = get_pin_type(spec->autocfg.line_out_type);
@@ -14003,6 +14323,8 @@ static int alc861_parse_auto_config(struct hda_codec *codec)
14003 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids); 14323 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
14004 set_capture_mixer(spec); 14324 set_capture_mixer(spec);
14005 14325
14326 alc_ssid_check(codec, 0x0e, 0x0f, 0x0b);
14327
14006 return 1; 14328 return 1;
14007} 14329}
14008 14330
@@ -14192,8 +14514,8 @@ static int patch_alc861(struct hda_codec *codec)
14192 alc861_cfg_tbl); 14514 alc861_cfg_tbl);
14193 14515
14194 if (board_config < 0) { 14516 if (board_config < 0) {
14195 printk(KERN_INFO "hda_codec: Unknown model for ALC861, " 14517 printk(KERN_INFO "hda_codec: Unknown model for %s, "
14196 "trying auto-probe from BIOS...\n"); 14518 "trying auto-probe from BIOS...\n", codec->chip_name);
14197 board_config = ALC861_AUTO; 14519 board_config = ALC861_AUTO;
14198 } 14520 }
14199 14521
@@ -14220,11 +14542,9 @@ static int patch_alc861(struct hda_codec *codec)
14220 if (board_config != ALC861_AUTO) 14542 if (board_config != ALC861_AUTO)
14221 setup_preset(spec, &alc861_presets[board_config]); 14543 setup_preset(spec, &alc861_presets[board_config]);
14222 14544
14223 spec->stream_name_analog = "ALC861 Analog";
14224 spec->stream_analog_playback = &alc861_pcm_analog_playback; 14545 spec->stream_analog_playback = &alc861_pcm_analog_playback;
14225 spec->stream_analog_capture = &alc861_pcm_analog_capture; 14546 spec->stream_analog_capture = &alc861_pcm_analog_capture;
14226 14547
14227 spec->stream_name_digital = "ALC861 Digital";
14228 spec->stream_digital_playback = &alc861_pcm_digital_playback; 14548 spec->stream_digital_playback = &alc861_pcm_digital_playback;
14229 spec->stream_digital_capture = &alc861_pcm_digital_capture; 14549 spec->stream_digital_capture = &alc861_pcm_digital_capture;
14230 14550
@@ -14611,19 +14931,6 @@ static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
14611 {} 14931 {}
14612}; 14932};
14613 14933
14614/* toggle speaker-output according to the hp-jack state */
14615static void alc861vd_lenovo_hp_automute(struct hda_codec *codec)
14616{
14617 unsigned int present;
14618 unsigned char bits;
14619
14620 present = snd_hda_codec_read(codec, 0x1b, 0,
14621 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
14622 bits = present ? HDA_AMP_MUTE : 0;
14623 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
14624 HDA_AMP_MUTE, bits);
14625}
14626
14627static void alc861vd_lenovo_mic_automute(struct hda_codec *codec) 14934static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
14628{ 14935{
14629 unsigned int present; 14936 unsigned int present;
@@ -14636,9 +14943,13 @@ static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
14636 HDA_AMP_MUTE, bits); 14943 HDA_AMP_MUTE, bits);
14637} 14944}
14638 14945
14639static void alc861vd_lenovo_automute(struct hda_codec *codec) 14946static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
14640{ 14947{
14641 alc861vd_lenovo_hp_automute(codec); 14948 struct alc_spec *spec = codec->spec;
14949
14950 spec->autocfg.hp_pins[0] = 0x1b;
14951 spec->autocfg.speaker_pins[0] = 0x14;
14952 alc_automute_amp(codec);
14642 alc861vd_lenovo_mic_automute(codec); 14953 alc861vd_lenovo_mic_automute(codec);
14643} 14954}
14644 14955
@@ -14646,12 +14957,12 @@ static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
14646 unsigned int res) 14957 unsigned int res)
14647{ 14958{
14648 switch (res >> 26) { 14959 switch (res >> 26) {
14649 case ALC880_HP_EVENT:
14650 alc861vd_lenovo_hp_automute(codec);
14651 break;
14652 case ALC880_MIC_EVENT: 14960 case ALC880_MIC_EVENT:
14653 alc861vd_lenovo_mic_automute(codec); 14961 alc861vd_lenovo_mic_automute(codec);
14654 break; 14962 break;
14963 default:
14964 alc_automute_amp_unsol_event(codec, res);
14965 break;
14655 } 14966 }
14656} 14967}
14657 14968
@@ -14701,20 +15012,13 @@ static struct hda_verb alc861vd_dallas_verbs[] = {
14701}; 15012};
14702 15013
14703/* toggle speaker-output according to the hp-jack state */ 15014/* toggle speaker-output according to the hp-jack state */
14704static void alc861vd_dallas_automute(struct hda_codec *codec) 15015static void alc861vd_dallas_init_hook(struct hda_codec *codec)
14705{ 15016{
14706 unsigned int present; 15017 struct alc_spec *spec = codec->spec;
14707
14708 present = snd_hda_codec_read(codec, 0x15, 0,
14709 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
14710 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
14711 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
14712}
14713 15018
14714static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int res) 15019 spec->autocfg.hp_pins[0] = 0x15;
14715{ 15020 spec->autocfg.speaker_pins[0] = 0x14;
14716 if ((res >> 26) == ALC880_HP_EVENT) 15021 alc_automute_amp(codec);
14717 alc861vd_dallas_automute(codec);
14718} 15022}
14719 15023
14720#ifdef CONFIG_SND_HDA_POWER_SAVE 15024#ifdef CONFIG_SND_HDA_POWER_SAVE
@@ -14828,7 +15132,7 @@ static struct alc_config_preset alc861vd_presets[] = {
14828 .channel_mode = alc861vd_3stack_2ch_modes, 15132 .channel_mode = alc861vd_3stack_2ch_modes,
14829 .input_mux = &alc861vd_capture_source, 15133 .input_mux = &alc861vd_capture_source,
14830 .unsol_event = alc861vd_lenovo_unsol_event, 15134 .unsol_event = alc861vd_lenovo_unsol_event,
14831 .init_hook = alc861vd_lenovo_automute, 15135 .init_hook = alc861vd_lenovo_init_hook,
14832 }, 15136 },
14833 [ALC861VD_DALLAS] = { 15137 [ALC861VD_DALLAS] = {
14834 .mixers = { alc861vd_dallas_mixer }, 15138 .mixers = { alc861vd_dallas_mixer },
@@ -14838,8 +15142,8 @@ static struct alc_config_preset alc861vd_presets[] = {
14838 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 15142 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14839 .channel_mode = alc861vd_3stack_2ch_modes, 15143 .channel_mode = alc861vd_3stack_2ch_modes,
14840 .input_mux = &alc861vd_dallas_capture_source, 15144 .input_mux = &alc861vd_dallas_capture_source,
14841 .unsol_event = alc861vd_dallas_unsol_event, 15145 .unsol_event = alc_automute_amp_unsol_event,
14842 .init_hook = alc861vd_dallas_automute, 15146 .init_hook = alc861vd_dallas_init_hook,
14843 }, 15147 },
14844 [ALC861VD_HP] = { 15148 [ALC861VD_HP] = {
14845 .mixers = { alc861vd_hp_mixer }, 15149 .mixers = { alc861vd_hp_mixer },
@@ -14850,8 +15154,8 @@ static struct alc_config_preset alc861vd_presets[] = {
14850 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 15154 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14851 .channel_mode = alc861vd_3stack_2ch_modes, 15155 .channel_mode = alc861vd_3stack_2ch_modes,
14852 .input_mux = &alc861vd_hp_capture_source, 15156 .input_mux = &alc861vd_hp_capture_source,
14853 .unsol_event = alc861vd_dallas_unsol_event, 15157 .unsol_event = alc_automute_amp_unsol_event,
14854 .init_hook = alc861vd_dallas_automute, 15158 .init_hook = alc861vd_dallas_init_hook,
14855 }, 15159 },
14856 [ALC660VD_ASUS_V1S] = { 15160 [ALC660VD_ASUS_V1S] = {
14857 .mixers = { alc861vd_lenovo_mixer }, 15161 .mixers = { alc861vd_lenovo_mixer },
@@ -14866,7 +15170,7 @@ static struct alc_config_preset alc861vd_presets[] = {
14866 .channel_mode = alc861vd_3stack_2ch_modes, 15170 .channel_mode = alc861vd_3stack_2ch_modes,
14867 .input_mux = &alc861vd_capture_source, 15171 .input_mux = &alc861vd_capture_source,
14868 .unsol_event = alc861vd_lenovo_unsol_event, 15172 .unsol_event = alc861vd_lenovo_unsol_event,
14869 .init_hook = alc861vd_lenovo_automute, 15173 .init_hook = alc861vd_lenovo_init_hook,
14870 }, 15174 },
14871}; 15175};
14872 15176
@@ -14884,7 +15188,6 @@ static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
14884 struct alc_spec *spec = codec->spec; 15188 struct alc_spec *spec = codec->spec;
14885 int i; 15189 int i;
14886 15190
14887 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
14888 for (i = 0; i <= HDA_SIDE; i++) { 15191 for (i = 0; i <= HDA_SIDE; i++) {
14889 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 15192 hda_nid_t nid = spec->autocfg.line_out_pins[i];
14890 int pin_type = get_pin_type(spec->autocfg.line_out_type); 15193 int pin_type = get_pin_type(spec->autocfg.line_out_type);
@@ -15102,6 +15405,8 @@ static int alc861vd_parse_auto_config(struct hda_codec *codec)
15102 if (err < 0) 15405 if (err < 0)
15103 return err; 15406 return err;
15104 15407
15408 alc_ssid_check(codec, 0x15, 0x1b, 0x14);
15409
15105 return 1; 15410 return 1;
15106} 15411}
15107 15412
@@ -15133,8 +15438,8 @@ static int patch_alc861vd(struct hda_codec *codec)
15133 alc861vd_cfg_tbl); 15438 alc861vd_cfg_tbl);
15134 15439
15135 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) { 15440 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
15136 printk(KERN_INFO "hda_codec: Unknown model for ALC660VD/" 15441 printk(KERN_INFO "hda_codec: Unknown model for %s, "
15137 "ALC861VD, trying auto-probe from BIOS...\n"); 15442 "trying auto-probe from BIOS...\n", codec->chip_name);
15138 board_config = ALC861VD_AUTO; 15443 board_config = ALC861VD_AUTO;
15139 } 15444 }
15140 15445
@@ -15162,13 +15467,8 @@ static int patch_alc861vd(struct hda_codec *codec)
15162 setup_preset(spec, &alc861vd_presets[board_config]); 15467 setup_preset(spec, &alc861vd_presets[board_config]);
15163 15468
15164 if (codec->vendor_id == 0x10ec0660) { 15469 if (codec->vendor_id == 0x10ec0660) {
15165 spec->stream_name_analog = "ALC660-VD Analog";
15166 spec->stream_name_digital = "ALC660-VD Digital";
15167 /* always turn on EAPD */ 15470 /* always turn on EAPD */
15168 add_verb(spec, alc660vd_eapd_verbs); 15471 add_verb(spec, alc660vd_eapd_verbs);
15169 } else {
15170 spec->stream_name_analog = "ALC861VD Analog";
15171 spec->stream_name_digital = "ALC861VD Digital";
15172 } 15472 }
15173 15473
15174 spec->stream_analog_playback = &alc861vd_pcm_analog_playback; 15474 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
@@ -15282,6 +15582,38 @@ static struct hda_input_mux alc663_m51va_capture_source = {
15282 }, 15582 },
15283}; 15583};
15284 15584
15585#if 1 /* set to 0 for testing other input sources below */
15586static struct hda_input_mux alc272_nc10_capture_source = {
15587 .num_items = 2,
15588 .items = {
15589 { "Autoselect Mic", 0x0 },
15590 { "Internal Mic", 0x1 },
15591 },
15592};
15593#else
15594static struct hda_input_mux alc272_nc10_capture_source = {
15595 .num_items = 16,
15596 .items = {
15597 { "Autoselect Mic", 0x0 },
15598 { "Internal Mic", 0x1 },
15599 { "In-0x02", 0x2 },
15600 { "In-0x03", 0x3 },
15601 { "In-0x04", 0x4 },
15602 { "In-0x05", 0x5 },
15603 { "In-0x06", 0x6 },
15604 { "In-0x07", 0x7 },
15605 { "In-0x08", 0x8 },
15606 { "In-0x09", 0x9 },
15607 { "In-0x0a", 0x0a },
15608 { "In-0x0b", 0x0b },
15609 { "In-0x0c", 0x0c },
15610 { "In-0x0d", 0x0d },
15611 { "In-0x0e", 0x0e },
15612 { "In-0x0f", 0x0f },
15613 },
15614};
15615#endif
15616
15285/* 15617/*
15286 * 2ch mode 15618 * 2ch mode
15287 */ 15619 */
@@ -15421,10 +15753,8 @@ static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
15421}; 15753};
15422 15754
15423static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = { 15755static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
15424 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 15756 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15425 15757 ALC262_HIPPO_MASTER_SWITCH,
15426 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15427 HDA_CODEC_MUTE("Line-Out Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15428 15758
15429 HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT), 15759 HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
15430 HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 15760 HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
@@ -15437,15 +15767,11 @@ static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
15437}; 15767};
15438 15768
15439static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = { 15769static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
15440 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT), 15770 ALC262_HIPPO_MASTER_SWITCH,
15441 HDA_CODEC_MUTE("Line-Out Playback Switch", 0x14, 0x0, HDA_OUTPUT), 15771 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15442 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT), 15772 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15443 HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT),
15444 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT), 15773 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
15445 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT), 15774 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
15446 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
15447 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
15448 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15449 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT), 15775 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
15450 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 15776 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15451 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 15777 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
@@ -15953,51 +16279,25 @@ static void alc662_eeepc_mic_automute(struct hda_codec *codec)
15953static void alc662_eeepc_unsol_event(struct hda_codec *codec, 16279static void alc662_eeepc_unsol_event(struct hda_codec *codec,
15954 unsigned int res) 16280 unsigned int res)
15955{ 16281{
15956 if ((res >> 26) == ALC880_HP_EVENT)
15957 alc262_hippo1_automute( codec );
15958
15959 if ((res >> 26) == ALC880_MIC_EVENT) 16282 if ((res >> 26) == ALC880_MIC_EVENT)
15960 alc662_eeepc_mic_automute(codec); 16283 alc662_eeepc_mic_automute(codec);
16284 else
16285 alc262_hippo_unsol_event(codec, res);
15961} 16286}
15962 16287
15963static void alc662_eeepc_inithook(struct hda_codec *codec) 16288static void alc662_eeepc_inithook(struct hda_codec *codec)
15964{ 16289{
15965 alc262_hippo1_automute( codec ); 16290 alc262_hippo1_init_hook(codec);
15966 alc662_eeepc_mic_automute(codec); 16291 alc662_eeepc_mic_automute(codec);
15967} 16292}
15968 16293
15969static void alc662_eeepc_ep20_automute(struct hda_codec *codec)
15970{
15971 unsigned int mute;
15972 unsigned int present;
15973
15974 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
15975 present = snd_hda_codec_read(codec, 0x14, 0,
15976 AC_VERB_GET_PIN_SENSE, 0);
15977 present = (present & 0x80000000) != 0;
15978 if (present) {
15979 /* mute internal speaker */
15980 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
15981 HDA_AMP_MUTE, HDA_AMP_MUTE);
15982 } else {
15983 /* unmute internal speaker if necessary */
15984 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
15985 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
15986 HDA_AMP_MUTE, mute);
15987 }
15988}
15989
15990/* unsolicited event for HP jack sensing */
15991static void alc662_eeepc_ep20_unsol_event(struct hda_codec *codec,
15992 unsigned int res)
15993{
15994 if ((res >> 26) == ALC880_HP_EVENT)
15995 alc662_eeepc_ep20_automute(codec);
15996}
15997
15998static void alc662_eeepc_ep20_inithook(struct hda_codec *codec) 16294static void alc662_eeepc_ep20_inithook(struct hda_codec *codec)
15999{ 16295{
16000 alc662_eeepc_ep20_automute(codec); 16296 struct alc_spec *spec = codec->spec;
16297
16298 spec->autocfg.hp_pins[0] = 0x14;
16299 spec->autocfg.speaker_pins[0] = 0x1b;
16300 alc262_hippo_master_update(codec);
16001} 16301}
16002 16302
16003static void alc663_m51va_speaker_automute(struct hda_codec *codec) 16303static void alc663_m51va_speaker_automute(struct hda_codec *codec)
@@ -16331,35 +16631,9 @@ static void alc663_g50v_inithook(struct hda_codec *codec)
16331 alc662_eeepc_mic_automute(codec); 16631 alc662_eeepc_mic_automute(codec);
16332} 16632}
16333 16633
16334/* bind hp and internal speaker mute (with plug check) */
16335static int alc662_ecs_master_sw_put(struct snd_kcontrol *kcontrol,
16336 struct snd_ctl_elem_value *ucontrol)
16337{
16338 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
16339 long *valp = ucontrol->value.integer.value;
16340 int change;
16341
16342 change = snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0,
16343 HDA_AMP_MUTE,
16344 valp[0] ? 0 : HDA_AMP_MUTE);
16345 change |= snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0,
16346 HDA_AMP_MUTE,
16347 valp[1] ? 0 : HDA_AMP_MUTE);
16348 if (change)
16349 alc262_hippo1_automute(codec);
16350 return change;
16351}
16352
16353static struct snd_kcontrol_new alc662_ecs_mixer[] = { 16634static struct snd_kcontrol_new alc662_ecs_mixer[] = {
16354 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT), 16635 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16355 { 16636 ALC262_HIPPO_MASTER_SWITCH,
16356 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
16357 .name = "Master Playback Switch",
16358 .info = snd_hda_mixer_amp_switch_info,
16359 .get = snd_hda_mixer_amp_switch_get,
16360 .put = alc662_ecs_master_sw_put,
16361 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
16362 },
16363 16637
16364 HDA_CODEC_VOLUME("e-Mic/LineIn Boost", 0x18, 0, HDA_INPUT), 16638 HDA_CODEC_VOLUME("e-Mic/LineIn Boost", 0x18, 0, HDA_INPUT),
16365 HDA_CODEC_VOLUME("e-Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT), 16639 HDA_CODEC_VOLUME("e-Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
@@ -16371,6 +16645,23 @@ static struct snd_kcontrol_new alc662_ecs_mixer[] = {
16371 { } /* end */ 16645 { } /* end */
16372}; 16646};
16373 16647
16648static struct snd_kcontrol_new alc272_nc10_mixer[] = {
16649 /* Master Playback automatically created from Speaker and Headphone */
16650 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16651 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
16652 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16653 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
16654
16655 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16656 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16657 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
16658
16659 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16660 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16661 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
16662 { } /* end */
16663};
16664
16374#ifdef CONFIG_SND_HDA_POWER_SAVE 16665#ifdef CONFIG_SND_HDA_POWER_SAVE
16375#define alc662_loopbacks alc880_loopbacks 16666#define alc662_loopbacks alc880_loopbacks
16376#endif 16667#endif
@@ -16404,6 +16695,9 @@ static const char *alc662_models[ALC662_MODEL_LAST] = {
16404 [ALC663_ASUS_MODE4] = "asus-mode4", 16695 [ALC663_ASUS_MODE4] = "asus-mode4",
16405 [ALC663_ASUS_MODE5] = "asus-mode5", 16696 [ALC663_ASUS_MODE5] = "asus-mode5",
16406 [ALC663_ASUS_MODE6] = "asus-mode6", 16697 [ALC663_ASUS_MODE6] = "asus-mode6",
16698 [ALC272_DELL] = "dell",
16699 [ALC272_DELL_ZM1] = "dell-zm1",
16700 [ALC272_SAMSUNG_NC10] = "samsung-nc10",
16407 [ALC662_AUTO] = "auto", 16701 [ALC662_AUTO] = "auto",
16408}; 16702};
16409 16703
@@ -16461,6 +16755,7 @@ static struct snd_pci_quirk alc662_cfg_tbl[] = {
16461 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS), 16755 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
16462 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K", 16756 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
16463 ALC662_3ST_6ch_DIG), 16757 ALC662_3ST_6ch_DIG),
16758 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
16464 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L", 16759 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
16465 ALC662_3ST_6ch_DIG), 16760 ALC662_3ST_6ch_DIG),
16466 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG), 16761 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
@@ -16551,7 +16846,7 @@ static struct alc_config_preset alc662_presets[] = {
16551 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), 16846 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16552 .channel_mode = alc662_3ST_6ch_modes, 16847 .channel_mode = alc662_3ST_6ch_modes,
16553 .input_mux = &alc662_lenovo_101e_capture_source, 16848 .input_mux = &alc662_lenovo_101e_capture_source,
16554 .unsol_event = alc662_eeepc_ep20_unsol_event, 16849 .unsol_event = alc662_eeepc_unsol_event,
16555 .init_hook = alc662_eeepc_ep20_inithook, 16850 .init_hook = alc662_eeepc_ep20_inithook,
16556 }, 16851 },
16557 [ALC662_ECS] = { 16852 [ALC662_ECS] = {
@@ -16732,6 +17027,18 @@ static struct alc_config_preset alc662_presets[] = {
16732 .unsol_event = alc663_m51va_unsol_event, 17027 .unsol_event = alc663_m51va_unsol_event,
16733 .init_hook = alc663_m51va_inithook, 17028 .init_hook = alc663_m51va_inithook,
16734 }, 17029 },
17030 [ALC272_SAMSUNG_NC10] = {
17031 .mixers = { alc272_nc10_mixer },
17032 .init_verbs = { alc662_init_verbs,
17033 alc663_21jd_amic_init_verbs },
17034 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
17035 .dac_nids = alc272_dac_nids,
17036 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17037 .channel_mode = alc662_3ST_2ch_modes,
17038 .input_mux = &alc272_nc10_capture_source,
17039 .unsol_event = alc663_mode4_unsol_event,
17040 .init_hook = alc663_mode4_inithook,
17041 },
16735}; 17042};
16736 17043
16737 17044
@@ -16926,7 +17233,6 @@ static void alc662_auto_init_multi_out(struct hda_codec *codec)
16926 struct alc_spec *spec = codec->spec; 17233 struct alc_spec *spec = codec->spec;
16927 int i; 17234 int i;
16928 17235
16929 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
16930 for (i = 0; i <= HDA_SIDE; i++) { 17236 for (i = 0; i <= HDA_SIDE; i++) {
16931 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 17237 hda_nid_t nid = spec->autocfg.line_out_pins[i];
16932 int pin_type = get_pin_type(spec->autocfg.line_out_type); 17238 int pin_type = get_pin_type(spec->autocfg.line_out_type);
@@ -17023,6 +17329,8 @@ static int alc662_parse_auto_config(struct hda_codec *codec)
17023 if (err < 0) 17329 if (err < 0)
17024 return err; 17330 return err;
17025 17331
17332 alc_ssid_check(codec, 0x15, 0x1b, 0x14);
17333
17026 return 1; 17334 return 1;
17027} 17335}
17028 17336
@@ -17055,8 +17363,8 @@ static int patch_alc662(struct hda_codec *codec)
17055 alc662_models, 17363 alc662_models,
17056 alc662_cfg_tbl); 17364 alc662_cfg_tbl);
17057 if (board_config < 0) { 17365 if (board_config < 0) {
17058 printk(KERN_INFO "hda_codec: Unknown model for ALC662, " 17366 printk(KERN_INFO "hda_codec: Unknown model for %s, "
17059 "trying auto-probe from BIOS...\n"); 17367 "trying auto-probe from BIOS...\n", codec->chip_name);
17060 board_config = ALC662_AUTO; 17368 board_config = ALC662_AUTO;
17061 } 17369 }
17062 17370
@@ -17083,17 +17391,6 @@ static int patch_alc662(struct hda_codec *codec)
17083 if (board_config != ALC662_AUTO) 17391 if (board_config != ALC662_AUTO)
17084 setup_preset(spec, &alc662_presets[board_config]); 17392 setup_preset(spec, &alc662_presets[board_config]);
17085 17393
17086 if (codec->vendor_id == 0x10ec0663) {
17087 spec->stream_name_analog = "ALC663 Analog";
17088 spec->stream_name_digital = "ALC663 Digital";
17089 } else if (codec->vendor_id == 0x10ec0272) {
17090 spec->stream_name_analog = "ALC272 Analog";
17091 spec->stream_name_digital = "ALC272 Digital";
17092 } else {
17093 spec->stream_name_analog = "ALC662 Analog";
17094 spec->stream_name_digital = "ALC662 Digital";
17095 }
17096
17097 spec->stream_analog_playback = &alc662_pcm_analog_playback; 17394 spec->stream_analog_playback = &alc662_pcm_analog_playback;
17098 spec->stream_analog_capture = &alc662_pcm_analog_capture; 17395 spec->stream_analog_capture = &alc662_pcm_analog_capture;
17099 17396
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 917bc5d3ac2..42f944bb641 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -100,6 +100,7 @@ enum {
100 STAC_HP_M4, 100 STAC_HP_M4,
101 STAC_HP_DV5, 101 STAC_HP_DV5,
102 STAC_HP_HDX, 102 STAC_HP_HDX,
103 STAC_HP_DV4_1222NR,
103 STAC_92HD71BXX_MODELS 104 STAC_92HD71BXX_MODELS
104}; 105};
105 106
@@ -150,6 +151,7 @@ enum {
150 STAC_D965_REF, 151 STAC_D965_REF,
151 STAC_D965_3ST, 152 STAC_D965_3ST,
152 STAC_D965_5ST, 153 STAC_D965_5ST,
154 STAC_D965_5ST_NO_FP,
153 STAC_DELL_3ST, 155 STAC_DELL_3ST,
154 STAC_DELL_BIOS, 156 STAC_DELL_BIOS,
155 STAC_927X_MODELS 157 STAC_927X_MODELS
@@ -192,6 +194,7 @@ struct sigmatel_spec {
192 unsigned int gpio_dir; 194 unsigned int gpio_dir;
193 unsigned int gpio_data; 195 unsigned int gpio_data;
194 unsigned int gpio_mute; 196 unsigned int gpio_mute;
197 unsigned int gpio_led;
195 198
196 /* stream */ 199 /* stream */
197 unsigned int stream_delay; 200 unsigned int stream_delay;
@@ -633,6 +636,40 @@ static int stac92xx_smux_enum_put(struct snd_kcontrol *kcontrol,
633 return 0; 636 return 0;
634} 637}
635 638
639static unsigned int stac92xx_vref_set(struct hda_codec *codec,
640 hda_nid_t nid, unsigned int new_vref)
641{
642 unsigned int error;
643 unsigned int pincfg;
644 pincfg = snd_hda_codec_read(codec, nid, 0,
645 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
646
647 pincfg &= 0xff;
648 pincfg &= ~(AC_PINCTL_VREFEN | AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN);
649 pincfg |= new_vref;
650
651 if (new_vref == AC_PINCTL_VREF_HIZ)
652 pincfg |= AC_PINCTL_OUT_EN;
653 else
654 pincfg |= AC_PINCTL_IN_EN;
655
656 error = snd_hda_codec_write_cache(codec, nid, 0,
657 AC_VERB_SET_PIN_WIDGET_CONTROL, pincfg);
658 if (error < 0)
659 return error;
660 else
661 return 1;
662}
663
664static unsigned int stac92xx_vref_get(struct hda_codec *codec, hda_nid_t nid)
665{
666 unsigned int vref;
667 vref = snd_hda_codec_read(codec, nid, 0,
668 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
669 vref &= AC_PINCTL_VREFEN;
670 return vref;
671}
672
636static int stac92xx_mux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 673static int stac92xx_mux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
637{ 674{
638 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 675 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
@@ -994,6 +1031,17 @@ static struct hda_verb stac9205_core_init[] = {
994 .private_value = verb_read | (verb_write << 16), \ 1031 .private_value = verb_read | (verb_write << 16), \
995 } 1032 }
996 1033
1034#define DC_BIAS(xname, idx, nid) \
1035 { \
1036 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1037 .name = xname, \
1038 .index = idx, \
1039 .info = stac92xx_dc_bias_info, \
1040 .get = stac92xx_dc_bias_get, \
1041 .put = stac92xx_dc_bias_put, \
1042 .private_value = nid, \
1043 }
1044
997static struct snd_kcontrol_new stac9200_mixer[] = { 1045static struct snd_kcontrol_new stac9200_mixer[] = {
998 HDA_CODEC_VOLUME("Master Playback Volume", 0xb, 0, HDA_OUTPUT), 1046 HDA_CODEC_VOLUME("Master Playback Volume", 0xb, 0, HDA_OUTPUT),
999 HDA_CODEC_MUTE("Master Playback Switch", 0xb, 0, HDA_OUTPUT), 1047 HDA_CODEC_MUTE("Master Playback Switch", 0xb, 0, HDA_OUTPUT),
@@ -1836,6 +1884,7 @@ static unsigned int *stac92hd71bxx_brd_tbl[STAC_92HD71BXX_MODELS] = {
1836 [STAC_HP_M4] = NULL, 1884 [STAC_HP_M4] = NULL,
1837 [STAC_HP_DV5] = NULL, 1885 [STAC_HP_DV5] = NULL,
1838 [STAC_HP_HDX] = NULL, 1886 [STAC_HP_HDX] = NULL,
1887 [STAC_HP_DV4_1222NR] = NULL,
1839}; 1888};
1840 1889
1841static const char *stac92hd71bxx_models[STAC_92HD71BXX_MODELS] = { 1890static const char *stac92hd71bxx_models[STAC_92HD71BXX_MODELS] = {
@@ -1847,6 +1896,7 @@ static const char *stac92hd71bxx_models[STAC_92HD71BXX_MODELS] = {
1847 [STAC_HP_M4] = "hp-m4", 1896 [STAC_HP_M4] = "hp-m4",
1848 [STAC_HP_DV5] = "hp-dv5", 1897 [STAC_HP_DV5] = "hp-dv5",
1849 [STAC_HP_HDX] = "hp-hdx", 1898 [STAC_HP_HDX] = "hp-hdx",
1899 [STAC_HP_DV4_1222NR] = "hp-dv4-1222nr",
1850}; 1900};
1851 1901
1852static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = { 1902static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = {
@@ -1855,6 +1905,8 @@ static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = {
1855 "DFI LanParty", STAC_92HD71BXX_REF), 1905 "DFI LanParty", STAC_92HD71BXX_REF),
1856 SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101, 1906 SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101,
1857 "DFI LanParty", STAC_92HD71BXX_REF), 1907 "DFI LanParty", STAC_92HD71BXX_REF),
1908 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30fb,
1909 "HP dv4-1222nr", STAC_HP_DV4_1222NR),
1858 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3080, 1910 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3080,
1859 "HP", STAC_HP_DV5), 1911 "HP", STAC_HP_DV5),
1860 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x30f0, 1912 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x30f0,
@@ -2154,6 +2206,13 @@ static unsigned int d965_5st_pin_configs[14] = {
2154 0x40000100, 0x40000100 2206 0x40000100, 0x40000100
2155}; 2207};
2156 2208
2209static unsigned int d965_5st_no_fp_pin_configs[14] = {
2210 0x40000100, 0x40000100, 0x0181304e, 0x01014010,
2211 0x01a19040, 0x01011012, 0x01016011, 0x40000100,
2212 0x40000100, 0x40000100, 0x40000100, 0x01442070,
2213 0x40000100, 0x40000100
2214};
2215
2157static unsigned int dell_3st_pin_configs[14] = { 2216static unsigned int dell_3st_pin_configs[14] = {
2158 0x02211230, 0x02a11220, 0x01a19040, 0x01114210, 2217 0x02211230, 0x02a11220, 0x01a19040, 0x01114210,
2159 0x01111212, 0x01116211, 0x01813050, 0x01112214, 2218 0x01111212, 0x01116211, 0x01813050, 0x01112214,
@@ -2166,6 +2225,7 @@ static unsigned int *stac927x_brd_tbl[STAC_927X_MODELS] = {
2166 [STAC_D965_REF] = ref927x_pin_configs, 2225 [STAC_D965_REF] = ref927x_pin_configs,
2167 [STAC_D965_3ST] = d965_3st_pin_configs, 2226 [STAC_D965_3ST] = d965_3st_pin_configs,
2168 [STAC_D965_5ST] = d965_5st_pin_configs, 2227 [STAC_D965_5ST] = d965_5st_pin_configs,
2228 [STAC_D965_5ST_NO_FP] = d965_5st_no_fp_pin_configs,
2169 [STAC_DELL_3ST] = dell_3st_pin_configs, 2229 [STAC_DELL_3ST] = dell_3st_pin_configs,
2170 [STAC_DELL_BIOS] = NULL, 2230 [STAC_DELL_BIOS] = NULL,
2171}; 2231};
@@ -2176,6 +2236,7 @@ static const char *stac927x_models[STAC_927X_MODELS] = {
2176 [STAC_D965_REF] = "ref", 2236 [STAC_D965_REF] = "ref",
2177 [STAC_D965_3ST] = "3stack", 2237 [STAC_D965_3ST] = "3stack",
2178 [STAC_D965_5ST] = "5stack", 2238 [STAC_D965_5ST] = "5stack",
2239 [STAC_D965_5ST_NO_FP] = "5stack-no-fp",
2179 [STAC_DELL_3ST] = "dell-3stack", 2240 [STAC_DELL_3ST] = "dell-3stack",
2180 [STAC_DELL_BIOS] = "dell-bios", 2241 [STAC_DELL_BIOS] = "dell-bios",
2181}; 2242};
@@ -2535,7 +2596,8 @@ static int stac92xx_build_pcms(struct hda_codec *codec)
2535 return 0; 2596 return 0;
2536} 2597}
2537 2598
2538static unsigned int stac92xx_get_vref(struct hda_codec *codec, hda_nid_t nid) 2599static unsigned int stac92xx_get_default_vref(struct hda_codec *codec,
2600 hda_nid_t nid)
2539{ 2601{
2540 unsigned int pincap = snd_hda_query_pin_caps(codec, nid); 2602 unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
2541 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT; 2603 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
@@ -2589,15 +2651,108 @@ static int stac92xx_hp_switch_put(struct snd_kcontrol *kcontrol,
2589 return 1; 2651 return 1;
2590} 2652}
2591 2653
2592#define stac92xx_io_switch_info snd_ctl_boolean_mono_info 2654static int stac92xx_dc_bias_info(struct snd_kcontrol *kcontrol,
2655 struct snd_ctl_elem_info *uinfo)
2656{
2657 int i;
2658 static char *texts[] = {
2659 "Mic In", "Line In", "Line Out"
2660 };
2661
2662 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2663 struct sigmatel_spec *spec = codec->spec;
2664 hda_nid_t nid = kcontrol->private_value;
2665
2666 if (nid == spec->mic_switch || nid == spec->line_switch)
2667 i = 3;
2668 else
2669 i = 2;
2670
2671 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2672 uinfo->value.enumerated.items = i;
2673 uinfo->count = 1;
2674 if (uinfo->value.enumerated.item >= i)
2675 uinfo->value.enumerated.item = i-1;
2676 strcpy(uinfo->value.enumerated.name,
2677 texts[uinfo->value.enumerated.item]);
2678
2679 return 0;
2680}
2681
2682static int stac92xx_dc_bias_get(struct snd_kcontrol *kcontrol,
2683 struct snd_ctl_elem_value *ucontrol)
2684{
2685 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2686 hda_nid_t nid = kcontrol->private_value;
2687 unsigned int vref = stac92xx_vref_get(codec, nid);
2688
2689 if (vref == stac92xx_get_default_vref(codec, nid))
2690 ucontrol->value.enumerated.item[0] = 0;
2691 else if (vref == AC_PINCTL_VREF_GRD)
2692 ucontrol->value.enumerated.item[0] = 1;
2693 else if (vref == AC_PINCTL_VREF_HIZ)
2694 ucontrol->value.enumerated.item[0] = 2;
2695
2696 return 0;
2697}
2698
2699static int stac92xx_dc_bias_put(struct snd_kcontrol *kcontrol,
2700 struct snd_ctl_elem_value *ucontrol)
2701{
2702 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2703 unsigned int new_vref = 0;
2704 unsigned int error;
2705 hda_nid_t nid = kcontrol->private_value;
2706
2707 if (ucontrol->value.enumerated.item[0] == 0)
2708 new_vref = stac92xx_get_default_vref(codec, nid);
2709 else if (ucontrol->value.enumerated.item[0] == 1)
2710 new_vref = AC_PINCTL_VREF_GRD;
2711 else if (ucontrol->value.enumerated.item[0] == 2)
2712 new_vref = AC_PINCTL_VREF_HIZ;
2713 else
2714 return 0;
2715
2716 if (new_vref != stac92xx_vref_get(codec, nid)) {
2717 error = stac92xx_vref_set(codec, nid, new_vref);
2718 return error;
2719 }
2720
2721 return 0;
2722}
2723
2724static int stac92xx_io_switch_info(struct snd_kcontrol *kcontrol,
2725 struct snd_ctl_elem_info *uinfo)
2726{
2727 static char *texts[2];
2728 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2729 struct sigmatel_spec *spec = codec->spec;
2730
2731 if (kcontrol->private_value == spec->line_switch)
2732 texts[0] = "Line In";
2733 else
2734 texts[0] = "Mic In";
2735 texts[1] = "Line Out";
2736 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2737 uinfo->value.enumerated.items = 2;
2738 uinfo->count = 1;
2739
2740 if (uinfo->value.enumerated.item >= 2)
2741 uinfo->value.enumerated.item = 1;
2742 strcpy(uinfo->value.enumerated.name,
2743 texts[uinfo->value.enumerated.item]);
2744
2745 return 0;
2746}
2593 2747
2594static int stac92xx_io_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 2748static int stac92xx_io_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
2595{ 2749{
2596 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2750 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2597 struct sigmatel_spec *spec = codec->spec; 2751 struct sigmatel_spec *spec = codec->spec;
2598 int io_idx = kcontrol-> private_value & 0xff; 2752 hda_nid_t nid = kcontrol->private_value;
2753 int io_idx = (nid == spec->mic_switch) ? 1 : 0;
2599 2754
2600 ucontrol->value.integer.value[0] = spec->io_switch[io_idx]; 2755 ucontrol->value.enumerated.item[0] = spec->io_switch[io_idx];
2601 return 0; 2756 return 0;
2602} 2757}
2603 2758
@@ -2605,9 +2760,9 @@ static int stac92xx_io_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_
2605{ 2760{
2606 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2761 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2607 struct sigmatel_spec *spec = codec->spec; 2762 struct sigmatel_spec *spec = codec->spec;
2608 hda_nid_t nid = kcontrol->private_value >> 8; 2763 hda_nid_t nid = kcontrol->private_value;
2609 int io_idx = kcontrol-> private_value & 0xff; 2764 int io_idx = (nid == spec->mic_switch) ? 1 : 0;
2610 unsigned short val = !!ucontrol->value.integer.value[0]; 2765 unsigned short val = !!ucontrol->value.enumerated.item[0];
2611 2766
2612 spec->io_switch[io_idx] = val; 2767 spec->io_switch[io_idx] = val;
2613 2768
@@ -2616,7 +2771,7 @@ static int stac92xx_io_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_
2616 else { 2771 else {
2617 unsigned int pinctl = AC_PINCTL_IN_EN; 2772 unsigned int pinctl = AC_PINCTL_IN_EN;
2618 if (io_idx) /* set VREF for mic */ 2773 if (io_idx) /* set VREF for mic */
2619 pinctl |= stac92xx_get_vref(codec, nid); 2774 pinctl |= stac92xx_get_default_vref(codec, nid);
2620 stac92xx_auto_set_pinctl(codec, nid, pinctl); 2775 stac92xx_auto_set_pinctl(codec, nid, pinctl);
2621 } 2776 }
2622 2777
@@ -2697,7 +2852,8 @@ enum {
2697 STAC_CTL_WIDGET_AMP_VOL, 2852 STAC_CTL_WIDGET_AMP_VOL,
2698 STAC_CTL_WIDGET_HP_SWITCH, 2853 STAC_CTL_WIDGET_HP_SWITCH,
2699 STAC_CTL_WIDGET_IO_SWITCH, 2854 STAC_CTL_WIDGET_IO_SWITCH,
2700 STAC_CTL_WIDGET_CLFE_SWITCH 2855 STAC_CTL_WIDGET_CLFE_SWITCH,
2856 STAC_CTL_WIDGET_DC_BIAS
2701}; 2857};
2702 2858
2703static struct snd_kcontrol_new stac92xx_control_templates[] = { 2859static struct snd_kcontrol_new stac92xx_control_templates[] = {
@@ -2709,6 +2865,7 @@ static struct snd_kcontrol_new stac92xx_control_templates[] = {
2709 STAC_CODEC_HP_SWITCH(NULL), 2865 STAC_CODEC_HP_SWITCH(NULL),
2710 STAC_CODEC_IO_SWITCH(NULL, 0), 2866 STAC_CODEC_IO_SWITCH(NULL, 0),
2711 STAC_CODEC_CLFE_SWITCH(NULL, 0), 2867 STAC_CODEC_CLFE_SWITCH(NULL, 0),
2868 DC_BIAS(NULL, 0, 0),
2712}; 2869};
2713 2870
2714/* add dynamic controls */ 2871/* add dynamic controls */
@@ -2772,6 +2929,34 @@ static struct snd_kcontrol_new stac_input_src_temp = {
2772 .put = stac92xx_mux_enum_put, 2929 .put = stac92xx_mux_enum_put,
2773}; 2930};
2774 2931
2932static inline int stac92xx_add_jack_mode_control(struct hda_codec *codec,
2933 hda_nid_t nid, int idx)
2934{
2935 int def_conf = snd_hda_codec_get_pincfg(codec, nid);
2936 int control = 0;
2937 struct sigmatel_spec *spec = codec->spec;
2938 char name[22];
2939
2940 if (!((get_defcfg_connect(def_conf)) & AC_JACK_PORT_FIXED)) {
2941 if (stac92xx_get_default_vref(codec, nid) == AC_PINCTL_VREF_GRD
2942 && nid == spec->line_switch)
2943 control = STAC_CTL_WIDGET_IO_SWITCH;
2944 else if (snd_hda_query_pin_caps(codec, nid)
2945 & (AC_PINCAP_VREF_GRD << AC_PINCAP_VREF_SHIFT))
2946 control = STAC_CTL_WIDGET_DC_BIAS;
2947 else if (nid == spec->mic_switch)
2948 control = STAC_CTL_WIDGET_IO_SWITCH;
2949 }
2950
2951 if (control) {
2952 strcpy(name, auto_pin_cfg_labels[idx]);
2953 return stac92xx_add_control(codec->spec, control,
2954 strcat(name, " Jack Mode"), nid);
2955 }
2956
2957 return 0;
2958}
2959
2775static int stac92xx_add_input_source(struct sigmatel_spec *spec) 2960static int stac92xx_add_input_source(struct sigmatel_spec *spec)
2776{ 2961{
2777 struct snd_kcontrol_new *knew; 2962 struct snd_kcontrol_new *knew;
@@ -3134,7 +3319,9 @@ static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec,
3134 const struct auto_pin_cfg *cfg) 3319 const struct auto_pin_cfg *cfg)
3135{ 3320{
3136 struct sigmatel_spec *spec = codec->spec; 3321 struct sigmatel_spec *spec = codec->spec;
3322 hda_nid_t nid;
3137 int err; 3323 int err;
3324 int idx;
3138 3325
3139 err = create_multi_out_ctls(codec, cfg->line_outs, cfg->line_out_pins, 3326 err = create_multi_out_ctls(codec, cfg->line_outs, cfg->line_out_pins,
3140 spec->multiout.dac_nids, 3327 spec->multiout.dac_nids,
@@ -3151,20 +3338,13 @@ static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec,
3151 return err; 3338 return err;
3152 } 3339 }
3153 3340
3154 if (spec->line_switch) { 3341 for (idx = AUTO_PIN_MIC; idx <= AUTO_PIN_FRONT_LINE; idx++) {
3155 err = stac92xx_add_control(spec, STAC_CTL_WIDGET_IO_SWITCH, 3342 nid = cfg->input_pins[idx];
3156 "Line In as Output Switch", 3343 if (nid) {
3157 spec->line_switch << 8); 3344 err = stac92xx_add_jack_mode_control(codec, nid, idx);
3158 if (err < 0) 3345 if (err < 0)
3159 return err; 3346 return err;
3160 } 3347 }
3161
3162 if (spec->mic_switch) {
3163 err = stac92xx_add_control(spec, STAC_CTL_WIDGET_IO_SWITCH,
3164 "Mic as Output Switch",
3165 (spec->mic_switch << 8) | 1);
3166 if (err < 0)
3167 return err;
3168 } 3348 }
3169 3349
3170 return 0; 3350 return 0;
@@ -3629,6 +3809,8 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out
3629 err = snd_hda_attach_beep_device(codec, nid); 3809 err = snd_hda_attach_beep_device(codec, nid);
3630 if (err < 0) 3810 if (err < 0)
3631 return err; 3811 return err;
3812 /* IDT/STAC codecs have linear beep tone parameter */
3813 codec->beep->linear_tone = 1;
3632 /* if no beep switch is available, make its own one */ 3814 /* if no beep switch is available, make its own one */
3633 caps = query_amp_caps(codec, nid, HDA_OUTPUT); 3815 caps = query_amp_caps(codec, nid, HDA_OUTPUT);
3634 if (codec->beep && 3816 if (codec->beep &&
@@ -4072,14 +4254,19 @@ static int stac92xx_init(struct hda_codec *codec)
4072 unsigned int pinctl, conf; 4254 unsigned int pinctl, conf;
4073 if (i == AUTO_PIN_MIC || i == AUTO_PIN_FRONT_MIC) { 4255 if (i == AUTO_PIN_MIC || i == AUTO_PIN_FRONT_MIC) {
4074 /* for mic pins, force to initialize */ 4256 /* for mic pins, force to initialize */
4075 pinctl = stac92xx_get_vref(codec, nid); 4257 pinctl = stac92xx_get_default_vref(codec, nid);
4076 pinctl |= AC_PINCTL_IN_EN; 4258 pinctl |= AC_PINCTL_IN_EN;
4077 stac92xx_auto_set_pinctl(codec, nid, pinctl); 4259 stac92xx_auto_set_pinctl(codec, nid, pinctl);
4078 } else { 4260 } else {
4079 pinctl = snd_hda_codec_read(codec, nid, 0, 4261 pinctl = snd_hda_codec_read(codec, nid, 0,
4080 AC_VERB_GET_PIN_WIDGET_CONTROL, 0); 4262 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4081 /* if PINCTL already set then skip */ 4263 /* if PINCTL already set then skip */
4082 if (!(pinctl & AC_PINCTL_IN_EN)) { 4264 /* Also, if both INPUT and OUTPUT are set,
4265 * it must be a BIOS bug; need to override, too
4266 */
4267 if (!(pinctl & AC_PINCTL_IN_EN) ||
4268 (pinctl & AC_PINCTL_OUT_EN)) {
4269 pinctl &= ~AC_PINCTL_OUT_EN;
4083 pinctl |= AC_PINCTL_IN_EN; 4270 pinctl |= AC_PINCTL_IN_EN;
4084 stac92xx_auto_set_pinctl(codec, nid, 4271 stac92xx_auto_set_pinctl(codec, nid,
4085 pinctl); 4272 pinctl);
@@ -4520,17 +4707,19 @@ static int stac92xx_resume(struct hda_codec *codec)
4520 return 0; 4707 return 0;
4521} 4708}
4522 4709
4523
4524/* 4710/*
4525 * using power check for controlling mute led of HP HDX notebooks 4711 * using power check for controlling mute led of HP notebooks
4526 * check for mute state only on Speakers (nid = 0x10) 4712 * check for mute state only on Speakers (nid = 0x10)
4527 * 4713 *
4528 * For this feature CONFIG_SND_HDA_POWER_SAVE is needed, otherwise 4714 * For this feature CONFIG_SND_HDA_POWER_SAVE is needed, otherwise
4529 * the LED is NOT working properly ! 4715 * the LED is NOT working properly !
4716 *
4717 * Changed name to reflect that it now works for any designated
4718 * model, not just HP HDX.
4530 */ 4719 */
4531 4720
4532#ifdef CONFIG_SND_HDA_POWER_SAVE 4721#ifdef CONFIG_SND_HDA_POWER_SAVE
4533static int stac92xx_hp_hdx_check_power_status(struct hda_codec *codec, 4722static int stac92xx_hp_check_power_status(struct hda_codec *codec,
4534 hda_nid_t nid) 4723 hda_nid_t nid)
4535{ 4724{
4536 struct sigmatel_spec *spec = codec->spec; 4725 struct sigmatel_spec *spec = codec->spec;
@@ -4538,9 +4727,9 @@ static int stac92xx_hp_hdx_check_power_status(struct hda_codec *codec,
4538 if (nid == 0x10) { 4727 if (nid == 0x10) {
4539 if (snd_hda_codec_amp_read(codec, nid, 0, HDA_OUTPUT, 0) & 4728 if (snd_hda_codec_amp_read(codec, nid, 0, HDA_OUTPUT, 0) &
4540 HDA_AMP_MUTE) 4729 HDA_AMP_MUTE)
4541 spec->gpio_data &= ~0x08; /* orange */ 4730 spec->gpio_data &= ~spec->gpio_led; /* orange */
4542 else 4731 else
4543 spec->gpio_data |= 0x08; /* white */ 4732 spec->gpio_data |= spec->gpio_led; /* white */
4544 4733
4545 stac_gpio_set(codec, spec->gpio_mask, 4734 stac_gpio_set(codec, spec->gpio_mask,
4546 spec->gpio_dir, 4735 spec->gpio_dir,
@@ -5186,6 +5375,15 @@ again:
5186 if (get_wcaps(codec, 0xa) & AC_WCAP_IN_AMP) 5375 if (get_wcaps(codec, 0xa) & AC_WCAP_IN_AMP)
5187 snd_hda_sequence_write_cache(codec, unmute_init); 5376 snd_hda_sequence_write_cache(codec, unmute_init);
5188 5377
5378 /* Some HP machines seem to have unstable codec communications
5379 * especially with ATI fglrx driver. For recovering from the
5380 * CORB/RIRB stall, allow the BUS reset and keep always sync
5381 */
5382 if (spec->board_config == STAC_HP_DV5) {
5383 codec->bus->sync_write = 1;
5384 codec->bus->allow_bus_reset = 1;
5385 }
5386
5189 spec->aloopback_ctl = stac92hd71bxx_loopback; 5387 spec->aloopback_ctl = stac92hd71bxx_loopback;
5190 spec->aloopback_mask = 0x50; 5388 spec->aloopback_mask = 0x50;
5191 spec->aloopback_shift = 0; 5389 spec->aloopback_shift = 0;
@@ -5219,6 +5417,15 @@ again:
5219 spec->num_smuxes = 0; 5417 spec->num_smuxes = 0;
5220 spec->num_dmuxes = 1; 5418 spec->num_dmuxes = 1;
5221 break; 5419 break;
5420 case STAC_HP_DV4_1222NR:
5421 spec->num_dmics = 1;
5422 /* I don't know if it needs 1 or 2 smuxes - will wait for
5423 * bug reports to fix if needed
5424 */
5425 spec->num_smuxes = 1;
5426 spec->num_dmuxes = 1;
5427 spec->gpio_led = 0x01;
5428 /* fallthrough */
5222 case STAC_HP_DV5: 5429 case STAC_HP_DV5:
5223 snd_hda_codec_set_pincfg(codec, 0x0d, 0x90170010); 5430 snd_hda_codec_set_pincfg(codec, 0x0d, 0x90170010);
5224 stac92xx_auto_set_pinctl(codec, 0x0d, AC_PINCTL_OUT_EN); 5431 stac92xx_auto_set_pinctl(codec, 0x0d, AC_PINCTL_OUT_EN);
@@ -5227,22 +5434,21 @@ again:
5227 spec->num_dmics = 1; 5434 spec->num_dmics = 1;
5228 spec->num_dmuxes = 1; 5435 spec->num_dmuxes = 1;
5229 spec->num_smuxes = 1; 5436 spec->num_smuxes = 1;
5230 /*
5231 * For controlling MUTE LED on HP HDX16/HDX18 notebooks,
5232 * the CONFIG_SND_HDA_POWER_SAVE is needed to be set.
5233 */
5234#ifdef CONFIG_SND_HDA_POWER_SAVE
5235 /* orange/white mute led on GPIO3, orange=0, white=1 */ 5437 /* orange/white mute led on GPIO3, orange=0, white=1 */
5236 spec->gpio_mask |= 0x08; 5438 spec->gpio_led = 0x08;
5237 spec->gpio_dir |= 0x08; 5439 break;
5238 spec->gpio_data |= 0x08; /* set to white */ 5440 }
5239 5441
5442#ifdef CONFIG_SND_HDA_POWER_SAVE
5443 if (spec->gpio_led) {
5444 spec->gpio_mask |= spec->gpio_led;
5445 spec->gpio_dir |= spec->gpio_led;
5446 spec->gpio_data |= spec->gpio_led;
5240 /* register check_power_status callback. */ 5447 /* register check_power_status callback. */
5241 codec->patch_ops.check_power_status = 5448 codec->patch_ops.check_power_status =
5242 stac92xx_hp_hdx_check_power_status; 5449 stac92xx_hp_check_power_status;
5450 }
5243#endif 5451#endif
5244 break;
5245 };
5246 5452
5247 spec->multiout.dac_nids = spec->dac_nids; 5453 spec->multiout.dac_nids = spec->dac_nids;
5248 if (spec->dinput_mux) 5454 if (spec->dinput_mux)
@@ -5267,7 +5473,7 @@ again:
5267 codec->proc_widget_hook = stac92hd7x_proc_hook; 5473 codec->proc_widget_hook = stac92hd7x_proc_hook;
5268 5474
5269 return 0; 5475 return 0;
5270}; 5476}
5271 5477
5272static int patch_stac922x(struct hda_codec *codec) 5478static int patch_stac922x(struct hda_codec *codec)
5273{ 5479{
@@ -5422,7 +5628,7 @@ static int patch_stac927x(struct hda_codec *codec)
5422 /* correct the device field to SPDIF out */ 5628 /* correct the device field to SPDIF out */
5423 snd_hda_codec_set_pincfg(codec, 0x21, 0x01442070); 5629 snd_hda_codec_set_pincfg(codec, 0x21, 0x01442070);
5424 break; 5630 break;
5425 }; 5631 }
5426 /* configure the analog microphone on some laptops */ 5632 /* configure the analog microphone on some laptops */
5427 snd_hda_codec_set_pincfg(codec, 0x0c, 0x90a79130); 5633 snd_hda_codec_set_pincfg(codec, 0x0c, 0x90a79130);
5428 /* correct the front output jack as a hp out */ 5634 /* correct the front output jack as a hp out */
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
index b25a5cc637d..8e004fb6961 100644
--- a/sound/pci/hda/patch_via.c
+++ b/sound/pci/hda/patch_via.c
@@ -205,7 +205,7 @@ struct via_spec {
205 205
206 /* playback */ 206 /* playback */
207 struct hda_multi_out multiout; 207 struct hda_multi_out multiout;
208 hda_nid_t extra_dig_out_nid; 208 hda_nid_t slave_dig_outs[2];
209 209
210 /* capture */ 210 /* capture */
211 unsigned int num_adc_nids; 211 unsigned int num_adc_nids;
@@ -731,21 +731,6 @@ static int via_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
731 return snd_hda_multi_out_dig_close(codec, &spec->multiout); 731 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
732} 732}
733 733
734/* setup SPDIF output stream */
735static void setup_dig_playback_stream(struct hda_codec *codec, hda_nid_t nid,
736 unsigned int stream_tag, unsigned int format)
737{
738 /* turn off SPDIF once; otherwise the IEC958 bits won't be updated */
739 if (codec->spdif_ctls & AC_DIG1_ENABLE)
740 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
741 codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff);
742 snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format);
743 /* turn on again (if needed) */
744 if (codec->spdif_ctls & AC_DIG1_ENABLE)
745 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
746 codec->spdif_ctls & 0xff);
747}
748
749static int via_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, 734static int via_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
750 struct hda_codec *codec, 735 struct hda_codec *codec,
751 unsigned int stream_tag, 736 unsigned int stream_tag,
@@ -753,19 +738,16 @@ static int via_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
753 struct snd_pcm_substream *substream) 738 struct snd_pcm_substream *substream)
754{ 739{
755 struct via_spec *spec = codec->spec; 740 struct via_spec *spec = codec->spec;
756 hda_nid_t nid; 741 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
757 742 stream_tag, format, substream);
758 /* 1st or 2nd S/PDIF */ 743}
759 if (substream->number == 0)
760 nid = spec->multiout.dig_out_nid;
761 else if (substream->number == 1)
762 nid = spec->extra_dig_out_nid;
763 else
764 return -1;
765 744
766 mutex_lock(&codec->spdif_mutex); 745static int via_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
767 setup_dig_playback_stream(codec, nid, stream_tag, format); 746 struct hda_codec *codec,
768 mutex_unlock(&codec->spdif_mutex); 747 struct snd_pcm_substream *substream)
748{
749 struct via_spec *spec = codec->spec;
750 snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
769 return 0; 751 return 0;
770} 752}
771 753
@@ -842,7 +824,8 @@ static struct hda_pcm_stream vt1708_pcm_digital_playback = {
842 .ops = { 824 .ops = {
843 .open = via_dig_playback_pcm_open, 825 .open = via_dig_playback_pcm_open,
844 .close = via_dig_playback_pcm_close, 826 .close = via_dig_playback_pcm_close,
845 .prepare = via_dig_playback_pcm_prepare 827 .prepare = via_dig_playback_pcm_prepare,
828 .cleanup = via_dig_playback_pcm_cleanup
846 }, 829 },
847}; 830};
848 831
@@ -874,13 +857,6 @@ static int via_build_controls(struct hda_codec *codec)
874 if (err < 0) 857 if (err < 0)
875 return err; 858 return err;
876 spec->multiout.share_spdif = 1; 859 spec->multiout.share_spdif = 1;
877
878 if (spec->extra_dig_out_nid) {
879 err = snd_hda_create_spdif_out_ctls(codec,
880 spec->extra_dig_out_nid);
881 if (err < 0)
882 return err;
883 }
884 } 860 }
885 if (spec->dig_in_nid) { 861 if (spec->dig_in_nid) {
886 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid); 862 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
@@ -1013,10 +989,6 @@ static void via_unsol_event(struct hda_codec *codec,
1013 via_gpio_control(codec); 989 via_gpio_control(codec);
1014} 990}
1015 991
1016static hda_nid_t slave_dig_outs[] = {
1017 0,
1018};
1019
1020static int via_init(struct hda_codec *codec) 992static int via_init(struct hda_codec *codec)
1021{ 993{
1022 struct via_spec *spec = codec->spec; 994 struct via_spec *spec = codec->spec;
@@ -1051,8 +1023,9 @@ static int via_init(struct hda_codec *codec)
1051 snd_hda_codec_write(codec, spec->autocfg.dig_in_pin, 0, 1023 snd_hda_codec_write(codec, spec->autocfg.dig_in_pin, 0,
1052 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN); 1024 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN);
1053 1025
1054 /* no slave outs */ 1026 /* assign slave outs */
1055 codec->slave_dig_outs = slave_dig_outs; 1027 if (spec->slave_dig_outs[0])
1028 codec->slave_dig_outs = spec->slave_dig_outs;
1056 1029
1057 return 0; 1030 return 0;
1058} 1031}
@@ -2134,7 +2107,8 @@ static struct hda_pcm_stream vt1708B_pcm_digital_playback = {
2134 .ops = { 2107 .ops = {
2135 .open = via_dig_playback_pcm_open, 2108 .open = via_dig_playback_pcm_open,
2136 .close = via_dig_playback_pcm_close, 2109 .close = via_dig_playback_pcm_close,
2137 .prepare = via_dig_playback_pcm_prepare 2110 .prepare = via_dig_playback_pcm_prepare,
2111 .cleanup = via_dig_playback_pcm_cleanup
2138 }, 2112 },
2139}; 2113};
2140 2114
@@ -2589,14 +2563,15 @@ static struct hda_pcm_stream vt1708S_pcm_analog_capture = {
2589}; 2563};
2590 2564
2591static struct hda_pcm_stream vt1708S_pcm_digital_playback = { 2565static struct hda_pcm_stream vt1708S_pcm_digital_playback = {
2592 .substreams = 2, 2566 .substreams = 1,
2593 .channels_min = 2, 2567 .channels_min = 2,
2594 .channels_max = 2, 2568 .channels_max = 2,
2595 /* NID is set in via_build_pcms */ 2569 /* NID is set in via_build_pcms */
2596 .ops = { 2570 .ops = {
2597 .open = via_dig_playback_pcm_open, 2571 .open = via_dig_playback_pcm_open,
2598 .close = via_dig_playback_pcm_close, 2572 .close = via_dig_playback_pcm_close,
2599 .prepare = via_dig_playback_pcm_prepare 2573 .prepare = via_dig_playback_pcm_prepare,
2574 .cleanup = via_dig_playback_pcm_cleanup
2600 }, 2575 },
2601}; 2576};
2602 2577
@@ -2805,14 +2780,37 @@ static int vt1708S_auto_create_analog_input_ctls(struct via_spec *spec,
2805 return 0; 2780 return 0;
2806} 2781}
2807 2782
2783/* fill out digital output widgets; one for master and one for slave outputs */
2784static void fill_dig_outs(struct hda_codec *codec)
2785{
2786 struct via_spec *spec = codec->spec;
2787 int i;
2788
2789 for (i = 0; i < spec->autocfg.dig_outs; i++) {
2790 hda_nid_t nid;
2791 int conn;
2792
2793 nid = spec->autocfg.dig_out_pins[i];
2794 if (!nid)
2795 continue;
2796 conn = snd_hda_get_connections(codec, nid, &nid, 1);
2797 if (conn < 1)
2798 continue;
2799 if (!spec->multiout.dig_out_nid)
2800 spec->multiout.dig_out_nid = nid;
2801 else {
2802 spec->slave_dig_outs[0] = nid;
2803 break; /* at most two dig outs */
2804 }
2805 }
2806}
2807
2808static int vt1708S_parse_auto_config(struct hda_codec *codec) 2808static int vt1708S_parse_auto_config(struct hda_codec *codec)
2809{ 2809{
2810 struct via_spec *spec = codec->spec; 2810 struct via_spec *spec = codec->spec;
2811 int err; 2811 int err;
2812 static hda_nid_t vt1708s_ignore[] = {0x21, 0};
2813 2812
2814 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 2813 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
2815 vt1708s_ignore);
2816 if (err < 0) 2814 if (err < 0)
2817 return err; 2815 return err;
2818 err = vt1708S_auto_fill_dac_nids(spec, &spec->autocfg); 2816 err = vt1708S_auto_fill_dac_nids(spec, &spec->autocfg);
@@ -2833,10 +2831,7 @@ static int vt1708S_parse_auto_config(struct hda_codec *codec)
2833 2831
2834 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 2832 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
2835 2833
2836 if (spec->autocfg.dig_outs) 2834 fill_dig_outs(codec);
2837 spec->multiout.dig_out_nid = VT1708S_DIGOUT_NID;
2838
2839 spec->extra_dig_out_nid = 0x15;
2840 2835
2841 if (spec->kctls.list) 2836 if (spec->kctls.list)
2842 spec->mixers[spec->num_mixers++] = spec->kctls.list; 2837 spec->mixers[spec->num_mixers++] = spec->kctls.list;
@@ -3000,7 +2995,8 @@ static struct hda_pcm_stream vt1702_pcm_digital_playback = {
3000 .ops = { 2995 .ops = {
3001 .open = via_dig_playback_pcm_open, 2996 .open = via_dig_playback_pcm_open,
3002 .close = via_dig_playback_pcm_close, 2997 .close = via_dig_playback_pcm_close,
3003 .prepare = via_dig_playback_pcm_prepare 2998 .prepare = via_dig_playback_pcm_prepare,
2999 .cleanup = via_dig_playback_pcm_cleanup
3004 }, 3000 },
3005}; 3001};
3006 3002
@@ -3128,10 +3124,8 @@ static int vt1702_parse_auto_config(struct hda_codec *codec)
3128{ 3124{
3129 struct via_spec *spec = codec->spec; 3125 struct via_spec *spec = codec->spec;
3130 int err; 3126 int err;
3131 static hda_nid_t vt1702_ignore[] = {0x1C, 0};
3132 3127
3133 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 3128 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
3134 vt1702_ignore);
3135 if (err < 0) 3129 if (err < 0)
3136 return err; 3130 return err;
3137 err = vt1702_auto_fill_dac_nids(spec, &spec->autocfg); 3131 err = vt1702_auto_fill_dac_nids(spec, &spec->autocfg);
@@ -3152,10 +3146,7 @@ static int vt1702_parse_auto_config(struct hda_codec *codec)
3152 3146
3153 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 3147 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
3154 3148
3155 if (spec->autocfg.dig_outs) 3149 fill_dig_outs(codec);
3156 spec->multiout.dig_out_nid = VT1702_DIGOUT_NID;
3157
3158 spec->extra_dig_out_nid = 0x1B;
3159 3150
3160 if (spec->kctls.list) 3151 if (spec->kctls.list)
3161 spec->mixers[spec->num_mixers++] = spec->kctls.list; 3152 spec->mixers[spec->num_mixers++] = spec->kctls.list;
diff --git a/sound/pci/riptide/riptide.c b/sound/pci/riptide/riptide.c
index 6f1034417a0..e51a5ef1954 100644
--- a/sound/pci/riptide/riptide.c
+++ b/sound/pci/riptide/riptide.c
@@ -889,7 +889,7 @@ static int sendcmd(struct cmdif *cif, u32 flags, u32 cmd, u32 parm,
889 spin_lock_irqsave(&cif->lock, irqflags); 889 spin_lock_irqsave(&cif->lock, irqflags);
890 while (i++ < CMDIF_TIMEOUT && !IS_READY(cif->hwport)) 890 while (i++ < CMDIF_TIMEOUT && !IS_READY(cif->hwport))
891 udelay(10); 891 udelay(10);
892 if (i >= CMDIF_TIMEOUT) { 892 if (i > CMDIF_TIMEOUT) {
893 err = -EBUSY; 893 err = -EBUSY;
894 goto errout; 894 goto errout;
895 } 895 }
@@ -907,8 +907,10 @@ static int sendcmd(struct cmdif *cif, u32 flags, u32 cmd, u32 parm,
907 WRITE_PORT_ULONG(cmdport->data1, cmd); /* write cmd */ 907 WRITE_PORT_ULONG(cmdport->data1, cmd); /* write cmd */
908 if ((flags & RESP) && ret) { 908 if ((flags & RESP) && ret) {
909 while (!IS_DATF(cmdport) && 909 while (!IS_DATF(cmdport) &&
910 time++ < CMDIF_TIMEOUT) 910 time < CMDIF_TIMEOUT) {
911 udelay(10); 911 udelay(10);
912 time++;
913 }
912 if (time < CMDIF_TIMEOUT) { /* read response */ 914 if (time < CMDIF_TIMEOUT) { /* read response */
913 ret->retlongs[0] = 915 ret->retlongs[0] =
914 READ_PORT_ULONG(cmdport->data1); 916 READ_PORT_ULONG(cmdport->data1);
@@ -1454,7 +1456,7 @@ static int snd_riptide_trigger(struct snd_pcm_substream *substream, int cmd)
1454 SEND_GPOS(cif, 0, data->id, &rptr); 1456 SEND_GPOS(cif, 0, data->id, &rptr);
1455 udelay(1); 1457 udelay(1);
1456 } while (i != rptr.retlongs[1] && j++ < MAX_WRITE_RETRY); 1458 } while (i != rptr.retlongs[1] && j++ < MAX_WRITE_RETRY);
1457 if (j >= MAX_WRITE_RETRY) 1459 if (j > MAX_WRITE_RETRY)
1458 snd_printk(KERN_ERR "Riptide: Could not stop stream!"); 1460 snd_printk(KERN_ERR "Riptide: Could not stop stream!");
1459 break; 1461 break;
1460 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 1462 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
@@ -1783,7 +1785,7 @@ snd_riptide_codec_write(struct snd_ac97 *ac97, unsigned short reg,
1783 SEND_SACR(cif, val, reg); 1785 SEND_SACR(cif, val, reg);
1784 SEND_RACR(cif, reg, &rptr); 1786 SEND_RACR(cif, reg, &rptr);
1785 } while (rptr.retwords[1] != val && i++ < MAX_WRITE_RETRY); 1787 } while (rptr.retwords[1] != val && i++ < MAX_WRITE_RETRY);
1786 if (i == MAX_WRITE_RETRY) 1788 if (i > MAX_WRITE_RETRY)
1787 snd_printdd("Write AC97 reg failed\n"); 1789 snd_printdd("Write AC97 reg failed\n");
1788} 1790}
1789 1791
diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
index d0d46295b65..3da5c029f93 100644
--- a/sound/pci/rme9652/hdsp.c
+++ b/sound/pci/rme9652/hdsp.c
@@ -28,6 +28,7 @@
28#include <linux/pci.h> 28#include <linux/pci.h>
29#include <linux/firmware.h> 29#include <linux/firmware.h>
30#include <linux/moduleparam.h> 30#include <linux/moduleparam.h>
31#include <linux/math64.h>
31 32
32#include <sound/core.h> 33#include <sound/core.h>
33#include <sound/control.h> 34#include <sound/control.h>
@@ -1047,7 +1048,6 @@ static int hdsp_set_interrupt_interval(struct hdsp *s, unsigned int frames)
1047static void hdsp_set_dds_value(struct hdsp *hdsp, int rate) 1048static void hdsp_set_dds_value(struct hdsp *hdsp, int rate)
1048{ 1049{
1049 u64 n; 1050 u64 n;
1050 u32 r;
1051 1051
1052 if (rate >= 112000) 1052 if (rate >= 112000)
1053 rate /= 4; 1053 rate /= 4;
@@ -1055,7 +1055,7 @@ static void hdsp_set_dds_value(struct hdsp *hdsp, int rate)
1055 rate /= 2; 1055 rate /= 2;
1056 1056
1057 n = DDS_NUMERATOR; 1057 n = DDS_NUMERATOR;
1058 div64_32(&n, rate, &r); 1058 n = div_u64(n, rate);
1059 /* n should be less than 2^32 for being written to FREQ register */ 1059 /* n should be less than 2^32 for being written to FREQ register */
1060 snd_BUG_ON(n >> 32); 1060 snd_BUG_ON(n >> 32);
1061 /* HDSP_freqReg and HDSP_resetPointer are the same, so keep the DDS 1061 /* HDSP_freqReg and HDSP_resetPointer are the same, so keep the DDS
@@ -3097,7 +3097,6 @@ static int snd_hdsp_get_adat_sync_check(struct snd_kcontrol *kcontrol, struct sn
3097static int hdsp_dds_offset(struct hdsp *hdsp) 3097static int hdsp_dds_offset(struct hdsp *hdsp)
3098{ 3098{
3099 u64 n; 3099 u64 n;
3100 u32 r;
3101 unsigned int dds_value = hdsp->dds_value; 3100 unsigned int dds_value = hdsp->dds_value;
3102 int system_sample_rate = hdsp->system_sample_rate; 3101 int system_sample_rate = hdsp->system_sample_rate;
3103 3102
@@ -3109,7 +3108,7 @@ static int hdsp_dds_offset(struct hdsp *hdsp)
3109 * dds_value = n / rate 3108 * dds_value = n / rate
3110 * rate = n / dds_value 3109 * rate = n / dds_value
3111 */ 3110 */
3112 div64_32(&n, dds_value, &r); 3111 n = div_u64(n, dds_value);
3113 if (system_sample_rate >= 112000) 3112 if (system_sample_rate >= 112000)
3114 n *= 4; 3113 n *= 4;
3115 else if (system_sample_rate >= 56000) 3114 else if (system_sample_rate >= 56000)
diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c
index bac2dc0c5d8..0dce331a2a3 100644
--- a/sound/pci/rme9652/hdspm.c
+++ b/sound/pci/rme9652/hdspm.c
@@ -29,6 +29,7 @@
29#include <linux/moduleparam.h> 29#include <linux/moduleparam.h>
30#include <linux/slab.h> 30#include <linux/slab.h>
31#include <linux/pci.h> 31#include <linux/pci.h>
32#include <linux/math64.h>
32#include <asm/io.h> 33#include <asm/io.h>
33 34
34#include <sound/core.h> 35#include <sound/core.h>
@@ -831,7 +832,6 @@ static int hdspm_set_interrupt_interval(struct hdspm * s, unsigned int frames)
831static void hdspm_set_dds_value(struct hdspm *hdspm, int rate) 832static void hdspm_set_dds_value(struct hdspm *hdspm, int rate)
832{ 833{
833 u64 n; 834 u64 n;
834 u32 r;
835 835
836 if (rate >= 112000) 836 if (rate >= 112000)
837 rate /= 4; 837 rate /= 4;
@@ -844,7 +844,7 @@ static void hdspm_set_dds_value(struct hdspm *hdspm, int rate)
844 */ 844 */
845 /* n = 104857600000000ULL; */ /* = 2^20 * 10^8 */ 845 /* n = 104857600000000ULL; */ /* = 2^20 * 10^8 */
846 n = 110100480000000ULL; /* Value checked for AES32 and MADI */ 846 n = 110100480000000ULL; /* Value checked for AES32 and MADI */
847 div64_32(&n, rate, &r); 847 n = div_u64(n, rate);
848 /* n should be less than 2^32 for being written to FREQ register */ 848 /* n should be less than 2^32 for being written to FREQ register */
849 snd_BUG_ON(n >> 32); 849 snd_BUG_ON(n >> 32);
850 hdspm_write(hdspm, HDSPM_freqReg, (u32)n); 850 hdspm_write(hdspm, HDSPM_freqReg, (u32)n);
diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c
index 809b233dd4a..1ef58c51c21 100644
--- a/sound/pci/via82xx.c
+++ b/sound/pci/via82xx.c
@@ -1687,7 +1687,7 @@ static int snd_via8233_pcmdxs_volume_put(struct snd_kcontrol *kcontrol,
1687 return change; 1687 return change;
1688} 1688}
1689 1689
1690static const DECLARE_TLV_DB_SCALE(db_scale_dxs, -9450, 150, 1); 1690static const DECLARE_TLV_DB_SCALE(db_scale_dxs, -4650, 150, 1);
1691 1691
1692static struct snd_kcontrol_new snd_via8233_pcmdxs_volume_control __devinitdata = { 1692static struct snd_kcontrol_new snd_via8233_pcmdxs_volume_control __devinitdata = {
1693 .name = "PCM Playback Volume", 1693 .name = "PCM Playback Volume",