Commit cb28e45ba2aa42393596a364d4f947027db8a1b5
Committed by
Jaroslav Kysela
1 parent
1d4b822be6
Exists in
master
and in
7 other branches
[ALSA] cs46xx - Fix PM support
Modules: CS46xx driver Fix PM support on CS46xx driver. Signed-off-by: Takashi Iwai <tiwai@suse.de>
Showing 3 changed files with 22 additions and 14 deletions Inline Diff
include/sound/cs46xx.h
1 | #ifndef __SOUND_CS46XX_H | 1 | #ifndef __SOUND_CS46XX_H |
2 | #define __SOUND_CS46XX_H | 2 | #define __SOUND_CS46XX_H |
3 | 3 | ||
4 | /* | 4 | /* |
5 | * Copyright (c) by Jaroslav Kysela <perex@suse.cz>, | 5 | * Copyright (c) by Jaroslav Kysela <perex@suse.cz>, |
6 | * Cirrus Logic, Inc. | 6 | * Cirrus Logic, Inc. |
7 | * Definitions for Cirrus Logic CS46xx chips | 7 | * Definitions for Cirrus Logic CS46xx chips |
8 | * | 8 | * |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of the GNU General Public License as published by | 11 | * it under the terms of the GNU General Public License as published by |
12 | * the Free Software Foundation; either version 2 of the License, or | 12 | * the Free Software Foundation; either version 2 of the License, or |
13 | * (at your option) any later version. | 13 | * (at your option) any later version. |
14 | * | 14 | * |
15 | * This program is distributed in the hope that it will be useful, | 15 | * This program is distributed in the hope that it will be useful, |
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
18 | * GNU General Public License for more details. | 18 | * GNU General Public License for more details. |
19 | * | 19 | * |
20 | * You should have received a copy of the GNU General Public License | 20 | * You should have received a copy of the GNU General Public License |
21 | * along with this program; if not, write to the Free Software | 21 | * along with this program; if not, write to the Free Software |
22 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 22 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
23 | * | 23 | * |
24 | */ | 24 | */ |
25 | 25 | ||
26 | #include "pcm.h" | 26 | #include "pcm.h" |
27 | #include "pcm-indirect.h" | 27 | #include "pcm-indirect.h" |
28 | #include "rawmidi.h" | 28 | #include "rawmidi.h" |
29 | #include "ac97_codec.h" | 29 | #include "ac97_codec.h" |
30 | #include "cs46xx_dsp_spos.h" | 30 | #include "cs46xx_dsp_spos.h" |
31 | 31 | ||
32 | /* | 32 | /* |
33 | * Direct registers | 33 | * Direct registers |
34 | */ | 34 | */ |
35 | 35 | ||
36 | /* | 36 | /* |
37 | * The following define the offsets of the registers accessed via base address | 37 | * The following define the offsets of the registers accessed via base address |
38 | * register zero on the CS46xx part. | 38 | * register zero on the CS46xx part. |
39 | */ | 39 | */ |
40 | #define BA0_HISR 0x00000000 | 40 | #define BA0_HISR 0x00000000 |
41 | #define BA0_HSR0 0x00000004 | 41 | #define BA0_HSR0 0x00000004 |
42 | #define BA0_HICR 0x00000008 | 42 | #define BA0_HICR 0x00000008 |
43 | #define BA0_DMSR 0x00000100 | 43 | #define BA0_DMSR 0x00000100 |
44 | #define BA0_HSAR 0x00000110 | 44 | #define BA0_HSAR 0x00000110 |
45 | #define BA0_HDAR 0x00000114 | 45 | #define BA0_HDAR 0x00000114 |
46 | #define BA0_HDMR 0x00000118 | 46 | #define BA0_HDMR 0x00000118 |
47 | #define BA0_HDCR 0x0000011C | 47 | #define BA0_HDCR 0x0000011C |
48 | #define BA0_PFMC 0x00000200 | 48 | #define BA0_PFMC 0x00000200 |
49 | #define BA0_PFCV1 0x00000204 | 49 | #define BA0_PFCV1 0x00000204 |
50 | #define BA0_PFCV2 0x00000208 | 50 | #define BA0_PFCV2 0x00000208 |
51 | #define BA0_PCICFG00 0x00000300 | 51 | #define BA0_PCICFG00 0x00000300 |
52 | #define BA0_PCICFG04 0x00000304 | 52 | #define BA0_PCICFG04 0x00000304 |
53 | #define BA0_PCICFG08 0x00000308 | 53 | #define BA0_PCICFG08 0x00000308 |
54 | #define BA0_PCICFG0C 0x0000030C | 54 | #define BA0_PCICFG0C 0x0000030C |
55 | #define BA0_PCICFG10 0x00000310 | 55 | #define BA0_PCICFG10 0x00000310 |
56 | #define BA0_PCICFG14 0x00000314 | 56 | #define BA0_PCICFG14 0x00000314 |
57 | #define BA0_PCICFG18 0x00000318 | 57 | #define BA0_PCICFG18 0x00000318 |
58 | #define BA0_PCICFG1C 0x0000031C | 58 | #define BA0_PCICFG1C 0x0000031C |
59 | #define BA0_PCICFG20 0x00000320 | 59 | #define BA0_PCICFG20 0x00000320 |
60 | #define BA0_PCICFG24 0x00000324 | 60 | #define BA0_PCICFG24 0x00000324 |
61 | #define BA0_PCICFG28 0x00000328 | 61 | #define BA0_PCICFG28 0x00000328 |
62 | #define BA0_PCICFG2C 0x0000032C | 62 | #define BA0_PCICFG2C 0x0000032C |
63 | #define BA0_PCICFG30 0x00000330 | 63 | #define BA0_PCICFG30 0x00000330 |
64 | #define BA0_PCICFG34 0x00000334 | 64 | #define BA0_PCICFG34 0x00000334 |
65 | #define BA0_PCICFG38 0x00000338 | 65 | #define BA0_PCICFG38 0x00000338 |
66 | #define BA0_PCICFG3C 0x0000033C | 66 | #define BA0_PCICFG3C 0x0000033C |
67 | #define BA0_CLKCR1 0x00000400 | 67 | #define BA0_CLKCR1 0x00000400 |
68 | #define BA0_CLKCR2 0x00000404 | 68 | #define BA0_CLKCR2 0x00000404 |
69 | #define BA0_PLLM 0x00000408 | 69 | #define BA0_PLLM 0x00000408 |
70 | #define BA0_PLLCC 0x0000040C | 70 | #define BA0_PLLCC 0x0000040C |
71 | #define BA0_FRR 0x00000410 | 71 | #define BA0_FRR 0x00000410 |
72 | #define BA0_CFL1 0x00000414 | 72 | #define BA0_CFL1 0x00000414 |
73 | #define BA0_CFL2 0x00000418 | 73 | #define BA0_CFL2 0x00000418 |
74 | #define BA0_SERMC1 0x00000420 | 74 | #define BA0_SERMC1 0x00000420 |
75 | #define BA0_SERMC2 0x00000424 | 75 | #define BA0_SERMC2 0x00000424 |
76 | #define BA0_SERC1 0x00000428 | 76 | #define BA0_SERC1 0x00000428 |
77 | #define BA0_SERC2 0x0000042C | 77 | #define BA0_SERC2 0x0000042C |
78 | #define BA0_SERC3 0x00000430 | 78 | #define BA0_SERC3 0x00000430 |
79 | #define BA0_SERC4 0x00000434 | 79 | #define BA0_SERC4 0x00000434 |
80 | #define BA0_SERC5 0x00000438 | 80 | #define BA0_SERC5 0x00000438 |
81 | #define BA0_SERBSP 0x0000043C | 81 | #define BA0_SERBSP 0x0000043C |
82 | #define BA0_SERBST 0x00000440 | 82 | #define BA0_SERBST 0x00000440 |
83 | #define BA0_SERBCM 0x00000444 | 83 | #define BA0_SERBCM 0x00000444 |
84 | #define BA0_SERBAD 0x00000448 | 84 | #define BA0_SERBAD 0x00000448 |
85 | #define BA0_SERBCF 0x0000044C | 85 | #define BA0_SERBCF 0x0000044C |
86 | #define BA0_SERBWP 0x00000450 | 86 | #define BA0_SERBWP 0x00000450 |
87 | #define BA0_SERBRP 0x00000454 | 87 | #define BA0_SERBRP 0x00000454 |
88 | #ifndef NO_CS4612 | 88 | #ifndef NO_CS4612 |
89 | #define BA0_ASER_FADDR 0x00000458 | 89 | #define BA0_ASER_FADDR 0x00000458 |
90 | #endif | 90 | #endif |
91 | #define BA0_ACCTL 0x00000460 | 91 | #define BA0_ACCTL 0x00000460 |
92 | #define BA0_ACSTS 0x00000464 | 92 | #define BA0_ACSTS 0x00000464 |
93 | #define BA0_ACOSV 0x00000468 | 93 | #define BA0_ACOSV 0x00000468 |
94 | #define BA0_ACCAD 0x0000046C | 94 | #define BA0_ACCAD 0x0000046C |
95 | #define BA0_ACCDA 0x00000470 | 95 | #define BA0_ACCDA 0x00000470 |
96 | #define BA0_ACISV 0x00000474 | 96 | #define BA0_ACISV 0x00000474 |
97 | #define BA0_ACSAD 0x00000478 | 97 | #define BA0_ACSAD 0x00000478 |
98 | #define BA0_ACSDA 0x0000047C | 98 | #define BA0_ACSDA 0x0000047C |
99 | #define BA0_JSPT 0x00000480 | 99 | #define BA0_JSPT 0x00000480 |
100 | #define BA0_JSCTL 0x00000484 | 100 | #define BA0_JSCTL 0x00000484 |
101 | #define BA0_JSC1 0x00000488 | 101 | #define BA0_JSC1 0x00000488 |
102 | #define BA0_JSC2 0x0000048C | 102 | #define BA0_JSC2 0x0000048C |
103 | #define BA0_MIDCR 0x00000490 | 103 | #define BA0_MIDCR 0x00000490 |
104 | #define BA0_MIDSR 0x00000494 | 104 | #define BA0_MIDSR 0x00000494 |
105 | #define BA0_MIDWP 0x00000498 | 105 | #define BA0_MIDWP 0x00000498 |
106 | #define BA0_MIDRP 0x0000049C | 106 | #define BA0_MIDRP 0x0000049C |
107 | #define BA0_JSIO 0x000004A0 | 107 | #define BA0_JSIO 0x000004A0 |
108 | #ifndef NO_CS4612 | 108 | #ifndef NO_CS4612 |
109 | #define BA0_ASER_MASTER 0x000004A4 | 109 | #define BA0_ASER_MASTER 0x000004A4 |
110 | #endif | 110 | #endif |
111 | #define BA0_CFGI 0x000004B0 | 111 | #define BA0_CFGI 0x000004B0 |
112 | #define BA0_SSVID 0x000004B4 | 112 | #define BA0_SSVID 0x000004B4 |
113 | #define BA0_GPIOR 0x000004B8 | 113 | #define BA0_GPIOR 0x000004B8 |
114 | #ifndef NO_CS4612 | 114 | #ifndef NO_CS4612 |
115 | #define BA0_EGPIODR 0x000004BC | 115 | #define BA0_EGPIODR 0x000004BC |
116 | #define BA0_EGPIOPTR 0x000004C0 | 116 | #define BA0_EGPIOPTR 0x000004C0 |
117 | #define BA0_EGPIOTR 0x000004C4 | 117 | #define BA0_EGPIOTR 0x000004C4 |
118 | #define BA0_EGPIOWR 0x000004C8 | 118 | #define BA0_EGPIOWR 0x000004C8 |
119 | #define BA0_EGPIOSR 0x000004CC | 119 | #define BA0_EGPIOSR 0x000004CC |
120 | #define BA0_SERC6 0x000004D0 | 120 | #define BA0_SERC6 0x000004D0 |
121 | #define BA0_SERC7 0x000004D4 | 121 | #define BA0_SERC7 0x000004D4 |
122 | #define BA0_SERACC 0x000004D8 | 122 | #define BA0_SERACC 0x000004D8 |
123 | #define BA0_ACCTL2 0x000004E0 | 123 | #define BA0_ACCTL2 0x000004E0 |
124 | #define BA0_ACSTS2 0x000004E4 | 124 | #define BA0_ACSTS2 0x000004E4 |
125 | #define BA0_ACOSV2 0x000004E8 | 125 | #define BA0_ACOSV2 0x000004E8 |
126 | #define BA0_ACCAD2 0x000004EC | 126 | #define BA0_ACCAD2 0x000004EC |
127 | #define BA0_ACCDA2 0x000004F0 | 127 | #define BA0_ACCDA2 0x000004F0 |
128 | #define BA0_ACISV2 0x000004F4 | 128 | #define BA0_ACISV2 0x000004F4 |
129 | #define BA0_ACSAD2 0x000004F8 | 129 | #define BA0_ACSAD2 0x000004F8 |
130 | #define BA0_ACSDA2 0x000004FC | 130 | #define BA0_ACSDA2 0x000004FC |
131 | #define BA0_IOTAC0 0x00000500 | 131 | #define BA0_IOTAC0 0x00000500 |
132 | #define BA0_IOTAC1 0x00000504 | 132 | #define BA0_IOTAC1 0x00000504 |
133 | #define BA0_IOTAC2 0x00000508 | 133 | #define BA0_IOTAC2 0x00000508 |
134 | #define BA0_IOTAC3 0x0000050C | 134 | #define BA0_IOTAC3 0x0000050C |
135 | #define BA0_IOTAC4 0x00000510 | 135 | #define BA0_IOTAC4 0x00000510 |
136 | #define BA0_IOTAC5 0x00000514 | 136 | #define BA0_IOTAC5 0x00000514 |
137 | #define BA0_IOTAC6 0x00000518 | 137 | #define BA0_IOTAC6 0x00000518 |
138 | #define BA0_IOTAC7 0x0000051C | 138 | #define BA0_IOTAC7 0x0000051C |
139 | #define BA0_IOTAC8 0x00000520 | 139 | #define BA0_IOTAC8 0x00000520 |
140 | #define BA0_IOTAC9 0x00000524 | 140 | #define BA0_IOTAC9 0x00000524 |
141 | #define BA0_IOTAC10 0x00000528 | 141 | #define BA0_IOTAC10 0x00000528 |
142 | #define BA0_IOTAC11 0x0000052C | 142 | #define BA0_IOTAC11 0x0000052C |
143 | #define BA0_IOTFR0 0x00000540 | 143 | #define BA0_IOTFR0 0x00000540 |
144 | #define BA0_IOTFR1 0x00000544 | 144 | #define BA0_IOTFR1 0x00000544 |
145 | #define BA0_IOTFR2 0x00000548 | 145 | #define BA0_IOTFR2 0x00000548 |
146 | #define BA0_IOTFR3 0x0000054C | 146 | #define BA0_IOTFR3 0x0000054C |
147 | #define BA0_IOTFR4 0x00000550 | 147 | #define BA0_IOTFR4 0x00000550 |
148 | #define BA0_IOTFR5 0x00000554 | 148 | #define BA0_IOTFR5 0x00000554 |
149 | #define BA0_IOTFR6 0x00000558 | 149 | #define BA0_IOTFR6 0x00000558 |
150 | #define BA0_IOTFR7 0x0000055C | 150 | #define BA0_IOTFR7 0x0000055C |
151 | #define BA0_IOTFIFO 0x00000580 | 151 | #define BA0_IOTFIFO 0x00000580 |
152 | #define BA0_IOTRRD 0x00000584 | 152 | #define BA0_IOTRRD 0x00000584 |
153 | #define BA0_IOTFP 0x00000588 | 153 | #define BA0_IOTFP 0x00000588 |
154 | #define BA0_IOTCR 0x0000058C | 154 | #define BA0_IOTCR 0x0000058C |
155 | #define BA0_DPCID 0x00000590 | 155 | #define BA0_DPCID 0x00000590 |
156 | #define BA0_DPCIA 0x00000594 | 156 | #define BA0_DPCIA 0x00000594 |
157 | #define BA0_DPCIC 0x00000598 | 157 | #define BA0_DPCIC 0x00000598 |
158 | #define BA0_PCPCIR 0x00000600 | 158 | #define BA0_PCPCIR 0x00000600 |
159 | #define BA0_PCPCIG 0x00000604 | 159 | #define BA0_PCPCIG 0x00000604 |
160 | #define BA0_PCPCIEN 0x00000608 | 160 | #define BA0_PCPCIEN 0x00000608 |
161 | #define BA0_EPCIPMC 0x00000610 | 161 | #define BA0_EPCIPMC 0x00000610 |
162 | #endif | 162 | #endif |
163 | 163 | ||
164 | /* | 164 | /* |
165 | * The following define the offsets of the registers and memories accessed via | 165 | * The following define the offsets of the registers and memories accessed via |
166 | * base address register one on the CS46xx part. | 166 | * base address register one on the CS46xx part. |
167 | */ | 167 | */ |
168 | #define BA1_SP_DMEM0 0x00000000 | 168 | #define BA1_SP_DMEM0 0x00000000 |
169 | #define BA1_SP_DMEM1 0x00010000 | 169 | #define BA1_SP_DMEM1 0x00010000 |
170 | #define BA1_SP_PMEM 0x00020000 | 170 | #define BA1_SP_PMEM 0x00020000 |
171 | #define BA1_SP_REG 0x00030000 | 171 | #define BA1_SP_REG 0x00030000 |
172 | #define BA1_SPCR 0x00030000 | 172 | #define BA1_SPCR 0x00030000 |
173 | #define BA1_DREG 0x00030004 | 173 | #define BA1_DREG 0x00030004 |
174 | #define BA1_DSRWP 0x00030008 | 174 | #define BA1_DSRWP 0x00030008 |
175 | #define BA1_TWPR 0x0003000C | 175 | #define BA1_TWPR 0x0003000C |
176 | #define BA1_SPWR 0x00030010 | 176 | #define BA1_SPWR 0x00030010 |
177 | #define BA1_SPIR 0x00030014 | 177 | #define BA1_SPIR 0x00030014 |
178 | #define BA1_FGR1 0x00030020 | 178 | #define BA1_FGR1 0x00030020 |
179 | #define BA1_SPCS 0x00030028 | 179 | #define BA1_SPCS 0x00030028 |
180 | #define BA1_SDSR 0x0003002C | 180 | #define BA1_SDSR 0x0003002C |
181 | #define BA1_FRMT 0x00030030 | 181 | #define BA1_FRMT 0x00030030 |
182 | #define BA1_FRCC 0x00030034 | 182 | #define BA1_FRCC 0x00030034 |
183 | #define BA1_FRSC 0x00030038 | 183 | #define BA1_FRSC 0x00030038 |
184 | #define BA1_OMNI_MEM 0x000E0000 | 184 | #define BA1_OMNI_MEM 0x000E0000 |
185 | 185 | ||
186 | 186 | ||
187 | /* | 187 | /* |
188 | * The following defines are for the flags in the host interrupt status | 188 | * The following defines are for the flags in the host interrupt status |
189 | * register. | 189 | * register. |
190 | */ | 190 | */ |
191 | #define HISR_VC_MASK 0x0000FFFF | 191 | #define HISR_VC_MASK 0x0000FFFF |
192 | #define HISR_VC0 0x00000001 | 192 | #define HISR_VC0 0x00000001 |
193 | #define HISR_VC1 0x00000002 | 193 | #define HISR_VC1 0x00000002 |
194 | #define HISR_VC2 0x00000004 | 194 | #define HISR_VC2 0x00000004 |
195 | #define HISR_VC3 0x00000008 | 195 | #define HISR_VC3 0x00000008 |
196 | #define HISR_VC4 0x00000010 | 196 | #define HISR_VC4 0x00000010 |
197 | #define HISR_VC5 0x00000020 | 197 | #define HISR_VC5 0x00000020 |
198 | #define HISR_VC6 0x00000040 | 198 | #define HISR_VC6 0x00000040 |
199 | #define HISR_VC7 0x00000080 | 199 | #define HISR_VC7 0x00000080 |
200 | #define HISR_VC8 0x00000100 | 200 | #define HISR_VC8 0x00000100 |
201 | #define HISR_VC9 0x00000200 | 201 | #define HISR_VC9 0x00000200 |
202 | #define HISR_VC10 0x00000400 | 202 | #define HISR_VC10 0x00000400 |
203 | #define HISR_VC11 0x00000800 | 203 | #define HISR_VC11 0x00000800 |
204 | #define HISR_VC12 0x00001000 | 204 | #define HISR_VC12 0x00001000 |
205 | #define HISR_VC13 0x00002000 | 205 | #define HISR_VC13 0x00002000 |
206 | #define HISR_VC14 0x00004000 | 206 | #define HISR_VC14 0x00004000 |
207 | #define HISR_VC15 0x00008000 | 207 | #define HISR_VC15 0x00008000 |
208 | #define HISR_INT0 0x00010000 | 208 | #define HISR_INT0 0x00010000 |
209 | #define HISR_INT1 0x00020000 | 209 | #define HISR_INT1 0x00020000 |
210 | #define HISR_DMAI 0x00040000 | 210 | #define HISR_DMAI 0x00040000 |
211 | #define HISR_FROVR 0x00080000 | 211 | #define HISR_FROVR 0x00080000 |
212 | #define HISR_MIDI 0x00100000 | 212 | #define HISR_MIDI 0x00100000 |
213 | #ifdef NO_CS4612 | 213 | #ifdef NO_CS4612 |
214 | #define HISR_RESERVED 0x0FE00000 | 214 | #define HISR_RESERVED 0x0FE00000 |
215 | #else | 215 | #else |
216 | #define HISR_SBINT 0x00200000 | 216 | #define HISR_SBINT 0x00200000 |
217 | #define HISR_RESERVED 0x0FC00000 | 217 | #define HISR_RESERVED 0x0FC00000 |
218 | #endif | 218 | #endif |
219 | #define HISR_H0P 0x40000000 | 219 | #define HISR_H0P 0x40000000 |
220 | #define HISR_INTENA 0x80000000 | 220 | #define HISR_INTENA 0x80000000 |
221 | 221 | ||
222 | /* | 222 | /* |
223 | * The following defines are for the flags in the host signal register 0. | 223 | * The following defines are for the flags in the host signal register 0. |
224 | */ | 224 | */ |
225 | #define HSR0_VC_MASK 0xFFFFFFFF | 225 | #define HSR0_VC_MASK 0xFFFFFFFF |
226 | #define HSR0_VC16 0x00000001 | 226 | #define HSR0_VC16 0x00000001 |
227 | #define HSR0_VC17 0x00000002 | 227 | #define HSR0_VC17 0x00000002 |
228 | #define HSR0_VC18 0x00000004 | 228 | #define HSR0_VC18 0x00000004 |
229 | #define HSR0_VC19 0x00000008 | 229 | #define HSR0_VC19 0x00000008 |
230 | #define HSR0_VC20 0x00000010 | 230 | #define HSR0_VC20 0x00000010 |
231 | #define HSR0_VC21 0x00000020 | 231 | #define HSR0_VC21 0x00000020 |
232 | #define HSR0_VC22 0x00000040 | 232 | #define HSR0_VC22 0x00000040 |
233 | #define HSR0_VC23 0x00000080 | 233 | #define HSR0_VC23 0x00000080 |
234 | #define HSR0_VC24 0x00000100 | 234 | #define HSR0_VC24 0x00000100 |
235 | #define HSR0_VC25 0x00000200 | 235 | #define HSR0_VC25 0x00000200 |
236 | #define HSR0_VC26 0x00000400 | 236 | #define HSR0_VC26 0x00000400 |
237 | #define HSR0_VC27 0x00000800 | 237 | #define HSR0_VC27 0x00000800 |
238 | #define HSR0_VC28 0x00001000 | 238 | #define HSR0_VC28 0x00001000 |
239 | #define HSR0_VC29 0x00002000 | 239 | #define HSR0_VC29 0x00002000 |
240 | #define HSR0_VC30 0x00004000 | 240 | #define HSR0_VC30 0x00004000 |
241 | #define HSR0_VC31 0x00008000 | 241 | #define HSR0_VC31 0x00008000 |
242 | #define HSR0_VC32 0x00010000 | 242 | #define HSR0_VC32 0x00010000 |
243 | #define HSR0_VC33 0x00020000 | 243 | #define HSR0_VC33 0x00020000 |
244 | #define HSR0_VC34 0x00040000 | 244 | #define HSR0_VC34 0x00040000 |
245 | #define HSR0_VC35 0x00080000 | 245 | #define HSR0_VC35 0x00080000 |
246 | #define HSR0_VC36 0x00100000 | 246 | #define HSR0_VC36 0x00100000 |
247 | #define HSR0_VC37 0x00200000 | 247 | #define HSR0_VC37 0x00200000 |
248 | #define HSR0_VC38 0x00400000 | 248 | #define HSR0_VC38 0x00400000 |
249 | #define HSR0_VC39 0x00800000 | 249 | #define HSR0_VC39 0x00800000 |
250 | #define HSR0_VC40 0x01000000 | 250 | #define HSR0_VC40 0x01000000 |
251 | #define HSR0_VC41 0x02000000 | 251 | #define HSR0_VC41 0x02000000 |
252 | #define HSR0_VC42 0x04000000 | 252 | #define HSR0_VC42 0x04000000 |
253 | #define HSR0_VC43 0x08000000 | 253 | #define HSR0_VC43 0x08000000 |
254 | #define HSR0_VC44 0x10000000 | 254 | #define HSR0_VC44 0x10000000 |
255 | #define HSR0_VC45 0x20000000 | 255 | #define HSR0_VC45 0x20000000 |
256 | #define HSR0_VC46 0x40000000 | 256 | #define HSR0_VC46 0x40000000 |
257 | #define HSR0_VC47 0x80000000 | 257 | #define HSR0_VC47 0x80000000 |
258 | 258 | ||
259 | /* | 259 | /* |
260 | * The following defines are for the flags in the host interrupt control | 260 | * The following defines are for the flags in the host interrupt control |
261 | * register. | 261 | * register. |
262 | */ | 262 | */ |
263 | #define HICR_IEV 0x00000001 | 263 | #define HICR_IEV 0x00000001 |
264 | #define HICR_CHGM 0x00000002 | 264 | #define HICR_CHGM 0x00000002 |
265 | 265 | ||
266 | /* | 266 | /* |
267 | * The following defines are for the flags in the DMA status register. | 267 | * The following defines are for the flags in the DMA status register. |
268 | */ | 268 | */ |
269 | #define DMSR_HP 0x00000001 | 269 | #define DMSR_HP 0x00000001 |
270 | #define DMSR_HR 0x00000002 | 270 | #define DMSR_HR 0x00000002 |
271 | #define DMSR_SP 0x00000004 | 271 | #define DMSR_SP 0x00000004 |
272 | #define DMSR_SR 0x00000008 | 272 | #define DMSR_SR 0x00000008 |
273 | 273 | ||
274 | /* | 274 | /* |
275 | * The following defines are for the flags in the host DMA source address | 275 | * The following defines are for the flags in the host DMA source address |
276 | * register. | 276 | * register. |
277 | */ | 277 | */ |
278 | #define HSAR_HOST_ADDR_MASK 0xFFFFFFFF | 278 | #define HSAR_HOST_ADDR_MASK 0xFFFFFFFF |
279 | #define HSAR_DSP_ADDR_MASK 0x0000FFFF | 279 | #define HSAR_DSP_ADDR_MASK 0x0000FFFF |
280 | #define HSAR_MEMID_MASK 0x000F0000 | 280 | #define HSAR_MEMID_MASK 0x000F0000 |
281 | #define HSAR_MEMID_SP_DMEM0 0x00000000 | 281 | #define HSAR_MEMID_SP_DMEM0 0x00000000 |
282 | #define HSAR_MEMID_SP_DMEM1 0x00010000 | 282 | #define HSAR_MEMID_SP_DMEM1 0x00010000 |
283 | #define HSAR_MEMID_SP_PMEM 0x00020000 | 283 | #define HSAR_MEMID_SP_PMEM 0x00020000 |
284 | #define HSAR_MEMID_SP_DEBUG 0x00030000 | 284 | #define HSAR_MEMID_SP_DEBUG 0x00030000 |
285 | #define HSAR_MEMID_OMNI_MEM 0x000E0000 | 285 | #define HSAR_MEMID_OMNI_MEM 0x000E0000 |
286 | #define HSAR_END 0x40000000 | 286 | #define HSAR_END 0x40000000 |
287 | #define HSAR_ERR 0x80000000 | 287 | #define HSAR_ERR 0x80000000 |
288 | 288 | ||
289 | /* | 289 | /* |
290 | * The following defines are for the flags in the host DMA destination address | 290 | * The following defines are for the flags in the host DMA destination address |
291 | * register. | 291 | * register. |
292 | */ | 292 | */ |
293 | #define HDAR_HOST_ADDR_MASK 0xFFFFFFFF | 293 | #define HDAR_HOST_ADDR_MASK 0xFFFFFFFF |
294 | #define HDAR_DSP_ADDR_MASK 0x0000FFFF | 294 | #define HDAR_DSP_ADDR_MASK 0x0000FFFF |
295 | #define HDAR_MEMID_MASK 0x000F0000 | 295 | #define HDAR_MEMID_MASK 0x000F0000 |
296 | #define HDAR_MEMID_SP_DMEM0 0x00000000 | 296 | #define HDAR_MEMID_SP_DMEM0 0x00000000 |
297 | #define HDAR_MEMID_SP_DMEM1 0x00010000 | 297 | #define HDAR_MEMID_SP_DMEM1 0x00010000 |
298 | #define HDAR_MEMID_SP_PMEM 0x00020000 | 298 | #define HDAR_MEMID_SP_PMEM 0x00020000 |
299 | #define HDAR_MEMID_SP_DEBUG 0x00030000 | 299 | #define HDAR_MEMID_SP_DEBUG 0x00030000 |
300 | #define HDAR_MEMID_OMNI_MEM 0x000E0000 | 300 | #define HDAR_MEMID_OMNI_MEM 0x000E0000 |
301 | #define HDAR_END 0x40000000 | 301 | #define HDAR_END 0x40000000 |
302 | #define HDAR_ERR 0x80000000 | 302 | #define HDAR_ERR 0x80000000 |
303 | 303 | ||
304 | /* | 304 | /* |
305 | * The following defines are for the flags in the host DMA control register. | 305 | * The following defines are for the flags in the host DMA control register. |
306 | */ | 306 | */ |
307 | #define HDMR_AC_MASK 0x0000F000 | 307 | #define HDMR_AC_MASK 0x0000F000 |
308 | #define HDMR_AC_8_16 0x00001000 | 308 | #define HDMR_AC_8_16 0x00001000 |
309 | #define HDMR_AC_M_S 0x00002000 | 309 | #define HDMR_AC_M_S 0x00002000 |
310 | #define HDMR_AC_B_L 0x00004000 | 310 | #define HDMR_AC_B_L 0x00004000 |
311 | #define HDMR_AC_S_U 0x00008000 | 311 | #define HDMR_AC_S_U 0x00008000 |
312 | 312 | ||
313 | /* | 313 | /* |
314 | * The following defines are for the flags in the host DMA control register. | 314 | * The following defines are for the flags in the host DMA control register. |
315 | */ | 315 | */ |
316 | #define HDCR_COUNT_MASK 0x000003FF | 316 | #define HDCR_COUNT_MASK 0x000003FF |
317 | #define HDCR_DONE 0x00004000 | 317 | #define HDCR_DONE 0x00004000 |
318 | #define HDCR_OPT 0x00008000 | 318 | #define HDCR_OPT 0x00008000 |
319 | #define HDCR_WBD 0x00400000 | 319 | #define HDCR_WBD 0x00400000 |
320 | #define HDCR_WBS 0x00800000 | 320 | #define HDCR_WBS 0x00800000 |
321 | #define HDCR_DMS_MASK 0x07000000 | 321 | #define HDCR_DMS_MASK 0x07000000 |
322 | #define HDCR_DMS_LINEAR 0x00000000 | 322 | #define HDCR_DMS_LINEAR 0x00000000 |
323 | #define HDCR_DMS_16_DWORDS 0x01000000 | 323 | #define HDCR_DMS_16_DWORDS 0x01000000 |
324 | #define HDCR_DMS_32_DWORDS 0x02000000 | 324 | #define HDCR_DMS_32_DWORDS 0x02000000 |
325 | #define HDCR_DMS_64_DWORDS 0x03000000 | 325 | #define HDCR_DMS_64_DWORDS 0x03000000 |
326 | #define HDCR_DMS_128_DWORDS 0x04000000 | 326 | #define HDCR_DMS_128_DWORDS 0x04000000 |
327 | #define HDCR_DMS_256_DWORDS 0x05000000 | 327 | #define HDCR_DMS_256_DWORDS 0x05000000 |
328 | #define HDCR_DMS_512_DWORDS 0x06000000 | 328 | #define HDCR_DMS_512_DWORDS 0x06000000 |
329 | #define HDCR_DMS_1024_DWORDS 0x07000000 | 329 | #define HDCR_DMS_1024_DWORDS 0x07000000 |
330 | #define HDCR_DH 0x08000000 | 330 | #define HDCR_DH 0x08000000 |
331 | #define HDCR_SMS_MASK 0x70000000 | 331 | #define HDCR_SMS_MASK 0x70000000 |
332 | #define HDCR_SMS_LINEAR 0x00000000 | 332 | #define HDCR_SMS_LINEAR 0x00000000 |
333 | #define HDCR_SMS_16_DWORDS 0x10000000 | 333 | #define HDCR_SMS_16_DWORDS 0x10000000 |
334 | #define HDCR_SMS_32_DWORDS 0x20000000 | 334 | #define HDCR_SMS_32_DWORDS 0x20000000 |
335 | #define HDCR_SMS_64_DWORDS 0x30000000 | 335 | #define HDCR_SMS_64_DWORDS 0x30000000 |
336 | #define HDCR_SMS_128_DWORDS 0x40000000 | 336 | #define HDCR_SMS_128_DWORDS 0x40000000 |
337 | #define HDCR_SMS_256_DWORDS 0x50000000 | 337 | #define HDCR_SMS_256_DWORDS 0x50000000 |
338 | #define HDCR_SMS_512_DWORDS 0x60000000 | 338 | #define HDCR_SMS_512_DWORDS 0x60000000 |
339 | #define HDCR_SMS_1024_DWORDS 0x70000000 | 339 | #define HDCR_SMS_1024_DWORDS 0x70000000 |
340 | #define HDCR_SH 0x80000000 | 340 | #define HDCR_SH 0x80000000 |
341 | #define HDCR_COUNT_SHIFT 0 | 341 | #define HDCR_COUNT_SHIFT 0 |
342 | 342 | ||
343 | /* | 343 | /* |
344 | * The following defines are for the flags in the performance monitor control | 344 | * The following defines are for the flags in the performance monitor control |
345 | * register. | 345 | * register. |
346 | */ | 346 | */ |
347 | #define PFMC_C1SS_MASK 0x0000001F | 347 | #define PFMC_C1SS_MASK 0x0000001F |
348 | #define PFMC_C1EV 0x00000020 | 348 | #define PFMC_C1EV 0x00000020 |
349 | #define PFMC_C1RS 0x00008000 | 349 | #define PFMC_C1RS 0x00008000 |
350 | #define PFMC_C2SS_MASK 0x001F0000 | 350 | #define PFMC_C2SS_MASK 0x001F0000 |
351 | #define PFMC_C2EV 0x00200000 | 351 | #define PFMC_C2EV 0x00200000 |
352 | #define PFMC_C2RS 0x80000000 | 352 | #define PFMC_C2RS 0x80000000 |
353 | #define PFMC_C1SS_SHIFT 0 | 353 | #define PFMC_C1SS_SHIFT 0 |
354 | #define PFMC_C2SS_SHIFT 16 | 354 | #define PFMC_C2SS_SHIFT 16 |
355 | #define PFMC_BUS_GRANT 0 | 355 | #define PFMC_BUS_GRANT 0 |
356 | #define PFMC_GRANT_AFTER_REQ 1 | 356 | #define PFMC_GRANT_AFTER_REQ 1 |
357 | #define PFMC_TRANSACTION 2 | 357 | #define PFMC_TRANSACTION 2 |
358 | #define PFMC_DWORD_TRANSFER 3 | 358 | #define PFMC_DWORD_TRANSFER 3 |
359 | #define PFMC_SLAVE_READ 4 | 359 | #define PFMC_SLAVE_READ 4 |
360 | #define PFMC_SLAVE_WRITE 5 | 360 | #define PFMC_SLAVE_WRITE 5 |
361 | #define PFMC_PREEMPTION 6 | 361 | #define PFMC_PREEMPTION 6 |
362 | #define PFMC_DISCONNECT_RETRY 7 | 362 | #define PFMC_DISCONNECT_RETRY 7 |
363 | #define PFMC_INTERRUPT 8 | 363 | #define PFMC_INTERRUPT 8 |
364 | #define PFMC_BUS_OWNERSHIP 9 | 364 | #define PFMC_BUS_OWNERSHIP 9 |
365 | #define PFMC_TRANSACTION_LAG 10 | 365 | #define PFMC_TRANSACTION_LAG 10 |
366 | #define PFMC_PCI_CLOCK 11 | 366 | #define PFMC_PCI_CLOCK 11 |
367 | #define PFMC_SERIAL_CLOCK 12 | 367 | #define PFMC_SERIAL_CLOCK 12 |
368 | #define PFMC_SP_CLOCK 13 | 368 | #define PFMC_SP_CLOCK 13 |
369 | 369 | ||
370 | /* | 370 | /* |
371 | * The following defines are for the flags in the performance counter value 1 | 371 | * The following defines are for the flags in the performance counter value 1 |
372 | * register. | 372 | * register. |
373 | */ | 373 | */ |
374 | #define PFCV1_PC1V_MASK 0xFFFFFFFF | 374 | #define PFCV1_PC1V_MASK 0xFFFFFFFF |
375 | #define PFCV1_PC1V_SHIFT 0 | 375 | #define PFCV1_PC1V_SHIFT 0 |
376 | 376 | ||
377 | /* | 377 | /* |
378 | * The following defines are for the flags in the performance counter value 2 | 378 | * The following defines are for the flags in the performance counter value 2 |
379 | * register. | 379 | * register. |
380 | */ | 380 | */ |
381 | #define PFCV2_PC2V_MASK 0xFFFFFFFF | 381 | #define PFCV2_PC2V_MASK 0xFFFFFFFF |
382 | #define PFCV2_PC2V_SHIFT 0 | 382 | #define PFCV2_PC2V_SHIFT 0 |
383 | 383 | ||
384 | /* | 384 | /* |
385 | * The following defines are for the flags in the clock control register 1. | 385 | * The following defines are for the flags in the clock control register 1. |
386 | */ | 386 | */ |
387 | #define CLKCR1_OSCS 0x00000001 | 387 | #define CLKCR1_OSCS 0x00000001 |
388 | #define CLKCR1_OSCP 0x00000002 | 388 | #define CLKCR1_OSCP 0x00000002 |
389 | #define CLKCR1_PLLSS_MASK 0x0000000C | 389 | #define CLKCR1_PLLSS_MASK 0x0000000C |
390 | #define CLKCR1_PLLSS_SERIAL 0x00000000 | 390 | #define CLKCR1_PLLSS_SERIAL 0x00000000 |
391 | #define CLKCR1_PLLSS_CRYSTAL 0x00000004 | 391 | #define CLKCR1_PLLSS_CRYSTAL 0x00000004 |
392 | #define CLKCR1_PLLSS_PCI 0x00000008 | 392 | #define CLKCR1_PLLSS_PCI 0x00000008 |
393 | #define CLKCR1_PLLSS_RESERVED 0x0000000C | 393 | #define CLKCR1_PLLSS_RESERVED 0x0000000C |
394 | #define CLKCR1_PLLP 0x00000010 | 394 | #define CLKCR1_PLLP 0x00000010 |
395 | #define CLKCR1_SWCE 0x00000020 | 395 | #define CLKCR1_SWCE 0x00000020 |
396 | #define CLKCR1_PLLOS 0x00000040 | 396 | #define CLKCR1_PLLOS 0x00000040 |
397 | 397 | ||
398 | /* | 398 | /* |
399 | * The following defines are for the flags in the clock control register 2. | 399 | * The following defines are for the flags in the clock control register 2. |
400 | */ | 400 | */ |
401 | #define CLKCR2_PDIVS_MASK 0x0000000F | 401 | #define CLKCR2_PDIVS_MASK 0x0000000F |
402 | #define CLKCR2_PDIVS_1 0x00000001 | 402 | #define CLKCR2_PDIVS_1 0x00000001 |
403 | #define CLKCR2_PDIVS_2 0x00000002 | 403 | #define CLKCR2_PDIVS_2 0x00000002 |
404 | #define CLKCR2_PDIVS_4 0x00000004 | 404 | #define CLKCR2_PDIVS_4 0x00000004 |
405 | #define CLKCR2_PDIVS_7 0x00000007 | 405 | #define CLKCR2_PDIVS_7 0x00000007 |
406 | #define CLKCR2_PDIVS_8 0x00000008 | 406 | #define CLKCR2_PDIVS_8 0x00000008 |
407 | #define CLKCR2_PDIVS_16 0x00000000 | 407 | #define CLKCR2_PDIVS_16 0x00000000 |
408 | 408 | ||
409 | /* | 409 | /* |
410 | * The following defines are for the flags in the PLL multiplier register. | 410 | * The following defines are for the flags in the PLL multiplier register. |
411 | */ | 411 | */ |
412 | #define PLLM_MASK 0x000000FF | 412 | #define PLLM_MASK 0x000000FF |
413 | #define PLLM_SHIFT 0 | 413 | #define PLLM_SHIFT 0 |
414 | 414 | ||
415 | /* | 415 | /* |
416 | * The following defines are for the flags in the PLL capacitor coefficient | 416 | * The following defines are for the flags in the PLL capacitor coefficient |
417 | * register. | 417 | * register. |
418 | */ | 418 | */ |
419 | #define PLLCC_CDR_MASK 0x00000007 | 419 | #define PLLCC_CDR_MASK 0x00000007 |
420 | #ifndef NO_CS4610 | 420 | #ifndef NO_CS4610 |
421 | #define PLLCC_CDR_240_350_MHZ 0x00000000 | 421 | #define PLLCC_CDR_240_350_MHZ 0x00000000 |
422 | #define PLLCC_CDR_184_265_MHZ 0x00000001 | 422 | #define PLLCC_CDR_184_265_MHZ 0x00000001 |
423 | #define PLLCC_CDR_144_205_MHZ 0x00000002 | 423 | #define PLLCC_CDR_144_205_MHZ 0x00000002 |
424 | #define PLLCC_CDR_111_160_MHZ 0x00000003 | 424 | #define PLLCC_CDR_111_160_MHZ 0x00000003 |
425 | #define PLLCC_CDR_87_123_MHZ 0x00000004 | 425 | #define PLLCC_CDR_87_123_MHZ 0x00000004 |
426 | #define PLLCC_CDR_67_96_MHZ 0x00000005 | 426 | #define PLLCC_CDR_67_96_MHZ 0x00000005 |
427 | #define PLLCC_CDR_52_74_MHZ 0x00000006 | 427 | #define PLLCC_CDR_52_74_MHZ 0x00000006 |
428 | #define PLLCC_CDR_45_58_MHZ 0x00000007 | 428 | #define PLLCC_CDR_45_58_MHZ 0x00000007 |
429 | #endif | 429 | #endif |
430 | #ifndef NO_CS4612 | 430 | #ifndef NO_CS4612 |
431 | #define PLLCC_CDR_271_398_MHZ 0x00000000 | 431 | #define PLLCC_CDR_271_398_MHZ 0x00000000 |
432 | #define PLLCC_CDR_227_330_MHZ 0x00000001 | 432 | #define PLLCC_CDR_227_330_MHZ 0x00000001 |
433 | #define PLLCC_CDR_167_239_MHZ 0x00000002 | 433 | #define PLLCC_CDR_167_239_MHZ 0x00000002 |
434 | #define PLLCC_CDR_150_215_MHZ 0x00000003 | 434 | #define PLLCC_CDR_150_215_MHZ 0x00000003 |
435 | #define PLLCC_CDR_107_154_MHZ 0x00000004 | 435 | #define PLLCC_CDR_107_154_MHZ 0x00000004 |
436 | #define PLLCC_CDR_98_140_MHZ 0x00000005 | 436 | #define PLLCC_CDR_98_140_MHZ 0x00000005 |
437 | #define PLLCC_CDR_73_104_MHZ 0x00000006 | 437 | #define PLLCC_CDR_73_104_MHZ 0x00000006 |
438 | #define PLLCC_CDR_63_90_MHZ 0x00000007 | 438 | #define PLLCC_CDR_63_90_MHZ 0x00000007 |
439 | #endif | 439 | #endif |
440 | #define PLLCC_LPF_MASK 0x000000F8 | 440 | #define PLLCC_LPF_MASK 0x000000F8 |
441 | #ifndef NO_CS4610 | 441 | #ifndef NO_CS4610 |
442 | #define PLLCC_LPF_23850_60000_KHZ 0x00000000 | 442 | #define PLLCC_LPF_23850_60000_KHZ 0x00000000 |
443 | #define PLLCC_LPF_7960_26290_KHZ 0x00000008 | 443 | #define PLLCC_LPF_7960_26290_KHZ 0x00000008 |
444 | #define PLLCC_LPF_4160_10980_KHZ 0x00000018 | 444 | #define PLLCC_LPF_4160_10980_KHZ 0x00000018 |
445 | #define PLLCC_LPF_1740_4580_KHZ 0x00000038 | 445 | #define PLLCC_LPF_1740_4580_KHZ 0x00000038 |
446 | #define PLLCC_LPF_724_1910_KHZ 0x00000078 | 446 | #define PLLCC_LPF_724_1910_KHZ 0x00000078 |
447 | #define PLLCC_LPF_317_798_KHZ 0x000000F8 | 447 | #define PLLCC_LPF_317_798_KHZ 0x000000F8 |
448 | #endif | 448 | #endif |
449 | #ifndef NO_CS4612 | 449 | #ifndef NO_CS4612 |
450 | #define PLLCC_LPF_25580_64530_KHZ 0x00000000 | 450 | #define PLLCC_LPF_25580_64530_KHZ 0x00000000 |
451 | #define PLLCC_LPF_14360_37270_KHZ 0x00000008 | 451 | #define PLLCC_LPF_14360_37270_KHZ 0x00000008 |
452 | #define PLLCC_LPF_6100_16020_KHZ 0x00000018 | 452 | #define PLLCC_LPF_6100_16020_KHZ 0x00000018 |
453 | #define PLLCC_LPF_2540_6690_KHZ 0x00000038 | 453 | #define PLLCC_LPF_2540_6690_KHZ 0x00000038 |
454 | #define PLLCC_LPF_1050_2780_KHZ 0x00000078 | 454 | #define PLLCC_LPF_1050_2780_KHZ 0x00000078 |
455 | #define PLLCC_LPF_450_1160_KHZ 0x000000F8 | 455 | #define PLLCC_LPF_450_1160_KHZ 0x000000F8 |
456 | #endif | 456 | #endif |
457 | 457 | ||
458 | /* | 458 | /* |
459 | * The following defines are for the flags in the feature reporting register. | 459 | * The following defines are for the flags in the feature reporting register. |
460 | */ | 460 | */ |
461 | #define FRR_FAB_MASK 0x00000003 | 461 | #define FRR_FAB_MASK 0x00000003 |
462 | #define FRR_MASK_MASK 0x0000001C | 462 | #define FRR_MASK_MASK 0x0000001C |
463 | #ifdef NO_CS4612 | 463 | #ifdef NO_CS4612 |
464 | #define FRR_CFOP_MASK 0x000000E0 | 464 | #define FRR_CFOP_MASK 0x000000E0 |
465 | #else | 465 | #else |
466 | #define FRR_CFOP_MASK 0x00000FE0 | 466 | #define FRR_CFOP_MASK 0x00000FE0 |
467 | #endif | 467 | #endif |
468 | #define FRR_CFOP_NOT_DVD 0x00000020 | 468 | #define FRR_CFOP_NOT_DVD 0x00000020 |
469 | #define FRR_CFOP_A3D 0x00000040 | 469 | #define FRR_CFOP_A3D 0x00000040 |
470 | #define FRR_CFOP_128_PIN 0x00000080 | 470 | #define FRR_CFOP_128_PIN 0x00000080 |
471 | #ifndef NO_CS4612 | 471 | #ifndef NO_CS4612 |
472 | #define FRR_CFOP_CS4280 0x00000800 | 472 | #define FRR_CFOP_CS4280 0x00000800 |
473 | #endif | 473 | #endif |
474 | #define FRR_FAB_SHIFT 0 | 474 | #define FRR_FAB_SHIFT 0 |
475 | #define FRR_MASK_SHIFT 2 | 475 | #define FRR_MASK_SHIFT 2 |
476 | #define FRR_CFOP_SHIFT 5 | 476 | #define FRR_CFOP_SHIFT 5 |
477 | 477 | ||
478 | /* | 478 | /* |
479 | * The following defines are for the flags in the configuration load 1 | 479 | * The following defines are for the flags in the configuration load 1 |
480 | * register. | 480 | * register. |
481 | */ | 481 | */ |
482 | #define CFL1_CLOCK_SOURCE_MASK 0x00000003 | 482 | #define CFL1_CLOCK_SOURCE_MASK 0x00000003 |
483 | #define CFL1_CLOCK_SOURCE_CS423X 0x00000000 | 483 | #define CFL1_CLOCK_SOURCE_CS423X 0x00000000 |
484 | #define CFL1_CLOCK_SOURCE_AC97 0x00000001 | 484 | #define CFL1_CLOCK_SOURCE_AC97 0x00000001 |
485 | #define CFL1_CLOCK_SOURCE_CRYSTAL 0x00000002 | 485 | #define CFL1_CLOCK_SOURCE_CRYSTAL 0x00000002 |
486 | #define CFL1_CLOCK_SOURCE_DUAL_AC97 0x00000003 | 486 | #define CFL1_CLOCK_SOURCE_DUAL_AC97 0x00000003 |
487 | #define CFL1_VALID_DATA_MASK 0x000000FF | 487 | #define CFL1_VALID_DATA_MASK 0x000000FF |
488 | 488 | ||
489 | /* | 489 | /* |
490 | * The following defines are for the flags in the configuration load 2 | 490 | * The following defines are for the flags in the configuration load 2 |
491 | * register. | 491 | * register. |
492 | */ | 492 | */ |
493 | #define CFL2_VALID_DATA_MASK 0x000000FF | 493 | #define CFL2_VALID_DATA_MASK 0x000000FF |
494 | 494 | ||
495 | /* | 495 | /* |
496 | * The following defines are for the flags in the serial port master control | 496 | * The following defines are for the flags in the serial port master control |
497 | * register 1. | 497 | * register 1. |
498 | */ | 498 | */ |
499 | #define SERMC1_MSPE 0x00000001 | 499 | #define SERMC1_MSPE 0x00000001 |
500 | #define SERMC1_PTC_MASK 0x0000000E | 500 | #define SERMC1_PTC_MASK 0x0000000E |
501 | #define SERMC1_PTC_CS423X 0x00000000 | 501 | #define SERMC1_PTC_CS423X 0x00000000 |
502 | #define SERMC1_PTC_AC97 0x00000002 | 502 | #define SERMC1_PTC_AC97 0x00000002 |
503 | #define SERMC1_PTC_DAC 0x00000004 | 503 | #define SERMC1_PTC_DAC 0x00000004 |
504 | #define SERMC1_PLB 0x00000010 | 504 | #define SERMC1_PLB 0x00000010 |
505 | #define SERMC1_XLB 0x00000020 | 505 | #define SERMC1_XLB 0x00000020 |
506 | 506 | ||
507 | /* | 507 | /* |
508 | * The following defines are for the flags in the serial port master control | 508 | * The following defines are for the flags in the serial port master control |
509 | * register 2. | 509 | * register 2. |
510 | */ | 510 | */ |
511 | #define SERMC2_LROE 0x00000001 | 511 | #define SERMC2_LROE 0x00000001 |
512 | #define SERMC2_MCOE 0x00000002 | 512 | #define SERMC2_MCOE 0x00000002 |
513 | #define SERMC2_MCDIV 0x00000004 | 513 | #define SERMC2_MCDIV 0x00000004 |
514 | 514 | ||
515 | /* | 515 | /* |
516 | * The following defines are for the flags in the serial port 1 configuration | 516 | * The following defines are for the flags in the serial port 1 configuration |
517 | * register. | 517 | * register. |
518 | */ | 518 | */ |
519 | #define SERC1_SO1EN 0x00000001 | 519 | #define SERC1_SO1EN 0x00000001 |
520 | #define SERC1_SO1F_MASK 0x0000000E | 520 | #define SERC1_SO1F_MASK 0x0000000E |
521 | #define SERC1_SO1F_CS423X 0x00000000 | 521 | #define SERC1_SO1F_CS423X 0x00000000 |
522 | #define SERC1_SO1F_AC97 0x00000002 | 522 | #define SERC1_SO1F_AC97 0x00000002 |
523 | #define SERC1_SO1F_DAC 0x00000004 | 523 | #define SERC1_SO1F_DAC 0x00000004 |
524 | #define SERC1_SO1F_SPDIF 0x00000006 | 524 | #define SERC1_SO1F_SPDIF 0x00000006 |
525 | 525 | ||
526 | /* | 526 | /* |
527 | * The following defines are for the flags in the serial port 2 configuration | 527 | * The following defines are for the flags in the serial port 2 configuration |
528 | * register. | 528 | * register. |
529 | */ | 529 | */ |
530 | #define SERC2_SI1EN 0x00000001 | 530 | #define SERC2_SI1EN 0x00000001 |
531 | #define SERC2_SI1F_MASK 0x0000000E | 531 | #define SERC2_SI1F_MASK 0x0000000E |
532 | #define SERC2_SI1F_CS423X 0x00000000 | 532 | #define SERC2_SI1F_CS423X 0x00000000 |
533 | #define SERC2_SI1F_AC97 0x00000002 | 533 | #define SERC2_SI1F_AC97 0x00000002 |
534 | #define SERC2_SI1F_ADC 0x00000004 | 534 | #define SERC2_SI1F_ADC 0x00000004 |
535 | #define SERC2_SI1F_SPDIF 0x00000006 | 535 | #define SERC2_SI1F_SPDIF 0x00000006 |
536 | 536 | ||
537 | /* | 537 | /* |
538 | * The following defines are for the flags in the serial port 3 configuration | 538 | * The following defines are for the flags in the serial port 3 configuration |
539 | * register. | 539 | * register. |
540 | */ | 540 | */ |
541 | #define SERC3_SO2EN 0x00000001 | 541 | #define SERC3_SO2EN 0x00000001 |
542 | #define SERC3_SO2F_MASK 0x00000006 | 542 | #define SERC3_SO2F_MASK 0x00000006 |
543 | #define SERC3_SO2F_DAC 0x00000000 | 543 | #define SERC3_SO2F_DAC 0x00000000 |
544 | #define SERC3_SO2F_SPDIF 0x00000002 | 544 | #define SERC3_SO2F_SPDIF 0x00000002 |
545 | 545 | ||
546 | /* | 546 | /* |
547 | * The following defines are for the flags in the serial port 4 configuration | 547 | * The following defines are for the flags in the serial port 4 configuration |
548 | * register. | 548 | * register. |
549 | */ | 549 | */ |
550 | #define SERC4_SO3EN 0x00000001 | 550 | #define SERC4_SO3EN 0x00000001 |
551 | #define SERC4_SO3F_MASK 0x00000006 | 551 | #define SERC4_SO3F_MASK 0x00000006 |
552 | #define SERC4_SO3F_DAC 0x00000000 | 552 | #define SERC4_SO3F_DAC 0x00000000 |
553 | #define SERC4_SO3F_SPDIF 0x00000002 | 553 | #define SERC4_SO3F_SPDIF 0x00000002 |
554 | 554 | ||
555 | /* | 555 | /* |
556 | * The following defines are for the flags in the serial port 5 configuration | 556 | * The following defines are for the flags in the serial port 5 configuration |
557 | * register. | 557 | * register. |
558 | */ | 558 | */ |
559 | #define SERC5_SI2EN 0x00000001 | 559 | #define SERC5_SI2EN 0x00000001 |
560 | #define SERC5_SI2F_MASK 0x00000006 | 560 | #define SERC5_SI2F_MASK 0x00000006 |
561 | #define SERC5_SI2F_ADC 0x00000000 | 561 | #define SERC5_SI2F_ADC 0x00000000 |
562 | #define SERC5_SI2F_SPDIF 0x00000002 | 562 | #define SERC5_SI2F_SPDIF 0x00000002 |
563 | 563 | ||
564 | /* | 564 | /* |
565 | * The following defines are for the flags in the serial port backdoor sample | 565 | * The following defines are for the flags in the serial port backdoor sample |
566 | * pointer register. | 566 | * pointer register. |
567 | */ | 567 | */ |
568 | #define SERBSP_FSP_MASK 0x0000000F | 568 | #define SERBSP_FSP_MASK 0x0000000F |
569 | #define SERBSP_FSP_SHIFT 0 | 569 | #define SERBSP_FSP_SHIFT 0 |
570 | 570 | ||
571 | /* | 571 | /* |
572 | * The following defines are for the flags in the serial port backdoor status | 572 | * The following defines are for the flags in the serial port backdoor status |
573 | * register. | 573 | * register. |
574 | */ | 574 | */ |
575 | #define SERBST_RRDY 0x00000001 | 575 | #define SERBST_RRDY 0x00000001 |
576 | #define SERBST_WBSY 0x00000002 | 576 | #define SERBST_WBSY 0x00000002 |
577 | 577 | ||
578 | /* | 578 | /* |
579 | * The following defines are for the flags in the serial port backdoor command | 579 | * The following defines are for the flags in the serial port backdoor command |
580 | * register. | 580 | * register. |
581 | */ | 581 | */ |
582 | #define SERBCM_RDC 0x00000001 | 582 | #define SERBCM_RDC 0x00000001 |
583 | #define SERBCM_WRC 0x00000002 | 583 | #define SERBCM_WRC 0x00000002 |
584 | 584 | ||
585 | /* | 585 | /* |
586 | * The following defines are for the flags in the serial port backdoor address | 586 | * The following defines are for the flags in the serial port backdoor address |
587 | * register. | 587 | * register. |
588 | */ | 588 | */ |
589 | #ifdef NO_CS4612 | 589 | #ifdef NO_CS4612 |
590 | #define SERBAD_FAD_MASK 0x000000FF | 590 | #define SERBAD_FAD_MASK 0x000000FF |
591 | #else | 591 | #else |
592 | #define SERBAD_FAD_MASK 0x000001FF | 592 | #define SERBAD_FAD_MASK 0x000001FF |
593 | #endif | 593 | #endif |
594 | #define SERBAD_FAD_SHIFT 0 | 594 | #define SERBAD_FAD_SHIFT 0 |
595 | 595 | ||
596 | /* | 596 | /* |
597 | * The following defines are for the flags in the serial port backdoor | 597 | * The following defines are for the flags in the serial port backdoor |
598 | * configuration register. | 598 | * configuration register. |
599 | */ | 599 | */ |
600 | #define SERBCF_HBP 0x00000001 | 600 | #define SERBCF_HBP 0x00000001 |
601 | 601 | ||
602 | /* | 602 | /* |
603 | * The following defines are for the flags in the serial port backdoor write | 603 | * The following defines are for the flags in the serial port backdoor write |
604 | * port register. | 604 | * port register. |
605 | */ | 605 | */ |
606 | #define SERBWP_FWD_MASK 0x000FFFFF | 606 | #define SERBWP_FWD_MASK 0x000FFFFF |
607 | #define SERBWP_FWD_SHIFT 0 | 607 | #define SERBWP_FWD_SHIFT 0 |
608 | 608 | ||
609 | /* | 609 | /* |
610 | * The following defines are for the flags in the serial port backdoor read | 610 | * The following defines are for the flags in the serial port backdoor read |
611 | * port register. | 611 | * port register. |
612 | */ | 612 | */ |
613 | #define SERBRP_FRD_MASK 0x000FFFFF | 613 | #define SERBRP_FRD_MASK 0x000FFFFF |
614 | #define SERBRP_FRD_SHIFT 0 | 614 | #define SERBRP_FRD_SHIFT 0 |
615 | 615 | ||
616 | /* | 616 | /* |
617 | * The following defines are for the flags in the async FIFO address register. | 617 | * The following defines are for the flags in the async FIFO address register. |
618 | */ | 618 | */ |
619 | #ifndef NO_CS4612 | 619 | #ifndef NO_CS4612 |
620 | #define ASER_FADDR_A1_MASK 0x000001FF | 620 | #define ASER_FADDR_A1_MASK 0x000001FF |
621 | #define ASER_FADDR_EN1 0x00008000 | 621 | #define ASER_FADDR_EN1 0x00008000 |
622 | #define ASER_FADDR_A2_MASK 0x01FF0000 | 622 | #define ASER_FADDR_A2_MASK 0x01FF0000 |
623 | #define ASER_FADDR_EN2 0x80000000 | 623 | #define ASER_FADDR_EN2 0x80000000 |
624 | #define ASER_FADDR_A1_SHIFT 0 | 624 | #define ASER_FADDR_A1_SHIFT 0 |
625 | #define ASER_FADDR_A2_SHIFT 16 | 625 | #define ASER_FADDR_A2_SHIFT 16 |
626 | #endif | 626 | #endif |
627 | 627 | ||
628 | /* | 628 | /* |
629 | * The following defines are for the flags in the AC97 control register. | 629 | * The following defines are for the flags in the AC97 control register. |
630 | */ | 630 | */ |
631 | #define ACCTL_RSTN 0x00000001 | 631 | #define ACCTL_RSTN 0x00000001 |
632 | #define ACCTL_ESYN 0x00000002 | 632 | #define ACCTL_ESYN 0x00000002 |
633 | #define ACCTL_VFRM 0x00000004 | 633 | #define ACCTL_VFRM 0x00000004 |
634 | #define ACCTL_DCV 0x00000008 | 634 | #define ACCTL_DCV 0x00000008 |
635 | #define ACCTL_CRW 0x00000010 | 635 | #define ACCTL_CRW 0x00000010 |
636 | #define ACCTL_ASYN 0x00000020 | 636 | #define ACCTL_ASYN 0x00000020 |
637 | #ifndef NO_CS4612 | 637 | #ifndef NO_CS4612 |
638 | #define ACCTL_TC 0x00000040 | 638 | #define ACCTL_TC 0x00000040 |
639 | #endif | 639 | #endif |
640 | 640 | ||
641 | /* | 641 | /* |
642 | * The following defines are for the flags in the AC97 status register. | 642 | * The following defines are for the flags in the AC97 status register. |
643 | */ | 643 | */ |
644 | #define ACSTS_CRDY 0x00000001 | 644 | #define ACSTS_CRDY 0x00000001 |
645 | #define ACSTS_VSTS 0x00000002 | 645 | #define ACSTS_VSTS 0x00000002 |
646 | #ifndef NO_CS4612 | 646 | #ifndef NO_CS4612 |
647 | #define ACSTS_WKUP 0x00000004 | 647 | #define ACSTS_WKUP 0x00000004 |
648 | #endif | 648 | #endif |
649 | 649 | ||
650 | /* | 650 | /* |
651 | * The following defines are for the flags in the AC97 output slot valid | 651 | * The following defines are for the flags in the AC97 output slot valid |
652 | * register. | 652 | * register. |
653 | */ | 653 | */ |
654 | #define ACOSV_SLV3 0x00000001 | 654 | #define ACOSV_SLV3 0x00000001 |
655 | #define ACOSV_SLV4 0x00000002 | 655 | #define ACOSV_SLV4 0x00000002 |
656 | #define ACOSV_SLV5 0x00000004 | 656 | #define ACOSV_SLV5 0x00000004 |
657 | #define ACOSV_SLV6 0x00000008 | 657 | #define ACOSV_SLV6 0x00000008 |
658 | #define ACOSV_SLV7 0x00000010 | 658 | #define ACOSV_SLV7 0x00000010 |
659 | #define ACOSV_SLV8 0x00000020 | 659 | #define ACOSV_SLV8 0x00000020 |
660 | #define ACOSV_SLV9 0x00000040 | 660 | #define ACOSV_SLV9 0x00000040 |
661 | #define ACOSV_SLV10 0x00000080 | 661 | #define ACOSV_SLV10 0x00000080 |
662 | #define ACOSV_SLV11 0x00000100 | 662 | #define ACOSV_SLV11 0x00000100 |
663 | #define ACOSV_SLV12 0x00000200 | 663 | #define ACOSV_SLV12 0x00000200 |
664 | 664 | ||
665 | /* | 665 | /* |
666 | * The following defines are for the flags in the AC97 command address | 666 | * The following defines are for the flags in the AC97 command address |
667 | * register. | 667 | * register. |
668 | */ | 668 | */ |
669 | #define ACCAD_CI_MASK 0x0000007F | 669 | #define ACCAD_CI_MASK 0x0000007F |
670 | #define ACCAD_CI_SHIFT 0 | 670 | #define ACCAD_CI_SHIFT 0 |
671 | 671 | ||
672 | /* | 672 | /* |
673 | * The following defines are for the flags in the AC97 command data register. | 673 | * The following defines are for the flags in the AC97 command data register. |
674 | */ | 674 | */ |
675 | #define ACCDA_CD_MASK 0x0000FFFF | 675 | #define ACCDA_CD_MASK 0x0000FFFF |
676 | #define ACCDA_CD_SHIFT 0 | 676 | #define ACCDA_CD_SHIFT 0 |
677 | 677 | ||
678 | /* | 678 | /* |
679 | * The following defines are for the flags in the AC97 input slot valid | 679 | * The following defines are for the flags in the AC97 input slot valid |
680 | * register. | 680 | * register. |
681 | */ | 681 | */ |
682 | #define ACISV_ISV3 0x00000001 | 682 | #define ACISV_ISV3 0x00000001 |
683 | #define ACISV_ISV4 0x00000002 | 683 | #define ACISV_ISV4 0x00000002 |
684 | #define ACISV_ISV5 0x00000004 | 684 | #define ACISV_ISV5 0x00000004 |
685 | #define ACISV_ISV6 0x00000008 | 685 | #define ACISV_ISV6 0x00000008 |
686 | #define ACISV_ISV7 0x00000010 | 686 | #define ACISV_ISV7 0x00000010 |
687 | #define ACISV_ISV8 0x00000020 | 687 | #define ACISV_ISV8 0x00000020 |
688 | #define ACISV_ISV9 0x00000040 | 688 | #define ACISV_ISV9 0x00000040 |
689 | #define ACISV_ISV10 0x00000080 | 689 | #define ACISV_ISV10 0x00000080 |
690 | #define ACISV_ISV11 0x00000100 | 690 | #define ACISV_ISV11 0x00000100 |
691 | #define ACISV_ISV12 0x00000200 | 691 | #define ACISV_ISV12 0x00000200 |
692 | 692 | ||
693 | /* | 693 | /* |
694 | * The following defines are for the flags in the AC97 status address | 694 | * The following defines are for the flags in the AC97 status address |
695 | * register. | 695 | * register. |
696 | */ | 696 | */ |
697 | #define ACSAD_SI_MASK 0x0000007F | 697 | #define ACSAD_SI_MASK 0x0000007F |
698 | #define ACSAD_SI_SHIFT 0 | 698 | #define ACSAD_SI_SHIFT 0 |
699 | 699 | ||
700 | /* | 700 | /* |
701 | * The following defines are for the flags in the AC97 status data register. | 701 | * The following defines are for the flags in the AC97 status data register. |
702 | */ | 702 | */ |
703 | #define ACSDA_SD_MASK 0x0000FFFF | 703 | #define ACSDA_SD_MASK 0x0000FFFF |
704 | #define ACSDA_SD_SHIFT 0 | 704 | #define ACSDA_SD_SHIFT 0 |
705 | 705 | ||
706 | /* | 706 | /* |
707 | * The following defines are for the flags in the joystick poll/trigger | 707 | * The following defines are for the flags in the joystick poll/trigger |
708 | * register. | 708 | * register. |
709 | */ | 709 | */ |
710 | #define JSPT_CAX 0x00000001 | 710 | #define JSPT_CAX 0x00000001 |
711 | #define JSPT_CAY 0x00000002 | 711 | #define JSPT_CAY 0x00000002 |
712 | #define JSPT_CBX 0x00000004 | 712 | #define JSPT_CBX 0x00000004 |
713 | #define JSPT_CBY 0x00000008 | 713 | #define JSPT_CBY 0x00000008 |
714 | #define JSPT_BA1 0x00000010 | 714 | #define JSPT_BA1 0x00000010 |
715 | #define JSPT_BA2 0x00000020 | 715 | #define JSPT_BA2 0x00000020 |
716 | #define JSPT_BB1 0x00000040 | 716 | #define JSPT_BB1 0x00000040 |
717 | #define JSPT_BB2 0x00000080 | 717 | #define JSPT_BB2 0x00000080 |
718 | 718 | ||
719 | /* | 719 | /* |
720 | * The following defines are for the flags in the joystick control register. | 720 | * The following defines are for the flags in the joystick control register. |
721 | */ | 721 | */ |
722 | #define JSCTL_SP_MASK 0x00000003 | 722 | #define JSCTL_SP_MASK 0x00000003 |
723 | #define JSCTL_SP_SLOW 0x00000000 | 723 | #define JSCTL_SP_SLOW 0x00000000 |
724 | #define JSCTL_SP_MEDIUM_SLOW 0x00000001 | 724 | #define JSCTL_SP_MEDIUM_SLOW 0x00000001 |
725 | #define JSCTL_SP_MEDIUM_FAST 0x00000002 | 725 | #define JSCTL_SP_MEDIUM_FAST 0x00000002 |
726 | #define JSCTL_SP_FAST 0x00000003 | 726 | #define JSCTL_SP_FAST 0x00000003 |
727 | #define JSCTL_ARE 0x00000004 | 727 | #define JSCTL_ARE 0x00000004 |
728 | 728 | ||
729 | /* | 729 | /* |
730 | * The following defines are for the flags in the joystick coordinate pair 1 | 730 | * The following defines are for the flags in the joystick coordinate pair 1 |
731 | * readback register. | 731 | * readback register. |
732 | */ | 732 | */ |
733 | #define JSC1_Y1V_MASK 0x0000FFFF | 733 | #define JSC1_Y1V_MASK 0x0000FFFF |
734 | #define JSC1_X1V_MASK 0xFFFF0000 | 734 | #define JSC1_X1V_MASK 0xFFFF0000 |
735 | #define JSC1_Y1V_SHIFT 0 | 735 | #define JSC1_Y1V_SHIFT 0 |
736 | #define JSC1_X1V_SHIFT 16 | 736 | #define JSC1_X1V_SHIFT 16 |
737 | 737 | ||
738 | /* | 738 | /* |
739 | * The following defines are for the flags in the joystick coordinate pair 2 | 739 | * The following defines are for the flags in the joystick coordinate pair 2 |
740 | * readback register. | 740 | * readback register. |
741 | */ | 741 | */ |
742 | #define JSC2_Y2V_MASK 0x0000FFFF | 742 | #define JSC2_Y2V_MASK 0x0000FFFF |
743 | #define JSC2_X2V_MASK 0xFFFF0000 | 743 | #define JSC2_X2V_MASK 0xFFFF0000 |
744 | #define JSC2_Y2V_SHIFT 0 | 744 | #define JSC2_Y2V_SHIFT 0 |
745 | #define JSC2_X2V_SHIFT 16 | 745 | #define JSC2_X2V_SHIFT 16 |
746 | 746 | ||
747 | /* | 747 | /* |
748 | * The following defines are for the flags in the MIDI control register. | 748 | * The following defines are for the flags in the MIDI control register. |
749 | */ | 749 | */ |
750 | #define MIDCR_TXE 0x00000001 /* Enable transmitting. */ | 750 | #define MIDCR_TXE 0x00000001 /* Enable transmitting. */ |
751 | #define MIDCR_RXE 0x00000002 /* Enable receiving. */ | 751 | #define MIDCR_RXE 0x00000002 /* Enable receiving. */ |
752 | #define MIDCR_RIE 0x00000004 /* Interrupt upon tx ready. */ | 752 | #define MIDCR_RIE 0x00000004 /* Interrupt upon tx ready. */ |
753 | #define MIDCR_TIE 0x00000008 /* Interrupt upon rx ready. */ | 753 | #define MIDCR_TIE 0x00000008 /* Interrupt upon rx ready. */ |
754 | #define MIDCR_MLB 0x00000010 /* Enable midi loopback. */ | 754 | #define MIDCR_MLB 0x00000010 /* Enable midi loopback. */ |
755 | #define MIDCR_MRST 0x00000020 /* Reset interface. */ | 755 | #define MIDCR_MRST 0x00000020 /* Reset interface. */ |
756 | 756 | ||
757 | /* | 757 | /* |
758 | * The following defines are for the flags in the MIDI status register. | 758 | * The following defines are for the flags in the MIDI status register. |
759 | */ | 759 | */ |
760 | #define MIDSR_TBF 0x00000001 /* Tx FIFO is full. */ | 760 | #define MIDSR_TBF 0x00000001 /* Tx FIFO is full. */ |
761 | #define MIDSR_RBE 0x00000002 /* Rx FIFO is empty. */ | 761 | #define MIDSR_RBE 0x00000002 /* Rx FIFO is empty. */ |
762 | 762 | ||
763 | /* | 763 | /* |
764 | * The following defines are for the flags in the MIDI write port register. | 764 | * The following defines are for the flags in the MIDI write port register. |
765 | */ | 765 | */ |
766 | #define MIDWP_MWD_MASK 0x000000FF | 766 | #define MIDWP_MWD_MASK 0x000000FF |
767 | #define MIDWP_MWD_SHIFT 0 | 767 | #define MIDWP_MWD_SHIFT 0 |
768 | 768 | ||
769 | /* | 769 | /* |
770 | * The following defines are for the flags in the MIDI read port register. | 770 | * The following defines are for the flags in the MIDI read port register. |
771 | */ | 771 | */ |
772 | #define MIDRP_MRD_MASK 0x000000FF | 772 | #define MIDRP_MRD_MASK 0x000000FF |
773 | #define MIDRP_MRD_SHIFT 0 | 773 | #define MIDRP_MRD_SHIFT 0 |
774 | 774 | ||
775 | /* | 775 | /* |
776 | * The following defines are for the flags in the joystick GPIO register. | 776 | * The following defines are for the flags in the joystick GPIO register. |
777 | */ | 777 | */ |
778 | #define JSIO_DAX 0x00000001 | 778 | #define JSIO_DAX 0x00000001 |
779 | #define JSIO_DAY 0x00000002 | 779 | #define JSIO_DAY 0x00000002 |
780 | #define JSIO_DBX 0x00000004 | 780 | #define JSIO_DBX 0x00000004 |
781 | #define JSIO_DBY 0x00000008 | 781 | #define JSIO_DBY 0x00000008 |
782 | #define JSIO_AXOE 0x00000010 | 782 | #define JSIO_AXOE 0x00000010 |
783 | #define JSIO_AYOE 0x00000020 | 783 | #define JSIO_AYOE 0x00000020 |
784 | #define JSIO_BXOE 0x00000040 | 784 | #define JSIO_BXOE 0x00000040 |
785 | #define JSIO_BYOE 0x00000080 | 785 | #define JSIO_BYOE 0x00000080 |
786 | 786 | ||
787 | /* | 787 | /* |
788 | * The following defines are for the flags in the master async/sync serial | 788 | * The following defines are for the flags in the master async/sync serial |
789 | * port enable register. | 789 | * port enable register. |
790 | */ | 790 | */ |
791 | #ifndef NO_CS4612 | 791 | #ifndef NO_CS4612 |
792 | #define ASER_MASTER_ME 0x00000001 | 792 | #define ASER_MASTER_ME 0x00000001 |
793 | #endif | 793 | #endif |
794 | 794 | ||
795 | /* | 795 | /* |
796 | * The following defines are for the flags in the configuration interface | 796 | * The following defines are for the flags in the configuration interface |
797 | * register. | 797 | * register. |
798 | */ | 798 | */ |
799 | #define CFGI_CLK 0x00000001 | 799 | #define CFGI_CLK 0x00000001 |
800 | #define CFGI_DOUT 0x00000002 | 800 | #define CFGI_DOUT 0x00000002 |
801 | #define CFGI_DIN_EEN 0x00000004 | 801 | #define CFGI_DIN_EEN 0x00000004 |
802 | #define CFGI_EELD 0x00000008 | 802 | #define CFGI_EELD 0x00000008 |
803 | 803 | ||
804 | /* | 804 | /* |
805 | * The following defines are for the flags in the subsystem ID and vendor ID | 805 | * The following defines are for the flags in the subsystem ID and vendor ID |
806 | * register. | 806 | * register. |
807 | */ | 807 | */ |
808 | #define SSVID_VID_MASK 0x0000FFFF | 808 | #define SSVID_VID_MASK 0x0000FFFF |
809 | #define SSVID_SID_MASK 0xFFFF0000 | 809 | #define SSVID_SID_MASK 0xFFFF0000 |
810 | #define SSVID_VID_SHIFT 0 | 810 | #define SSVID_VID_SHIFT 0 |
811 | #define SSVID_SID_SHIFT 16 | 811 | #define SSVID_SID_SHIFT 16 |
812 | 812 | ||
813 | /* | 813 | /* |
814 | * The following defines are for the flags in the GPIO pin interface register. | 814 | * The following defines are for the flags in the GPIO pin interface register. |
815 | */ | 815 | */ |
816 | #define GPIOR_VOLDN 0x00000001 | 816 | #define GPIOR_VOLDN 0x00000001 |
817 | #define GPIOR_VOLUP 0x00000002 | 817 | #define GPIOR_VOLUP 0x00000002 |
818 | #define GPIOR_SI2D 0x00000004 | 818 | #define GPIOR_SI2D 0x00000004 |
819 | #define GPIOR_SI2OE 0x00000008 | 819 | #define GPIOR_SI2OE 0x00000008 |
820 | 820 | ||
821 | /* | 821 | /* |
822 | * The following defines are for the flags in the extended GPIO pin direction | 822 | * The following defines are for the flags in the extended GPIO pin direction |
823 | * register. | 823 | * register. |
824 | */ | 824 | */ |
825 | #ifndef NO_CS4612 | 825 | #ifndef NO_CS4612 |
826 | #define EGPIODR_GPOE0 0x00000001 | 826 | #define EGPIODR_GPOE0 0x00000001 |
827 | #define EGPIODR_GPOE1 0x00000002 | 827 | #define EGPIODR_GPOE1 0x00000002 |
828 | #define EGPIODR_GPOE2 0x00000004 | 828 | #define EGPIODR_GPOE2 0x00000004 |
829 | #define EGPIODR_GPOE3 0x00000008 | 829 | #define EGPIODR_GPOE3 0x00000008 |
830 | #define EGPIODR_GPOE4 0x00000010 | 830 | #define EGPIODR_GPOE4 0x00000010 |
831 | #define EGPIODR_GPOE5 0x00000020 | 831 | #define EGPIODR_GPOE5 0x00000020 |
832 | #define EGPIODR_GPOE6 0x00000040 | 832 | #define EGPIODR_GPOE6 0x00000040 |
833 | #define EGPIODR_GPOE7 0x00000080 | 833 | #define EGPIODR_GPOE7 0x00000080 |
834 | #define EGPIODR_GPOE8 0x00000100 | 834 | #define EGPIODR_GPOE8 0x00000100 |
835 | #endif | 835 | #endif |
836 | 836 | ||
837 | /* | 837 | /* |
838 | * The following defines are for the flags in the extended GPIO pin polarity/ | 838 | * The following defines are for the flags in the extended GPIO pin polarity/ |
839 | * type register. | 839 | * type register. |
840 | */ | 840 | */ |
841 | #ifndef NO_CS4612 | 841 | #ifndef NO_CS4612 |
842 | #define EGPIOPTR_GPPT0 0x00000001 | 842 | #define EGPIOPTR_GPPT0 0x00000001 |
843 | #define EGPIOPTR_GPPT1 0x00000002 | 843 | #define EGPIOPTR_GPPT1 0x00000002 |
844 | #define EGPIOPTR_GPPT2 0x00000004 | 844 | #define EGPIOPTR_GPPT2 0x00000004 |
845 | #define EGPIOPTR_GPPT3 0x00000008 | 845 | #define EGPIOPTR_GPPT3 0x00000008 |
846 | #define EGPIOPTR_GPPT4 0x00000010 | 846 | #define EGPIOPTR_GPPT4 0x00000010 |
847 | #define EGPIOPTR_GPPT5 0x00000020 | 847 | #define EGPIOPTR_GPPT5 0x00000020 |
848 | #define EGPIOPTR_GPPT6 0x00000040 | 848 | #define EGPIOPTR_GPPT6 0x00000040 |
849 | #define EGPIOPTR_GPPT7 0x00000080 | 849 | #define EGPIOPTR_GPPT7 0x00000080 |
850 | #define EGPIOPTR_GPPT8 0x00000100 | 850 | #define EGPIOPTR_GPPT8 0x00000100 |
851 | #endif | 851 | #endif |
852 | 852 | ||
853 | /* | 853 | /* |
854 | * The following defines are for the flags in the extended GPIO pin sticky | 854 | * The following defines are for the flags in the extended GPIO pin sticky |
855 | * register. | 855 | * register. |
856 | */ | 856 | */ |
857 | #ifndef NO_CS4612 | 857 | #ifndef NO_CS4612 |
858 | #define EGPIOTR_GPS0 0x00000001 | 858 | #define EGPIOTR_GPS0 0x00000001 |
859 | #define EGPIOTR_GPS1 0x00000002 | 859 | #define EGPIOTR_GPS1 0x00000002 |
860 | #define EGPIOTR_GPS2 0x00000004 | 860 | #define EGPIOTR_GPS2 0x00000004 |
861 | #define EGPIOTR_GPS3 0x00000008 | 861 | #define EGPIOTR_GPS3 0x00000008 |
862 | #define EGPIOTR_GPS4 0x00000010 | 862 | #define EGPIOTR_GPS4 0x00000010 |
863 | #define EGPIOTR_GPS5 0x00000020 | 863 | #define EGPIOTR_GPS5 0x00000020 |
864 | #define EGPIOTR_GPS6 0x00000040 | 864 | #define EGPIOTR_GPS6 0x00000040 |
865 | #define EGPIOTR_GPS7 0x00000080 | 865 | #define EGPIOTR_GPS7 0x00000080 |
866 | #define EGPIOTR_GPS8 0x00000100 | 866 | #define EGPIOTR_GPS8 0x00000100 |
867 | #endif | 867 | #endif |
868 | 868 | ||
869 | /* | 869 | /* |
870 | * The following defines are for the flags in the extended GPIO ping wakeup | 870 | * The following defines are for the flags in the extended GPIO ping wakeup |
871 | * register. | 871 | * register. |
872 | */ | 872 | */ |
873 | #ifndef NO_CS4612 | 873 | #ifndef NO_CS4612 |
874 | #define EGPIOWR_GPW0 0x00000001 | 874 | #define EGPIOWR_GPW0 0x00000001 |
875 | #define EGPIOWR_GPW1 0x00000002 | 875 | #define EGPIOWR_GPW1 0x00000002 |
876 | #define EGPIOWR_GPW2 0x00000004 | 876 | #define EGPIOWR_GPW2 0x00000004 |
877 | #define EGPIOWR_GPW3 0x00000008 | 877 | #define EGPIOWR_GPW3 0x00000008 |
878 | #define EGPIOWR_GPW4 0x00000010 | 878 | #define EGPIOWR_GPW4 0x00000010 |
879 | #define EGPIOWR_GPW5 0x00000020 | 879 | #define EGPIOWR_GPW5 0x00000020 |
880 | #define EGPIOWR_GPW6 0x00000040 | 880 | #define EGPIOWR_GPW6 0x00000040 |
881 | #define EGPIOWR_GPW7 0x00000080 | 881 | #define EGPIOWR_GPW7 0x00000080 |
882 | #define EGPIOWR_GPW8 0x00000100 | 882 | #define EGPIOWR_GPW8 0x00000100 |
883 | #endif | 883 | #endif |
884 | 884 | ||
885 | /* | 885 | /* |
886 | * The following defines are for the flags in the extended GPIO pin status | 886 | * The following defines are for the flags in the extended GPIO pin status |
887 | * register. | 887 | * register. |
888 | */ | 888 | */ |
889 | #ifndef NO_CS4612 | 889 | #ifndef NO_CS4612 |
890 | #define EGPIOSR_GPS0 0x00000001 | 890 | #define EGPIOSR_GPS0 0x00000001 |
891 | #define EGPIOSR_GPS1 0x00000002 | 891 | #define EGPIOSR_GPS1 0x00000002 |
892 | #define EGPIOSR_GPS2 0x00000004 | 892 | #define EGPIOSR_GPS2 0x00000004 |
893 | #define EGPIOSR_GPS3 0x00000008 | 893 | #define EGPIOSR_GPS3 0x00000008 |
894 | #define EGPIOSR_GPS4 0x00000010 | 894 | #define EGPIOSR_GPS4 0x00000010 |
895 | #define EGPIOSR_GPS5 0x00000020 | 895 | #define EGPIOSR_GPS5 0x00000020 |
896 | #define EGPIOSR_GPS6 0x00000040 | 896 | #define EGPIOSR_GPS6 0x00000040 |
897 | #define EGPIOSR_GPS7 0x00000080 | 897 | #define EGPIOSR_GPS7 0x00000080 |
898 | #define EGPIOSR_GPS8 0x00000100 | 898 | #define EGPIOSR_GPS8 0x00000100 |
899 | #endif | 899 | #endif |
900 | 900 | ||
901 | /* | 901 | /* |
902 | * The following defines are for the flags in the serial port 6 configuration | 902 | * The following defines are for the flags in the serial port 6 configuration |
903 | * register. | 903 | * register. |
904 | */ | 904 | */ |
905 | #ifndef NO_CS4612 | 905 | #ifndef NO_CS4612 |
906 | #define SERC6_ASDO2EN 0x00000001 | 906 | #define SERC6_ASDO2EN 0x00000001 |
907 | #endif | 907 | #endif |
908 | 908 | ||
909 | /* | 909 | /* |
910 | * The following defines are for the flags in the serial port 7 configuration | 910 | * The following defines are for the flags in the serial port 7 configuration |
911 | * register. | 911 | * register. |
912 | */ | 912 | */ |
913 | #ifndef NO_CS4612 | 913 | #ifndef NO_CS4612 |
914 | #define SERC7_ASDI2EN 0x00000001 | 914 | #define SERC7_ASDI2EN 0x00000001 |
915 | #define SERC7_POSILB 0x00000002 | 915 | #define SERC7_POSILB 0x00000002 |
916 | #define SERC7_SIPOLB 0x00000004 | 916 | #define SERC7_SIPOLB 0x00000004 |
917 | #define SERC7_SOSILB 0x00000008 | 917 | #define SERC7_SOSILB 0x00000008 |
918 | #define SERC7_SISOLB 0x00000010 | 918 | #define SERC7_SISOLB 0x00000010 |
919 | #endif | 919 | #endif |
920 | 920 | ||
921 | /* | 921 | /* |
922 | * The following defines are for the flags in the serial port AC link | 922 | * The following defines are for the flags in the serial port AC link |
923 | * configuration register. | 923 | * configuration register. |
924 | */ | 924 | */ |
925 | #ifndef NO_CS4612 | 925 | #ifndef NO_CS4612 |
926 | #define SERACC_CHIP_TYPE_MASK 0x00000001 | 926 | #define SERACC_CHIP_TYPE_MASK 0x00000001 |
927 | #define SERACC_CHIP_TYPE_1_03 0x00000000 | 927 | #define SERACC_CHIP_TYPE_1_03 0x00000000 |
928 | #define SERACC_CHIP_TYPE_2_0 0x00000001 | 928 | #define SERACC_CHIP_TYPE_2_0 0x00000001 |
929 | #define SERACC_TWO_CODECS 0x00000002 | 929 | #define SERACC_TWO_CODECS 0x00000002 |
930 | #define SERACC_MDM 0x00000004 | 930 | #define SERACC_MDM 0x00000004 |
931 | #define SERACC_HSP 0x00000008 | 931 | #define SERACC_HSP 0x00000008 |
932 | #define SERACC_ODT 0x00000010 /* only CS4630 */ | 932 | #define SERACC_ODT 0x00000010 /* only CS4630 */ |
933 | #endif | 933 | #endif |
934 | 934 | ||
935 | /* | 935 | /* |
936 | * The following defines are for the flags in the AC97 control register 2. | 936 | * The following defines are for the flags in the AC97 control register 2. |
937 | */ | 937 | */ |
938 | #ifndef NO_CS4612 | 938 | #ifndef NO_CS4612 |
939 | #define ACCTL2_RSTN 0x00000001 | 939 | #define ACCTL2_RSTN 0x00000001 |
940 | #define ACCTL2_ESYN 0x00000002 | 940 | #define ACCTL2_ESYN 0x00000002 |
941 | #define ACCTL2_VFRM 0x00000004 | 941 | #define ACCTL2_VFRM 0x00000004 |
942 | #define ACCTL2_DCV 0x00000008 | 942 | #define ACCTL2_DCV 0x00000008 |
943 | #define ACCTL2_CRW 0x00000010 | 943 | #define ACCTL2_CRW 0x00000010 |
944 | #define ACCTL2_ASYN 0x00000020 | 944 | #define ACCTL2_ASYN 0x00000020 |
945 | #endif | 945 | #endif |
946 | 946 | ||
947 | /* | 947 | /* |
948 | * The following defines are for the flags in the AC97 status register 2. | 948 | * The following defines are for the flags in the AC97 status register 2. |
949 | */ | 949 | */ |
950 | #ifndef NO_CS4612 | 950 | #ifndef NO_CS4612 |
951 | #define ACSTS2_CRDY 0x00000001 | 951 | #define ACSTS2_CRDY 0x00000001 |
952 | #define ACSTS2_VSTS 0x00000002 | 952 | #define ACSTS2_VSTS 0x00000002 |
953 | #endif | 953 | #endif |
954 | 954 | ||
955 | /* | 955 | /* |
956 | * The following defines are for the flags in the AC97 output slot valid | 956 | * The following defines are for the flags in the AC97 output slot valid |
957 | * register 2. | 957 | * register 2. |
958 | */ | 958 | */ |
959 | #ifndef NO_CS4612 | 959 | #ifndef NO_CS4612 |
960 | #define ACOSV2_SLV3 0x00000001 | 960 | #define ACOSV2_SLV3 0x00000001 |
961 | #define ACOSV2_SLV4 0x00000002 | 961 | #define ACOSV2_SLV4 0x00000002 |
962 | #define ACOSV2_SLV5 0x00000004 | 962 | #define ACOSV2_SLV5 0x00000004 |
963 | #define ACOSV2_SLV6 0x00000008 | 963 | #define ACOSV2_SLV6 0x00000008 |
964 | #define ACOSV2_SLV7 0x00000010 | 964 | #define ACOSV2_SLV7 0x00000010 |
965 | #define ACOSV2_SLV8 0x00000020 | 965 | #define ACOSV2_SLV8 0x00000020 |
966 | #define ACOSV2_SLV9 0x00000040 | 966 | #define ACOSV2_SLV9 0x00000040 |
967 | #define ACOSV2_SLV10 0x00000080 | 967 | #define ACOSV2_SLV10 0x00000080 |
968 | #define ACOSV2_SLV11 0x00000100 | 968 | #define ACOSV2_SLV11 0x00000100 |
969 | #define ACOSV2_SLV12 0x00000200 | 969 | #define ACOSV2_SLV12 0x00000200 |
970 | #endif | 970 | #endif |
971 | 971 | ||
972 | /* | 972 | /* |
973 | * The following defines are for the flags in the AC97 command address | 973 | * The following defines are for the flags in the AC97 command address |
974 | * register 2. | 974 | * register 2. |
975 | */ | 975 | */ |
976 | #ifndef NO_CS4612 | 976 | #ifndef NO_CS4612 |
977 | #define ACCAD2_CI_MASK 0x0000007F | 977 | #define ACCAD2_CI_MASK 0x0000007F |
978 | #define ACCAD2_CI_SHIFT 0 | 978 | #define ACCAD2_CI_SHIFT 0 |
979 | #endif | 979 | #endif |
980 | 980 | ||
981 | /* | 981 | /* |
982 | * The following defines are for the flags in the AC97 command data register | 982 | * The following defines are for the flags in the AC97 command data register |
983 | * 2. | 983 | * 2. |
984 | */ | 984 | */ |
985 | #ifndef NO_CS4612 | 985 | #ifndef NO_CS4612 |
986 | #define ACCDA2_CD_MASK 0x0000FFFF | 986 | #define ACCDA2_CD_MASK 0x0000FFFF |
987 | #define ACCDA2_CD_SHIFT 0 | 987 | #define ACCDA2_CD_SHIFT 0 |
988 | #endif | 988 | #endif |
989 | 989 | ||
990 | /* | 990 | /* |
991 | * The following defines are for the flags in the AC97 input slot valid | 991 | * The following defines are for the flags in the AC97 input slot valid |
992 | * register 2. | 992 | * register 2. |
993 | */ | 993 | */ |
994 | #ifndef NO_CS4612 | 994 | #ifndef NO_CS4612 |
995 | #define ACISV2_ISV3 0x00000001 | 995 | #define ACISV2_ISV3 0x00000001 |
996 | #define ACISV2_ISV4 0x00000002 | 996 | #define ACISV2_ISV4 0x00000002 |
997 | #define ACISV2_ISV5 0x00000004 | 997 | #define ACISV2_ISV5 0x00000004 |
998 | #define ACISV2_ISV6 0x00000008 | 998 | #define ACISV2_ISV6 0x00000008 |
999 | #define ACISV2_ISV7 0x00000010 | 999 | #define ACISV2_ISV7 0x00000010 |
1000 | #define ACISV2_ISV8 0x00000020 | 1000 | #define ACISV2_ISV8 0x00000020 |
1001 | #define ACISV2_ISV9 0x00000040 | 1001 | #define ACISV2_ISV9 0x00000040 |
1002 | #define ACISV2_ISV10 0x00000080 | 1002 | #define ACISV2_ISV10 0x00000080 |
1003 | #define ACISV2_ISV11 0x00000100 | 1003 | #define ACISV2_ISV11 0x00000100 |
1004 | #define ACISV2_ISV12 0x00000200 | 1004 | #define ACISV2_ISV12 0x00000200 |
1005 | #endif | 1005 | #endif |
1006 | 1006 | ||
1007 | /* | 1007 | /* |
1008 | * The following defines are for the flags in the AC97 status address | 1008 | * The following defines are for the flags in the AC97 status address |
1009 | * register 2. | 1009 | * register 2. |
1010 | */ | 1010 | */ |
1011 | #ifndef NO_CS4612 | 1011 | #ifndef NO_CS4612 |
1012 | #define ACSAD2_SI_MASK 0x0000007F | 1012 | #define ACSAD2_SI_MASK 0x0000007F |
1013 | #define ACSAD2_SI_SHIFT 0 | 1013 | #define ACSAD2_SI_SHIFT 0 |
1014 | #endif | 1014 | #endif |
1015 | 1015 | ||
1016 | /* | 1016 | /* |
1017 | * The following defines are for the flags in the AC97 status data register 2. | 1017 | * The following defines are for the flags in the AC97 status data register 2. |
1018 | */ | 1018 | */ |
1019 | #ifndef NO_CS4612 | 1019 | #ifndef NO_CS4612 |
1020 | #define ACSDA2_SD_MASK 0x0000FFFF | 1020 | #define ACSDA2_SD_MASK 0x0000FFFF |
1021 | #define ACSDA2_SD_SHIFT 0 | 1021 | #define ACSDA2_SD_SHIFT 0 |
1022 | #endif | 1022 | #endif |
1023 | 1023 | ||
1024 | /* | 1024 | /* |
1025 | * The following defines are for the flags in the I/O trap address and control | 1025 | * The following defines are for the flags in the I/O trap address and control |
1026 | * registers (all 12). | 1026 | * registers (all 12). |
1027 | */ | 1027 | */ |
1028 | #ifndef NO_CS4612 | 1028 | #ifndef NO_CS4612 |
1029 | #define IOTAC_SA_MASK 0x0000FFFF | 1029 | #define IOTAC_SA_MASK 0x0000FFFF |
1030 | #define IOTAC_MSK_MASK 0x000F0000 | 1030 | #define IOTAC_MSK_MASK 0x000F0000 |
1031 | #define IOTAC_IODC_MASK 0x06000000 | 1031 | #define IOTAC_IODC_MASK 0x06000000 |
1032 | #define IOTAC_IODC_16_BIT 0x00000000 | 1032 | #define IOTAC_IODC_16_BIT 0x00000000 |
1033 | #define IOTAC_IODC_10_BIT 0x02000000 | 1033 | #define IOTAC_IODC_10_BIT 0x02000000 |
1034 | #define IOTAC_IODC_12_BIT 0x04000000 | 1034 | #define IOTAC_IODC_12_BIT 0x04000000 |
1035 | #define IOTAC_WSPI 0x08000000 | 1035 | #define IOTAC_WSPI 0x08000000 |
1036 | #define IOTAC_RSPI 0x10000000 | 1036 | #define IOTAC_RSPI 0x10000000 |
1037 | #define IOTAC_WSE 0x20000000 | 1037 | #define IOTAC_WSE 0x20000000 |
1038 | #define IOTAC_WE 0x40000000 | 1038 | #define IOTAC_WE 0x40000000 |
1039 | #define IOTAC_RE 0x80000000 | 1039 | #define IOTAC_RE 0x80000000 |
1040 | #define IOTAC_SA_SHIFT 0 | 1040 | #define IOTAC_SA_SHIFT 0 |
1041 | #define IOTAC_MSK_SHIFT 16 | 1041 | #define IOTAC_MSK_SHIFT 16 |
1042 | #endif | 1042 | #endif |
1043 | 1043 | ||
1044 | /* | 1044 | /* |
1045 | * The following defines are for the flags in the I/O trap fast read registers | 1045 | * The following defines are for the flags in the I/O trap fast read registers |
1046 | * (all 8). | 1046 | * (all 8). |
1047 | */ | 1047 | */ |
1048 | #ifndef NO_CS4612 | 1048 | #ifndef NO_CS4612 |
1049 | #define IOTFR_D_MASK 0x0000FFFF | 1049 | #define IOTFR_D_MASK 0x0000FFFF |
1050 | #define IOTFR_A_MASK 0x000F0000 | 1050 | #define IOTFR_A_MASK 0x000F0000 |
1051 | #define IOTFR_R_MASK 0x0F000000 | 1051 | #define IOTFR_R_MASK 0x0F000000 |
1052 | #define IOTFR_ALL 0x40000000 | 1052 | #define IOTFR_ALL 0x40000000 |
1053 | #define IOTFR_VL 0x80000000 | 1053 | #define IOTFR_VL 0x80000000 |
1054 | #define IOTFR_D_SHIFT 0 | 1054 | #define IOTFR_D_SHIFT 0 |
1055 | #define IOTFR_A_SHIFT 16 | 1055 | #define IOTFR_A_SHIFT 16 |
1056 | #define IOTFR_R_SHIFT 24 | 1056 | #define IOTFR_R_SHIFT 24 |
1057 | #endif | 1057 | #endif |
1058 | 1058 | ||
1059 | /* | 1059 | /* |
1060 | * The following defines are for the flags in the I/O trap FIFO register. | 1060 | * The following defines are for the flags in the I/O trap FIFO register. |
1061 | */ | 1061 | */ |
1062 | #ifndef NO_CS4612 | 1062 | #ifndef NO_CS4612 |
1063 | #define IOTFIFO_BA_MASK 0x00003FFF | 1063 | #define IOTFIFO_BA_MASK 0x00003FFF |
1064 | #define IOTFIFO_S_MASK 0x00FF0000 | 1064 | #define IOTFIFO_S_MASK 0x00FF0000 |
1065 | #define IOTFIFO_OF 0x40000000 | 1065 | #define IOTFIFO_OF 0x40000000 |
1066 | #define IOTFIFO_SPIOF 0x80000000 | 1066 | #define IOTFIFO_SPIOF 0x80000000 |
1067 | #define IOTFIFO_BA_SHIFT 0 | 1067 | #define IOTFIFO_BA_SHIFT 0 |
1068 | #define IOTFIFO_S_SHIFT 16 | 1068 | #define IOTFIFO_S_SHIFT 16 |
1069 | #endif | 1069 | #endif |
1070 | 1070 | ||
1071 | /* | 1071 | /* |
1072 | * The following defines are for the flags in the I/O trap retry read data | 1072 | * The following defines are for the flags in the I/O trap retry read data |
1073 | * register. | 1073 | * register. |
1074 | */ | 1074 | */ |
1075 | #ifndef NO_CS4612 | 1075 | #ifndef NO_CS4612 |
1076 | #define IOTRRD_D_MASK 0x0000FFFF | 1076 | #define IOTRRD_D_MASK 0x0000FFFF |
1077 | #define IOTRRD_RDV 0x80000000 | 1077 | #define IOTRRD_RDV 0x80000000 |
1078 | #define IOTRRD_D_SHIFT 0 | 1078 | #define IOTRRD_D_SHIFT 0 |
1079 | #endif | 1079 | #endif |
1080 | 1080 | ||
1081 | /* | 1081 | /* |
1082 | * The following defines are for the flags in the I/O trap FIFO pointer | 1082 | * The following defines are for the flags in the I/O trap FIFO pointer |
1083 | * register. | 1083 | * register. |
1084 | */ | 1084 | */ |
1085 | #ifndef NO_CS4612 | 1085 | #ifndef NO_CS4612 |
1086 | #define IOTFP_CA_MASK 0x00003FFF | 1086 | #define IOTFP_CA_MASK 0x00003FFF |
1087 | #define IOTFP_PA_MASK 0x3FFF0000 | 1087 | #define IOTFP_PA_MASK 0x3FFF0000 |
1088 | #define IOTFP_CA_SHIFT 0 | 1088 | #define IOTFP_CA_SHIFT 0 |
1089 | #define IOTFP_PA_SHIFT 16 | 1089 | #define IOTFP_PA_SHIFT 16 |
1090 | #endif | 1090 | #endif |
1091 | 1091 | ||
1092 | /* | 1092 | /* |
1093 | * The following defines are for the flags in the I/O trap control register. | 1093 | * The following defines are for the flags in the I/O trap control register. |
1094 | */ | 1094 | */ |
1095 | #ifndef NO_CS4612 | 1095 | #ifndef NO_CS4612 |
1096 | #define IOTCR_ITD 0x00000001 | 1096 | #define IOTCR_ITD 0x00000001 |
1097 | #define IOTCR_HRV 0x00000002 | 1097 | #define IOTCR_HRV 0x00000002 |
1098 | #define IOTCR_SRV 0x00000004 | 1098 | #define IOTCR_SRV 0x00000004 |
1099 | #define IOTCR_DTI 0x00000008 | 1099 | #define IOTCR_DTI 0x00000008 |
1100 | #define IOTCR_DFI 0x00000010 | 1100 | #define IOTCR_DFI 0x00000010 |
1101 | #define IOTCR_DDP 0x00000020 | 1101 | #define IOTCR_DDP 0x00000020 |
1102 | #define IOTCR_JTE 0x00000040 | 1102 | #define IOTCR_JTE 0x00000040 |
1103 | #define IOTCR_PPE 0x00000080 | 1103 | #define IOTCR_PPE 0x00000080 |
1104 | #endif | 1104 | #endif |
1105 | 1105 | ||
1106 | /* | 1106 | /* |
1107 | * The following defines are for the flags in the direct PCI data register. | 1107 | * The following defines are for the flags in the direct PCI data register. |
1108 | */ | 1108 | */ |
1109 | #ifndef NO_CS4612 | 1109 | #ifndef NO_CS4612 |
1110 | #define DPCID_D_MASK 0xFFFFFFFF | 1110 | #define DPCID_D_MASK 0xFFFFFFFF |
1111 | #define DPCID_D_SHIFT 0 | 1111 | #define DPCID_D_SHIFT 0 |
1112 | #endif | 1112 | #endif |
1113 | 1113 | ||
1114 | /* | 1114 | /* |
1115 | * The following defines are for the flags in the direct PCI address register. | 1115 | * The following defines are for the flags in the direct PCI address register. |
1116 | */ | 1116 | */ |
1117 | #ifndef NO_CS4612 | 1117 | #ifndef NO_CS4612 |
1118 | #define DPCIA_A_MASK 0xFFFFFFFF | 1118 | #define DPCIA_A_MASK 0xFFFFFFFF |
1119 | #define DPCIA_A_SHIFT 0 | 1119 | #define DPCIA_A_SHIFT 0 |
1120 | #endif | 1120 | #endif |
1121 | 1121 | ||
1122 | /* | 1122 | /* |
1123 | * The following defines are for the flags in the direct PCI command register. | 1123 | * The following defines are for the flags in the direct PCI command register. |
1124 | */ | 1124 | */ |
1125 | #ifndef NO_CS4612 | 1125 | #ifndef NO_CS4612 |
1126 | #define DPCIC_C_MASK 0x0000000F | 1126 | #define DPCIC_C_MASK 0x0000000F |
1127 | #define DPCIC_C_IOREAD 0x00000002 | 1127 | #define DPCIC_C_IOREAD 0x00000002 |
1128 | #define DPCIC_C_IOWRITE 0x00000003 | 1128 | #define DPCIC_C_IOWRITE 0x00000003 |
1129 | #define DPCIC_BE_MASK 0x000000F0 | 1129 | #define DPCIC_BE_MASK 0x000000F0 |
1130 | #endif | 1130 | #endif |
1131 | 1131 | ||
1132 | /* | 1132 | /* |
1133 | * The following defines are for the flags in the PC/PCI request register. | 1133 | * The following defines are for the flags in the PC/PCI request register. |
1134 | */ | 1134 | */ |
1135 | #ifndef NO_CS4612 | 1135 | #ifndef NO_CS4612 |
1136 | #define PCPCIR_RDC_MASK 0x00000007 | 1136 | #define PCPCIR_RDC_MASK 0x00000007 |
1137 | #define PCPCIR_C_MASK 0x00007000 | 1137 | #define PCPCIR_C_MASK 0x00007000 |
1138 | #define PCPCIR_REQ 0x00008000 | 1138 | #define PCPCIR_REQ 0x00008000 |
1139 | #define PCPCIR_RDC_SHIFT 0 | 1139 | #define PCPCIR_RDC_SHIFT 0 |
1140 | #define PCPCIR_C_SHIFT 12 | 1140 | #define PCPCIR_C_SHIFT 12 |
1141 | #endif | 1141 | #endif |
1142 | 1142 | ||
1143 | /* | 1143 | /* |
1144 | * The following defines are for the flags in the PC/PCI grant register. | 1144 | * The following defines are for the flags in the PC/PCI grant register. |
1145 | */ | 1145 | */ |
1146 | #ifndef NO_CS4612 | 1146 | #ifndef NO_CS4612 |
1147 | #define PCPCIG_GDC_MASK 0x00000007 | 1147 | #define PCPCIG_GDC_MASK 0x00000007 |
1148 | #define PCPCIG_VL 0x00008000 | 1148 | #define PCPCIG_VL 0x00008000 |
1149 | #define PCPCIG_GDC_SHIFT 0 | 1149 | #define PCPCIG_GDC_SHIFT 0 |
1150 | #endif | 1150 | #endif |
1151 | 1151 | ||
1152 | /* | 1152 | /* |
1153 | * The following defines are for the flags in the PC/PCI master enable | 1153 | * The following defines are for the flags in the PC/PCI master enable |
1154 | * register. | 1154 | * register. |
1155 | */ | 1155 | */ |
1156 | #ifndef NO_CS4612 | 1156 | #ifndef NO_CS4612 |
1157 | #define PCPCIEN_EN 0x00000001 | 1157 | #define PCPCIEN_EN 0x00000001 |
1158 | #endif | 1158 | #endif |
1159 | 1159 | ||
1160 | /* | 1160 | /* |
1161 | * The following defines are for the flags in the extended PCI power | 1161 | * The following defines are for the flags in the extended PCI power |
1162 | * management control register. | 1162 | * management control register. |
1163 | */ | 1163 | */ |
1164 | #ifndef NO_CS4612 | 1164 | #ifndef NO_CS4612 |
1165 | #define EPCIPMC_GWU 0x00000001 | 1165 | #define EPCIPMC_GWU 0x00000001 |
1166 | #define EPCIPMC_FSPC 0x00000002 | 1166 | #define EPCIPMC_FSPC 0x00000002 |
1167 | #endif | 1167 | #endif |
1168 | 1168 | ||
1169 | /* | 1169 | /* |
1170 | * The following defines are for the flags in the SP control register. | 1170 | * The following defines are for the flags in the SP control register. |
1171 | */ | 1171 | */ |
1172 | #define SPCR_RUN 0x00000001 | 1172 | #define SPCR_RUN 0x00000001 |
1173 | #define SPCR_STPFR 0x00000002 | 1173 | #define SPCR_STPFR 0x00000002 |
1174 | #define SPCR_RUNFR 0x00000004 | 1174 | #define SPCR_RUNFR 0x00000004 |
1175 | #define SPCR_TICK 0x00000008 | 1175 | #define SPCR_TICK 0x00000008 |
1176 | #define SPCR_DRQEN 0x00000020 | 1176 | #define SPCR_DRQEN 0x00000020 |
1177 | #define SPCR_RSTSP 0x00000040 | 1177 | #define SPCR_RSTSP 0x00000040 |
1178 | #define SPCR_OREN 0x00000080 | 1178 | #define SPCR_OREN 0x00000080 |
1179 | #ifndef NO_CS4612 | 1179 | #ifndef NO_CS4612 |
1180 | #define SPCR_PCIINT 0x00000100 | 1180 | #define SPCR_PCIINT 0x00000100 |
1181 | #define SPCR_OINTD 0x00000200 | 1181 | #define SPCR_OINTD 0x00000200 |
1182 | #define SPCR_CRE 0x00008000 | 1182 | #define SPCR_CRE 0x00008000 |
1183 | #endif | 1183 | #endif |
1184 | 1184 | ||
1185 | /* | 1185 | /* |
1186 | * The following defines are for the flags in the debug index register. | 1186 | * The following defines are for the flags in the debug index register. |
1187 | */ | 1187 | */ |
1188 | #define DREG_REGID_MASK 0x0000007F | 1188 | #define DREG_REGID_MASK 0x0000007F |
1189 | #define DREG_DEBUG 0x00000080 | 1189 | #define DREG_DEBUG 0x00000080 |
1190 | #define DREG_RGBK_MASK 0x00000700 | 1190 | #define DREG_RGBK_MASK 0x00000700 |
1191 | #define DREG_TRAP 0x00000800 | 1191 | #define DREG_TRAP 0x00000800 |
1192 | #if !defined(NO_CS4612) | 1192 | #if !defined(NO_CS4612) |
1193 | #if !defined(NO_CS4615) | 1193 | #if !defined(NO_CS4615) |
1194 | #define DREG_TRAPX 0x00001000 | 1194 | #define DREG_TRAPX 0x00001000 |
1195 | #endif | 1195 | #endif |
1196 | #endif | 1196 | #endif |
1197 | #define DREG_REGID_SHIFT 0 | 1197 | #define DREG_REGID_SHIFT 0 |
1198 | #define DREG_RGBK_SHIFT 8 | 1198 | #define DREG_RGBK_SHIFT 8 |
1199 | #define DREG_RGBK_REGID_MASK 0x0000077F | 1199 | #define DREG_RGBK_REGID_MASK 0x0000077F |
1200 | #define DREG_REGID_R0 0x00000010 | 1200 | #define DREG_REGID_R0 0x00000010 |
1201 | #define DREG_REGID_R1 0x00000011 | 1201 | #define DREG_REGID_R1 0x00000011 |
1202 | #define DREG_REGID_R2 0x00000012 | 1202 | #define DREG_REGID_R2 0x00000012 |
1203 | #define DREG_REGID_R3 0x00000013 | 1203 | #define DREG_REGID_R3 0x00000013 |
1204 | #define DREG_REGID_R4 0x00000014 | 1204 | #define DREG_REGID_R4 0x00000014 |
1205 | #define DREG_REGID_R5 0x00000015 | 1205 | #define DREG_REGID_R5 0x00000015 |
1206 | #define DREG_REGID_R6 0x00000016 | 1206 | #define DREG_REGID_R6 0x00000016 |
1207 | #define DREG_REGID_R7 0x00000017 | 1207 | #define DREG_REGID_R7 0x00000017 |
1208 | #define DREG_REGID_R8 0x00000018 | 1208 | #define DREG_REGID_R8 0x00000018 |
1209 | #define DREG_REGID_R9 0x00000019 | 1209 | #define DREG_REGID_R9 0x00000019 |
1210 | #define DREG_REGID_RA 0x0000001A | 1210 | #define DREG_REGID_RA 0x0000001A |
1211 | #define DREG_REGID_RB 0x0000001B | 1211 | #define DREG_REGID_RB 0x0000001B |
1212 | #define DREG_REGID_RC 0x0000001C | 1212 | #define DREG_REGID_RC 0x0000001C |
1213 | #define DREG_REGID_RD 0x0000001D | 1213 | #define DREG_REGID_RD 0x0000001D |
1214 | #define DREG_REGID_RE 0x0000001E | 1214 | #define DREG_REGID_RE 0x0000001E |
1215 | #define DREG_REGID_RF 0x0000001F | 1215 | #define DREG_REGID_RF 0x0000001F |
1216 | #define DREG_REGID_RA_BUS_LOW 0x00000020 | 1216 | #define DREG_REGID_RA_BUS_LOW 0x00000020 |
1217 | #define DREG_REGID_RA_BUS_HIGH 0x00000038 | 1217 | #define DREG_REGID_RA_BUS_HIGH 0x00000038 |
1218 | #define DREG_REGID_YBUS_LOW 0x00000050 | 1218 | #define DREG_REGID_YBUS_LOW 0x00000050 |
1219 | #define DREG_REGID_YBUS_HIGH 0x00000058 | 1219 | #define DREG_REGID_YBUS_HIGH 0x00000058 |
1220 | #define DREG_REGID_TRAP_0 0x00000100 | 1220 | #define DREG_REGID_TRAP_0 0x00000100 |
1221 | #define DREG_REGID_TRAP_1 0x00000101 | 1221 | #define DREG_REGID_TRAP_1 0x00000101 |
1222 | #define DREG_REGID_TRAP_2 0x00000102 | 1222 | #define DREG_REGID_TRAP_2 0x00000102 |
1223 | #define DREG_REGID_TRAP_3 0x00000103 | 1223 | #define DREG_REGID_TRAP_3 0x00000103 |
1224 | #define DREG_REGID_TRAP_4 0x00000104 | 1224 | #define DREG_REGID_TRAP_4 0x00000104 |
1225 | #define DREG_REGID_TRAP_5 0x00000105 | 1225 | #define DREG_REGID_TRAP_5 0x00000105 |
1226 | #define DREG_REGID_TRAP_6 0x00000106 | 1226 | #define DREG_REGID_TRAP_6 0x00000106 |
1227 | #define DREG_REGID_TRAP_7 0x00000107 | 1227 | #define DREG_REGID_TRAP_7 0x00000107 |
1228 | #define DREG_REGID_INDIRECT_ADDRESS 0x0000010E | 1228 | #define DREG_REGID_INDIRECT_ADDRESS 0x0000010E |
1229 | #define DREG_REGID_TOP_OF_STACK 0x0000010F | 1229 | #define DREG_REGID_TOP_OF_STACK 0x0000010F |
1230 | #if !defined(NO_CS4612) | 1230 | #if !defined(NO_CS4612) |
1231 | #if !defined(NO_CS4615) | 1231 | #if !defined(NO_CS4615) |
1232 | #define DREG_REGID_TRAP_8 0x00000110 | 1232 | #define DREG_REGID_TRAP_8 0x00000110 |
1233 | #define DREG_REGID_TRAP_9 0x00000111 | 1233 | #define DREG_REGID_TRAP_9 0x00000111 |
1234 | #define DREG_REGID_TRAP_10 0x00000112 | 1234 | #define DREG_REGID_TRAP_10 0x00000112 |
1235 | #define DREG_REGID_TRAP_11 0x00000113 | 1235 | #define DREG_REGID_TRAP_11 0x00000113 |
1236 | #define DREG_REGID_TRAP_12 0x00000114 | 1236 | #define DREG_REGID_TRAP_12 0x00000114 |
1237 | #define DREG_REGID_TRAP_13 0x00000115 | 1237 | #define DREG_REGID_TRAP_13 0x00000115 |
1238 | #define DREG_REGID_TRAP_14 0x00000116 | 1238 | #define DREG_REGID_TRAP_14 0x00000116 |
1239 | #define DREG_REGID_TRAP_15 0x00000117 | 1239 | #define DREG_REGID_TRAP_15 0x00000117 |
1240 | #define DREG_REGID_TRAP_16 0x00000118 | 1240 | #define DREG_REGID_TRAP_16 0x00000118 |
1241 | #define DREG_REGID_TRAP_17 0x00000119 | 1241 | #define DREG_REGID_TRAP_17 0x00000119 |
1242 | #define DREG_REGID_TRAP_18 0x0000011A | 1242 | #define DREG_REGID_TRAP_18 0x0000011A |
1243 | #define DREG_REGID_TRAP_19 0x0000011B | 1243 | #define DREG_REGID_TRAP_19 0x0000011B |
1244 | #define DREG_REGID_TRAP_20 0x0000011C | 1244 | #define DREG_REGID_TRAP_20 0x0000011C |
1245 | #define DREG_REGID_TRAP_21 0x0000011D | 1245 | #define DREG_REGID_TRAP_21 0x0000011D |
1246 | #define DREG_REGID_TRAP_22 0x0000011E | 1246 | #define DREG_REGID_TRAP_22 0x0000011E |
1247 | #define DREG_REGID_TRAP_23 0x0000011F | 1247 | #define DREG_REGID_TRAP_23 0x0000011F |
1248 | #endif | 1248 | #endif |
1249 | #endif | 1249 | #endif |
1250 | #define DREG_REGID_RSA0_LOW 0x00000200 | 1250 | #define DREG_REGID_RSA0_LOW 0x00000200 |
1251 | #define DREG_REGID_RSA0_HIGH 0x00000201 | 1251 | #define DREG_REGID_RSA0_HIGH 0x00000201 |
1252 | #define DREG_REGID_RSA1_LOW 0x00000202 | 1252 | #define DREG_REGID_RSA1_LOW 0x00000202 |
1253 | #define DREG_REGID_RSA1_HIGH 0x00000203 | 1253 | #define DREG_REGID_RSA1_HIGH 0x00000203 |
1254 | #define DREG_REGID_RSA2 0x00000204 | 1254 | #define DREG_REGID_RSA2 0x00000204 |
1255 | #define DREG_REGID_RSA3 0x00000205 | 1255 | #define DREG_REGID_RSA3 0x00000205 |
1256 | #define DREG_REGID_RSI0_LOW 0x00000206 | 1256 | #define DREG_REGID_RSI0_LOW 0x00000206 |
1257 | #define DREG_REGID_RSI0_HIGH 0x00000207 | 1257 | #define DREG_REGID_RSI0_HIGH 0x00000207 |
1258 | #define DREG_REGID_RSI1 0x00000208 | 1258 | #define DREG_REGID_RSI1 0x00000208 |
1259 | #define DREG_REGID_RSI2 0x00000209 | 1259 | #define DREG_REGID_RSI2 0x00000209 |
1260 | #define DREG_REGID_SAGUSTATUS 0x0000020A | 1260 | #define DREG_REGID_SAGUSTATUS 0x0000020A |
1261 | #define DREG_REGID_RSCONFIG01_LOW 0x0000020B | 1261 | #define DREG_REGID_RSCONFIG01_LOW 0x0000020B |
1262 | #define DREG_REGID_RSCONFIG01_HIGH 0x0000020C | 1262 | #define DREG_REGID_RSCONFIG01_HIGH 0x0000020C |
1263 | #define DREG_REGID_RSCONFIG23_LOW 0x0000020D | 1263 | #define DREG_REGID_RSCONFIG23_LOW 0x0000020D |
1264 | #define DREG_REGID_RSCONFIG23_HIGH 0x0000020E | 1264 | #define DREG_REGID_RSCONFIG23_HIGH 0x0000020E |
1265 | #define DREG_REGID_RSDMA01E 0x0000020F | 1265 | #define DREG_REGID_RSDMA01E 0x0000020F |
1266 | #define DREG_REGID_RSDMA23E 0x00000210 | 1266 | #define DREG_REGID_RSDMA23E 0x00000210 |
1267 | #define DREG_REGID_RSD0_LOW 0x00000211 | 1267 | #define DREG_REGID_RSD0_LOW 0x00000211 |
1268 | #define DREG_REGID_RSD0_HIGH 0x00000212 | 1268 | #define DREG_REGID_RSD0_HIGH 0x00000212 |
1269 | #define DREG_REGID_RSD1_LOW 0x00000213 | 1269 | #define DREG_REGID_RSD1_LOW 0x00000213 |
1270 | #define DREG_REGID_RSD1_HIGH 0x00000214 | 1270 | #define DREG_REGID_RSD1_HIGH 0x00000214 |
1271 | #define DREG_REGID_RSD2_LOW 0x00000215 | 1271 | #define DREG_REGID_RSD2_LOW 0x00000215 |
1272 | #define DREG_REGID_RSD2_HIGH 0x00000216 | 1272 | #define DREG_REGID_RSD2_HIGH 0x00000216 |
1273 | #define DREG_REGID_RSD3_LOW 0x00000217 | 1273 | #define DREG_REGID_RSD3_LOW 0x00000217 |
1274 | #define DREG_REGID_RSD3_HIGH 0x00000218 | 1274 | #define DREG_REGID_RSD3_HIGH 0x00000218 |
1275 | #define DREG_REGID_SRAR_HIGH 0x0000021A | 1275 | #define DREG_REGID_SRAR_HIGH 0x0000021A |
1276 | #define DREG_REGID_SRAR_LOW 0x0000021B | 1276 | #define DREG_REGID_SRAR_LOW 0x0000021B |
1277 | #define DREG_REGID_DMA_STATE 0x0000021C | 1277 | #define DREG_REGID_DMA_STATE 0x0000021C |
1278 | #define DREG_REGID_CURRENT_DMA_STREAM 0x0000021D | 1278 | #define DREG_REGID_CURRENT_DMA_STREAM 0x0000021D |
1279 | #define DREG_REGID_NEXT_DMA_STREAM 0x0000021E | 1279 | #define DREG_REGID_NEXT_DMA_STREAM 0x0000021E |
1280 | #define DREG_REGID_CPU_STATUS 0x00000300 | 1280 | #define DREG_REGID_CPU_STATUS 0x00000300 |
1281 | #define DREG_REGID_MAC_MODE 0x00000301 | 1281 | #define DREG_REGID_MAC_MODE 0x00000301 |
1282 | #define DREG_REGID_STACK_AND_REPEAT 0x00000302 | 1282 | #define DREG_REGID_STACK_AND_REPEAT 0x00000302 |
1283 | #define DREG_REGID_INDEX0 0x00000304 | 1283 | #define DREG_REGID_INDEX0 0x00000304 |
1284 | #define DREG_REGID_INDEX1 0x00000305 | 1284 | #define DREG_REGID_INDEX1 0x00000305 |
1285 | #define DREG_REGID_DMA_STATE_0_3 0x00000400 | 1285 | #define DREG_REGID_DMA_STATE_0_3 0x00000400 |
1286 | #define DREG_REGID_DMA_STATE_4_7 0x00000404 | 1286 | #define DREG_REGID_DMA_STATE_4_7 0x00000404 |
1287 | #define DREG_REGID_DMA_STATE_8_11 0x00000408 | 1287 | #define DREG_REGID_DMA_STATE_8_11 0x00000408 |
1288 | #define DREG_REGID_DMA_STATE_12_15 0x0000040C | 1288 | #define DREG_REGID_DMA_STATE_12_15 0x0000040C |
1289 | #define DREG_REGID_DMA_STATE_16_19 0x00000410 | 1289 | #define DREG_REGID_DMA_STATE_16_19 0x00000410 |
1290 | #define DREG_REGID_DMA_STATE_20_23 0x00000414 | 1290 | #define DREG_REGID_DMA_STATE_20_23 0x00000414 |
1291 | #define DREG_REGID_DMA_STATE_24_27 0x00000418 | 1291 | #define DREG_REGID_DMA_STATE_24_27 0x00000418 |
1292 | #define DREG_REGID_DMA_STATE_28_31 0x0000041C | 1292 | #define DREG_REGID_DMA_STATE_28_31 0x0000041C |
1293 | #define DREG_REGID_DMA_STATE_32_35 0x00000420 | 1293 | #define DREG_REGID_DMA_STATE_32_35 0x00000420 |
1294 | #define DREG_REGID_DMA_STATE_36_39 0x00000424 | 1294 | #define DREG_REGID_DMA_STATE_36_39 0x00000424 |
1295 | #define DREG_REGID_DMA_STATE_40_43 0x00000428 | 1295 | #define DREG_REGID_DMA_STATE_40_43 0x00000428 |
1296 | #define DREG_REGID_DMA_STATE_44_47 0x0000042C | 1296 | #define DREG_REGID_DMA_STATE_44_47 0x0000042C |
1297 | #define DREG_REGID_DMA_STATE_48_51 0x00000430 | 1297 | #define DREG_REGID_DMA_STATE_48_51 0x00000430 |
1298 | #define DREG_REGID_DMA_STATE_52_55 0x00000434 | 1298 | #define DREG_REGID_DMA_STATE_52_55 0x00000434 |
1299 | #define DREG_REGID_DMA_STATE_56_59 0x00000438 | 1299 | #define DREG_REGID_DMA_STATE_56_59 0x00000438 |
1300 | #define DREG_REGID_DMA_STATE_60_63 0x0000043C | 1300 | #define DREG_REGID_DMA_STATE_60_63 0x0000043C |
1301 | #define DREG_REGID_DMA_STATE_64_67 0x00000440 | 1301 | #define DREG_REGID_DMA_STATE_64_67 0x00000440 |
1302 | #define DREG_REGID_DMA_STATE_68_71 0x00000444 | 1302 | #define DREG_REGID_DMA_STATE_68_71 0x00000444 |
1303 | #define DREG_REGID_DMA_STATE_72_75 0x00000448 | 1303 | #define DREG_REGID_DMA_STATE_72_75 0x00000448 |
1304 | #define DREG_REGID_DMA_STATE_76_79 0x0000044C | 1304 | #define DREG_REGID_DMA_STATE_76_79 0x0000044C |
1305 | #define DREG_REGID_DMA_STATE_80_83 0x00000450 | 1305 | #define DREG_REGID_DMA_STATE_80_83 0x00000450 |
1306 | #define DREG_REGID_DMA_STATE_84_87 0x00000454 | 1306 | #define DREG_REGID_DMA_STATE_84_87 0x00000454 |
1307 | #define DREG_REGID_DMA_STATE_88_91 0x00000458 | 1307 | #define DREG_REGID_DMA_STATE_88_91 0x00000458 |
1308 | #define DREG_REGID_DMA_STATE_92_95 0x0000045C | 1308 | #define DREG_REGID_DMA_STATE_92_95 0x0000045C |
1309 | #define DREG_REGID_TRAP_SELECT 0x00000500 | 1309 | #define DREG_REGID_TRAP_SELECT 0x00000500 |
1310 | #define DREG_REGID_TRAP_WRITE_0 0x00000500 | 1310 | #define DREG_REGID_TRAP_WRITE_0 0x00000500 |
1311 | #define DREG_REGID_TRAP_WRITE_1 0x00000501 | 1311 | #define DREG_REGID_TRAP_WRITE_1 0x00000501 |
1312 | #define DREG_REGID_TRAP_WRITE_2 0x00000502 | 1312 | #define DREG_REGID_TRAP_WRITE_2 0x00000502 |
1313 | #define DREG_REGID_TRAP_WRITE_3 0x00000503 | 1313 | #define DREG_REGID_TRAP_WRITE_3 0x00000503 |
1314 | #define DREG_REGID_TRAP_WRITE_4 0x00000504 | 1314 | #define DREG_REGID_TRAP_WRITE_4 0x00000504 |
1315 | #define DREG_REGID_TRAP_WRITE_5 0x00000505 | 1315 | #define DREG_REGID_TRAP_WRITE_5 0x00000505 |
1316 | #define DREG_REGID_TRAP_WRITE_6 0x00000506 | 1316 | #define DREG_REGID_TRAP_WRITE_6 0x00000506 |
1317 | #define DREG_REGID_TRAP_WRITE_7 0x00000507 | 1317 | #define DREG_REGID_TRAP_WRITE_7 0x00000507 |
1318 | #if !defined(NO_CS4612) | 1318 | #if !defined(NO_CS4612) |
1319 | #if !defined(NO_CS4615) | 1319 | #if !defined(NO_CS4615) |
1320 | #define DREG_REGID_TRAP_WRITE_8 0x00000510 | 1320 | #define DREG_REGID_TRAP_WRITE_8 0x00000510 |
1321 | #define DREG_REGID_TRAP_WRITE_9 0x00000511 | 1321 | #define DREG_REGID_TRAP_WRITE_9 0x00000511 |
1322 | #define DREG_REGID_TRAP_WRITE_10 0x00000512 | 1322 | #define DREG_REGID_TRAP_WRITE_10 0x00000512 |
1323 | #define DREG_REGID_TRAP_WRITE_11 0x00000513 | 1323 | #define DREG_REGID_TRAP_WRITE_11 0x00000513 |
1324 | #define DREG_REGID_TRAP_WRITE_12 0x00000514 | 1324 | #define DREG_REGID_TRAP_WRITE_12 0x00000514 |
1325 | #define DREG_REGID_TRAP_WRITE_13 0x00000515 | 1325 | #define DREG_REGID_TRAP_WRITE_13 0x00000515 |
1326 | #define DREG_REGID_TRAP_WRITE_14 0x00000516 | 1326 | #define DREG_REGID_TRAP_WRITE_14 0x00000516 |
1327 | #define DREG_REGID_TRAP_WRITE_15 0x00000517 | 1327 | #define DREG_REGID_TRAP_WRITE_15 0x00000517 |
1328 | #define DREG_REGID_TRAP_WRITE_16 0x00000518 | 1328 | #define DREG_REGID_TRAP_WRITE_16 0x00000518 |
1329 | #define DREG_REGID_TRAP_WRITE_17 0x00000519 | 1329 | #define DREG_REGID_TRAP_WRITE_17 0x00000519 |
1330 | #define DREG_REGID_TRAP_WRITE_18 0x0000051A | 1330 | #define DREG_REGID_TRAP_WRITE_18 0x0000051A |
1331 | #define DREG_REGID_TRAP_WRITE_19 0x0000051B | 1331 | #define DREG_REGID_TRAP_WRITE_19 0x0000051B |
1332 | #define DREG_REGID_TRAP_WRITE_20 0x0000051C | 1332 | #define DREG_REGID_TRAP_WRITE_20 0x0000051C |
1333 | #define DREG_REGID_TRAP_WRITE_21 0x0000051D | 1333 | #define DREG_REGID_TRAP_WRITE_21 0x0000051D |
1334 | #define DREG_REGID_TRAP_WRITE_22 0x0000051E | 1334 | #define DREG_REGID_TRAP_WRITE_22 0x0000051E |
1335 | #define DREG_REGID_TRAP_WRITE_23 0x0000051F | 1335 | #define DREG_REGID_TRAP_WRITE_23 0x0000051F |
1336 | #endif | 1336 | #endif |
1337 | #endif | 1337 | #endif |
1338 | #define DREG_REGID_MAC0_ACC0_LOW 0x00000600 | 1338 | #define DREG_REGID_MAC0_ACC0_LOW 0x00000600 |
1339 | #define DREG_REGID_MAC0_ACC1_LOW 0x00000601 | 1339 | #define DREG_REGID_MAC0_ACC1_LOW 0x00000601 |
1340 | #define DREG_REGID_MAC0_ACC2_LOW 0x00000602 | 1340 | #define DREG_REGID_MAC0_ACC2_LOW 0x00000602 |
1341 | #define DREG_REGID_MAC0_ACC3_LOW 0x00000603 | 1341 | #define DREG_REGID_MAC0_ACC3_LOW 0x00000603 |
1342 | #define DREG_REGID_MAC1_ACC0_LOW 0x00000604 | 1342 | #define DREG_REGID_MAC1_ACC0_LOW 0x00000604 |
1343 | #define DREG_REGID_MAC1_ACC1_LOW 0x00000605 | 1343 | #define DREG_REGID_MAC1_ACC1_LOW 0x00000605 |
1344 | #define DREG_REGID_MAC1_ACC2_LOW 0x00000606 | 1344 | #define DREG_REGID_MAC1_ACC2_LOW 0x00000606 |
1345 | #define DREG_REGID_MAC1_ACC3_LOW 0x00000607 | 1345 | #define DREG_REGID_MAC1_ACC3_LOW 0x00000607 |
1346 | #define DREG_REGID_MAC0_ACC0_MID 0x00000608 | 1346 | #define DREG_REGID_MAC0_ACC0_MID 0x00000608 |
1347 | #define DREG_REGID_MAC0_ACC1_MID 0x00000609 | 1347 | #define DREG_REGID_MAC0_ACC1_MID 0x00000609 |
1348 | #define DREG_REGID_MAC0_ACC2_MID 0x0000060A | 1348 | #define DREG_REGID_MAC0_ACC2_MID 0x0000060A |
1349 | #define DREG_REGID_MAC0_ACC3_MID 0x0000060B | 1349 | #define DREG_REGID_MAC0_ACC3_MID 0x0000060B |
1350 | #define DREG_REGID_MAC1_ACC0_MID 0x0000060C | 1350 | #define DREG_REGID_MAC1_ACC0_MID 0x0000060C |
1351 | #define DREG_REGID_MAC1_ACC1_MID 0x0000060D | 1351 | #define DREG_REGID_MAC1_ACC1_MID 0x0000060D |
1352 | #define DREG_REGID_MAC1_ACC2_MID 0x0000060E | 1352 | #define DREG_REGID_MAC1_ACC2_MID 0x0000060E |
1353 | #define DREG_REGID_MAC1_ACC3_MID 0x0000060F | 1353 | #define DREG_REGID_MAC1_ACC3_MID 0x0000060F |
1354 | #define DREG_REGID_MAC0_ACC0_HIGH 0x00000610 | 1354 | #define DREG_REGID_MAC0_ACC0_HIGH 0x00000610 |
1355 | #define DREG_REGID_MAC0_ACC1_HIGH 0x00000611 | 1355 | #define DREG_REGID_MAC0_ACC1_HIGH 0x00000611 |
1356 | #define DREG_REGID_MAC0_ACC2_HIGH 0x00000612 | 1356 | #define DREG_REGID_MAC0_ACC2_HIGH 0x00000612 |
1357 | #define DREG_REGID_MAC0_ACC3_HIGH 0x00000613 | 1357 | #define DREG_REGID_MAC0_ACC3_HIGH 0x00000613 |
1358 | #define DREG_REGID_MAC1_ACC0_HIGH 0x00000614 | 1358 | #define DREG_REGID_MAC1_ACC0_HIGH 0x00000614 |
1359 | #define DREG_REGID_MAC1_ACC1_HIGH 0x00000615 | 1359 | #define DREG_REGID_MAC1_ACC1_HIGH 0x00000615 |
1360 | #define DREG_REGID_MAC1_ACC2_HIGH 0x00000616 | 1360 | #define DREG_REGID_MAC1_ACC2_HIGH 0x00000616 |
1361 | #define DREG_REGID_MAC1_ACC3_HIGH 0x00000617 | 1361 | #define DREG_REGID_MAC1_ACC3_HIGH 0x00000617 |
1362 | #define DREG_REGID_RSHOUT_LOW 0x00000620 | 1362 | #define DREG_REGID_RSHOUT_LOW 0x00000620 |
1363 | #define DREG_REGID_RSHOUT_MID 0x00000628 | 1363 | #define DREG_REGID_RSHOUT_MID 0x00000628 |
1364 | #define DREG_REGID_RSHOUT_HIGH 0x00000630 | 1364 | #define DREG_REGID_RSHOUT_HIGH 0x00000630 |
1365 | 1365 | ||
1366 | /* | 1366 | /* |
1367 | * The following defines are for the flags in the DMA stream requestor write | 1367 | * The following defines are for the flags in the DMA stream requestor write |
1368 | */ | 1368 | */ |
1369 | #define DSRWP_DSR_MASK 0x0000000F | 1369 | #define DSRWP_DSR_MASK 0x0000000F |
1370 | #define DSRWP_DSR_BG_RQ 0x00000001 | 1370 | #define DSRWP_DSR_BG_RQ 0x00000001 |
1371 | #define DSRWP_DSR_PRIORITY_MASK 0x00000006 | 1371 | #define DSRWP_DSR_PRIORITY_MASK 0x00000006 |
1372 | #define DSRWP_DSR_PRIORITY_0 0x00000000 | 1372 | #define DSRWP_DSR_PRIORITY_0 0x00000000 |
1373 | #define DSRWP_DSR_PRIORITY_1 0x00000002 | 1373 | #define DSRWP_DSR_PRIORITY_1 0x00000002 |
1374 | #define DSRWP_DSR_PRIORITY_2 0x00000004 | 1374 | #define DSRWP_DSR_PRIORITY_2 0x00000004 |
1375 | #define DSRWP_DSR_PRIORITY_3 0x00000006 | 1375 | #define DSRWP_DSR_PRIORITY_3 0x00000006 |
1376 | #define DSRWP_DSR_RQ_PENDING 0x00000008 | 1376 | #define DSRWP_DSR_RQ_PENDING 0x00000008 |
1377 | 1377 | ||
1378 | /* | 1378 | /* |
1379 | * The following defines are for the flags in the trap write port register. | 1379 | * The following defines are for the flags in the trap write port register. |
1380 | */ | 1380 | */ |
1381 | #define TWPR_TW_MASK 0x0000FFFF | 1381 | #define TWPR_TW_MASK 0x0000FFFF |
1382 | #define TWPR_TW_SHIFT 0 | 1382 | #define TWPR_TW_SHIFT 0 |
1383 | 1383 | ||
1384 | /* | 1384 | /* |
1385 | * The following defines are for the flags in the stack pointer write | 1385 | * The following defines are for the flags in the stack pointer write |
1386 | * register. | 1386 | * register. |
1387 | */ | 1387 | */ |
1388 | #define SPWR_STKP_MASK 0x0000000F | 1388 | #define SPWR_STKP_MASK 0x0000000F |
1389 | #define SPWR_STKP_SHIFT 0 | 1389 | #define SPWR_STKP_SHIFT 0 |
1390 | 1390 | ||
1391 | /* | 1391 | /* |
1392 | * The following defines are for the flags in the SP interrupt register. | 1392 | * The following defines are for the flags in the SP interrupt register. |
1393 | */ | 1393 | */ |
1394 | #define SPIR_FRI 0x00000001 | 1394 | #define SPIR_FRI 0x00000001 |
1395 | #define SPIR_DOI 0x00000002 | 1395 | #define SPIR_DOI 0x00000002 |
1396 | #define SPIR_GPI2 0x00000004 | 1396 | #define SPIR_GPI2 0x00000004 |
1397 | #define SPIR_GPI3 0x00000008 | 1397 | #define SPIR_GPI3 0x00000008 |
1398 | #define SPIR_IP0 0x00000010 | 1398 | #define SPIR_IP0 0x00000010 |
1399 | #define SPIR_IP1 0x00000020 | 1399 | #define SPIR_IP1 0x00000020 |
1400 | #define SPIR_IP2 0x00000040 | 1400 | #define SPIR_IP2 0x00000040 |
1401 | #define SPIR_IP3 0x00000080 | 1401 | #define SPIR_IP3 0x00000080 |
1402 | 1402 | ||
1403 | /* | 1403 | /* |
1404 | * The following defines are for the flags in the functional group 1 register. | 1404 | * The following defines are for the flags in the functional group 1 register. |
1405 | */ | 1405 | */ |
1406 | #define FGR1_F1S_MASK 0x0000FFFF | 1406 | #define FGR1_F1S_MASK 0x0000FFFF |
1407 | #define FGR1_F1S_SHIFT 0 | 1407 | #define FGR1_F1S_SHIFT 0 |
1408 | 1408 | ||
1409 | /* | 1409 | /* |
1410 | * The following defines are for the flags in the SP clock status register. | 1410 | * The following defines are for the flags in the SP clock status register. |
1411 | */ | 1411 | */ |
1412 | #define SPCS_FRI 0x00000001 | 1412 | #define SPCS_FRI 0x00000001 |
1413 | #define SPCS_DOI 0x00000002 | 1413 | #define SPCS_DOI 0x00000002 |
1414 | #define SPCS_GPI2 0x00000004 | 1414 | #define SPCS_GPI2 0x00000004 |
1415 | #define SPCS_GPI3 0x00000008 | 1415 | #define SPCS_GPI3 0x00000008 |
1416 | #define SPCS_IP0 0x00000010 | 1416 | #define SPCS_IP0 0x00000010 |
1417 | #define SPCS_IP1 0x00000020 | 1417 | #define SPCS_IP1 0x00000020 |
1418 | #define SPCS_IP2 0x00000040 | 1418 | #define SPCS_IP2 0x00000040 |
1419 | #define SPCS_IP3 0x00000080 | 1419 | #define SPCS_IP3 0x00000080 |
1420 | #define SPCS_SPRUN 0x00000100 | 1420 | #define SPCS_SPRUN 0x00000100 |
1421 | #define SPCS_SLEEP 0x00000200 | 1421 | #define SPCS_SLEEP 0x00000200 |
1422 | #define SPCS_FG 0x00000400 | 1422 | #define SPCS_FG 0x00000400 |
1423 | #define SPCS_ORUN 0x00000800 | 1423 | #define SPCS_ORUN 0x00000800 |
1424 | #define SPCS_IRQ 0x00001000 | 1424 | #define SPCS_IRQ 0x00001000 |
1425 | #define SPCS_FGN_MASK 0x0000E000 | 1425 | #define SPCS_FGN_MASK 0x0000E000 |
1426 | #define SPCS_FGN_SHIFT 13 | 1426 | #define SPCS_FGN_SHIFT 13 |
1427 | 1427 | ||
1428 | /* | 1428 | /* |
1429 | * The following defines are for the flags in the SP DMA requestor status | 1429 | * The following defines are for the flags in the SP DMA requestor status |
1430 | * register. | 1430 | * register. |
1431 | */ | 1431 | */ |
1432 | #define SDSR_DCS_MASK 0x000000FF | 1432 | #define SDSR_DCS_MASK 0x000000FF |
1433 | #define SDSR_DCS_SHIFT 0 | 1433 | #define SDSR_DCS_SHIFT 0 |
1434 | #define SDSR_DCS_NONE 0x00000007 | 1434 | #define SDSR_DCS_NONE 0x00000007 |
1435 | 1435 | ||
1436 | /* | 1436 | /* |
1437 | * The following defines are for the flags in the frame timer register. | 1437 | * The following defines are for the flags in the frame timer register. |
1438 | */ | 1438 | */ |
1439 | #define FRMT_FTV_MASK 0x0000FFFF | 1439 | #define FRMT_FTV_MASK 0x0000FFFF |
1440 | #define FRMT_FTV_SHIFT 0 | 1440 | #define FRMT_FTV_SHIFT 0 |
1441 | 1441 | ||
1442 | /* | 1442 | /* |
1443 | * The following defines are for the flags in the frame timer current count | 1443 | * The following defines are for the flags in the frame timer current count |
1444 | * register. | 1444 | * register. |
1445 | */ | 1445 | */ |
1446 | #define FRCC_FCC_MASK 0x0000FFFF | 1446 | #define FRCC_FCC_MASK 0x0000FFFF |
1447 | #define FRCC_FCC_SHIFT 0 | 1447 | #define FRCC_FCC_SHIFT 0 |
1448 | 1448 | ||
1449 | /* | 1449 | /* |
1450 | * The following defines are for the flags in the frame timer save count | 1450 | * The following defines are for the flags in the frame timer save count |
1451 | * register. | 1451 | * register. |
1452 | */ | 1452 | */ |
1453 | #define FRSC_FCS_MASK 0x0000FFFF | 1453 | #define FRSC_FCS_MASK 0x0000FFFF |
1454 | #define FRSC_FCS_SHIFT 0 | 1454 | #define FRSC_FCS_SHIFT 0 |
1455 | 1455 | ||
1456 | /* | 1456 | /* |
1457 | * The following define the various flags stored in the scatter/gather | 1457 | * The following define the various flags stored in the scatter/gather |
1458 | * descriptors. | 1458 | * descriptors. |
1459 | */ | 1459 | */ |
1460 | #define DMA_SG_NEXT_ENTRY_MASK 0x00000FF8 | 1460 | #define DMA_SG_NEXT_ENTRY_MASK 0x00000FF8 |
1461 | #define DMA_SG_SAMPLE_END_MASK 0x0FFF0000 | 1461 | #define DMA_SG_SAMPLE_END_MASK 0x0FFF0000 |
1462 | #define DMA_SG_SAMPLE_END_FLAG 0x10000000 | 1462 | #define DMA_SG_SAMPLE_END_FLAG 0x10000000 |
1463 | #define DMA_SG_LOOP_END_FLAG 0x20000000 | 1463 | #define DMA_SG_LOOP_END_FLAG 0x20000000 |
1464 | #define DMA_SG_SIGNAL_END_FLAG 0x40000000 | 1464 | #define DMA_SG_SIGNAL_END_FLAG 0x40000000 |
1465 | #define DMA_SG_SIGNAL_PAGE_FLAG 0x80000000 | 1465 | #define DMA_SG_SIGNAL_PAGE_FLAG 0x80000000 |
1466 | #define DMA_SG_NEXT_ENTRY_SHIFT 3 | 1466 | #define DMA_SG_NEXT_ENTRY_SHIFT 3 |
1467 | #define DMA_SG_SAMPLE_END_SHIFT 16 | 1467 | #define DMA_SG_SAMPLE_END_SHIFT 16 |
1468 | 1468 | ||
1469 | /* | 1469 | /* |
1470 | * The following define the offsets of the fields within the on-chip generic | 1470 | * The following define the offsets of the fields within the on-chip generic |
1471 | * DMA requestor. | 1471 | * DMA requestor. |
1472 | */ | 1472 | */ |
1473 | #define DMA_RQ_CONTROL1 0x00000000 | 1473 | #define DMA_RQ_CONTROL1 0x00000000 |
1474 | #define DMA_RQ_CONTROL2 0x00000004 | 1474 | #define DMA_RQ_CONTROL2 0x00000004 |
1475 | #define DMA_RQ_SOURCE_ADDR 0x00000008 | 1475 | #define DMA_RQ_SOURCE_ADDR 0x00000008 |
1476 | #define DMA_RQ_DESTINATION_ADDR 0x0000000C | 1476 | #define DMA_RQ_DESTINATION_ADDR 0x0000000C |
1477 | #define DMA_RQ_NEXT_PAGE_ADDR 0x00000010 | 1477 | #define DMA_RQ_NEXT_PAGE_ADDR 0x00000010 |
1478 | #define DMA_RQ_NEXT_PAGE_SGDESC 0x00000014 | 1478 | #define DMA_RQ_NEXT_PAGE_SGDESC 0x00000014 |
1479 | #define DMA_RQ_LOOP_START_ADDR 0x00000018 | 1479 | #define DMA_RQ_LOOP_START_ADDR 0x00000018 |
1480 | #define DMA_RQ_POST_LOOP_ADDR 0x0000001C | 1480 | #define DMA_RQ_POST_LOOP_ADDR 0x0000001C |
1481 | #define DMA_RQ_PAGE_MAP_ADDR 0x00000020 | 1481 | #define DMA_RQ_PAGE_MAP_ADDR 0x00000020 |
1482 | 1482 | ||
1483 | /* | 1483 | /* |
1484 | * The following defines are for the flags in the first control word of the | 1484 | * The following defines are for the flags in the first control word of the |
1485 | * on-chip generic DMA requestor. | 1485 | * on-chip generic DMA requestor. |
1486 | */ | 1486 | */ |
1487 | #define DMA_RQ_C1_COUNT_MASK 0x000003FF | 1487 | #define DMA_RQ_C1_COUNT_MASK 0x000003FF |
1488 | #define DMA_RQ_C1_DESTINATION_SCATTER 0x00001000 | 1488 | #define DMA_RQ_C1_DESTINATION_SCATTER 0x00001000 |
1489 | #define DMA_RQ_C1_SOURCE_GATHER 0x00002000 | 1489 | #define DMA_RQ_C1_SOURCE_GATHER 0x00002000 |
1490 | #define DMA_RQ_C1_DONE_FLAG 0x00004000 | 1490 | #define DMA_RQ_C1_DONE_FLAG 0x00004000 |
1491 | #define DMA_RQ_C1_OPTIMIZE_STATE 0x00008000 | 1491 | #define DMA_RQ_C1_OPTIMIZE_STATE 0x00008000 |
1492 | #define DMA_RQ_C1_SAMPLE_END_STATE_MASK 0x00030000 | 1492 | #define DMA_RQ_C1_SAMPLE_END_STATE_MASK 0x00030000 |
1493 | #define DMA_RQ_C1_FULL_PAGE 0x00000000 | 1493 | #define DMA_RQ_C1_FULL_PAGE 0x00000000 |
1494 | #define DMA_RQ_C1_BEFORE_SAMPLE_END 0x00010000 | 1494 | #define DMA_RQ_C1_BEFORE_SAMPLE_END 0x00010000 |
1495 | #define DMA_RQ_C1_PAGE_MAP_ERROR 0x00020000 | 1495 | #define DMA_RQ_C1_PAGE_MAP_ERROR 0x00020000 |
1496 | #define DMA_RQ_C1_AT_SAMPLE_END 0x00030000 | 1496 | #define DMA_RQ_C1_AT_SAMPLE_END 0x00030000 |
1497 | #define DMA_RQ_C1_LOOP_END_STATE_MASK 0x000C0000 | 1497 | #define DMA_RQ_C1_LOOP_END_STATE_MASK 0x000C0000 |
1498 | #define DMA_RQ_C1_NOT_LOOP_END 0x00000000 | 1498 | #define DMA_RQ_C1_NOT_LOOP_END 0x00000000 |
1499 | #define DMA_RQ_C1_BEFORE_LOOP_END 0x00040000 | 1499 | #define DMA_RQ_C1_BEFORE_LOOP_END 0x00040000 |
1500 | #define DMA_RQ_C1_2PAGE_LOOP_BEGIN 0x00080000 | 1500 | #define DMA_RQ_C1_2PAGE_LOOP_BEGIN 0x00080000 |
1501 | #define DMA_RQ_C1_LOOP_BEGIN 0x000C0000 | 1501 | #define DMA_RQ_C1_LOOP_BEGIN 0x000C0000 |
1502 | #define DMA_RQ_C1_PAGE_MAP_MASK 0x00300000 | 1502 | #define DMA_RQ_C1_PAGE_MAP_MASK 0x00300000 |
1503 | #define DMA_RQ_C1_PM_NONE_PENDING 0x00000000 | 1503 | #define DMA_RQ_C1_PM_NONE_PENDING 0x00000000 |
1504 | #define DMA_RQ_C1_PM_NEXT_PENDING 0x00100000 | 1504 | #define DMA_RQ_C1_PM_NEXT_PENDING 0x00100000 |
1505 | #define DMA_RQ_C1_PM_RESERVED 0x00200000 | 1505 | #define DMA_RQ_C1_PM_RESERVED 0x00200000 |
1506 | #define DMA_RQ_C1_PM_LOOP_NEXT_PENDING 0x00300000 | 1506 | #define DMA_RQ_C1_PM_LOOP_NEXT_PENDING 0x00300000 |
1507 | #define DMA_RQ_C1_WRITEBACK_DEST_FLAG 0x00400000 | 1507 | #define DMA_RQ_C1_WRITEBACK_DEST_FLAG 0x00400000 |
1508 | #define DMA_RQ_C1_WRITEBACK_SRC_FLAG 0x00800000 | 1508 | #define DMA_RQ_C1_WRITEBACK_SRC_FLAG 0x00800000 |
1509 | #define DMA_RQ_C1_DEST_SIZE_MASK 0x07000000 | 1509 | #define DMA_RQ_C1_DEST_SIZE_MASK 0x07000000 |
1510 | #define DMA_RQ_C1_DEST_LINEAR 0x00000000 | 1510 | #define DMA_RQ_C1_DEST_LINEAR 0x00000000 |
1511 | #define DMA_RQ_C1_DEST_MOD16 0x01000000 | 1511 | #define DMA_RQ_C1_DEST_MOD16 0x01000000 |
1512 | #define DMA_RQ_C1_DEST_MOD32 0x02000000 | 1512 | #define DMA_RQ_C1_DEST_MOD32 0x02000000 |
1513 | #define DMA_RQ_C1_DEST_MOD64 0x03000000 | 1513 | #define DMA_RQ_C1_DEST_MOD64 0x03000000 |
1514 | #define DMA_RQ_C1_DEST_MOD128 0x04000000 | 1514 | #define DMA_RQ_C1_DEST_MOD128 0x04000000 |
1515 | #define DMA_RQ_C1_DEST_MOD256 0x05000000 | 1515 | #define DMA_RQ_C1_DEST_MOD256 0x05000000 |
1516 | #define DMA_RQ_C1_DEST_MOD512 0x06000000 | 1516 | #define DMA_RQ_C1_DEST_MOD512 0x06000000 |
1517 | #define DMA_RQ_C1_DEST_MOD1024 0x07000000 | 1517 | #define DMA_RQ_C1_DEST_MOD1024 0x07000000 |
1518 | #define DMA_RQ_C1_DEST_ON_HOST 0x08000000 | 1518 | #define DMA_RQ_C1_DEST_ON_HOST 0x08000000 |
1519 | #define DMA_RQ_C1_SOURCE_SIZE_MASK 0x70000000 | 1519 | #define DMA_RQ_C1_SOURCE_SIZE_MASK 0x70000000 |
1520 | #define DMA_RQ_C1_SOURCE_LINEAR 0x00000000 | 1520 | #define DMA_RQ_C1_SOURCE_LINEAR 0x00000000 |
1521 | #define DMA_RQ_C1_SOURCE_MOD16 0x10000000 | 1521 | #define DMA_RQ_C1_SOURCE_MOD16 0x10000000 |
1522 | #define DMA_RQ_C1_SOURCE_MOD32 0x20000000 | 1522 | #define DMA_RQ_C1_SOURCE_MOD32 0x20000000 |
1523 | #define DMA_RQ_C1_SOURCE_MOD64 0x30000000 | 1523 | #define DMA_RQ_C1_SOURCE_MOD64 0x30000000 |
1524 | #define DMA_RQ_C1_SOURCE_MOD128 0x40000000 | 1524 | #define DMA_RQ_C1_SOURCE_MOD128 0x40000000 |
1525 | #define DMA_RQ_C1_SOURCE_MOD256 0x50000000 | 1525 | #define DMA_RQ_C1_SOURCE_MOD256 0x50000000 |
1526 | #define DMA_RQ_C1_SOURCE_MOD512 0x60000000 | 1526 | #define DMA_RQ_C1_SOURCE_MOD512 0x60000000 |
1527 | #define DMA_RQ_C1_SOURCE_MOD1024 0x70000000 | 1527 | #define DMA_RQ_C1_SOURCE_MOD1024 0x70000000 |
1528 | #define DMA_RQ_C1_SOURCE_ON_HOST 0x80000000 | 1528 | #define DMA_RQ_C1_SOURCE_ON_HOST 0x80000000 |
1529 | #define DMA_RQ_C1_COUNT_SHIFT 0 | 1529 | #define DMA_RQ_C1_COUNT_SHIFT 0 |
1530 | 1530 | ||
1531 | /* | 1531 | /* |
1532 | * The following defines are for the flags in the second control word of the | 1532 | * The following defines are for the flags in the second control word of the |
1533 | * on-chip generic DMA requestor. | 1533 | * on-chip generic DMA requestor. |
1534 | */ | 1534 | */ |
1535 | #define DMA_RQ_C2_VIRTUAL_CHANNEL_MASK 0x0000003F | 1535 | #define DMA_RQ_C2_VIRTUAL_CHANNEL_MASK 0x0000003F |
1536 | #define DMA_RQ_C2_VIRTUAL_SIGNAL_MASK 0x00000300 | 1536 | #define DMA_RQ_C2_VIRTUAL_SIGNAL_MASK 0x00000300 |
1537 | #define DMA_RQ_C2_NO_VIRTUAL_SIGNAL 0x00000000 | 1537 | #define DMA_RQ_C2_NO_VIRTUAL_SIGNAL 0x00000000 |
1538 | #define DMA_RQ_C2_SIGNAL_EVERY_DMA 0x00000100 | 1538 | #define DMA_RQ_C2_SIGNAL_EVERY_DMA 0x00000100 |
1539 | #define DMA_RQ_C2_SIGNAL_SOURCE_PINGPONG 0x00000200 | 1539 | #define DMA_RQ_C2_SIGNAL_SOURCE_PINGPONG 0x00000200 |
1540 | #define DMA_RQ_C2_SIGNAL_DEST_PINGPONG 0x00000300 | 1540 | #define DMA_RQ_C2_SIGNAL_DEST_PINGPONG 0x00000300 |
1541 | #define DMA_RQ_C2_AUDIO_CONVERT_MASK 0x0000F000 | 1541 | #define DMA_RQ_C2_AUDIO_CONVERT_MASK 0x0000F000 |
1542 | #define DMA_RQ_C2_AC_NONE 0x00000000 | 1542 | #define DMA_RQ_C2_AC_NONE 0x00000000 |
1543 | #define DMA_RQ_C2_AC_8_TO_16_BIT 0x00001000 | 1543 | #define DMA_RQ_C2_AC_8_TO_16_BIT 0x00001000 |
1544 | #define DMA_RQ_C2_AC_MONO_TO_STEREO 0x00002000 | 1544 | #define DMA_RQ_C2_AC_MONO_TO_STEREO 0x00002000 |
1545 | #define DMA_RQ_C2_AC_ENDIAN_CONVERT 0x00004000 | 1545 | #define DMA_RQ_C2_AC_ENDIAN_CONVERT 0x00004000 |
1546 | #define DMA_RQ_C2_AC_SIGNED_CONVERT 0x00008000 | 1546 | #define DMA_RQ_C2_AC_SIGNED_CONVERT 0x00008000 |
1547 | #define DMA_RQ_C2_LOOP_END_MASK 0x0FFF0000 | 1547 | #define DMA_RQ_C2_LOOP_END_MASK 0x0FFF0000 |
1548 | #define DMA_RQ_C2_LOOP_MASK 0x30000000 | 1548 | #define DMA_RQ_C2_LOOP_MASK 0x30000000 |
1549 | #define DMA_RQ_C2_NO_LOOP 0x00000000 | 1549 | #define DMA_RQ_C2_NO_LOOP 0x00000000 |
1550 | #define DMA_RQ_C2_ONE_PAGE_LOOP 0x10000000 | 1550 | #define DMA_RQ_C2_ONE_PAGE_LOOP 0x10000000 |
1551 | #define DMA_RQ_C2_TWO_PAGE_LOOP 0x20000000 | 1551 | #define DMA_RQ_C2_TWO_PAGE_LOOP 0x20000000 |
1552 | #define DMA_RQ_C2_MULTI_PAGE_LOOP 0x30000000 | 1552 | #define DMA_RQ_C2_MULTI_PAGE_LOOP 0x30000000 |
1553 | #define DMA_RQ_C2_SIGNAL_LOOP_BACK 0x40000000 | 1553 | #define DMA_RQ_C2_SIGNAL_LOOP_BACK 0x40000000 |
1554 | #define DMA_RQ_C2_SIGNAL_POST_BEGIN_PAGE 0x80000000 | 1554 | #define DMA_RQ_C2_SIGNAL_POST_BEGIN_PAGE 0x80000000 |
1555 | #define DMA_RQ_C2_VIRTUAL_CHANNEL_SHIFT 0 | 1555 | #define DMA_RQ_C2_VIRTUAL_CHANNEL_SHIFT 0 |
1556 | #define DMA_RQ_C2_LOOP_END_SHIFT 16 | 1556 | #define DMA_RQ_C2_LOOP_END_SHIFT 16 |
1557 | 1557 | ||
1558 | /* | 1558 | /* |
1559 | * The following defines are for the flags in the source and destination words | 1559 | * The following defines are for the flags in the source and destination words |
1560 | * of the on-chip generic DMA requestor. | 1560 | * of the on-chip generic DMA requestor. |
1561 | */ | 1561 | */ |
1562 | #define DMA_RQ_SD_ADDRESS_MASK 0x0000FFFF | 1562 | #define DMA_RQ_SD_ADDRESS_MASK 0x0000FFFF |
1563 | #define DMA_RQ_SD_MEMORY_ID_MASK 0x000F0000 | 1563 | #define DMA_RQ_SD_MEMORY_ID_MASK 0x000F0000 |
1564 | #define DMA_RQ_SD_SP_PARAM_ADDR 0x00000000 | 1564 | #define DMA_RQ_SD_SP_PARAM_ADDR 0x00000000 |
1565 | #define DMA_RQ_SD_SP_SAMPLE_ADDR 0x00010000 | 1565 | #define DMA_RQ_SD_SP_SAMPLE_ADDR 0x00010000 |
1566 | #define DMA_RQ_SD_SP_PROGRAM_ADDR 0x00020000 | 1566 | #define DMA_RQ_SD_SP_PROGRAM_ADDR 0x00020000 |
1567 | #define DMA_RQ_SD_SP_DEBUG_ADDR 0x00030000 | 1567 | #define DMA_RQ_SD_SP_DEBUG_ADDR 0x00030000 |
1568 | #define DMA_RQ_SD_OMNIMEM_ADDR 0x000E0000 | 1568 | #define DMA_RQ_SD_OMNIMEM_ADDR 0x000E0000 |
1569 | #define DMA_RQ_SD_END_FLAG 0x40000000 | 1569 | #define DMA_RQ_SD_END_FLAG 0x40000000 |
1570 | #define DMA_RQ_SD_ERROR_FLAG 0x80000000 | 1570 | #define DMA_RQ_SD_ERROR_FLAG 0x80000000 |
1571 | #define DMA_RQ_SD_ADDRESS_SHIFT 0 | 1571 | #define DMA_RQ_SD_ADDRESS_SHIFT 0 |
1572 | 1572 | ||
1573 | /* | 1573 | /* |
1574 | * The following defines are for the flags in the page map address word of the | 1574 | * The following defines are for the flags in the page map address word of the |
1575 | * on-chip generic DMA requestor. | 1575 | * on-chip generic DMA requestor. |
1576 | */ | 1576 | */ |
1577 | #define DMA_RQ_PMA_LOOP_THIRD_PAGE_ENTRY_MASK 0x00000FF8 | 1577 | #define DMA_RQ_PMA_LOOP_THIRD_PAGE_ENTRY_MASK 0x00000FF8 |
1578 | #define DMA_RQ_PMA_PAGE_TABLE_MASK 0xFFFFF000 | 1578 | #define DMA_RQ_PMA_PAGE_TABLE_MASK 0xFFFFF000 |
1579 | #define DMA_RQ_PMA_LOOP_THIRD_PAGE_ENTRY_SHIFT 3 | 1579 | #define DMA_RQ_PMA_LOOP_THIRD_PAGE_ENTRY_SHIFT 3 |
1580 | #define DMA_RQ_PMA_PAGE_TABLE_SHIFT 12 | 1580 | #define DMA_RQ_PMA_PAGE_TABLE_SHIFT 12 |
1581 | 1581 | ||
1582 | #define BA1_VARIDEC_BUF_1 0x000 | 1582 | #define BA1_VARIDEC_BUF_1 0x000 |
1583 | 1583 | ||
1584 | #define BA1_PDTC 0x0c0 /* BA1_PLAY_DMA_TRANSACTION_COUNT_REG */ | 1584 | #define BA1_PDTC 0x0c0 /* BA1_PLAY_DMA_TRANSACTION_COUNT_REG */ |
1585 | #define BA1_PFIE 0x0c4 /* BA1_PLAY_FORMAT_&_INTERRUPT_ENABLE_REG */ | 1585 | #define BA1_PFIE 0x0c4 /* BA1_PLAY_FORMAT_&_INTERRUPT_ENABLE_REG */ |
1586 | #define BA1_PBA 0x0c8 /* BA1_PLAY_BUFFER_ADDRESS */ | 1586 | #define BA1_PBA 0x0c8 /* BA1_PLAY_BUFFER_ADDRESS */ |
1587 | #define BA1_PVOL 0x0f8 /* BA1_PLAY_VOLUME_REG */ | 1587 | #define BA1_PVOL 0x0f8 /* BA1_PLAY_VOLUME_REG */ |
1588 | #define BA1_PSRC 0x288 /* BA1_PLAY_SAMPLE_RATE_CORRECTION_REG */ | 1588 | #define BA1_PSRC 0x288 /* BA1_PLAY_SAMPLE_RATE_CORRECTION_REG */ |
1589 | #define BA1_PCTL 0x2a4 /* BA1_PLAY_CONTROL_REG */ | 1589 | #define BA1_PCTL 0x2a4 /* BA1_PLAY_CONTROL_REG */ |
1590 | #define BA1_PPI 0x2b4 /* BA1_PLAY_PHASE_INCREMENT_REG */ | 1590 | #define BA1_PPI 0x2b4 /* BA1_PLAY_PHASE_INCREMENT_REG */ |
1591 | 1591 | ||
1592 | #define BA1_CCTL 0x064 /* BA1_CAPTURE_CONTROL_REG */ | 1592 | #define BA1_CCTL 0x064 /* BA1_CAPTURE_CONTROL_REG */ |
1593 | #define BA1_CIE 0x104 /* BA1_CAPTURE_INTERRUPT_ENABLE_REG */ | 1593 | #define BA1_CIE 0x104 /* BA1_CAPTURE_INTERRUPT_ENABLE_REG */ |
1594 | #define BA1_CBA 0x10c /* BA1_CAPTURE_BUFFER_ADDRESS */ | 1594 | #define BA1_CBA 0x10c /* BA1_CAPTURE_BUFFER_ADDRESS */ |
1595 | #define BA1_CSRC 0x2c8 /* BA1_CAPTURE_SAMPLE_RATE_CORRECTION_REG */ | 1595 | #define BA1_CSRC 0x2c8 /* BA1_CAPTURE_SAMPLE_RATE_CORRECTION_REG */ |
1596 | #define BA1_CCI 0x2d8 /* BA1_CAPTURE_COEFFICIENT_INCREMENT_REG */ | 1596 | #define BA1_CCI 0x2d8 /* BA1_CAPTURE_COEFFICIENT_INCREMENT_REG */ |
1597 | #define BA1_CD 0x2e0 /* BA1_CAPTURE_DELAY_REG */ | 1597 | #define BA1_CD 0x2e0 /* BA1_CAPTURE_DELAY_REG */ |
1598 | #define BA1_CPI 0x2f4 /* BA1_CAPTURE_PHASE_INCREMENT_REG */ | 1598 | #define BA1_CPI 0x2f4 /* BA1_CAPTURE_PHASE_INCREMENT_REG */ |
1599 | #define BA1_CVOL 0x2f8 /* BA1_CAPTURE_VOLUME_REG */ | 1599 | #define BA1_CVOL 0x2f8 /* BA1_CAPTURE_VOLUME_REG */ |
1600 | 1600 | ||
1601 | #define BA1_CFG1 0x134 /* BA1_CAPTURE_FRAME_GROUP_1_REG */ | 1601 | #define BA1_CFG1 0x134 /* BA1_CAPTURE_FRAME_GROUP_1_REG */ |
1602 | #define BA1_CFG2 0x138 /* BA1_CAPTURE_FRAME_GROUP_2_REG */ | 1602 | #define BA1_CFG2 0x138 /* BA1_CAPTURE_FRAME_GROUP_2_REG */ |
1603 | #define BA1_CCST 0x13c /* BA1_CAPTURE_CONSTANT_REG */ | 1603 | #define BA1_CCST 0x13c /* BA1_CAPTURE_CONSTANT_REG */ |
1604 | #define BA1_CSPB 0x340 /* BA1_CAPTURE_SPB_ADDRESS */ | 1604 | #define BA1_CSPB 0x340 /* BA1_CAPTURE_SPB_ADDRESS */ |
1605 | 1605 | ||
1606 | /* | 1606 | /* |
1607 | * | 1607 | * |
1608 | */ | 1608 | */ |
1609 | 1609 | ||
1610 | #define CS46XX_MODE_OUTPUT (1<<0) /* MIDI UART - output */ | 1610 | #define CS46XX_MODE_OUTPUT (1<<0) /* MIDI UART - output */ |
1611 | #define CS46XX_MODE_INPUT (1<<1) /* MIDI UART - input */ | 1611 | #define CS46XX_MODE_INPUT (1<<1) /* MIDI UART - input */ |
1612 | 1612 | ||
1613 | /* | 1613 | /* |
1614 | * | 1614 | * |
1615 | */ | 1615 | */ |
1616 | 1616 | ||
1617 | #define SAVE_REG_MAX 0x10 | 1617 | #define SAVE_REG_MAX 0x10 |
1618 | #define POWER_DOWN_ALL 0x7f0f | 1618 | #define POWER_DOWN_ALL 0x7f0f |
1619 | 1619 | ||
1620 | /* maxinum number of AC97 codecs connected, AC97 2.0 defined 4 */ | 1620 | /* maxinum number of AC97 codecs connected, AC97 2.0 defined 4 */ |
1621 | #define MAX_NR_AC97 4 | 1621 | #define MAX_NR_AC97 4 |
1622 | #define CS46XX_PRIMARY_CODEC_INDEX 0 | 1622 | #define CS46XX_PRIMARY_CODEC_INDEX 0 |
1623 | #define CS46XX_SECONDARY_CODEC_INDEX 1 | 1623 | #define CS46XX_SECONDARY_CODEC_INDEX 1 |
1624 | #define CS46XX_SECONDARY_CODEC_OFFSET 0x80 | 1624 | #define CS46XX_SECONDARY_CODEC_OFFSET 0x80 |
1625 | #define CS46XX_DSP_CAPTURE_CHANNEL 1 | 1625 | #define CS46XX_DSP_CAPTURE_CHANNEL 1 |
1626 | 1626 | ||
1627 | /* capture */ | 1627 | /* capture */ |
1628 | #define CS46XX_DSP_CAPTURE_CHANNEL 1 | 1628 | #define CS46XX_DSP_CAPTURE_CHANNEL 1 |
1629 | 1629 | ||
1630 | /* mixer */ | 1630 | /* mixer */ |
1631 | #define CS46XX_MIXER_SPDIF_INPUT_ELEMENT 1 | 1631 | #define CS46XX_MIXER_SPDIF_INPUT_ELEMENT 1 |
1632 | #define CS46XX_MIXER_SPDIF_OUTPUT_ELEMENT 2 | 1632 | #define CS46XX_MIXER_SPDIF_OUTPUT_ELEMENT 2 |
1633 | 1633 | ||
1634 | 1634 | ||
1635 | struct snd_cs46xx_pcm { | 1635 | struct snd_cs46xx_pcm { |
1636 | struct snd_dma_buffer hw_buf; | 1636 | struct snd_dma_buffer hw_buf; |
1637 | 1637 | ||
1638 | unsigned int ctl; | 1638 | unsigned int ctl; |
1639 | unsigned int shift; /* Shift count to trasform frames in bytes */ | 1639 | unsigned int shift; /* Shift count to trasform frames in bytes */ |
1640 | struct snd_pcm_indirect pcm_rec; | 1640 | struct snd_pcm_indirect pcm_rec; |
1641 | struct snd_pcm_substream *substream; | 1641 | struct snd_pcm_substream *substream; |
1642 | 1642 | ||
1643 | struct dsp_pcm_channel_descriptor * pcm_channel; | 1643 | struct dsp_pcm_channel_descriptor * pcm_channel; |
1644 | 1644 | ||
1645 | int pcm_channel_id; /* Fron Rear, Center Lfe ... */ | 1645 | int pcm_channel_id; /* Fron Rear, Center Lfe ... */ |
1646 | }; | 1646 | }; |
1647 | 1647 | ||
1648 | struct snd_cs46xx_region { | 1648 | struct snd_cs46xx_region { |
1649 | char name[24]; | 1649 | char name[24]; |
1650 | unsigned long base; | 1650 | unsigned long base; |
1651 | void __iomem *remap_addr; | 1651 | void __iomem *remap_addr; |
1652 | unsigned long size; | 1652 | unsigned long size; |
1653 | struct resource *resource; | 1653 | struct resource *resource; |
1654 | }; | 1654 | }; |
1655 | 1655 | ||
1656 | struct snd_cs46xx { | 1656 | struct snd_cs46xx { |
1657 | int irq; | 1657 | int irq; |
1658 | unsigned long ba0_addr; | 1658 | unsigned long ba0_addr; |
1659 | unsigned long ba1_addr; | 1659 | unsigned long ba1_addr; |
1660 | union { | 1660 | union { |
1661 | struct { | 1661 | struct { |
1662 | struct snd_cs46xx_region ba0; | 1662 | struct snd_cs46xx_region ba0; |
1663 | struct snd_cs46xx_region data0; | 1663 | struct snd_cs46xx_region data0; |
1664 | struct snd_cs46xx_region data1; | 1664 | struct snd_cs46xx_region data1; |
1665 | struct snd_cs46xx_region pmem; | 1665 | struct snd_cs46xx_region pmem; |
1666 | struct snd_cs46xx_region reg; | 1666 | struct snd_cs46xx_region reg; |
1667 | } name; | 1667 | } name; |
1668 | struct snd_cs46xx_region idx[5]; | 1668 | struct snd_cs46xx_region idx[5]; |
1669 | } region; | 1669 | } region; |
1670 | 1670 | ||
1671 | unsigned int mode; | 1671 | unsigned int mode; |
1672 | 1672 | ||
1673 | struct { | 1673 | struct { |
1674 | struct snd_dma_buffer hw_buf; | 1674 | struct snd_dma_buffer hw_buf; |
1675 | 1675 | ||
1676 | unsigned int ctl; | 1676 | unsigned int ctl; |
1677 | unsigned int shift; /* Shift count to trasform frames in bytes */ | 1677 | unsigned int shift; /* Shift count to trasform frames in bytes */ |
1678 | struct snd_pcm_indirect pcm_rec; | 1678 | struct snd_pcm_indirect pcm_rec; |
1679 | struct snd_pcm_substream *substream; | 1679 | struct snd_pcm_substream *substream; |
1680 | } capt; | 1680 | } capt; |
1681 | 1681 | ||
1682 | 1682 | ||
1683 | int nr_ac97_codecs; | 1683 | int nr_ac97_codecs; |
1684 | struct snd_ac97_bus *ac97_bus; | 1684 | struct snd_ac97_bus *ac97_bus; |
1685 | struct snd_ac97 *ac97[MAX_NR_AC97]; | 1685 | struct snd_ac97 *ac97[MAX_NR_AC97]; |
1686 | 1686 | ||
1687 | struct pci_dev *pci; | 1687 | struct pci_dev *pci; |
1688 | struct snd_card *card; | 1688 | struct snd_card *card; |
1689 | struct snd_pcm *pcm; | 1689 | struct snd_pcm *pcm; |
1690 | 1690 | ||
1691 | struct snd_rawmidi *rmidi; | 1691 | struct snd_rawmidi *rmidi; |
1692 | struct snd_rawmidi_substream *midi_input; | 1692 | struct snd_rawmidi_substream *midi_input; |
1693 | struct snd_rawmidi_substream *midi_output; | 1693 | struct snd_rawmidi_substream *midi_output; |
1694 | 1694 | ||
1695 | spinlock_t reg_lock; | 1695 | spinlock_t reg_lock; |
1696 | unsigned int midcr; | 1696 | unsigned int midcr; |
1697 | unsigned int uartm; | 1697 | unsigned int uartm; |
1698 | 1698 | ||
1699 | int amplifier; | 1699 | int amplifier; |
1700 | void (*amplifier_ctrl)(struct snd_cs46xx *, int); | 1700 | void (*amplifier_ctrl)(struct snd_cs46xx *, int); |
1701 | void (*active_ctrl)(struct snd_cs46xx *, int); | 1701 | void (*active_ctrl)(struct snd_cs46xx *, int); |
1702 | void (*mixer_init)(struct snd_cs46xx *); | 1702 | void (*mixer_init)(struct snd_cs46xx *); |
1703 | 1703 | ||
1704 | int acpi_port; | 1704 | int acpi_port; |
1705 | struct snd_kcontrol *eapd_switch; /* for amplifier hack */ | 1705 | struct snd_kcontrol *eapd_switch; /* for amplifier hack */ |
1706 | int accept_valid; /* accept mmap valid (for OSS) */ | 1706 | int accept_valid; /* accept mmap valid (for OSS) */ |
1707 | 1707 | ||
1708 | struct gameport *gameport; | 1708 | struct gameport *gameport; |
1709 | 1709 | ||
1710 | #ifdef CONFIG_SND_CS46XX_DEBUG_GPIO | 1710 | #ifdef CONFIG_SND_CS46XX_DEBUG_GPIO |
1711 | int current_gpio; | 1711 | int current_gpio; |
1712 | #endif | 1712 | #endif |
1713 | #ifdef CONFIG_SND_CS46XX_NEW_DSP | 1713 | #ifdef CONFIG_SND_CS46XX_NEW_DSP |
1714 | struct semaphore spos_mutex; | 1714 | struct semaphore spos_mutex; |
1715 | 1715 | ||
1716 | struct dsp_spos_instance * dsp_spos_instance; | 1716 | struct dsp_spos_instance * dsp_spos_instance; |
1717 | 1717 | ||
1718 | struct snd_pcm *pcm_rear; | 1718 | struct snd_pcm *pcm_rear; |
1719 | struct snd_pcm *pcm_center_lfe; | 1719 | struct snd_pcm *pcm_center_lfe; |
1720 | struct snd_pcm *pcm_iec958; | 1720 | struct snd_pcm *pcm_iec958; |
1721 | #else /* for compatibility */ | 1721 | #else /* for compatibility */ |
1722 | struct snd_cs46xx_pcm *playback_pcm; | 1722 | struct snd_cs46xx_pcm *playback_pcm; |
1723 | unsigned int play_ctl; | 1723 | unsigned int play_ctl; |
1724 | #endif | 1724 | #endif |
1725 | }; | 1725 | }; |
1726 | 1726 | ||
1727 | int snd_cs46xx_create(struct snd_card *card, | 1727 | int snd_cs46xx_create(struct snd_card *card, |
1728 | struct pci_dev *pci, | 1728 | struct pci_dev *pci, |
1729 | int external_amp, int thinkpad, | 1729 | int external_amp, int thinkpad, |
1730 | struct snd_cs46xx **rcodec); | 1730 | struct snd_cs46xx **rcodec); |
1731 | int snd_cs46xx_suspend(struct pci_dev *pci, pm_message_t state); | ||
1732 | int snd_cs46xx_resume(struct pci_dev *pci); | ||
1731 | 1733 | ||
1732 | int snd_cs46xx_pcm(struct snd_cs46xx *chip, int device, struct snd_pcm **rpcm); | 1734 | int snd_cs46xx_pcm(struct snd_cs46xx *chip, int device, struct snd_pcm **rpcm); |
1733 | int snd_cs46xx_pcm_rear(struct snd_cs46xx *chip, int device, struct snd_pcm **rpcm); | 1735 | int snd_cs46xx_pcm_rear(struct snd_cs46xx *chip, int device, struct snd_pcm **rpcm); |
1734 | int snd_cs46xx_pcm_iec958(struct snd_cs46xx *chip, int device, struct snd_pcm **rpcm); | 1736 | int snd_cs46xx_pcm_iec958(struct snd_cs46xx *chip, int device, struct snd_pcm **rpcm); |
1735 | int snd_cs46xx_pcm_center_lfe(struct snd_cs46xx *chip, int device, struct snd_pcm **rpcm); | 1737 | int snd_cs46xx_pcm_center_lfe(struct snd_cs46xx *chip, int device, struct snd_pcm **rpcm); |
1736 | int snd_cs46xx_mixer(struct snd_cs46xx *chip, int spdif_device); | 1738 | int snd_cs46xx_mixer(struct snd_cs46xx *chip, int spdif_device); |
1737 | int snd_cs46xx_midi(struct snd_cs46xx *chip, int device, struct snd_rawmidi **rmidi); | 1739 | int snd_cs46xx_midi(struct snd_cs46xx *chip, int device, struct snd_rawmidi **rmidi); |
1738 | int snd_cs46xx_start_dsp(struct snd_cs46xx *chip); | 1740 | int snd_cs46xx_start_dsp(struct snd_cs46xx *chip); |
1739 | int snd_cs46xx_gameport(struct snd_cs46xx *chip); | 1741 | int snd_cs46xx_gameport(struct snd_cs46xx *chip); |
1740 | 1742 | ||
1741 | #endif /* __SOUND_CS46XX_H */ | 1743 | #endif /* __SOUND_CS46XX_H */ |
1742 | 1744 |
sound/pci/cs46xx/cs46xx.c
1 | /* | 1 | /* |
2 | * The driver for the Cirrus Logic's Sound Fusion CS46XX based soundcards | 2 | * The driver for the Cirrus Logic's Sound Fusion CS46XX based soundcards |
3 | * Copyright (c) by Jaroslav Kysela <perex@suse.cz> | 3 | * Copyright (c) by Jaroslav Kysela <perex@suse.cz> |
4 | * | 4 | * |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 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 | 8 | * the Free Software Foundation; either version 2 of the License, or |
9 | * (at your option) any later version. | 9 | * (at your option) any later version. |
10 | * | 10 | * |
11 | * This program is distributed in the hope that it will be useful, | 11 | * This program is distributed in the hope that it will be useful, |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | * GNU General Public License for more details. | 14 | * GNU General Public License for more details. |
15 | * | 15 | * |
16 | * You should have received a copy of the GNU General Public License | 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 | 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 | 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
19 | * | 19 | * |
20 | */ | 20 | */ |
21 | 21 | ||
22 | /* | 22 | /* |
23 | NOTES: | 23 | NOTES: |
24 | - sometimes the sound is metallic and sibilant, unloading and | 24 | - sometimes the sound is metallic and sibilant, unloading and |
25 | reloading the module may solve this. | 25 | reloading the module may solve this. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | #include <sound/driver.h> | 28 | #include <sound/driver.h> |
29 | #include <linux/pci.h> | 29 | #include <linux/pci.h> |
30 | #include <linux/time.h> | 30 | #include <linux/time.h> |
31 | #include <linux/init.h> | 31 | #include <linux/init.h> |
32 | #include <linux/moduleparam.h> | 32 | #include <linux/moduleparam.h> |
33 | #include <sound/core.h> | 33 | #include <sound/core.h> |
34 | #include <sound/cs46xx.h> | 34 | #include <sound/cs46xx.h> |
35 | #include <sound/initval.h> | 35 | #include <sound/initval.h> |
36 | 36 | ||
37 | MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>"); | 37 | MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>"); |
38 | MODULE_DESCRIPTION("Cirrus Logic Sound Fusion CS46XX"); | 38 | MODULE_DESCRIPTION("Cirrus Logic Sound Fusion CS46XX"); |
39 | MODULE_LICENSE("GPL"); | 39 | MODULE_LICENSE("GPL"); |
40 | MODULE_SUPPORTED_DEVICE("{{Cirrus Logic,Sound Fusion (CS4280)}," | 40 | MODULE_SUPPORTED_DEVICE("{{Cirrus Logic,Sound Fusion (CS4280)}," |
41 | "{Cirrus Logic,Sound Fusion (CS4610)}," | 41 | "{Cirrus Logic,Sound Fusion (CS4610)}," |
42 | "{Cirrus Logic,Sound Fusion (CS4612)}," | 42 | "{Cirrus Logic,Sound Fusion (CS4612)}," |
43 | "{Cirrus Logic,Sound Fusion (CS4615)}," | 43 | "{Cirrus Logic,Sound Fusion (CS4615)}," |
44 | "{Cirrus Logic,Sound Fusion (CS4622)}," | 44 | "{Cirrus Logic,Sound Fusion (CS4622)}," |
45 | "{Cirrus Logic,Sound Fusion (CS4624)}," | 45 | "{Cirrus Logic,Sound Fusion (CS4624)}," |
46 | "{Cirrus Logic,Sound Fusion (CS4630)}}"); | 46 | "{Cirrus Logic,Sound Fusion (CS4630)}}"); |
47 | 47 | ||
48 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ | 48 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ |
49 | static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ | 49 | static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ |
50 | static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ | 50 | static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ |
51 | static int external_amp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; | 51 | static int external_amp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; |
52 | static int thinkpad[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; | 52 | static int thinkpad[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; |
53 | static int mmap_valid[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1}; | 53 | static int mmap_valid[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1}; |
54 | 54 | ||
55 | module_param_array(index, int, NULL, 0444); | 55 | module_param_array(index, int, NULL, 0444); |
56 | MODULE_PARM_DESC(index, "Index value for the CS46xx soundcard."); | 56 | MODULE_PARM_DESC(index, "Index value for the CS46xx soundcard."); |
57 | module_param_array(id, charp, NULL, 0444); | 57 | module_param_array(id, charp, NULL, 0444); |
58 | MODULE_PARM_DESC(id, "ID string for the CS46xx soundcard."); | 58 | MODULE_PARM_DESC(id, "ID string for the CS46xx soundcard."); |
59 | module_param_array(enable, bool, NULL, 0444); | 59 | module_param_array(enable, bool, NULL, 0444); |
60 | MODULE_PARM_DESC(enable, "Enable CS46xx soundcard."); | 60 | MODULE_PARM_DESC(enable, "Enable CS46xx soundcard."); |
61 | module_param_array(external_amp, bool, NULL, 0444); | 61 | module_param_array(external_amp, bool, NULL, 0444); |
62 | MODULE_PARM_DESC(external_amp, "Force to enable external amplifer."); | 62 | MODULE_PARM_DESC(external_amp, "Force to enable external amplifer."); |
63 | module_param_array(thinkpad, bool, NULL, 0444); | 63 | module_param_array(thinkpad, bool, NULL, 0444); |
64 | MODULE_PARM_DESC(thinkpad, "Force to enable Thinkpad's CLKRUN control."); | 64 | MODULE_PARM_DESC(thinkpad, "Force to enable Thinkpad's CLKRUN control."); |
65 | module_param_array(mmap_valid, bool, NULL, 0444); | 65 | module_param_array(mmap_valid, bool, NULL, 0444); |
66 | MODULE_PARM_DESC(mmap_valid, "Support OSS mmap."); | 66 | MODULE_PARM_DESC(mmap_valid, "Support OSS mmap."); |
67 | 67 | ||
68 | static struct pci_device_id snd_cs46xx_ids[] = { | 68 | static struct pci_device_id snd_cs46xx_ids[] = { |
69 | { 0x1013, 0x6001, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* CS4280 */ | 69 | { 0x1013, 0x6001, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* CS4280 */ |
70 | { 0x1013, 0x6003, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* CS4612 */ | 70 | { 0x1013, 0x6003, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* CS4612 */ |
71 | { 0x1013, 0x6004, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* CS4615 */ | 71 | { 0x1013, 0x6004, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* CS4615 */ |
72 | { 0, } | 72 | { 0, } |
73 | }; | 73 | }; |
74 | 74 | ||
75 | MODULE_DEVICE_TABLE(pci, snd_cs46xx_ids); | 75 | MODULE_DEVICE_TABLE(pci, snd_cs46xx_ids); |
76 | 76 | ||
77 | static int __devinit snd_card_cs46xx_probe(struct pci_dev *pci, | 77 | static int __devinit snd_card_cs46xx_probe(struct pci_dev *pci, |
78 | const struct pci_device_id *pci_id) | 78 | const struct pci_device_id *pci_id) |
79 | { | 79 | { |
80 | static int dev; | 80 | static int dev; |
81 | struct snd_card *card; | 81 | struct snd_card *card; |
82 | struct snd_cs46xx *chip; | 82 | struct snd_cs46xx *chip; |
83 | int err; | 83 | int err; |
84 | 84 | ||
85 | if (dev >= SNDRV_CARDS) | 85 | if (dev >= SNDRV_CARDS) |
86 | return -ENODEV; | 86 | return -ENODEV; |
87 | if (!enable[dev]) { | 87 | if (!enable[dev]) { |
88 | dev++; | 88 | dev++; |
89 | return -ENOENT; | 89 | return -ENOENT; |
90 | } | 90 | } |
91 | 91 | ||
92 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); | 92 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); |
93 | if (card == NULL) | 93 | if (card == NULL) |
94 | return -ENOMEM; | 94 | return -ENOMEM; |
95 | if ((err = snd_cs46xx_create(card, pci, | 95 | if ((err = snd_cs46xx_create(card, pci, |
96 | external_amp[dev], thinkpad[dev], | 96 | external_amp[dev], thinkpad[dev], |
97 | &chip)) < 0) { | 97 | &chip)) < 0) { |
98 | snd_card_free(card); | 98 | snd_card_free(card); |
99 | return err; | 99 | return err; |
100 | } | 100 | } |
101 | card->private_data = chip; | ||
101 | chip->accept_valid = mmap_valid[dev]; | 102 | chip->accept_valid = mmap_valid[dev]; |
102 | if ((err = snd_cs46xx_pcm(chip, 0, NULL)) < 0) { | 103 | if ((err = snd_cs46xx_pcm(chip, 0, NULL)) < 0) { |
103 | snd_card_free(card); | 104 | snd_card_free(card); |
104 | return err; | 105 | return err; |
105 | } | 106 | } |
106 | #ifdef CONFIG_SND_CS46XX_NEW_DSP | 107 | #ifdef CONFIG_SND_CS46XX_NEW_DSP |
107 | if ((err = snd_cs46xx_pcm_rear(chip,1, NULL)) < 0) { | 108 | if ((err = snd_cs46xx_pcm_rear(chip,1, NULL)) < 0) { |
108 | snd_card_free(card); | 109 | snd_card_free(card); |
109 | return err; | 110 | return err; |
110 | } | 111 | } |
111 | if ((err = snd_cs46xx_pcm_iec958(chip,2,NULL)) < 0) { | 112 | if ((err = snd_cs46xx_pcm_iec958(chip,2,NULL)) < 0) { |
112 | snd_card_free(card); | 113 | snd_card_free(card); |
113 | return err; | 114 | return err; |
114 | } | 115 | } |
115 | #endif | 116 | #endif |
116 | if ((err = snd_cs46xx_mixer(chip, 2)) < 0) { | 117 | if ((err = snd_cs46xx_mixer(chip, 2)) < 0) { |
117 | snd_card_free(card); | 118 | snd_card_free(card); |
118 | return err; | 119 | return err; |
119 | } | 120 | } |
120 | #ifdef CONFIG_SND_CS46XX_NEW_DSP | 121 | #ifdef CONFIG_SND_CS46XX_NEW_DSP |
121 | if (chip->nr_ac97_codecs ==2) { | 122 | if (chip->nr_ac97_codecs ==2) { |
122 | if ((err = snd_cs46xx_pcm_center_lfe(chip,3,NULL)) < 0) { | 123 | if ((err = snd_cs46xx_pcm_center_lfe(chip,3,NULL)) < 0) { |
123 | snd_card_free(card); | 124 | snd_card_free(card); |
124 | return err; | 125 | return err; |
125 | } | 126 | } |
126 | } | 127 | } |
127 | #endif | 128 | #endif |
128 | if ((err = snd_cs46xx_midi(chip, 0, NULL)) < 0) { | 129 | if ((err = snd_cs46xx_midi(chip, 0, NULL)) < 0) { |
129 | snd_card_free(card); | 130 | snd_card_free(card); |
130 | return err; | 131 | return err; |
131 | } | 132 | } |
132 | if ((err = snd_cs46xx_start_dsp(chip)) < 0) { | 133 | if ((err = snd_cs46xx_start_dsp(chip)) < 0) { |
133 | snd_card_free(card); | 134 | snd_card_free(card); |
134 | return err; | 135 | return err; |
135 | } | 136 | } |
136 | 137 | ||
137 | 138 | ||
138 | snd_cs46xx_gameport(chip); | 139 | snd_cs46xx_gameport(chip); |
139 | 140 | ||
140 | strcpy(card->driver, "CS46xx"); | 141 | strcpy(card->driver, "CS46xx"); |
141 | strcpy(card->shortname, "Sound Fusion CS46xx"); | 142 | strcpy(card->shortname, "Sound Fusion CS46xx"); |
142 | sprintf(card->longname, "%s at 0x%lx/0x%lx, irq %i", | 143 | sprintf(card->longname, "%s at 0x%lx/0x%lx, irq %i", |
143 | card->shortname, | 144 | card->shortname, |
144 | chip->ba0_addr, | 145 | chip->ba0_addr, |
145 | chip->ba1_addr, | 146 | chip->ba1_addr, |
146 | chip->irq); | 147 | chip->irq); |
147 | 148 | ||
148 | if ((err = snd_card_register(card)) < 0) { | 149 | if ((err = snd_card_register(card)) < 0) { |
149 | snd_card_free(card); | 150 | snd_card_free(card); |
150 | return err; | 151 | return err; |
151 | } | 152 | } |
152 | 153 | ||
153 | pci_set_drvdata(pci, card); | 154 | pci_set_drvdata(pci, card); |
154 | dev++; | 155 | dev++; |
155 | return 0; | 156 | return 0; |
156 | } | 157 | } |
157 | 158 | ||
158 | static void __devexit snd_card_cs46xx_remove(struct pci_dev *pci) | 159 | static void __devexit snd_card_cs46xx_remove(struct pci_dev *pci) |
159 | { | 160 | { |
160 | snd_card_free(pci_get_drvdata(pci)); | 161 | snd_card_free(pci_get_drvdata(pci)); |
161 | pci_set_drvdata(pci, NULL); | 162 | pci_set_drvdata(pci, NULL); |
162 | } | 163 | } |
163 | 164 | ||
164 | static struct pci_driver driver = { | 165 | static struct pci_driver driver = { |
165 | .name = "Sound Fusion CS46xx", | 166 | .name = "Sound Fusion CS46xx", |
166 | .id_table = snd_cs46xx_ids, | 167 | .id_table = snd_cs46xx_ids, |
167 | .probe = snd_card_cs46xx_probe, | 168 | .probe = snd_card_cs46xx_probe, |
168 | .remove = __devexit_p(snd_card_cs46xx_remove), | 169 | .remove = __devexit_p(snd_card_cs46xx_remove), |
169 | SND_PCI_PM_CALLBACKS | 170 | #ifdef CONFIG_PM |
171 | .suspend = snd_cs46xx_suspend, | ||
172 | .resume = snd_cs46xx_resume, | ||
173 | #endif | ||
170 | }; | 174 | }; |
171 | 175 | ||
172 | static int __init alsa_card_cs46xx_init(void) | 176 | static int __init alsa_card_cs46xx_init(void) |
173 | { | 177 | { |
174 | return pci_register_driver(&driver); | 178 | return pci_register_driver(&driver); |
175 | } | 179 | } |
176 | 180 | ||
177 | static void __exit alsa_card_cs46xx_exit(void) | 181 | static void __exit alsa_card_cs46xx_exit(void) |
178 | { | 182 | { |
179 | pci_unregister_driver(&driver); | 183 | pci_unregister_driver(&driver); |
180 | } | 184 | } |
181 | 185 | ||
182 | module_init(alsa_card_cs46xx_init) | 186 | module_init(alsa_card_cs46xx_init) |
183 | module_exit(alsa_card_cs46xx_exit) | 187 | module_exit(alsa_card_cs46xx_exit) |
184 | 188 |
sound/pci/cs46xx/cs46xx_lib.c
1 | /* | 1 | /* |
2 | * Copyright (c) by Jaroslav Kysela <perex@suse.cz> | 2 | * Copyright (c) by Jaroslav Kysela <perex@suse.cz> |
3 | * Abramo Bagnara <abramo@alsa-project.org> | 3 | * Abramo Bagnara <abramo@alsa-project.org> |
4 | * Cirrus Logic, Inc. | 4 | * Cirrus Logic, Inc. |
5 | * Routines for control of Cirrus Logic CS461x chips | 5 | * Routines for control of Cirrus Logic CS461x chips |
6 | * | 6 | * |
7 | * KNOWN BUGS: | 7 | * KNOWN BUGS: |
8 | * - Sometimes the SPDIF input DSP tasks get's unsynchronized | 8 | * - Sometimes the SPDIF input DSP tasks get's unsynchronized |
9 | * and the SPDIF get somewhat "distorcionated", or/and left right channel | 9 | * and the SPDIF get somewhat "distorcionated", or/and left right channel |
10 | * are swapped. To get around this problem when it happens, mute and unmute | 10 | * are swapped. To get around this problem when it happens, mute and unmute |
11 | * the SPDIF input mixer controll. | 11 | * the SPDIF input mixer controll. |
12 | * - On the Hercules Game Theater XP the amplifier are sometimes turned | 12 | * - On the Hercules Game Theater XP the amplifier are sometimes turned |
13 | * off on inadecuate moments which causes distorcions on sound. | 13 | * off on inadecuate moments which causes distorcions on sound. |
14 | * | 14 | * |
15 | * TODO: | 15 | * TODO: |
16 | * - Secondary CODEC on some soundcards | 16 | * - Secondary CODEC on some soundcards |
17 | * - SPDIF input support for other sample rates then 48khz | 17 | * - SPDIF input support for other sample rates then 48khz |
18 | * - Posibility to mix the SPDIF output with analog sources. | 18 | * - Posibility to mix the SPDIF output with analog sources. |
19 | * - PCM channels for Center and LFE on secondary codec | 19 | * - PCM channels for Center and LFE on secondary codec |
20 | * | 20 | * |
21 | * NOTE: with CONFIG_SND_CS46XX_NEW_DSP unset uses old DSP image (which | 21 | * NOTE: with CONFIG_SND_CS46XX_NEW_DSP unset uses old DSP image (which |
22 | * is default configuration), no SPDIF, no secondary codec, no | 22 | * is default configuration), no SPDIF, no secondary codec, no |
23 | * multi channel PCM. But known to work. | 23 | * multi channel PCM. But known to work. |
24 | * | 24 | * |
25 | * FINALLY: A credit to the developers Tom and Jordan | 25 | * FINALLY: A credit to the developers Tom and Jordan |
26 | * at Cirrus for have helping me out with the DSP, however we | 26 | * at Cirrus for have helping me out with the DSP, however we |
27 | * still don't have sufficient documentation and technical | 27 | * still don't have sufficient documentation and technical |
28 | * references to be able to implement all fancy feutures | 28 | * references to be able to implement all fancy feutures |
29 | * supported by the cs46xx DSP's. | 29 | * supported by the cs46xx DSP's. |
30 | * Benny <benny@hostmobility.com> | 30 | * Benny <benny@hostmobility.com> |
31 | * | 31 | * |
32 | * This program is free software; you can redistribute it and/or modify | 32 | * This program is free software; you can redistribute it and/or modify |
33 | * it under the terms of the GNU General Public License as published by | 33 | * it under the terms of the GNU General Public License as published by |
34 | * the Free Software Foundation; either version 2 of the License, or | 34 | * the Free Software Foundation; either version 2 of the License, or |
35 | * (at your option) any later version. | 35 | * (at your option) any later version. |
36 | * | 36 | * |
37 | * This program is distributed in the hope that it will be useful, | 37 | * This program is distributed in the hope that it will be useful, |
38 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 38 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
39 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 39 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
40 | * GNU General Public License for more details. | 40 | * GNU General Public License for more details. |
41 | * | 41 | * |
42 | * You should have received a copy of the GNU General Public License | 42 | * You should have received a copy of the GNU General Public License |
43 | * along with this program; if not, write to the Free Software | 43 | * along with this program; if not, write to the Free Software |
44 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 44 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
45 | * | 45 | * |
46 | */ | 46 | */ |
47 | 47 | ||
48 | #include <sound/driver.h> | 48 | #include <sound/driver.h> |
49 | #include <linux/delay.h> | 49 | #include <linux/delay.h> |
50 | #include <linux/pci.h> | 50 | #include <linux/pci.h> |
51 | #include <linux/pm.h> | 51 | #include <linux/pm.h> |
52 | #include <linux/init.h> | 52 | #include <linux/init.h> |
53 | #include <linux/interrupt.h> | 53 | #include <linux/interrupt.h> |
54 | #include <linux/slab.h> | 54 | #include <linux/slab.h> |
55 | #include <linux/gameport.h> | 55 | #include <linux/gameport.h> |
56 | 56 | ||
57 | #include <sound/core.h> | 57 | #include <sound/core.h> |
58 | #include <sound/control.h> | 58 | #include <sound/control.h> |
59 | #include <sound/info.h> | 59 | #include <sound/info.h> |
60 | #include <sound/pcm.h> | 60 | #include <sound/pcm.h> |
61 | #include <sound/pcm_params.h> | 61 | #include <sound/pcm_params.h> |
62 | #include <sound/cs46xx.h> | 62 | #include <sound/cs46xx.h> |
63 | 63 | ||
64 | #include <asm/io.h> | 64 | #include <asm/io.h> |
65 | 65 | ||
66 | #include "cs46xx_lib.h" | 66 | #include "cs46xx_lib.h" |
67 | #include "dsp_spos.h" | 67 | #include "dsp_spos.h" |
68 | 68 | ||
69 | static void amp_voyetra(struct snd_cs46xx *chip, int change); | 69 | static void amp_voyetra(struct snd_cs46xx *chip, int change); |
70 | 70 | ||
71 | #ifdef CONFIG_SND_CS46XX_NEW_DSP | 71 | #ifdef CONFIG_SND_CS46XX_NEW_DSP |
72 | static struct snd_pcm_ops snd_cs46xx_playback_rear_ops; | 72 | static struct snd_pcm_ops snd_cs46xx_playback_rear_ops; |
73 | static struct snd_pcm_ops snd_cs46xx_playback_indirect_rear_ops; | 73 | static struct snd_pcm_ops snd_cs46xx_playback_indirect_rear_ops; |
74 | static struct snd_pcm_ops snd_cs46xx_playback_clfe_ops; | 74 | static struct snd_pcm_ops snd_cs46xx_playback_clfe_ops; |
75 | static struct snd_pcm_ops snd_cs46xx_playback_indirect_clfe_ops; | 75 | static struct snd_pcm_ops snd_cs46xx_playback_indirect_clfe_ops; |
76 | static struct snd_pcm_ops snd_cs46xx_playback_iec958_ops; | 76 | static struct snd_pcm_ops snd_cs46xx_playback_iec958_ops; |
77 | static struct snd_pcm_ops snd_cs46xx_playback_indirect_iec958_ops; | 77 | static struct snd_pcm_ops snd_cs46xx_playback_indirect_iec958_ops; |
78 | #endif | 78 | #endif |
79 | 79 | ||
80 | static struct snd_pcm_ops snd_cs46xx_playback_ops; | 80 | static struct snd_pcm_ops snd_cs46xx_playback_ops; |
81 | static struct snd_pcm_ops snd_cs46xx_playback_indirect_ops; | 81 | static struct snd_pcm_ops snd_cs46xx_playback_indirect_ops; |
82 | static struct snd_pcm_ops snd_cs46xx_capture_ops; | 82 | static struct snd_pcm_ops snd_cs46xx_capture_ops; |
83 | static struct snd_pcm_ops snd_cs46xx_capture_indirect_ops; | 83 | static struct snd_pcm_ops snd_cs46xx_capture_indirect_ops; |
84 | 84 | ||
85 | static unsigned short snd_cs46xx_codec_read(struct snd_cs46xx *chip, | 85 | static unsigned short snd_cs46xx_codec_read(struct snd_cs46xx *chip, |
86 | unsigned short reg, | 86 | unsigned short reg, |
87 | int codec_index) | 87 | int codec_index) |
88 | { | 88 | { |
89 | int count; | 89 | int count; |
90 | unsigned short result,tmp; | 90 | unsigned short result,tmp; |
91 | u32 offset = 0; | 91 | u32 offset = 0; |
92 | snd_assert ( (codec_index == CS46XX_PRIMARY_CODEC_INDEX) || | 92 | snd_assert ( (codec_index == CS46XX_PRIMARY_CODEC_INDEX) || |
93 | (codec_index == CS46XX_SECONDARY_CODEC_INDEX), | 93 | (codec_index == CS46XX_SECONDARY_CODEC_INDEX), |
94 | return -EINVAL); | 94 | return -EINVAL); |
95 | 95 | ||
96 | chip->active_ctrl(chip, 1); | 96 | chip->active_ctrl(chip, 1); |
97 | 97 | ||
98 | if (codec_index == CS46XX_SECONDARY_CODEC_INDEX) | 98 | if (codec_index == CS46XX_SECONDARY_CODEC_INDEX) |
99 | offset = CS46XX_SECONDARY_CODEC_OFFSET; | 99 | offset = CS46XX_SECONDARY_CODEC_OFFSET; |
100 | 100 | ||
101 | /* | 101 | /* |
102 | * 1. Write ACCAD = Command Address Register = 46Ch for AC97 register address | 102 | * 1. Write ACCAD = Command Address Register = 46Ch for AC97 register address |
103 | * 2. Write ACCDA = Command Data Register = 470h for data to write to AC97 | 103 | * 2. Write ACCDA = Command Data Register = 470h for data to write to AC97 |
104 | * 3. Write ACCTL = Control Register = 460h for initiating the write7---55 | 104 | * 3. Write ACCTL = Control Register = 460h for initiating the write7---55 |
105 | * 4. Read ACCTL = 460h, DCV should be reset by now and 460h = 17h | 105 | * 4. Read ACCTL = 460h, DCV should be reset by now and 460h = 17h |
106 | * 5. if DCV not cleared, break and return error | 106 | * 5. if DCV not cleared, break and return error |
107 | * 6. Read ACSTS = Status Register = 464h, check VSTS bit | 107 | * 6. Read ACSTS = Status Register = 464h, check VSTS bit |
108 | */ | 108 | */ |
109 | 109 | ||
110 | snd_cs46xx_peekBA0(chip, BA0_ACSDA + offset); | 110 | snd_cs46xx_peekBA0(chip, BA0_ACSDA + offset); |
111 | 111 | ||
112 | tmp = snd_cs46xx_peekBA0(chip, BA0_ACCTL); | 112 | tmp = snd_cs46xx_peekBA0(chip, BA0_ACCTL); |
113 | if ((tmp & ACCTL_VFRM) == 0) { | 113 | if ((tmp & ACCTL_VFRM) == 0) { |
114 | snd_printk(KERN_WARNING "cs46xx: ACCTL_VFRM not set 0x%x\n",tmp); | 114 | snd_printk(KERN_WARNING "cs46xx: ACCTL_VFRM not set 0x%x\n",tmp); |
115 | snd_cs46xx_pokeBA0(chip, BA0_ACCTL, (tmp & (~ACCTL_ESYN)) | ACCTL_VFRM ); | 115 | snd_cs46xx_pokeBA0(chip, BA0_ACCTL, (tmp & (~ACCTL_ESYN)) | ACCTL_VFRM ); |
116 | msleep(50); | 116 | msleep(50); |
117 | tmp = snd_cs46xx_peekBA0(chip, BA0_ACCTL + offset); | 117 | tmp = snd_cs46xx_peekBA0(chip, BA0_ACCTL + offset); |
118 | snd_cs46xx_pokeBA0(chip, BA0_ACCTL, tmp | ACCTL_ESYN | ACCTL_VFRM ); | 118 | snd_cs46xx_pokeBA0(chip, BA0_ACCTL, tmp | ACCTL_ESYN | ACCTL_VFRM ); |
119 | 119 | ||
120 | } | 120 | } |
121 | 121 | ||
122 | /* | 122 | /* |
123 | * Setup the AC97 control registers on the CS461x to send the | 123 | * Setup the AC97 control registers on the CS461x to send the |
124 | * appropriate command to the AC97 to perform the read. | 124 | * appropriate command to the AC97 to perform the read. |
125 | * ACCAD = Command Address Register = 46Ch | 125 | * ACCAD = Command Address Register = 46Ch |
126 | * ACCDA = Command Data Register = 470h | 126 | * ACCDA = Command Data Register = 470h |
127 | * ACCTL = Control Register = 460h | 127 | * ACCTL = Control Register = 460h |
128 | * set DCV - will clear when process completed | 128 | * set DCV - will clear when process completed |
129 | * set CRW - Read command | 129 | * set CRW - Read command |
130 | * set VFRM - valid frame enabled | 130 | * set VFRM - valid frame enabled |
131 | * set ESYN - ASYNC generation enabled | 131 | * set ESYN - ASYNC generation enabled |
132 | * set RSTN - ARST# inactive, AC97 codec not reset | 132 | * set RSTN - ARST# inactive, AC97 codec not reset |
133 | */ | 133 | */ |
134 | 134 | ||
135 | snd_cs46xx_pokeBA0(chip, BA0_ACCAD, reg); | 135 | snd_cs46xx_pokeBA0(chip, BA0_ACCAD, reg); |
136 | snd_cs46xx_pokeBA0(chip, BA0_ACCDA, 0); | 136 | snd_cs46xx_pokeBA0(chip, BA0_ACCDA, 0); |
137 | if (codec_index == CS46XX_PRIMARY_CODEC_INDEX) { | 137 | if (codec_index == CS46XX_PRIMARY_CODEC_INDEX) { |
138 | snd_cs46xx_pokeBA0(chip, BA0_ACCTL,/* clear ACCTL_DCV */ ACCTL_CRW | | 138 | snd_cs46xx_pokeBA0(chip, BA0_ACCTL,/* clear ACCTL_DCV */ ACCTL_CRW | |
139 | ACCTL_VFRM | ACCTL_ESYN | | 139 | ACCTL_VFRM | ACCTL_ESYN | |
140 | ACCTL_RSTN); | 140 | ACCTL_RSTN); |
141 | snd_cs46xx_pokeBA0(chip, BA0_ACCTL, ACCTL_DCV | ACCTL_CRW | | 141 | snd_cs46xx_pokeBA0(chip, BA0_ACCTL, ACCTL_DCV | ACCTL_CRW | |
142 | ACCTL_VFRM | ACCTL_ESYN | | 142 | ACCTL_VFRM | ACCTL_ESYN | |
143 | ACCTL_RSTN); | 143 | ACCTL_RSTN); |
144 | } else { | 144 | } else { |
145 | snd_cs46xx_pokeBA0(chip, BA0_ACCTL, ACCTL_DCV | ACCTL_TC | | 145 | snd_cs46xx_pokeBA0(chip, BA0_ACCTL, ACCTL_DCV | ACCTL_TC | |
146 | ACCTL_CRW | ACCTL_VFRM | ACCTL_ESYN | | 146 | ACCTL_CRW | ACCTL_VFRM | ACCTL_ESYN | |
147 | ACCTL_RSTN); | 147 | ACCTL_RSTN); |
148 | } | 148 | } |
149 | 149 | ||
150 | /* | 150 | /* |
151 | * Wait for the read to occur. | 151 | * Wait for the read to occur. |
152 | */ | 152 | */ |
153 | for (count = 0; count < 1000; count++) { | 153 | for (count = 0; count < 1000; count++) { |
154 | /* | 154 | /* |
155 | * First, we want to wait for a short time. | 155 | * First, we want to wait for a short time. |
156 | */ | 156 | */ |
157 | udelay(10); | 157 | udelay(10); |
158 | /* | 158 | /* |
159 | * Now, check to see if the read has completed. | 159 | * Now, check to see if the read has completed. |
160 | * ACCTL = 460h, DCV should be reset by now and 460h = 17h | 160 | * ACCTL = 460h, DCV should be reset by now and 460h = 17h |
161 | */ | 161 | */ |
162 | if (!(snd_cs46xx_peekBA0(chip, BA0_ACCTL) & ACCTL_DCV)) | 162 | if (!(snd_cs46xx_peekBA0(chip, BA0_ACCTL) & ACCTL_DCV)) |
163 | goto ok1; | 163 | goto ok1; |
164 | } | 164 | } |
165 | 165 | ||
166 | snd_printk(KERN_ERR "AC'97 read problem (ACCTL_DCV), reg = 0x%x\n", reg); | 166 | snd_printk(KERN_ERR "AC'97 read problem (ACCTL_DCV), reg = 0x%x\n", reg); |
167 | result = 0xffff; | 167 | result = 0xffff; |
168 | goto end; | 168 | goto end; |
169 | 169 | ||
170 | ok1: | 170 | ok1: |
171 | /* | 171 | /* |
172 | * Wait for the valid status bit to go active. | 172 | * Wait for the valid status bit to go active. |
173 | */ | 173 | */ |
174 | for (count = 0; count < 100; count++) { | 174 | for (count = 0; count < 100; count++) { |
175 | /* | 175 | /* |
176 | * Read the AC97 status register. | 176 | * Read the AC97 status register. |
177 | * ACSTS = Status Register = 464h | 177 | * ACSTS = Status Register = 464h |
178 | * VSTS - Valid Status | 178 | * VSTS - Valid Status |
179 | */ | 179 | */ |
180 | if (snd_cs46xx_peekBA0(chip, BA0_ACSTS + offset) & ACSTS_VSTS) | 180 | if (snd_cs46xx_peekBA0(chip, BA0_ACSTS + offset) & ACSTS_VSTS) |
181 | goto ok2; | 181 | goto ok2; |
182 | udelay(10); | 182 | udelay(10); |
183 | } | 183 | } |
184 | 184 | ||
185 | snd_printk(KERN_ERR "AC'97 read problem (ACSTS_VSTS), codec_index %d, reg = 0x%x\n", codec_index, reg); | 185 | snd_printk(KERN_ERR "AC'97 read problem (ACSTS_VSTS), codec_index %d, reg = 0x%x\n", codec_index, reg); |
186 | result = 0xffff; | 186 | result = 0xffff; |
187 | goto end; | 187 | goto end; |
188 | 188 | ||
189 | ok2: | 189 | ok2: |
190 | /* | 190 | /* |
191 | * Read the data returned from the AC97 register. | 191 | * Read the data returned from the AC97 register. |
192 | * ACSDA = Status Data Register = 474h | 192 | * ACSDA = Status Data Register = 474h |
193 | */ | 193 | */ |
194 | #if 0 | 194 | #if 0 |
195 | printk("e) reg = 0x%x, val = 0x%x, BA0_ACCAD = 0x%x\n", reg, | 195 | printk("e) reg = 0x%x, val = 0x%x, BA0_ACCAD = 0x%x\n", reg, |
196 | snd_cs46xx_peekBA0(chip, BA0_ACSDA), | 196 | snd_cs46xx_peekBA0(chip, BA0_ACSDA), |
197 | snd_cs46xx_peekBA0(chip, BA0_ACCAD)); | 197 | snd_cs46xx_peekBA0(chip, BA0_ACCAD)); |
198 | #endif | 198 | #endif |
199 | 199 | ||
200 | //snd_cs46xx_peekBA0(chip, BA0_ACCAD); | 200 | //snd_cs46xx_peekBA0(chip, BA0_ACCAD); |
201 | result = snd_cs46xx_peekBA0(chip, BA0_ACSDA + offset); | 201 | result = snd_cs46xx_peekBA0(chip, BA0_ACSDA + offset); |
202 | end: | 202 | end: |
203 | chip->active_ctrl(chip, -1); | 203 | chip->active_ctrl(chip, -1); |
204 | return result; | 204 | return result; |
205 | } | 205 | } |
206 | 206 | ||
207 | static unsigned short snd_cs46xx_ac97_read(struct snd_ac97 * ac97, | 207 | static unsigned short snd_cs46xx_ac97_read(struct snd_ac97 * ac97, |
208 | unsigned short reg) | 208 | unsigned short reg) |
209 | { | 209 | { |
210 | struct snd_cs46xx *chip = ac97->private_data; | 210 | struct snd_cs46xx *chip = ac97->private_data; |
211 | unsigned short val; | 211 | unsigned short val; |
212 | int codec_index = ac97->num; | 212 | int codec_index = ac97->num; |
213 | 213 | ||
214 | snd_assert(codec_index == CS46XX_PRIMARY_CODEC_INDEX || | 214 | snd_assert(codec_index == CS46XX_PRIMARY_CODEC_INDEX || |
215 | codec_index == CS46XX_SECONDARY_CODEC_INDEX, | 215 | codec_index == CS46XX_SECONDARY_CODEC_INDEX, |
216 | return 0xffff); | 216 | return 0xffff); |
217 | 217 | ||
218 | val = snd_cs46xx_codec_read(chip, reg, codec_index); | 218 | val = snd_cs46xx_codec_read(chip, reg, codec_index); |
219 | 219 | ||
220 | return val; | 220 | return val; |
221 | } | 221 | } |
222 | 222 | ||
223 | 223 | ||
224 | static void snd_cs46xx_codec_write(struct snd_cs46xx *chip, | 224 | static void snd_cs46xx_codec_write(struct snd_cs46xx *chip, |
225 | unsigned short reg, | 225 | unsigned short reg, |
226 | unsigned short val, | 226 | unsigned short val, |
227 | int codec_index) | 227 | int codec_index) |
228 | { | 228 | { |
229 | int count; | 229 | int count; |
230 | 230 | ||
231 | snd_assert ((codec_index == CS46XX_PRIMARY_CODEC_INDEX) || | 231 | snd_assert ((codec_index == CS46XX_PRIMARY_CODEC_INDEX) || |
232 | (codec_index == CS46XX_SECONDARY_CODEC_INDEX), | 232 | (codec_index == CS46XX_SECONDARY_CODEC_INDEX), |
233 | return); | 233 | return); |
234 | 234 | ||
235 | chip->active_ctrl(chip, 1); | 235 | chip->active_ctrl(chip, 1); |
236 | 236 | ||
237 | /* | 237 | /* |
238 | * 1. Write ACCAD = Command Address Register = 46Ch for AC97 register address | 238 | * 1. Write ACCAD = Command Address Register = 46Ch for AC97 register address |
239 | * 2. Write ACCDA = Command Data Register = 470h for data to write to AC97 | 239 | * 2. Write ACCDA = Command Data Register = 470h for data to write to AC97 |
240 | * 3. Write ACCTL = Control Register = 460h for initiating the write | 240 | * 3. Write ACCTL = Control Register = 460h for initiating the write |
241 | * 4. Read ACCTL = 460h, DCV should be reset by now and 460h = 07h | 241 | * 4. Read ACCTL = 460h, DCV should be reset by now and 460h = 07h |
242 | * 5. if DCV not cleared, break and return error | 242 | * 5. if DCV not cleared, break and return error |
243 | */ | 243 | */ |
244 | 244 | ||
245 | /* | 245 | /* |
246 | * Setup the AC97 control registers on the CS461x to send the | 246 | * Setup the AC97 control registers on the CS461x to send the |
247 | * appropriate command to the AC97 to perform the read. | 247 | * appropriate command to the AC97 to perform the read. |
248 | * ACCAD = Command Address Register = 46Ch | 248 | * ACCAD = Command Address Register = 46Ch |
249 | * ACCDA = Command Data Register = 470h | 249 | * ACCDA = Command Data Register = 470h |
250 | * ACCTL = Control Register = 460h | 250 | * ACCTL = Control Register = 460h |
251 | * set DCV - will clear when process completed | 251 | * set DCV - will clear when process completed |
252 | * reset CRW - Write command | 252 | * reset CRW - Write command |
253 | * set VFRM - valid frame enabled | 253 | * set VFRM - valid frame enabled |
254 | * set ESYN - ASYNC generation enabled | 254 | * set ESYN - ASYNC generation enabled |
255 | * set RSTN - ARST# inactive, AC97 codec not reset | 255 | * set RSTN - ARST# inactive, AC97 codec not reset |
256 | */ | 256 | */ |
257 | snd_cs46xx_pokeBA0(chip, BA0_ACCAD , reg); | 257 | snd_cs46xx_pokeBA0(chip, BA0_ACCAD , reg); |
258 | snd_cs46xx_pokeBA0(chip, BA0_ACCDA , val); | 258 | snd_cs46xx_pokeBA0(chip, BA0_ACCDA , val); |
259 | snd_cs46xx_peekBA0(chip, BA0_ACCTL); | 259 | snd_cs46xx_peekBA0(chip, BA0_ACCTL); |
260 | 260 | ||
261 | if (codec_index == CS46XX_PRIMARY_CODEC_INDEX) { | 261 | if (codec_index == CS46XX_PRIMARY_CODEC_INDEX) { |
262 | snd_cs46xx_pokeBA0(chip, BA0_ACCTL, /* clear ACCTL_DCV */ ACCTL_VFRM | | 262 | snd_cs46xx_pokeBA0(chip, BA0_ACCTL, /* clear ACCTL_DCV */ ACCTL_VFRM | |
263 | ACCTL_ESYN | ACCTL_RSTN); | 263 | ACCTL_ESYN | ACCTL_RSTN); |
264 | snd_cs46xx_pokeBA0(chip, BA0_ACCTL, ACCTL_DCV | ACCTL_VFRM | | 264 | snd_cs46xx_pokeBA0(chip, BA0_ACCTL, ACCTL_DCV | ACCTL_VFRM | |
265 | ACCTL_ESYN | ACCTL_RSTN); | 265 | ACCTL_ESYN | ACCTL_RSTN); |
266 | } else { | 266 | } else { |
267 | snd_cs46xx_pokeBA0(chip, BA0_ACCTL, ACCTL_DCV | ACCTL_TC | | 267 | snd_cs46xx_pokeBA0(chip, BA0_ACCTL, ACCTL_DCV | ACCTL_TC | |
268 | ACCTL_VFRM | ACCTL_ESYN | ACCTL_RSTN); | 268 | ACCTL_VFRM | ACCTL_ESYN | ACCTL_RSTN); |
269 | } | 269 | } |
270 | 270 | ||
271 | for (count = 0; count < 4000; count++) { | 271 | for (count = 0; count < 4000; count++) { |
272 | /* | 272 | /* |
273 | * First, we want to wait for a short time. | 273 | * First, we want to wait for a short time. |
274 | */ | 274 | */ |
275 | udelay(10); | 275 | udelay(10); |
276 | /* | 276 | /* |
277 | * Now, check to see if the write has completed. | 277 | * Now, check to see if the write has completed. |
278 | * ACCTL = 460h, DCV should be reset by now and 460h = 07h | 278 | * ACCTL = 460h, DCV should be reset by now and 460h = 07h |
279 | */ | 279 | */ |
280 | if (!(snd_cs46xx_peekBA0(chip, BA0_ACCTL) & ACCTL_DCV)) { | 280 | if (!(snd_cs46xx_peekBA0(chip, BA0_ACCTL) & ACCTL_DCV)) { |
281 | goto end; | 281 | goto end; |
282 | } | 282 | } |
283 | } | 283 | } |
284 | snd_printk(KERN_ERR "AC'97 write problem, codec_index = %d, reg = 0x%x, val = 0x%x\n", codec_index, reg, val); | 284 | snd_printk(KERN_ERR "AC'97 write problem, codec_index = %d, reg = 0x%x, val = 0x%x\n", codec_index, reg, val); |
285 | end: | 285 | end: |
286 | chip->active_ctrl(chip, -1); | 286 | chip->active_ctrl(chip, -1); |
287 | } | 287 | } |
288 | 288 | ||
289 | static void snd_cs46xx_ac97_write(struct snd_ac97 *ac97, | 289 | static void snd_cs46xx_ac97_write(struct snd_ac97 *ac97, |
290 | unsigned short reg, | 290 | unsigned short reg, |
291 | unsigned short val) | 291 | unsigned short val) |
292 | { | 292 | { |
293 | struct snd_cs46xx *chip = ac97->private_data; | 293 | struct snd_cs46xx *chip = ac97->private_data; |
294 | int codec_index = ac97->num; | 294 | int codec_index = ac97->num; |
295 | 295 | ||
296 | snd_assert(codec_index == CS46XX_PRIMARY_CODEC_INDEX || | 296 | snd_assert(codec_index == CS46XX_PRIMARY_CODEC_INDEX || |
297 | codec_index == CS46XX_SECONDARY_CODEC_INDEX, | 297 | codec_index == CS46XX_SECONDARY_CODEC_INDEX, |
298 | return); | 298 | return); |
299 | 299 | ||
300 | snd_cs46xx_codec_write(chip, reg, val, codec_index); | 300 | snd_cs46xx_codec_write(chip, reg, val, codec_index); |
301 | } | 301 | } |
302 | 302 | ||
303 | 303 | ||
304 | /* | 304 | /* |
305 | * Chip initialization | 305 | * Chip initialization |
306 | */ | 306 | */ |
307 | 307 | ||
308 | int snd_cs46xx_download(struct snd_cs46xx *chip, | 308 | int snd_cs46xx_download(struct snd_cs46xx *chip, |
309 | u32 *src, | 309 | u32 *src, |
310 | unsigned long offset, | 310 | unsigned long offset, |
311 | unsigned long len) | 311 | unsigned long len) |
312 | { | 312 | { |
313 | void __iomem *dst; | 313 | void __iomem *dst; |
314 | unsigned int bank = offset >> 16; | 314 | unsigned int bank = offset >> 16; |
315 | offset = offset & 0xffff; | 315 | offset = offset & 0xffff; |
316 | 316 | ||
317 | snd_assert(!(offset & 3) && !(len & 3), return -EINVAL); | 317 | snd_assert(!(offset & 3) && !(len & 3), return -EINVAL); |
318 | dst = chip->region.idx[bank+1].remap_addr + offset; | 318 | dst = chip->region.idx[bank+1].remap_addr + offset; |
319 | len /= sizeof(u32); | 319 | len /= sizeof(u32); |
320 | 320 | ||
321 | /* writel already converts 32-bit value to right endianess */ | 321 | /* writel already converts 32-bit value to right endianess */ |
322 | while (len-- > 0) { | 322 | while (len-- > 0) { |
323 | writel(*src++, dst); | 323 | writel(*src++, dst); |
324 | dst += sizeof(u32); | 324 | dst += sizeof(u32); |
325 | } | 325 | } |
326 | return 0; | 326 | return 0; |
327 | } | 327 | } |
328 | 328 | ||
329 | #ifdef CONFIG_SND_CS46XX_NEW_DSP | 329 | #ifdef CONFIG_SND_CS46XX_NEW_DSP |
330 | 330 | ||
331 | #include "imgs/cwc4630.h" | 331 | #include "imgs/cwc4630.h" |
332 | #include "imgs/cwcasync.h" | 332 | #include "imgs/cwcasync.h" |
333 | #include "imgs/cwcsnoop.h" | 333 | #include "imgs/cwcsnoop.h" |
334 | #include "imgs/cwcbinhack.h" | 334 | #include "imgs/cwcbinhack.h" |
335 | #include "imgs/cwcdma.h" | 335 | #include "imgs/cwcdma.h" |
336 | 336 | ||
337 | int snd_cs46xx_clear_BA1(struct snd_cs46xx *chip, | 337 | int snd_cs46xx_clear_BA1(struct snd_cs46xx *chip, |
338 | unsigned long offset, | 338 | unsigned long offset, |
339 | unsigned long len) | 339 | unsigned long len) |
340 | { | 340 | { |
341 | void __iomem *dst; | 341 | void __iomem *dst; |
342 | unsigned int bank = offset >> 16; | 342 | unsigned int bank = offset >> 16; |
343 | offset = offset & 0xffff; | 343 | offset = offset & 0xffff; |
344 | 344 | ||
345 | snd_assert(!(offset & 3) && !(len & 3), return -EINVAL); | 345 | snd_assert(!(offset & 3) && !(len & 3), return -EINVAL); |
346 | dst = chip->region.idx[bank+1].remap_addr + offset; | 346 | dst = chip->region.idx[bank+1].remap_addr + offset; |
347 | len /= sizeof(u32); | 347 | len /= sizeof(u32); |
348 | 348 | ||
349 | /* writel already converts 32-bit value to right endianess */ | 349 | /* writel already converts 32-bit value to right endianess */ |
350 | while (len-- > 0) { | 350 | while (len-- > 0) { |
351 | writel(0, dst); | 351 | writel(0, dst); |
352 | dst += sizeof(u32); | 352 | dst += sizeof(u32); |
353 | } | 353 | } |
354 | return 0; | 354 | return 0; |
355 | } | 355 | } |
356 | 356 | ||
357 | #else /* old DSP image */ | 357 | #else /* old DSP image */ |
358 | 358 | ||
359 | #include "cs46xx_image.h" | 359 | #include "cs46xx_image.h" |
360 | 360 | ||
361 | int snd_cs46xx_download_image(struct snd_cs46xx *chip) | 361 | int snd_cs46xx_download_image(struct snd_cs46xx *chip) |
362 | { | 362 | { |
363 | int idx, err; | 363 | int idx, err; |
364 | unsigned long offset = 0; | 364 | unsigned long offset = 0; |
365 | 365 | ||
366 | for (idx = 0; idx < BA1_MEMORY_COUNT; idx++) { | 366 | for (idx = 0; idx < BA1_MEMORY_COUNT; idx++) { |
367 | if ((err = snd_cs46xx_download(chip, | 367 | if ((err = snd_cs46xx_download(chip, |
368 | &BA1Struct.map[offset], | 368 | &BA1Struct.map[offset], |
369 | BA1Struct.memory[idx].offset, | 369 | BA1Struct.memory[idx].offset, |
370 | BA1Struct.memory[idx].size)) < 0) | 370 | BA1Struct.memory[idx].size)) < 0) |
371 | return err; | 371 | return err; |
372 | offset += BA1Struct.memory[idx].size >> 2; | 372 | offset += BA1Struct.memory[idx].size >> 2; |
373 | } | 373 | } |
374 | return 0; | 374 | return 0; |
375 | } | 375 | } |
376 | #endif /* CONFIG_SND_CS46XX_NEW_DSP */ | 376 | #endif /* CONFIG_SND_CS46XX_NEW_DSP */ |
377 | 377 | ||
378 | /* | 378 | /* |
379 | * Chip reset | 379 | * Chip reset |
380 | */ | 380 | */ |
381 | 381 | ||
382 | static void snd_cs46xx_reset(struct snd_cs46xx *chip) | 382 | static void snd_cs46xx_reset(struct snd_cs46xx *chip) |
383 | { | 383 | { |
384 | int idx; | 384 | int idx; |
385 | 385 | ||
386 | /* | 386 | /* |
387 | * Write the reset bit of the SP control register. | 387 | * Write the reset bit of the SP control register. |
388 | */ | 388 | */ |
389 | snd_cs46xx_poke(chip, BA1_SPCR, SPCR_RSTSP); | 389 | snd_cs46xx_poke(chip, BA1_SPCR, SPCR_RSTSP); |
390 | 390 | ||
391 | /* | 391 | /* |
392 | * Write the control register. | 392 | * Write the control register. |
393 | */ | 393 | */ |
394 | snd_cs46xx_poke(chip, BA1_SPCR, SPCR_DRQEN); | 394 | snd_cs46xx_poke(chip, BA1_SPCR, SPCR_DRQEN); |
395 | 395 | ||
396 | /* | 396 | /* |
397 | * Clear the trap registers. | 397 | * Clear the trap registers. |
398 | */ | 398 | */ |
399 | for (idx = 0; idx < 8; idx++) { | 399 | for (idx = 0; idx < 8; idx++) { |
400 | snd_cs46xx_poke(chip, BA1_DREG, DREG_REGID_TRAP_SELECT + idx); | 400 | snd_cs46xx_poke(chip, BA1_DREG, DREG_REGID_TRAP_SELECT + idx); |
401 | snd_cs46xx_poke(chip, BA1_TWPR, 0xFFFF); | 401 | snd_cs46xx_poke(chip, BA1_TWPR, 0xFFFF); |
402 | } | 402 | } |
403 | snd_cs46xx_poke(chip, BA1_DREG, 0); | 403 | snd_cs46xx_poke(chip, BA1_DREG, 0); |
404 | 404 | ||
405 | /* | 405 | /* |
406 | * Set the frame timer to reflect the number of cycles per frame. | 406 | * Set the frame timer to reflect the number of cycles per frame. |
407 | */ | 407 | */ |
408 | snd_cs46xx_poke(chip, BA1_FRMT, 0xadf); | 408 | snd_cs46xx_poke(chip, BA1_FRMT, 0xadf); |
409 | } | 409 | } |
410 | 410 | ||
411 | static int cs46xx_wait_for_fifo(struct snd_cs46xx * chip,int retry_timeout) | 411 | static int cs46xx_wait_for_fifo(struct snd_cs46xx * chip,int retry_timeout) |
412 | { | 412 | { |
413 | u32 i, status = 0; | 413 | u32 i, status = 0; |
414 | /* | 414 | /* |
415 | * Make sure the previous FIFO write operation has completed. | 415 | * Make sure the previous FIFO write operation has completed. |
416 | */ | 416 | */ |
417 | for(i = 0; i < 50; i++){ | 417 | for(i = 0; i < 50; i++){ |
418 | status = snd_cs46xx_peekBA0(chip, BA0_SERBST); | 418 | status = snd_cs46xx_peekBA0(chip, BA0_SERBST); |
419 | 419 | ||
420 | if( !(status & SERBST_WBSY) ) | 420 | if( !(status & SERBST_WBSY) ) |
421 | break; | 421 | break; |
422 | 422 | ||
423 | mdelay(retry_timeout); | 423 | mdelay(retry_timeout); |
424 | } | 424 | } |
425 | 425 | ||
426 | if(status & SERBST_WBSY) { | 426 | if(status & SERBST_WBSY) { |
427 | snd_printk( KERN_ERR "cs46xx: failure waiting for FIFO command to complete\n"); | 427 | snd_printk( KERN_ERR "cs46xx: failure waiting for FIFO command to complete\n"); |
428 | 428 | ||
429 | return -EINVAL; | 429 | return -EINVAL; |
430 | } | 430 | } |
431 | 431 | ||
432 | return 0; | 432 | return 0; |
433 | } | 433 | } |
434 | 434 | ||
435 | static void snd_cs46xx_clear_serial_FIFOs(struct snd_cs46xx *chip) | 435 | static void snd_cs46xx_clear_serial_FIFOs(struct snd_cs46xx *chip) |
436 | { | 436 | { |
437 | int idx, powerdown = 0; | 437 | int idx, powerdown = 0; |
438 | unsigned int tmp; | 438 | unsigned int tmp; |
439 | 439 | ||
440 | /* | 440 | /* |
441 | * See if the devices are powered down. If so, we must power them up first | 441 | * See if the devices are powered down. If so, we must power them up first |
442 | * or they will not respond. | 442 | * or they will not respond. |
443 | */ | 443 | */ |
444 | tmp = snd_cs46xx_peekBA0(chip, BA0_CLKCR1); | 444 | tmp = snd_cs46xx_peekBA0(chip, BA0_CLKCR1); |
445 | if (!(tmp & CLKCR1_SWCE)) { | 445 | if (!(tmp & CLKCR1_SWCE)) { |
446 | snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, tmp | CLKCR1_SWCE); | 446 | snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, tmp | CLKCR1_SWCE); |
447 | powerdown = 1; | 447 | powerdown = 1; |
448 | } | 448 | } |
449 | 449 | ||
450 | /* | 450 | /* |
451 | * We want to clear out the serial port FIFOs so we don't end up playing | 451 | * We want to clear out the serial port FIFOs so we don't end up playing |
452 | * whatever random garbage happens to be in them. We fill the sample FIFOS | 452 | * whatever random garbage happens to be in them. We fill the sample FIFOS |
453 | * with zero (silence). | 453 | * with zero (silence). |
454 | */ | 454 | */ |
455 | snd_cs46xx_pokeBA0(chip, BA0_SERBWP, 0); | 455 | snd_cs46xx_pokeBA0(chip, BA0_SERBWP, 0); |
456 | 456 | ||
457 | /* | 457 | /* |
458 | * Fill all 256 sample FIFO locations. | 458 | * Fill all 256 sample FIFO locations. |
459 | */ | 459 | */ |
460 | for (idx = 0; idx < 0xFF; idx++) { | 460 | for (idx = 0; idx < 0xFF; idx++) { |
461 | /* | 461 | /* |
462 | * Make sure the previous FIFO write operation has completed. | 462 | * Make sure the previous FIFO write operation has completed. |
463 | */ | 463 | */ |
464 | if (cs46xx_wait_for_fifo(chip,1)) { | 464 | if (cs46xx_wait_for_fifo(chip,1)) { |
465 | snd_printdd ("failed waiting for FIFO at addr (%02X)\n",idx); | 465 | snd_printdd ("failed waiting for FIFO at addr (%02X)\n",idx); |
466 | 466 | ||
467 | if (powerdown) | 467 | if (powerdown) |
468 | snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, tmp); | 468 | snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, tmp); |
469 | 469 | ||
470 | break; | 470 | break; |
471 | } | 471 | } |
472 | /* | 472 | /* |
473 | * Write the serial port FIFO index. | 473 | * Write the serial port FIFO index. |
474 | */ | 474 | */ |
475 | snd_cs46xx_pokeBA0(chip, BA0_SERBAD, idx); | 475 | snd_cs46xx_pokeBA0(chip, BA0_SERBAD, idx); |
476 | /* | 476 | /* |
477 | * Tell the serial port to load the new value into the FIFO location. | 477 | * Tell the serial port to load the new value into the FIFO location. |
478 | */ | 478 | */ |
479 | snd_cs46xx_pokeBA0(chip, BA0_SERBCM, SERBCM_WRC); | 479 | snd_cs46xx_pokeBA0(chip, BA0_SERBCM, SERBCM_WRC); |
480 | } | 480 | } |
481 | /* | 481 | /* |
482 | * Now, if we powered up the devices, then power them back down again. | 482 | * Now, if we powered up the devices, then power them back down again. |
483 | * This is kinda ugly, but should never happen. | 483 | * This is kinda ugly, but should never happen. |
484 | */ | 484 | */ |
485 | if (powerdown) | 485 | if (powerdown) |
486 | snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, tmp); | 486 | snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, tmp); |
487 | } | 487 | } |
488 | 488 | ||
489 | static void snd_cs46xx_proc_start(struct snd_cs46xx *chip) | 489 | static void snd_cs46xx_proc_start(struct snd_cs46xx *chip) |
490 | { | 490 | { |
491 | int cnt; | 491 | int cnt; |
492 | 492 | ||
493 | /* | 493 | /* |
494 | * Set the frame timer to reflect the number of cycles per frame. | 494 | * Set the frame timer to reflect the number of cycles per frame. |
495 | */ | 495 | */ |
496 | snd_cs46xx_poke(chip, BA1_FRMT, 0xadf); | 496 | snd_cs46xx_poke(chip, BA1_FRMT, 0xadf); |
497 | /* | 497 | /* |
498 | * Turn on the run, run at frame, and DMA enable bits in the local copy of | 498 | * Turn on the run, run at frame, and DMA enable bits in the local copy of |
499 | * the SP control register. | 499 | * the SP control register. |
500 | */ | 500 | */ |
501 | snd_cs46xx_poke(chip, BA1_SPCR, SPCR_RUN | SPCR_RUNFR | SPCR_DRQEN); | 501 | snd_cs46xx_poke(chip, BA1_SPCR, SPCR_RUN | SPCR_RUNFR | SPCR_DRQEN); |
502 | /* | 502 | /* |
503 | * Wait until the run at frame bit resets itself in the SP control | 503 | * Wait until the run at frame bit resets itself in the SP control |
504 | * register. | 504 | * register. |
505 | */ | 505 | */ |
506 | for (cnt = 0; cnt < 25; cnt++) { | 506 | for (cnt = 0; cnt < 25; cnt++) { |
507 | udelay(50); | 507 | udelay(50); |
508 | if (!(snd_cs46xx_peek(chip, BA1_SPCR) & SPCR_RUNFR)) | 508 | if (!(snd_cs46xx_peek(chip, BA1_SPCR) & SPCR_RUNFR)) |
509 | break; | 509 | break; |
510 | } | 510 | } |
511 | 511 | ||
512 | if (snd_cs46xx_peek(chip, BA1_SPCR) & SPCR_RUNFR) | 512 | if (snd_cs46xx_peek(chip, BA1_SPCR) & SPCR_RUNFR) |
513 | snd_printk(KERN_ERR "SPCR_RUNFR never reset\n"); | 513 | snd_printk(KERN_ERR "SPCR_RUNFR never reset\n"); |
514 | } | 514 | } |
515 | 515 | ||
516 | static void snd_cs46xx_proc_stop(struct snd_cs46xx *chip) | 516 | static void snd_cs46xx_proc_stop(struct snd_cs46xx *chip) |
517 | { | 517 | { |
518 | /* | 518 | /* |
519 | * Turn off the run, run at frame, and DMA enable bits in the local copy of | 519 | * Turn off the run, run at frame, and DMA enable bits in the local copy of |
520 | * the SP control register. | 520 | * the SP control register. |
521 | */ | 521 | */ |
522 | snd_cs46xx_poke(chip, BA1_SPCR, 0); | 522 | snd_cs46xx_poke(chip, BA1_SPCR, 0); |
523 | } | 523 | } |
524 | 524 | ||
525 | /* | 525 | /* |
526 | * Sample rate routines | 526 | * Sample rate routines |
527 | */ | 527 | */ |
528 | 528 | ||
529 | #define GOF_PER_SEC 200 | 529 | #define GOF_PER_SEC 200 |
530 | 530 | ||
531 | static void snd_cs46xx_set_play_sample_rate(struct snd_cs46xx *chip, unsigned int rate) | 531 | static void snd_cs46xx_set_play_sample_rate(struct snd_cs46xx *chip, unsigned int rate) |
532 | { | 532 | { |
533 | unsigned long flags; | 533 | unsigned long flags; |
534 | unsigned int tmp1, tmp2; | 534 | unsigned int tmp1, tmp2; |
535 | unsigned int phiIncr; | 535 | unsigned int phiIncr; |
536 | unsigned int correctionPerGOF, correctionPerSec; | 536 | unsigned int correctionPerGOF, correctionPerSec; |
537 | 537 | ||
538 | /* | 538 | /* |
539 | * Compute the values used to drive the actual sample rate conversion. | 539 | * Compute the values used to drive the actual sample rate conversion. |
540 | * The following formulas are being computed, using inline assembly | 540 | * The following formulas are being computed, using inline assembly |
541 | * since we need to use 64 bit arithmetic to compute the values: | 541 | * since we need to use 64 bit arithmetic to compute the values: |
542 | * | 542 | * |
543 | * phiIncr = floor((Fs,in * 2^26) / Fs,out) | 543 | * phiIncr = floor((Fs,in * 2^26) / Fs,out) |
544 | * correctionPerGOF = floor((Fs,in * 2^26 - Fs,out * phiIncr) / | 544 | * correctionPerGOF = floor((Fs,in * 2^26 - Fs,out * phiIncr) / |
545 | * GOF_PER_SEC) | 545 | * GOF_PER_SEC) |
546 | * ulCorrectionPerSec = Fs,in * 2^26 - Fs,out * phiIncr -M | 546 | * ulCorrectionPerSec = Fs,in * 2^26 - Fs,out * phiIncr -M |
547 | * GOF_PER_SEC * correctionPerGOF | 547 | * GOF_PER_SEC * correctionPerGOF |
548 | * | 548 | * |
549 | * i.e. | 549 | * i.e. |
550 | * | 550 | * |
551 | * phiIncr:other = dividend:remainder((Fs,in * 2^26) / Fs,out) | 551 | * phiIncr:other = dividend:remainder((Fs,in * 2^26) / Fs,out) |
552 | * correctionPerGOF:correctionPerSec = | 552 | * correctionPerGOF:correctionPerSec = |
553 | * dividend:remainder(ulOther / GOF_PER_SEC) | 553 | * dividend:remainder(ulOther / GOF_PER_SEC) |
554 | */ | 554 | */ |
555 | tmp1 = rate << 16; | 555 | tmp1 = rate << 16; |
556 | phiIncr = tmp1 / 48000; | 556 | phiIncr = tmp1 / 48000; |
557 | tmp1 -= phiIncr * 48000; | 557 | tmp1 -= phiIncr * 48000; |
558 | tmp1 <<= 10; | 558 | tmp1 <<= 10; |
559 | phiIncr <<= 10; | 559 | phiIncr <<= 10; |
560 | tmp2 = tmp1 / 48000; | 560 | tmp2 = tmp1 / 48000; |
561 | phiIncr += tmp2; | 561 | phiIncr += tmp2; |
562 | tmp1 -= tmp2 * 48000; | 562 | tmp1 -= tmp2 * 48000; |
563 | correctionPerGOF = tmp1 / GOF_PER_SEC; | 563 | correctionPerGOF = tmp1 / GOF_PER_SEC; |
564 | tmp1 -= correctionPerGOF * GOF_PER_SEC; | 564 | tmp1 -= correctionPerGOF * GOF_PER_SEC; |
565 | correctionPerSec = tmp1; | 565 | correctionPerSec = tmp1; |
566 | 566 | ||
567 | /* | 567 | /* |
568 | * Fill in the SampleRateConverter control block. | 568 | * Fill in the SampleRateConverter control block. |
569 | */ | 569 | */ |
570 | spin_lock_irqsave(&chip->reg_lock, flags); | 570 | spin_lock_irqsave(&chip->reg_lock, flags); |
571 | snd_cs46xx_poke(chip, BA1_PSRC, | 571 | snd_cs46xx_poke(chip, BA1_PSRC, |
572 | ((correctionPerSec << 16) & 0xFFFF0000) | (correctionPerGOF & 0xFFFF)); | 572 | ((correctionPerSec << 16) & 0xFFFF0000) | (correctionPerGOF & 0xFFFF)); |
573 | snd_cs46xx_poke(chip, BA1_PPI, phiIncr); | 573 | snd_cs46xx_poke(chip, BA1_PPI, phiIncr); |
574 | spin_unlock_irqrestore(&chip->reg_lock, flags); | 574 | spin_unlock_irqrestore(&chip->reg_lock, flags); |
575 | } | 575 | } |
576 | 576 | ||
577 | static void snd_cs46xx_set_capture_sample_rate(struct snd_cs46xx *chip, unsigned int rate) | 577 | static void snd_cs46xx_set_capture_sample_rate(struct snd_cs46xx *chip, unsigned int rate) |
578 | { | 578 | { |
579 | unsigned long flags; | 579 | unsigned long flags; |
580 | unsigned int phiIncr, coeffIncr, tmp1, tmp2; | 580 | unsigned int phiIncr, coeffIncr, tmp1, tmp2; |
581 | unsigned int correctionPerGOF, correctionPerSec, initialDelay; | 581 | unsigned int correctionPerGOF, correctionPerSec, initialDelay; |
582 | unsigned int frameGroupLength, cnt; | 582 | unsigned int frameGroupLength, cnt; |
583 | 583 | ||
584 | /* | 584 | /* |
585 | * We can only decimate by up to a factor of 1/9th the hardware rate. | 585 | * We can only decimate by up to a factor of 1/9th the hardware rate. |
586 | * Correct the value if an attempt is made to stray outside that limit. | 586 | * Correct the value if an attempt is made to stray outside that limit. |
587 | */ | 587 | */ |
588 | if ((rate * 9) < 48000) | 588 | if ((rate * 9) < 48000) |
589 | rate = 48000 / 9; | 589 | rate = 48000 / 9; |
590 | 590 | ||
591 | /* | 591 | /* |
592 | * We can not capture at at rate greater than the Input Rate (48000). | 592 | * We can not capture at at rate greater than the Input Rate (48000). |
593 | * Return an error if an attempt is made to stray outside that limit. | 593 | * Return an error if an attempt is made to stray outside that limit. |
594 | */ | 594 | */ |
595 | if (rate > 48000) | 595 | if (rate > 48000) |
596 | rate = 48000; | 596 | rate = 48000; |
597 | 597 | ||
598 | /* | 598 | /* |
599 | * Compute the values used to drive the actual sample rate conversion. | 599 | * Compute the values used to drive the actual sample rate conversion. |
600 | * The following formulas are being computed, using inline assembly | 600 | * The following formulas are being computed, using inline assembly |
601 | * since we need to use 64 bit arithmetic to compute the values: | 601 | * since we need to use 64 bit arithmetic to compute the values: |
602 | * | 602 | * |
603 | * coeffIncr = -floor((Fs,out * 2^23) / Fs,in) | 603 | * coeffIncr = -floor((Fs,out * 2^23) / Fs,in) |
604 | * phiIncr = floor((Fs,in * 2^26) / Fs,out) | 604 | * phiIncr = floor((Fs,in * 2^26) / Fs,out) |
605 | * correctionPerGOF = floor((Fs,in * 2^26 - Fs,out * phiIncr) / | 605 | * correctionPerGOF = floor((Fs,in * 2^26 - Fs,out * phiIncr) / |
606 | * GOF_PER_SEC) | 606 | * GOF_PER_SEC) |
607 | * correctionPerSec = Fs,in * 2^26 - Fs,out * phiIncr - | 607 | * correctionPerSec = Fs,in * 2^26 - Fs,out * phiIncr - |
608 | * GOF_PER_SEC * correctionPerGOF | 608 | * GOF_PER_SEC * correctionPerGOF |
609 | * initialDelay = ceil((24 * Fs,in) / Fs,out) | 609 | * initialDelay = ceil((24 * Fs,in) / Fs,out) |
610 | * | 610 | * |
611 | * i.e. | 611 | * i.e. |
612 | * | 612 | * |
613 | * coeffIncr = neg(dividend((Fs,out * 2^23) / Fs,in)) | 613 | * coeffIncr = neg(dividend((Fs,out * 2^23) / Fs,in)) |
614 | * phiIncr:ulOther = dividend:remainder((Fs,in * 2^26) / Fs,out) | 614 | * phiIncr:ulOther = dividend:remainder((Fs,in * 2^26) / Fs,out) |
615 | * correctionPerGOF:correctionPerSec = | 615 | * correctionPerGOF:correctionPerSec = |
616 | * dividend:remainder(ulOther / GOF_PER_SEC) | 616 | * dividend:remainder(ulOther / GOF_PER_SEC) |
617 | * initialDelay = dividend(((24 * Fs,in) + Fs,out - 1) / Fs,out) | 617 | * initialDelay = dividend(((24 * Fs,in) + Fs,out - 1) / Fs,out) |
618 | */ | 618 | */ |
619 | 619 | ||
620 | tmp1 = rate << 16; | 620 | tmp1 = rate << 16; |
621 | coeffIncr = tmp1 / 48000; | 621 | coeffIncr = tmp1 / 48000; |
622 | tmp1 -= coeffIncr * 48000; | 622 | tmp1 -= coeffIncr * 48000; |
623 | tmp1 <<= 7; | 623 | tmp1 <<= 7; |
624 | coeffIncr <<= 7; | 624 | coeffIncr <<= 7; |
625 | coeffIncr += tmp1 / 48000; | 625 | coeffIncr += tmp1 / 48000; |
626 | coeffIncr ^= 0xFFFFFFFF; | 626 | coeffIncr ^= 0xFFFFFFFF; |
627 | coeffIncr++; | 627 | coeffIncr++; |
628 | tmp1 = 48000 << 16; | 628 | tmp1 = 48000 << 16; |
629 | phiIncr = tmp1 / rate; | 629 | phiIncr = tmp1 / rate; |
630 | tmp1 -= phiIncr * rate; | 630 | tmp1 -= phiIncr * rate; |
631 | tmp1 <<= 10; | 631 | tmp1 <<= 10; |
632 | phiIncr <<= 10; | 632 | phiIncr <<= 10; |
633 | tmp2 = tmp1 / rate; | 633 | tmp2 = tmp1 / rate; |
634 | phiIncr += tmp2; | 634 | phiIncr += tmp2; |
635 | tmp1 -= tmp2 * rate; | 635 | tmp1 -= tmp2 * rate; |
636 | correctionPerGOF = tmp1 / GOF_PER_SEC; | 636 | correctionPerGOF = tmp1 / GOF_PER_SEC; |
637 | tmp1 -= correctionPerGOF * GOF_PER_SEC; | 637 | tmp1 -= correctionPerGOF * GOF_PER_SEC; |
638 | correctionPerSec = tmp1; | 638 | correctionPerSec = tmp1; |
639 | initialDelay = ((48000 * 24) + rate - 1) / rate; | 639 | initialDelay = ((48000 * 24) + rate - 1) / rate; |
640 | 640 | ||
641 | /* | 641 | /* |
642 | * Fill in the VariDecimate control block. | 642 | * Fill in the VariDecimate control block. |
643 | */ | 643 | */ |
644 | spin_lock_irqsave(&chip->reg_lock, flags); | 644 | spin_lock_irqsave(&chip->reg_lock, flags); |
645 | snd_cs46xx_poke(chip, BA1_CSRC, | 645 | snd_cs46xx_poke(chip, BA1_CSRC, |
646 | ((correctionPerSec << 16) & 0xFFFF0000) | (correctionPerGOF & 0xFFFF)); | 646 | ((correctionPerSec << 16) & 0xFFFF0000) | (correctionPerGOF & 0xFFFF)); |
647 | snd_cs46xx_poke(chip, BA1_CCI, coeffIncr); | 647 | snd_cs46xx_poke(chip, BA1_CCI, coeffIncr); |
648 | snd_cs46xx_poke(chip, BA1_CD, | 648 | snd_cs46xx_poke(chip, BA1_CD, |
649 | (((BA1_VARIDEC_BUF_1 + (initialDelay << 2)) << 16) & 0xFFFF0000) | 0x80); | 649 | (((BA1_VARIDEC_BUF_1 + (initialDelay << 2)) << 16) & 0xFFFF0000) | 0x80); |
650 | snd_cs46xx_poke(chip, BA1_CPI, phiIncr); | 650 | snd_cs46xx_poke(chip, BA1_CPI, phiIncr); |
651 | spin_unlock_irqrestore(&chip->reg_lock, flags); | 651 | spin_unlock_irqrestore(&chip->reg_lock, flags); |
652 | 652 | ||
653 | /* | 653 | /* |
654 | * Figure out the frame group length for the write back task. Basically, | 654 | * Figure out the frame group length for the write back task. Basically, |
655 | * this is just the factors of 24000 (2^6*3*5^3) that are not present in | 655 | * this is just the factors of 24000 (2^6*3*5^3) that are not present in |
656 | * the output sample rate. | 656 | * the output sample rate. |
657 | */ | 657 | */ |
658 | frameGroupLength = 1; | 658 | frameGroupLength = 1; |
659 | for (cnt = 2; cnt <= 64; cnt *= 2) { | 659 | for (cnt = 2; cnt <= 64; cnt *= 2) { |
660 | if (((rate / cnt) * cnt) != rate) | 660 | if (((rate / cnt) * cnt) != rate) |
661 | frameGroupLength *= 2; | 661 | frameGroupLength *= 2; |
662 | } | 662 | } |
663 | if (((rate / 3) * 3) != rate) { | 663 | if (((rate / 3) * 3) != rate) { |
664 | frameGroupLength *= 3; | 664 | frameGroupLength *= 3; |
665 | } | 665 | } |
666 | for (cnt = 5; cnt <= 125; cnt *= 5) { | 666 | for (cnt = 5; cnt <= 125; cnt *= 5) { |
667 | if (((rate / cnt) * cnt) != rate) | 667 | if (((rate / cnt) * cnt) != rate) |
668 | frameGroupLength *= 5; | 668 | frameGroupLength *= 5; |
669 | } | 669 | } |
670 | 670 | ||
671 | /* | 671 | /* |
672 | * Fill in the WriteBack control block. | 672 | * Fill in the WriteBack control block. |
673 | */ | 673 | */ |
674 | spin_lock_irqsave(&chip->reg_lock, flags); | 674 | spin_lock_irqsave(&chip->reg_lock, flags); |
675 | snd_cs46xx_poke(chip, BA1_CFG1, frameGroupLength); | 675 | snd_cs46xx_poke(chip, BA1_CFG1, frameGroupLength); |
676 | snd_cs46xx_poke(chip, BA1_CFG2, (0x00800000 | frameGroupLength)); | 676 | snd_cs46xx_poke(chip, BA1_CFG2, (0x00800000 | frameGroupLength)); |
677 | snd_cs46xx_poke(chip, BA1_CCST, 0x0000FFFF); | 677 | snd_cs46xx_poke(chip, BA1_CCST, 0x0000FFFF); |
678 | snd_cs46xx_poke(chip, BA1_CSPB, ((65536 * rate) / 24000)); | 678 | snd_cs46xx_poke(chip, BA1_CSPB, ((65536 * rate) / 24000)); |
679 | snd_cs46xx_poke(chip, (BA1_CSPB + 4), 0x0000FFFF); | 679 | snd_cs46xx_poke(chip, (BA1_CSPB + 4), 0x0000FFFF); |
680 | spin_unlock_irqrestore(&chip->reg_lock, flags); | 680 | spin_unlock_irqrestore(&chip->reg_lock, flags); |
681 | } | 681 | } |
682 | 682 | ||
683 | /* | 683 | /* |
684 | * PCM part | 684 | * PCM part |
685 | */ | 685 | */ |
686 | 686 | ||
687 | static void snd_cs46xx_pb_trans_copy(struct snd_pcm_substream *substream, | 687 | static void snd_cs46xx_pb_trans_copy(struct snd_pcm_substream *substream, |
688 | struct snd_pcm_indirect *rec, size_t bytes) | 688 | struct snd_pcm_indirect *rec, size_t bytes) |
689 | { | 689 | { |
690 | struct snd_pcm_runtime *runtime = substream->runtime; | 690 | struct snd_pcm_runtime *runtime = substream->runtime; |
691 | struct snd_cs46xx_pcm * cpcm = runtime->private_data; | 691 | struct snd_cs46xx_pcm * cpcm = runtime->private_data; |
692 | memcpy(cpcm->hw_buf.area + rec->hw_data, runtime->dma_area + rec->sw_data, bytes); | 692 | memcpy(cpcm->hw_buf.area + rec->hw_data, runtime->dma_area + rec->sw_data, bytes); |
693 | } | 693 | } |
694 | 694 | ||
695 | static int snd_cs46xx_playback_transfer(struct snd_pcm_substream *substream) | 695 | static int snd_cs46xx_playback_transfer(struct snd_pcm_substream *substream) |
696 | { | 696 | { |
697 | struct snd_pcm_runtime *runtime = substream->runtime; | 697 | struct snd_pcm_runtime *runtime = substream->runtime; |
698 | struct snd_cs46xx_pcm * cpcm = runtime->private_data; | 698 | struct snd_cs46xx_pcm * cpcm = runtime->private_data; |
699 | snd_pcm_indirect_playback_transfer(substream, &cpcm->pcm_rec, snd_cs46xx_pb_trans_copy); | 699 | snd_pcm_indirect_playback_transfer(substream, &cpcm->pcm_rec, snd_cs46xx_pb_trans_copy); |
700 | return 0; | 700 | return 0; |
701 | } | 701 | } |
702 | 702 | ||
703 | static void snd_cs46xx_cp_trans_copy(struct snd_pcm_substream *substream, | 703 | static void snd_cs46xx_cp_trans_copy(struct snd_pcm_substream *substream, |
704 | struct snd_pcm_indirect *rec, size_t bytes) | 704 | struct snd_pcm_indirect *rec, size_t bytes) |
705 | { | 705 | { |
706 | struct snd_cs46xx *chip = snd_pcm_substream_chip(substream); | 706 | struct snd_cs46xx *chip = snd_pcm_substream_chip(substream); |
707 | struct snd_pcm_runtime *runtime = substream->runtime; | 707 | struct snd_pcm_runtime *runtime = substream->runtime; |
708 | memcpy(runtime->dma_area + rec->sw_data, | 708 | memcpy(runtime->dma_area + rec->sw_data, |
709 | chip->capt.hw_buf.area + rec->hw_data, bytes); | 709 | chip->capt.hw_buf.area + rec->hw_data, bytes); |
710 | } | 710 | } |
711 | 711 | ||
712 | static int snd_cs46xx_capture_transfer(struct snd_pcm_substream *substream) | 712 | static int snd_cs46xx_capture_transfer(struct snd_pcm_substream *substream) |
713 | { | 713 | { |
714 | struct snd_cs46xx *chip = snd_pcm_substream_chip(substream); | 714 | struct snd_cs46xx *chip = snd_pcm_substream_chip(substream); |
715 | snd_pcm_indirect_capture_transfer(substream, &chip->capt.pcm_rec, snd_cs46xx_cp_trans_copy); | 715 | snd_pcm_indirect_capture_transfer(substream, &chip->capt.pcm_rec, snd_cs46xx_cp_trans_copy); |
716 | return 0; | 716 | return 0; |
717 | } | 717 | } |
718 | 718 | ||
719 | static snd_pcm_uframes_t snd_cs46xx_playback_direct_pointer(struct snd_pcm_substream *substream) | 719 | static snd_pcm_uframes_t snd_cs46xx_playback_direct_pointer(struct snd_pcm_substream *substream) |
720 | { | 720 | { |
721 | struct snd_cs46xx *chip = snd_pcm_substream_chip(substream); | 721 | struct snd_cs46xx *chip = snd_pcm_substream_chip(substream); |
722 | size_t ptr; | 722 | size_t ptr; |
723 | struct snd_cs46xx_pcm *cpcm = substream->runtime->private_data; | 723 | struct snd_cs46xx_pcm *cpcm = substream->runtime->private_data; |
724 | snd_assert (cpcm->pcm_channel,return -ENXIO); | 724 | snd_assert (cpcm->pcm_channel,return -ENXIO); |
725 | 725 | ||
726 | #ifdef CONFIG_SND_CS46XX_NEW_DSP | 726 | #ifdef CONFIG_SND_CS46XX_NEW_DSP |
727 | ptr = snd_cs46xx_peek(chip, (cpcm->pcm_channel->pcm_reader_scb->address + 2) << 2); | 727 | ptr = snd_cs46xx_peek(chip, (cpcm->pcm_channel->pcm_reader_scb->address + 2) << 2); |
728 | #else | 728 | #else |
729 | ptr = snd_cs46xx_peek(chip, BA1_PBA); | 729 | ptr = snd_cs46xx_peek(chip, BA1_PBA); |
730 | #endif | 730 | #endif |
731 | ptr -= cpcm->hw_buf.addr; | 731 | ptr -= cpcm->hw_buf.addr; |
732 | return ptr >> cpcm->shift; | 732 | return ptr >> cpcm->shift; |
733 | } | 733 | } |
734 | 734 | ||
735 | static snd_pcm_uframes_t snd_cs46xx_playback_indirect_pointer(struct snd_pcm_substream *substream) | 735 | static snd_pcm_uframes_t snd_cs46xx_playback_indirect_pointer(struct snd_pcm_substream *substream) |
736 | { | 736 | { |
737 | struct snd_cs46xx *chip = snd_pcm_substream_chip(substream); | 737 | struct snd_cs46xx *chip = snd_pcm_substream_chip(substream); |
738 | size_t ptr; | 738 | size_t ptr; |
739 | struct snd_cs46xx_pcm *cpcm = substream->runtime->private_data; | 739 | struct snd_cs46xx_pcm *cpcm = substream->runtime->private_data; |
740 | 740 | ||
741 | #ifdef CONFIG_SND_CS46XX_NEW_DSP | 741 | #ifdef CONFIG_SND_CS46XX_NEW_DSP |
742 | snd_assert (cpcm->pcm_channel,return -ENXIO); | 742 | snd_assert (cpcm->pcm_channel,return -ENXIO); |
743 | ptr = snd_cs46xx_peek(chip, (cpcm->pcm_channel->pcm_reader_scb->address + 2) << 2); | 743 | ptr = snd_cs46xx_peek(chip, (cpcm->pcm_channel->pcm_reader_scb->address + 2) << 2); |
744 | #else | 744 | #else |
745 | ptr = snd_cs46xx_peek(chip, BA1_PBA); | 745 | ptr = snd_cs46xx_peek(chip, BA1_PBA); |
746 | #endif | 746 | #endif |
747 | ptr -= cpcm->hw_buf.addr; | 747 | ptr -= cpcm->hw_buf.addr; |
748 | return snd_pcm_indirect_playback_pointer(substream, &cpcm->pcm_rec, ptr); | 748 | return snd_pcm_indirect_playback_pointer(substream, &cpcm->pcm_rec, ptr); |
749 | } | 749 | } |
750 | 750 | ||
751 | static snd_pcm_uframes_t snd_cs46xx_capture_direct_pointer(struct snd_pcm_substream *substream) | 751 | static snd_pcm_uframes_t snd_cs46xx_capture_direct_pointer(struct snd_pcm_substream *substream) |
752 | { | 752 | { |
753 | struct snd_cs46xx *chip = snd_pcm_substream_chip(substream); | 753 | struct snd_cs46xx *chip = snd_pcm_substream_chip(substream); |
754 | size_t ptr = snd_cs46xx_peek(chip, BA1_CBA) - chip->capt.hw_buf.addr; | 754 | size_t ptr = snd_cs46xx_peek(chip, BA1_CBA) - chip->capt.hw_buf.addr; |
755 | return ptr >> chip->capt.shift; | 755 | return ptr >> chip->capt.shift; |
756 | } | 756 | } |
757 | 757 | ||
758 | static snd_pcm_uframes_t snd_cs46xx_capture_indirect_pointer(struct snd_pcm_substream *substream) | 758 | static snd_pcm_uframes_t snd_cs46xx_capture_indirect_pointer(struct snd_pcm_substream *substream) |
759 | { | 759 | { |
760 | struct snd_cs46xx *chip = snd_pcm_substream_chip(substream); | 760 | struct snd_cs46xx *chip = snd_pcm_substream_chip(substream); |
761 | size_t ptr = snd_cs46xx_peek(chip, BA1_CBA) - chip->capt.hw_buf.addr; | 761 | size_t ptr = snd_cs46xx_peek(chip, BA1_CBA) - chip->capt.hw_buf.addr; |
762 | return snd_pcm_indirect_capture_pointer(substream, &chip->capt.pcm_rec, ptr); | 762 | return snd_pcm_indirect_capture_pointer(substream, &chip->capt.pcm_rec, ptr); |
763 | } | 763 | } |
764 | 764 | ||
765 | static int snd_cs46xx_playback_trigger(struct snd_pcm_substream *substream, | 765 | static int snd_cs46xx_playback_trigger(struct snd_pcm_substream *substream, |
766 | int cmd) | 766 | int cmd) |
767 | { | 767 | { |
768 | struct snd_cs46xx *chip = snd_pcm_substream_chip(substream); | 768 | struct snd_cs46xx *chip = snd_pcm_substream_chip(substream); |
769 | /*struct snd_pcm_runtime *runtime = substream->runtime;*/ | 769 | /*struct snd_pcm_runtime *runtime = substream->runtime;*/ |
770 | int result = 0; | 770 | int result = 0; |
771 | 771 | ||
772 | #ifdef CONFIG_SND_CS46XX_NEW_DSP | 772 | #ifdef CONFIG_SND_CS46XX_NEW_DSP |
773 | struct snd_cs46xx_pcm *cpcm = substream->runtime->private_data; | 773 | struct snd_cs46xx_pcm *cpcm = substream->runtime->private_data; |
774 | if (! cpcm->pcm_channel) { | 774 | if (! cpcm->pcm_channel) { |
775 | return -ENXIO; | 775 | return -ENXIO; |
776 | } | 776 | } |
777 | #endif | 777 | #endif |
778 | switch (cmd) { | 778 | switch (cmd) { |
779 | case SNDRV_PCM_TRIGGER_START: | 779 | case SNDRV_PCM_TRIGGER_START: |
780 | case SNDRV_PCM_TRIGGER_RESUME: | 780 | case SNDRV_PCM_TRIGGER_RESUME: |
781 | #ifdef CONFIG_SND_CS46XX_NEW_DSP | 781 | #ifdef CONFIG_SND_CS46XX_NEW_DSP |
782 | /* magic value to unmute PCM stream playback volume */ | 782 | /* magic value to unmute PCM stream playback volume */ |
783 | snd_cs46xx_poke(chip, (cpcm->pcm_channel->pcm_reader_scb->address + | 783 | snd_cs46xx_poke(chip, (cpcm->pcm_channel->pcm_reader_scb->address + |
784 | SCBVolumeCtrl) << 2, 0x80008000); | 784 | SCBVolumeCtrl) << 2, 0x80008000); |
785 | 785 | ||
786 | if (cpcm->pcm_channel->unlinked) | 786 | if (cpcm->pcm_channel->unlinked) |
787 | cs46xx_dsp_pcm_link(chip,cpcm->pcm_channel); | 787 | cs46xx_dsp_pcm_link(chip,cpcm->pcm_channel); |
788 | 788 | ||
789 | if (substream->runtime->periods != CS46XX_FRAGS) | 789 | if (substream->runtime->periods != CS46XX_FRAGS) |
790 | snd_cs46xx_playback_transfer(substream); | 790 | snd_cs46xx_playback_transfer(substream); |
791 | #else | 791 | #else |
792 | spin_lock(&chip->reg_lock); | 792 | spin_lock(&chip->reg_lock); |
793 | if (substream->runtime->periods != CS46XX_FRAGS) | 793 | if (substream->runtime->periods != CS46XX_FRAGS) |
794 | snd_cs46xx_playback_transfer(substream); | 794 | snd_cs46xx_playback_transfer(substream); |
795 | { unsigned int tmp; | 795 | { unsigned int tmp; |
796 | tmp = snd_cs46xx_peek(chip, BA1_PCTL); | 796 | tmp = snd_cs46xx_peek(chip, BA1_PCTL); |
797 | tmp &= 0x0000ffff; | 797 | tmp &= 0x0000ffff; |
798 | snd_cs46xx_poke(chip, BA1_PCTL, chip->play_ctl | tmp); | 798 | snd_cs46xx_poke(chip, BA1_PCTL, chip->play_ctl | tmp); |
799 | } | 799 | } |
800 | spin_unlock(&chip->reg_lock); | 800 | spin_unlock(&chip->reg_lock); |
801 | #endif | 801 | #endif |
802 | break; | 802 | break; |
803 | case SNDRV_PCM_TRIGGER_STOP: | 803 | case SNDRV_PCM_TRIGGER_STOP: |
804 | case SNDRV_PCM_TRIGGER_SUSPEND: | 804 | case SNDRV_PCM_TRIGGER_SUSPEND: |
805 | #ifdef CONFIG_SND_CS46XX_NEW_DSP | 805 | #ifdef CONFIG_SND_CS46XX_NEW_DSP |
806 | /* magic mute channel */ | 806 | /* magic mute channel */ |
807 | snd_cs46xx_poke(chip, (cpcm->pcm_channel->pcm_reader_scb->address + | 807 | snd_cs46xx_poke(chip, (cpcm->pcm_channel->pcm_reader_scb->address + |
808 | SCBVolumeCtrl) << 2, 0xffffffff); | 808 | SCBVolumeCtrl) << 2, 0xffffffff); |
809 | 809 | ||
810 | if (!cpcm->pcm_channel->unlinked) | 810 | if (!cpcm->pcm_channel->unlinked) |
811 | cs46xx_dsp_pcm_unlink(chip,cpcm->pcm_channel); | 811 | cs46xx_dsp_pcm_unlink(chip,cpcm->pcm_channel); |
812 | #else | 812 | #else |
813 | spin_lock(&chip->reg_lock); | 813 | spin_lock(&chip->reg_lock); |
814 | { unsigned int tmp; | 814 | { unsigned int tmp; |
815 | tmp = snd_cs46xx_peek(chip, BA1_PCTL); | 815 | tmp = snd_cs46xx_peek(chip, BA1_PCTL); |
816 | tmp &= 0x0000ffff; | 816 | tmp &= 0x0000ffff; |
817 | snd_cs46xx_poke(chip, BA1_PCTL, tmp); | 817 | snd_cs46xx_poke(chip, BA1_PCTL, tmp); |
818 | } | 818 | } |
819 | spin_unlock(&chip->reg_lock); | 819 | spin_unlock(&chip->reg_lock); |
820 | #endif | 820 | #endif |
821 | break; | 821 | break; |
822 | default: | 822 | default: |
823 | result = -EINVAL; | 823 | result = -EINVAL; |
824 | break; | 824 | break; |
825 | } | 825 | } |
826 | 826 | ||
827 | return result; | 827 | return result; |
828 | } | 828 | } |
829 | 829 | ||
830 | static int snd_cs46xx_capture_trigger(struct snd_pcm_substream *substream, | 830 | static int snd_cs46xx_capture_trigger(struct snd_pcm_substream *substream, |
831 | int cmd) | 831 | int cmd) |
832 | { | 832 | { |
833 | struct snd_cs46xx *chip = snd_pcm_substream_chip(substream); | 833 | struct snd_cs46xx *chip = snd_pcm_substream_chip(substream); |
834 | unsigned int tmp; | 834 | unsigned int tmp; |
835 | int result = 0; | 835 | int result = 0; |
836 | 836 | ||
837 | spin_lock(&chip->reg_lock); | 837 | spin_lock(&chip->reg_lock); |
838 | switch (cmd) { | 838 | switch (cmd) { |
839 | case SNDRV_PCM_TRIGGER_START: | 839 | case SNDRV_PCM_TRIGGER_START: |
840 | case SNDRV_PCM_TRIGGER_RESUME: | 840 | case SNDRV_PCM_TRIGGER_RESUME: |
841 | tmp = snd_cs46xx_peek(chip, BA1_CCTL); | 841 | tmp = snd_cs46xx_peek(chip, BA1_CCTL); |
842 | tmp &= 0xffff0000; | 842 | tmp &= 0xffff0000; |
843 | snd_cs46xx_poke(chip, BA1_CCTL, chip->capt.ctl | tmp); | 843 | snd_cs46xx_poke(chip, BA1_CCTL, chip->capt.ctl | tmp); |
844 | break; | 844 | break; |
845 | case SNDRV_PCM_TRIGGER_STOP: | 845 | case SNDRV_PCM_TRIGGER_STOP: |
846 | case SNDRV_PCM_TRIGGER_SUSPEND: | 846 | case SNDRV_PCM_TRIGGER_SUSPEND: |
847 | tmp = snd_cs46xx_peek(chip, BA1_CCTL); | 847 | tmp = snd_cs46xx_peek(chip, BA1_CCTL); |
848 | tmp &= 0xffff0000; | 848 | tmp &= 0xffff0000; |
849 | snd_cs46xx_poke(chip, BA1_CCTL, tmp); | 849 | snd_cs46xx_poke(chip, BA1_CCTL, tmp); |
850 | break; | 850 | break; |
851 | default: | 851 | default: |
852 | result = -EINVAL; | 852 | result = -EINVAL; |
853 | break; | 853 | break; |
854 | } | 854 | } |
855 | spin_unlock(&chip->reg_lock); | 855 | spin_unlock(&chip->reg_lock); |
856 | 856 | ||
857 | return result; | 857 | return result; |
858 | } | 858 | } |
859 | 859 | ||
860 | #ifdef CONFIG_SND_CS46XX_NEW_DSP | 860 | #ifdef CONFIG_SND_CS46XX_NEW_DSP |
861 | static int _cs46xx_adjust_sample_rate (struct snd_cs46xx *chip, struct snd_cs46xx_pcm *cpcm, | 861 | static int _cs46xx_adjust_sample_rate (struct snd_cs46xx *chip, struct snd_cs46xx_pcm *cpcm, |
862 | int sample_rate) | 862 | int sample_rate) |
863 | { | 863 | { |
864 | 864 | ||
865 | /* If PCMReaderSCB and SrcTaskSCB not created yet ... */ | 865 | /* If PCMReaderSCB and SrcTaskSCB not created yet ... */ |
866 | if ( cpcm->pcm_channel == NULL) { | 866 | if ( cpcm->pcm_channel == NULL) { |
867 | cpcm->pcm_channel = cs46xx_dsp_create_pcm_channel (chip, sample_rate, | 867 | cpcm->pcm_channel = cs46xx_dsp_create_pcm_channel (chip, sample_rate, |
868 | cpcm, cpcm->hw_buf.addr,cpcm->pcm_channel_id); | 868 | cpcm, cpcm->hw_buf.addr,cpcm->pcm_channel_id); |
869 | if (cpcm->pcm_channel == NULL) { | 869 | if (cpcm->pcm_channel == NULL) { |
870 | snd_printk(KERN_ERR "cs46xx: failed to create virtual PCM channel\n"); | 870 | snd_printk(KERN_ERR "cs46xx: failed to create virtual PCM channel\n"); |
871 | return -ENOMEM; | 871 | return -ENOMEM; |
872 | } | 872 | } |
873 | cpcm->pcm_channel->sample_rate = sample_rate; | 873 | cpcm->pcm_channel->sample_rate = sample_rate; |
874 | } else | 874 | } else |
875 | /* if sample rate is changed */ | 875 | /* if sample rate is changed */ |
876 | if ((int)cpcm->pcm_channel->sample_rate != sample_rate) { | 876 | if ((int)cpcm->pcm_channel->sample_rate != sample_rate) { |
877 | int unlinked = cpcm->pcm_channel->unlinked; | 877 | int unlinked = cpcm->pcm_channel->unlinked; |
878 | cs46xx_dsp_destroy_pcm_channel (chip,cpcm->pcm_channel); | 878 | cs46xx_dsp_destroy_pcm_channel (chip,cpcm->pcm_channel); |
879 | 879 | ||
880 | if ( (cpcm->pcm_channel = cs46xx_dsp_create_pcm_channel (chip, sample_rate, cpcm, | 880 | if ( (cpcm->pcm_channel = cs46xx_dsp_create_pcm_channel (chip, sample_rate, cpcm, |
881 | cpcm->hw_buf.addr, | 881 | cpcm->hw_buf.addr, |
882 | cpcm->pcm_channel_id)) == NULL) { | 882 | cpcm->pcm_channel_id)) == NULL) { |
883 | snd_printk(KERN_ERR "cs46xx: failed to re-create virtual PCM channel\n"); | 883 | snd_printk(KERN_ERR "cs46xx: failed to re-create virtual PCM channel\n"); |
884 | return -ENOMEM; | 884 | return -ENOMEM; |
885 | } | 885 | } |
886 | 886 | ||
887 | if (!unlinked) cs46xx_dsp_pcm_link (chip,cpcm->pcm_channel); | 887 | if (!unlinked) cs46xx_dsp_pcm_link (chip,cpcm->pcm_channel); |
888 | cpcm->pcm_channel->sample_rate = sample_rate; | 888 | cpcm->pcm_channel->sample_rate = sample_rate; |
889 | } | 889 | } |
890 | 890 | ||
891 | return 0; | 891 | return 0; |
892 | } | 892 | } |
893 | #endif | 893 | #endif |
894 | 894 | ||
895 | 895 | ||
896 | static int snd_cs46xx_playback_hw_params(struct snd_pcm_substream *substream, | 896 | static int snd_cs46xx_playback_hw_params(struct snd_pcm_substream *substream, |
897 | struct snd_pcm_hw_params *hw_params) | 897 | struct snd_pcm_hw_params *hw_params) |
898 | { | 898 | { |
899 | struct snd_pcm_runtime *runtime = substream->runtime; | 899 | struct snd_pcm_runtime *runtime = substream->runtime; |
900 | struct snd_cs46xx_pcm *cpcm; | 900 | struct snd_cs46xx_pcm *cpcm; |
901 | int err; | 901 | int err; |
902 | #ifdef CONFIG_SND_CS46XX_NEW_DSP | 902 | #ifdef CONFIG_SND_CS46XX_NEW_DSP |
903 | struct snd_cs46xx *chip = snd_pcm_substream_chip(substream); | 903 | struct snd_cs46xx *chip = snd_pcm_substream_chip(substream); |
904 | int sample_rate = params_rate(hw_params); | 904 | int sample_rate = params_rate(hw_params); |
905 | int period_size = params_period_bytes(hw_params); | 905 | int period_size = params_period_bytes(hw_params); |
906 | #endif | 906 | #endif |
907 | cpcm = runtime->private_data; | 907 | cpcm = runtime->private_data; |
908 | 908 | ||
909 | #ifdef CONFIG_SND_CS46XX_NEW_DSP | 909 | #ifdef CONFIG_SND_CS46XX_NEW_DSP |
910 | snd_assert (sample_rate != 0, return -ENXIO); | 910 | snd_assert (sample_rate != 0, return -ENXIO); |
911 | 911 | ||
912 | down (&chip->spos_mutex); | 912 | down (&chip->spos_mutex); |
913 | 913 | ||
914 | if (_cs46xx_adjust_sample_rate (chip,cpcm,sample_rate)) { | 914 | if (_cs46xx_adjust_sample_rate (chip,cpcm,sample_rate)) { |
915 | up (&chip->spos_mutex); | 915 | up (&chip->spos_mutex); |
916 | return -ENXIO; | 916 | return -ENXIO; |
917 | } | 917 | } |
918 | 918 | ||
919 | snd_assert (cpcm->pcm_channel != NULL); | 919 | snd_assert (cpcm->pcm_channel != NULL); |
920 | if (!cpcm->pcm_channel) { | 920 | if (!cpcm->pcm_channel) { |
921 | up (&chip->spos_mutex); | 921 | up (&chip->spos_mutex); |
922 | return -ENXIO; | 922 | return -ENXIO; |
923 | } | 923 | } |
924 | 924 | ||
925 | 925 | ||
926 | if (cs46xx_dsp_pcm_channel_set_period (chip,cpcm->pcm_channel,period_size)) { | 926 | if (cs46xx_dsp_pcm_channel_set_period (chip,cpcm->pcm_channel,period_size)) { |
927 | up (&chip->spos_mutex); | 927 | up (&chip->spos_mutex); |
928 | return -EINVAL; | 928 | return -EINVAL; |
929 | } | 929 | } |
930 | 930 | ||
931 | snd_printdd ("period_size (%d), periods (%d) buffer_size(%d)\n", | 931 | snd_printdd ("period_size (%d), periods (%d) buffer_size(%d)\n", |
932 | period_size, params_periods(hw_params), | 932 | period_size, params_periods(hw_params), |
933 | params_buffer_bytes(hw_params)); | 933 | params_buffer_bytes(hw_params)); |
934 | #endif | 934 | #endif |
935 | 935 | ||
936 | if (params_periods(hw_params) == CS46XX_FRAGS) { | 936 | if (params_periods(hw_params) == CS46XX_FRAGS) { |
937 | if (runtime->dma_area != cpcm->hw_buf.area) | 937 | if (runtime->dma_area != cpcm->hw_buf.area) |
938 | snd_pcm_lib_free_pages(substream); | 938 | snd_pcm_lib_free_pages(substream); |
939 | runtime->dma_area = cpcm->hw_buf.area; | 939 | runtime->dma_area = cpcm->hw_buf.area; |
940 | runtime->dma_addr = cpcm->hw_buf.addr; | 940 | runtime->dma_addr = cpcm->hw_buf.addr; |
941 | runtime->dma_bytes = cpcm->hw_buf.bytes; | 941 | runtime->dma_bytes = cpcm->hw_buf.bytes; |
942 | 942 | ||
943 | 943 | ||
944 | #ifdef CONFIG_SND_CS46XX_NEW_DSP | 944 | #ifdef CONFIG_SND_CS46XX_NEW_DSP |
945 | if (cpcm->pcm_channel_id == DSP_PCM_MAIN_CHANNEL) { | 945 | if (cpcm->pcm_channel_id == DSP_PCM_MAIN_CHANNEL) { |
946 | substream->ops = &snd_cs46xx_playback_ops; | 946 | substream->ops = &snd_cs46xx_playback_ops; |
947 | } else if (cpcm->pcm_channel_id == DSP_PCM_REAR_CHANNEL) { | 947 | } else if (cpcm->pcm_channel_id == DSP_PCM_REAR_CHANNEL) { |
948 | substream->ops = &snd_cs46xx_playback_rear_ops; | 948 | substream->ops = &snd_cs46xx_playback_rear_ops; |
949 | } else if (cpcm->pcm_channel_id == DSP_PCM_CENTER_LFE_CHANNEL) { | 949 | } else if (cpcm->pcm_channel_id == DSP_PCM_CENTER_LFE_CHANNEL) { |
950 | substream->ops = &snd_cs46xx_playback_clfe_ops; | 950 | substream->ops = &snd_cs46xx_playback_clfe_ops; |
951 | } else if (cpcm->pcm_channel_id == DSP_IEC958_CHANNEL) { | 951 | } else if (cpcm->pcm_channel_id == DSP_IEC958_CHANNEL) { |
952 | substream->ops = &snd_cs46xx_playback_iec958_ops; | 952 | substream->ops = &snd_cs46xx_playback_iec958_ops; |
953 | } else { | 953 | } else { |
954 | snd_assert(0); | 954 | snd_assert(0); |
955 | } | 955 | } |
956 | #else | 956 | #else |
957 | substream->ops = &snd_cs46xx_playback_ops; | 957 | substream->ops = &snd_cs46xx_playback_ops; |
958 | #endif | 958 | #endif |
959 | 959 | ||
960 | } else { | 960 | } else { |
961 | if (runtime->dma_area == cpcm->hw_buf.area) { | 961 | if (runtime->dma_area == cpcm->hw_buf.area) { |
962 | runtime->dma_area = NULL; | 962 | runtime->dma_area = NULL; |
963 | runtime->dma_addr = 0; | 963 | runtime->dma_addr = 0; |
964 | runtime->dma_bytes = 0; | 964 | runtime->dma_bytes = 0; |
965 | } | 965 | } |
966 | if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0) { | 966 | if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0) { |
967 | #ifdef CONFIG_SND_CS46XX_NEW_DSP | 967 | #ifdef CONFIG_SND_CS46XX_NEW_DSP |
968 | up (&chip->spos_mutex); | 968 | up (&chip->spos_mutex); |
969 | #endif | 969 | #endif |
970 | return err; | 970 | return err; |
971 | } | 971 | } |
972 | 972 | ||
973 | #ifdef CONFIG_SND_CS46XX_NEW_DSP | 973 | #ifdef CONFIG_SND_CS46XX_NEW_DSP |
974 | if (cpcm->pcm_channel_id == DSP_PCM_MAIN_CHANNEL) { | 974 | if (cpcm->pcm_channel_id == DSP_PCM_MAIN_CHANNEL) { |
975 | substream->ops = &snd_cs46xx_playback_indirect_ops; | 975 | substream->ops = &snd_cs46xx_playback_indirect_ops; |
976 | } else if (cpcm->pcm_channel_id == DSP_PCM_REAR_CHANNEL) { | 976 | } else if (cpcm->pcm_channel_id == DSP_PCM_REAR_CHANNEL) { |
977 | substream->ops = &snd_cs46xx_playback_indirect_rear_ops; | 977 | substream->ops = &snd_cs46xx_playback_indirect_rear_ops; |
978 | } else if (cpcm->pcm_channel_id == DSP_PCM_CENTER_LFE_CHANNEL) { | 978 | } else if (cpcm->pcm_channel_id == DSP_PCM_CENTER_LFE_CHANNEL) { |
979 | substream->ops = &snd_cs46xx_playback_indirect_clfe_ops; | 979 | substream->ops = &snd_cs46xx_playback_indirect_clfe_ops; |
980 | } else if (cpcm->pcm_channel_id == DSP_IEC958_CHANNEL) { | 980 | } else if (cpcm->pcm_channel_id == DSP_IEC958_CHANNEL) { |
981 | substream->ops = &snd_cs46xx_playback_indirect_iec958_ops; | 981 | substream->ops = &snd_cs46xx_playback_indirect_iec958_ops; |
982 | } else { | 982 | } else { |
983 | snd_assert(0); | 983 | snd_assert(0); |
984 | } | 984 | } |
985 | #else | 985 | #else |
986 | substream->ops = &snd_cs46xx_playback_indirect_ops; | 986 | substream->ops = &snd_cs46xx_playback_indirect_ops; |
987 | #endif | 987 | #endif |
988 | 988 | ||
989 | } | 989 | } |
990 | 990 | ||
991 | #ifdef CONFIG_SND_CS46XX_NEW_DSP | 991 | #ifdef CONFIG_SND_CS46XX_NEW_DSP |
992 | up (&chip->spos_mutex); | 992 | up (&chip->spos_mutex); |
993 | #endif | 993 | #endif |
994 | 994 | ||
995 | return 0; | 995 | return 0; |
996 | } | 996 | } |
997 | 997 | ||
998 | static int snd_cs46xx_playback_hw_free(struct snd_pcm_substream *substream) | 998 | static int snd_cs46xx_playback_hw_free(struct snd_pcm_substream *substream) |
999 | { | 999 | { |
1000 | /*struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);*/ | 1000 | /*struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);*/ |
1001 | struct snd_pcm_runtime *runtime = substream->runtime; | 1001 | struct snd_pcm_runtime *runtime = substream->runtime; |
1002 | struct snd_cs46xx_pcm *cpcm; | 1002 | struct snd_cs46xx_pcm *cpcm; |
1003 | 1003 | ||
1004 | cpcm = runtime->private_data; | 1004 | cpcm = runtime->private_data; |
1005 | 1005 | ||
1006 | /* if play_back open fails, then this function | 1006 | /* if play_back open fails, then this function |
1007 | is called and cpcm can actually be NULL here */ | 1007 | is called and cpcm can actually be NULL here */ |
1008 | if (!cpcm) return -ENXIO; | 1008 | if (!cpcm) return -ENXIO; |
1009 | 1009 | ||
1010 | if (runtime->dma_area != cpcm->hw_buf.area) | 1010 | if (runtime->dma_area != cpcm->hw_buf.area) |
1011 | snd_pcm_lib_free_pages(substream); | 1011 | snd_pcm_lib_free_pages(substream); |
1012 | 1012 | ||
1013 | runtime->dma_area = NULL; | 1013 | runtime->dma_area = NULL; |
1014 | runtime->dma_addr = 0; | 1014 | runtime->dma_addr = 0; |
1015 | runtime->dma_bytes = 0; | 1015 | runtime->dma_bytes = 0; |
1016 | 1016 | ||
1017 | return 0; | 1017 | return 0; |
1018 | } | 1018 | } |
1019 | 1019 | ||
1020 | static int snd_cs46xx_playback_prepare(struct snd_pcm_substream *substream) | 1020 | static int snd_cs46xx_playback_prepare(struct snd_pcm_substream *substream) |
1021 | { | 1021 | { |
1022 | unsigned int tmp; | 1022 | unsigned int tmp; |
1023 | unsigned int pfie; | 1023 | unsigned int pfie; |
1024 | struct snd_cs46xx *chip = snd_pcm_substream_chip(substream); | 1024 | struct snd_cs46xx *chip = snd_pcm_substream_chip(substream); |
1025 | struct snd_pcm_runtime *runtime = substream->runtime; | 1025 | struct snd_pcm_runtime *runtime = substream->runtime; |
1026 | struct snd_cs46xx_pcm *cpcm; | 1026 | struct snd_cs46xx_pcm *cpcm; |
1027 | 1027 | ||
1028 | cpcm = runtime->private_data; | 1028 | cpcm = runtime->private_data; |
1029 | 1029 | ||
1030 | #ifdef CONFIG_SND_CS46XX_NEW_DSP | 1030 | #ifdef CONFIG_SND_CS46XX_NEW_DSP |
1031 | snd_assert (cpcm->pcm_channel != NULL, return -ENXIO); | 1031 | snd_assert (cpcm->pcm_channel != NULL, return -ENXIO); |
1032 | 1032 | ||
1033 | pfie = snd_cs46xx_peek(chip, (cpcm->pcm_channel->pcm_reader_scb->address + 1) << 2 ); | 1033 | pfie = snd_cs46xx_peek(chip, (cpcm->pcm_channel->pcm_reader_scb->address + 1) << 2 ); |
1034 | pfie &= ~0x0000f03f; | 1034 | pfie &= ~0x0000f03f; |
1035 | #else | 1035 | #else |
1036 | /* old dsp */ | 1036 | /* old dsp */ |
1037 | pfie = snd_cs46xx_peek(chip, BA1_PFIE); | 1037 | pfie = snd_cs46xx_peek(chip, BA1_PFIE); |
1038 | pfie &= ~0x0000f03f; | 1038 | pfie &= ~0x0000f03f; |
1039 | #endif | 1039 | #endif |
1040 | 1040 | ||
1041 | cpcm->shift = 2; | 1041 | cpcm->shift = 2; |
1042 | /* if to convert from stereo to mono */ | 1042 | /* if to convert from stereo to mono */ |
1043 | if (runtime->channels == 1) { | 1043 | if (runtime->channels == 1) { |
1044 | cpcm->shift--; | 1044 | cpcm->shift--; |
1045 | pfie |= 0x00002000; | 1045 | pfie |= 0x00002000; |
1046 | } | 1046 | } |
1047 | /* if to convert from 8 bit to 16 bit */ | 1047 | /* if to convert from 8 bit to 16 bit */ |
1048 | if (snd_pcm_format_width(runtime->format) == 8) { | 1048 | if (snd_pcm_format_width(runtime->format) == 8) { |
1049 | cpcm->shift--; | 1049 | cpcm->shift--; |
1050 | pfie |= 0x00001000; | 1050 | pfie |= 0x00001000; |
1051 | } | 1051 | } |
1052 | /* if to convert to unsigned */ | 1052 | /* if to convert to unsigned */ |
1053 | if (snd_pcm_format_unsigned(runtime->format)) | 1053 | if (snd_pcm_format_unsigned(runtime->format)) |
1054 | pfie |= 0x00008000; | 1054 | pfie |= 0x00008000; |
1055 | 1055 | ||
1056 | /* Never convert byte order when sample stream is 8 bit */ | 1056 | /* Never convert byte order when sample stream is 8 bit */ |
1057 | if (snd_pcm_format_width(runtime->format) != 8) { | 1057 | if (snd_pcm_format_width(runtime->format) != 8) { |
1058 | /* convert from big endian to little endian */ | 1058 | /* convert from big endian to little endian */ |
1059 | if (snd_pcm_format_big_endian(runtime->format)) | 1059 | if (snd_pcm_format_big_endian(runtime->format)) |
1060 | pfie |= 0x00004000; | 1060 | pfie |= 0x00004000; |
1061 | } | 1061 | } |
1062 | 1062 | ||
1063 | memset(&cpcm->pcm_rec, 0, sizeof(cpcm->pcm_rec)); | 1063 | memset(&cpcm->pcm_rec, 0, sizeof(cpcm->pcm_rec)); |
1064 | cpcm->pcm_rec.sw_buffer_size = snd_pcm_lib_buffer_bytes(substream); | 1064 | cpcm->pcm_rec.sw_buffer_size = snd_pcm_lib_buffer_bytes(substream); |
1065 | cpcm->pcm_rec.hw_buffer_size = runtime->period_size * CS46XX_FRAGS << cpcm->shift; | 1065 | cpcm->pcm_rec.hw_buffer_size = runtime->period_size * CS46XX_FRAGS << cpcm->shift; |
1066 | 1066 | ||
1067 | #ifdef CONFIG_SND_CS46XX_NEW_DSP | 1067 | #ifdef CONFIG_SND_CS46XX_NEW_DSP |
1068 | 1068 | ||
1069 | tmp = snd_cs46xx_peek(chip, (cpcm->pcm_channel->pcm_reader_scb->address) << 2); | 1069 | tmp = snd_cs46xx_peek(chip, (cpcm->pcm_channel->pcm_reader_scb->address) << 2); |
1070 | tmp &= ~0x000003ff; | 1070 | tmp &= ~0x000003ff; |
1071 | tmp |= (4 << cpcm->shift) - 1; | 1071 | tmp |= (4 << cpcm->shift) - 1; |
1072 | /* playback transaction count register */ | 1072 | /* playback transaction count register */ |
1073 | snd_cs46xx_poke(chip, (cpcm->pcm_channel->pcm_reader_scb->address) << 2, tmp); | 1073 | snd_cs46xx_poke(chip, (cpcm->pcm_channel->pcm_reader_scb->address) << 2, tmp); |
1074 | 1074 | ||
1075 | /* playback format && interrupt enable */ | 1075 | /* playback format && interrupt enable */ |
1076 | snd_cs46xx_poke(chip, (cpcm->pcm_channel->pcm_reader_scb->address + 1) << 2, pfie | cpcm->pcm_channel->pcm_slot); | 1076 | snd_cs46xx_poke(chip, (cpcm->pcm_channel->pcm_reader_scb->address + 1) << 2, pfie | cpcm->pcm_channel->pcm_slot); |
1077 | #else | 1077 | #else |
1078 | snd_cs46xx_poke(chip, BA1_PBA, cpcm->hw_buf.addr); | 1078 | snd_cs46xx_poke(chip, BA1_PBA, cpcm->hw_buf.addr); |
1079 | tmp = snd_cs46xx_peek(chip, BA1_PDTC); | 1079 | tmp = snd_cs46xx_peek(chip, BA1_PDTC); |
1080 | tmp &= ~0x000003ff; | 1080 | tmp &= ~0x000003ff; |
1081 | tmp |= (4 << cpcm->shift) - 1; | 1081 | tmp |= (4 << cpcm->shift) - 1; |
1082 | snd_cs46xx_poke(chip, BA1_PDTC, tmp); | 1082 | snd_cs46xx_poke(chip, BA1_PDTC, tmp); |
1083 | snd_cs46xx_poke(chip, BA1_PFIE, pfie); | 1083 | snd_cs46xx_poke(chip, BA1_PFIE, pfie); |
1084 | snd_cs46xx_set_play_sample_rate(chip, runtime->rate); | 1084 | snd_cs46xx_set_play_sample_rate(chip, runtime->rate); |
1085 | #endif | 1085 | #endif |
1086 | 1086 | ||
1087 | return 0; | 1087 | return 0; |
1088 | } | 1088 | } |
1089 | 1089 | ||
1090 | static int snd_cs46xx_capture_hw_params(struct snd_pcm_substream *substream, | 1090 | static int snd_cs46xx_capture_hw_params(struct snd_pcm_substream *substream, |
1091 | struct snd_pcm_hw_params *hw_params) | 1091 | struct snd_pcm_hw_params *hw_params) |
1092 | { | 1092 | { |
1093 | struct snd_cs46xx *chip = snd_pcm_substream_chip(substream); | 1093 | struct snd_cs46xx *chip = snd_pcm_substream_chip(substream); |
1094 | struct snd_pcm_runtime *runtime = substream->runtime; | 1094 | struct snd_pcm_runtime *runtime = substream->runtime; |
1095 | int err; | 1095 | int err; |
1096 | 1096 | ||
1097 | #ifdef CONFIG_SND_CS46XX_NEW_DSP | 1097 | #ifdef CONFIG_SND_CS46XX_NEW_DSP |
1098 | cs46xx_dsp_pcm_ostream_set_period (chip, params_period_bytes(hw_params)); | 1098 | cs46xx_dsp_pcm_ostream_set_period (chip, params_period_bytes(hw_params)); |
1099 | #endif | 1099 | #endif |
1100 | if (runtime->periods == CS46XX_FRAGS) { | 1100 | if (runtime->periods == CS46XX_FRAGS) { |
1101 | if (runtime->dma_area != chip->capt.hw_buf.area) | 1101 | if (runtime->dma_area != chip->capt.hw_buf.area) |
1102 | snd_pcm_lib_free_pages(substream); | 1102 | snd_pcm_lib_free_pages(substream); |
1103 | runtime->dma_area = chip->capt.hw_buf.area; | 1103 | runtime->dma_area = chip->capt.hw_buf.area; |
1104 | runtime->dma_addr = chip->capt.hw_buf.addr; | 1104 | runtime->dma_addr = chip->capt.hw_buf.addr; |
1105 | runtime->dma_bytes = chip->capt.hw_buf.bytes; | 1105 | runtime->dma_bytes = chip->capt.hw_buf.bytes; |
1106 | substream->ops = &snd_cs46xx_capture_ops; | 1106 | substream->ops = &snd_cs46xx_capture_ops; |
1107 | } else { | 1107 | } else { |
1108 | if (runtime->dma_area == chip->capt.hw_buf.area) { | 1108 | if (runtime->dma_area == chip->capt.hw_buf.area) { |
1109 | runtime->dma_area = NULL; | 1109 | runtime->dma_area = NULL; |
1110 | runtime->dma_addr = 0; | 1110 | runtime->dma_addr = 0; |
1111 | runtime->dma_bytes = 0; | 1111 | runtime->dma_bytes = 0; |
1112 | } | 1112 | } |
1113 | if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0) | 1113 | if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0) |
1114 | return err; | 1114 | return err; |
1115 | substream->ops = &snd_cs46xx_capture_indirect_ops; | 1115 | substream->ops = &snd_cs46xx_capture_indirect_ops; |
1116 | } | 1116 | } |
1117 | 1117 | ||
1118 | return 0; | 1118 | return 0; |
1119 | } | 1119 | } |
1120 | 1120 | ||
1121 | static int snd_cs46xx_capture_hw_free(struct snd_pcm_substream *substream) | 1121 | static int snd_cs46xx_capture_hw_free(struct snd_pcm_substream *substream) |
1122 | { | 1122 | { |
1123 | struct snd_cs46xx *chip = snd_pcm_substream_chip(substream); | 1123 | struct snd_cs46xx *chip = snd_pcm_substream_chip(substream); |
1124 | struct snd_pcm_runtime *runtime = substream->runtime; | 1124 | struct snd_pcm_runtime *runtime = substream->runtime; |
1125 | 1125 | ||
1126 | if (runtime->dma_area != chip->capt.hw_buf.area) | 1126 | if (runtime->dma_area != chip->capt.hw_buf.area) |
1127 | snd_pcm_lib_free_pages(substream); | 1127 | snd_pcm_lib_free_pages(substream); |
1128 | runtime->dma_area = NULL; | 1128 | runtime->dma_area = NULL; |
1129 | runtime->dma_addr = 0; | 1129 | runtime->dma_addr = 0; |
1130 | runtime->dma_bytes = 0; | 1130 | runtime->dma_bytes = 0; |
1131 | 1131 | ||
1132 | return 0; | 1132 | return 0; |
1133 | } | 1133 | } |
1134 | 1134 | ||
1135 | static int snd_cs46xx_capture_prepare(struct snd_pcm_substream *substream) | 1135 | static int snd_cs46xx_capture_prepare(struct snd_pcm_substream *substream) |
1136 | { | 1136 | { |
1137 | struct snd_cs46xx *chip = snd_pcm_substream_chip(substream); | 1137 | struct snd_cs46xx *chip = snd_pcm_substream_chip(substream); |
1138 | struct snd_pcm_runtime *runtime = substream->runtime; | 1138 | struct snd_pcm_runtime *runtime = substream->runtime; |
1139 | 1139 | ||
1140 | snd_cs46xx_poke(chip, BA1_CBA, chip->capt.hw_buf.addr); | 1140 | snd_cs46xx_poke(chip, BA1_CBA, chip->capt.hw_buf.addr); |
1141 | chip->capt.shift = 2; | 1141 | chip->capt.shift = 2; |
1142 | memset(&chip->capt.pcm_rec, 0, sizeof(chip->capt.pcm_rec)); | 1142 | memset(&chip->capt.pcm_rec, 0, sizeof(chip->capt.pcm_rec)); |
1143 | chip->capt.pcm_rec.sw_buffer_size = snd_pcm_lib_buffer_bytes(substream); | 1143 | chip->capt.pcm_rec.sw_buffer_size = snd_pcm_lib_buffer_bytes(substream); |
1144 | chip->capt.pcm_rec.hw_buffer_size = runtime->period_size * CS46XX_FRAGS << 2; | 1144 | chip->capt.pcm_rec.hw_buffer_size = runtime->period_size * CS46XX_FRAGS << 2; |
1145 | snd_cs46xx_set_capture_sample_rate(chip, runtime->rate); | 1145 | snd_cs46xx_set_capture_sample_rate(chip, runtime->rate); |
1146 | 1146 | ||
1147 | return 0; | 1147 | return 0; |
1148 | } | 1148 | } |
1149 | 1149 | ||
1150 | static irqreturn_t snd_cs46xx_interrupt(int irq, void *dev_id, struct pt_regs *regs) | 1150 | static irqreturn_t snd_cs46xx_interrupt(int irq, void *dev_id, struct pt_regs *regs) |
1151 | { | 1151 | { |
1152 | struct snd_cs46xx *chip = dev_id; | 1152 | struct snd_cs46xx *chip = dev_id; |
1153 | u32 status1; | 1153 | u32 status1; |
1154 | #ifdef CONFIG_SND_CS46XX_NEW_DSP | 1154 | #ifdef CONFIG_SND_CS46XX_NEW_DSP |
1155 | struct dsp_spos_instance * ins = chip->dsp_spos_instance; | 1155 | struct dsp_spos_instance * ins = chip->dsp_spos_instance; |
1156 | u32 status2; | 1156 | u32 status2; |
1157 | int i; | 1157 | int i; |
1158 | struct snd_cs46xx_pcm *cpcm = NULL; | 1158 | struct snd_cs46xx_pcm *cpcm = NULL; |
1159 | #endif | 1159 | #endif |
1160 | 1160 | ||
1161 | /* | 1161 | /* |
1162 | * Read the Interrupt Status Register to clear the interrupt | 1162 | * Read the Interrupt Status Register to clear the interrupt |
1163 | */ | 1163 | */ |
1164 | status1 = snd_cs46xx_peekBA0(chip, BA0_HISR); | 1164 | status1 = snd_cs46xx_peekBA0(chip, BA0_HISR); |
1165 | if ((status1 & 0x7fffffff) == 0) { | 1165 | if ((status1 & 0x7fffffff) == 0) { |
1166 | snd_cs46xx_pokeBA0(chip, BA0_HICR, HICR_CHGM | HICR_IEV); | 1166 | snd_cs46xx_pokeBA0(chip, BA0_HICR, HICR_CHGM | HICR_IEV); |
1167 | return IRQ_NONE; | 1167 | return IRQ_NONE; |
1168 | } | 1168 | } |
1169 | 1169 | ||
1170 | #ifdef CONFIG_SND_CS46XX_NEW_DSP | 1170 | #ifdef CONFIG_SND_CS46XX_NEW_DSP |
1171 | status2 = snd_cs46xx_peekBA0(chip, BA0_HSR0); | 1171 | status2 = snd_cs46xx_peekBA0(chip, BA0_HSR0); |
1172 | 1172 | ||
1173 | for (i = 0; i < DSP_MAX_PCM_CHANNELS; ++i) { | 1173 | for (i = 0; i < DSP_MAX_PCM_CHANNELS; ++i) { |
1174 | if (i <= 15) { | 1174 | if (i <= 15) { |
1175 | if ( status1 & (1 << i) ) { | 1175 | if ( status1 & (1 << i) ) { |
1176 | if (i == CS46XX_DSP_CAPTURE_CHANNEL) { | 1176 | if (i == CS46XX_DSP_CAPTURE_CHANNEL) { |
1177 | if (chip->capt.substream) | 1177 | if (chip->capt.substream) |
1178 | snd_pcm_period_elapsed(chip->capt.substream); | 1178 | snd_pcm_period_elapsed(chip->capt.substream); |
1179 | } else { | 1179 | } else { |
1180 | if (ins->pcm_channels[i].active && | 1180 | if (ins->pcm_channels[i].active && |
1181 | ins->pcm_channels[i].private_data && | 1181 | ins->pcm_channels[i].private_data && |
1182 | !ins->pcm_channels[i].unlinked) { | 1182 | !ins->pcm_channels[i].unlinked) { |
1183 | cpcm = ins->pcm_channels[i].private_data; | 1183 | cpcm = ins->pcm_channels[i].private_data; |
1184 | snd_pcm_period_elapsed(cpcm->substream); | 1184 | snd_pcm_period_elapsed(cpcm->substream); |
1185 | } | 1185 | } |
1186 | } | 1186 | } |
1187 | } | 1187 | } |
1188 | } else { | 1188 | } else { |
1189 | if ( status2 & (1 << (i - 16))) { | 1189 | if ( status2 & (1 << (i - 16))) { |
1190 | if (ins->pcm_channels[i].active && | 1190 | if (ins->pcm_channels[i].active && |
1191 | ins->pcm_channels[i].private_data && | 1191 | ins->pcm_channels[i].private_data && |
1192 | !ins->pcm_channels[i].unlinked) { | 1192 | !ins->pcm_channels[i].unlinked) { |
1193 | cpcm = ins->pcm_channels[i].private_data; | 1193 | cpcm = ins->pcm_channels[i].private_data; |
1194 | snd_pcm_period_elapsed(cpcm->substream); | 1194 | snd_pcm_period_elapsed(cpcm->substream); |
1195 | } | 1195 | } |
1196 | } | 1196 | } |
1197 | } | 1197 | } |
1198 | } | 1198 | } |
1199 | 1199 | ||
1200 | #else | 1200 | #else |
1201 | /* old dsp */ | 1201 | /* old dsp */ |
1202 | if ((status1 & HISR_VC0) && chip->playback_pcm) { | 1202 | if ((status1 & HISR_VC0) && chip->playback_pcm) { |
1203 | if (chip->playback_pcm->substream) | 1203 | if (chip->playback_pcm->substream) |
1204 | snd_pcm_period_elapsed(chip->playback_pcm->substream); | 1204 | snd_pcm_period_elapsed(chip->playback_pcm->substream); |
1205 | } | 1205 | } |
1206 | if ((status1 & HISR_VC1) && chip->pcm) { | 1206 | if ((status1 & HISR_VC1) && chip->pcm) { |
1207 | if (chip->capt.substream) | 1207 | if (chip->capt.substream) |
1208 | snd_pcm_period_elapsed(chip->capt.substream); | 1208 | snd_pcm_period_elapsed(chip->capt.substream); |
1209 | } | 1209 | } |
1210 | #endif | 1210 | #endif |
1211 | 1211 | ||
1212 | if ((status1 & HISR_MIDI) && chip->rmidi) { | 1212 | if ((status1 & HISR_MIDI) && chip->rmidi) { |
1213 | unsigned char c; | 1213 | unsigned char c; |
1214 | 1214 | ||
1215 | spin_lock(&chip->reg_lock); | 1215 | spin_lock(&chip->reg_lock); |
1216 | while ((snd_cs46xx_peekBA0(chip, BA0_MIDSR) & MIDSR_RBE) == 0) { | 1216 | while ((snd_cs46xx_peekBA0(chip, BA0_MIDSR) & MIDSR_RBE) == 0) { |
1217 | c = snd_cs46xx_peekBA0(chip, BA0_MIDRP); | 1217 | c = snd_cs46xx_peekBA0(chip, BA0_MIDRP); |
1218 | if ((chip->midcr & MIDCR_RIE) == 0) | 1218 | if ((chip->midcr & MIDCR_RIE) == 0) |
1219 | continue; | 1219 | continue; |
1220 | snd_rawmidi_receive(chip->midi_input, &c, 1); | 1220 | snd_rawmidi_receive(chip->midi_input, &c, 1); |
1221 | } | 1221 | } |
1222 | while ((snd_cs46xx_peekBA0(chip, BA0_MIDSR) & MIDSR_TBF) == 0) { | 1222 | while ((snd_cs46xx_peekBA0(chip, BA0_MIDSR) & MIDSR_TBF) == 0) { |
1223 | if ((chip->midcr & MIDCR_TIE) == 0) | 1223 | if ((chip->midcr & MIDCR_TIE) == 0) |
1224 | break; | 1224 | break; |
1225 | if (snd_rawmidi_transmit(chip->midi_output, &c, 1) != 1) { | 1225 | if (snd_rawmidi_transmit(chip->midi_output, &c, 1) != 1) { |
1226 | chip->midcr &= ~MIDCR_TIE; | 1226 | chip->midcr &= ~MIDCR_TIE; |
1227 | snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr); | 1227 | snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr); |
1228 | break; | 1228 | break; |
1229 | } | 1229 | } |
1230 | snd_cs46xx_pokeBA0(chip, BA0_MIDWP, c); | 1230 | snd_cs46xx_pokeBA0(chip, BA0_MIDWP, c); |
1231 | } | 1231 | } |
1232 | spin_unlock(&chip->reg_lock); | 1232 | spin_unlock(&chip->reg_lock); |
1233 | } | 1233 | } |
1234 | /* | 1234 | /* |
1235 | * EOI to the PCI part....reenables interrupts | 1235 | * EOI to the PCI part....reenables interrupts |
1236 | */ | 1236 | */ |
1237 | snd_cs46xx_pokeBA0(chip, BA0_HICR, HICR_CHGM | HICR_IEV); | 1237 | snd_cs46xx_pokeBA0(chip, BA0_HICR, HICR_CHGM | HICR_IEV); |
1238 | 1238 | ||
1239 | return IRQ_HANDLED; | 1239 | return IRQ_HANDLED; |
1240 | } | 1240 | } |
1241 | 1241 | ||
1242 | static struct snd_pcm_hardware snd_cs46xx_playback = | 1242 | static struct snd_pcm_hardware snd_cs46xx_playback = |
1243 | { | 1243 | { |
1244 | .info = (SNDRV_PCM_INFO_MMAP | | 1244 | .info = (SNDRV_PCM_INFO_MMAP | |
1245 | SNDRV_PCM_INFO_INTERLEAVED | | 1245 | SNDRV_PCM_INFO_INTERLEAVED | |
1246 | SNDRV_PCM_INFO_BLOCK_TRANSFER /*|*/ | 1246 | SNDRV_PCM_INFO_BLOCK_TRANSFER /*|*/ |
1247 | /*SNDRV_PCM_INFO_RESUME*/), | 1247 | /*SNDRV_PCM_INFO_RESUME*/), |
1248 | .formats = (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 | | 1248 | .formats = (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 | |
1249 | SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE | | 1249 | SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE | |
1250 | SNDRV_PCM_FMTBIT_U16_LE | SNDRV_PCM_FMTBIT_U16_BE), | 1250 | SNDRV_PCM_FMTBIT_U16_LE | SNDRV_PCM_FMTBIT_U16_BE), |
1251 | .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000, | 1251 | .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000, |
1252 | .rate_min = 5500, | 1252 | .rate_min = 5500, |
1253 | .rate_max = 48000, | 1253 | .rate_max = 48000, |
1254 | .channels_min = 1, | 1254 | .channels_min = 1, |
1255 | .channels_max = 2, | 1255 | .channels_max = 2, |
1256 | .buffer_bytes_max = (256 * 1024), | 1256 | .buffer_bytes_max = (256 * 1024), |
1257 | .period_bytes_min = CS46XX_MIN_PERIOD_SIZE, | 1257 | .period_bytes_min = CS46XX_MIN_PERIOD_SIZE, |
1258 | .period_bytes_max = CS46XX_MAX_PERIOD_SIZE, | 1258 | .period_bytes_max = CS46XX_MAX_PERIOD_SIZE, |
1259 | .periods_min = CS46XX_FRAGS, | 1259 | .periods_min = CS46XX_FRAGS, |
1260 | .periods_max = 1024, | 1260 | .periods_max = 1024, |
1261 | .fifo_size = 0, | 1261 | .fifo_size = 0, |
1262 | }; | 1262 | }; |
1263 | 1263 | ||
1264 | static struct snd_pcm_hardware snd_cs46xx_capture = | 1264 | static struct snd_pcm_hardware snd_cs46xx_capture = |
1265 | { | 1265 | { |
1266 | .info = (SNDRV_PCM_INFO_MMAP | | 1266 | .info = (SNDRV_PCM_INFO_MMAP | |
1267 | SNDRV_PCM_INFO_INTERLEAVED | | 1267 | SNDRV_PCM_INFO_INTERLEAVED | |
1268 | SNDRV_PCM_INFO_BLOCK_TRANSFER /*|*/ | 1268 | SNDRV_PCM_INFO_BLOCK_TRANSFER /*|*/ |
1269 | /*SNDRV_PCM_INFO_RESUME*/), | 1269 | /*SNDRV_PCM_INFO_RESUME*/), |
1270 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | 1270 | .formats = SNDRV_PCM_FMTBIT_S16_LE, |
1271 | .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000, | 1271 | .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000, |
1272 | .rate_min = 5500, | 1272 | .rate_min = 5500, |
1273 | .rate_max = 48000, | 1273 | .rate_max = 48000, |
1274 | .channels_min = 2, | 1274 | .channels_min = 2, |
1275 | .channels_max = 2, | 1275 | .channels_max = 2, |
1276 | .buffer_bytes_max = (256 * 1024), | 1276 | .buffer_bytes_max = (256 * 1024), |
1277 | .period_bytes_min = CS46XX_MIN_PERIOD_SIZE, | 1277 | .period_bytes_min = CS46XX_MIN_PERIOD_SIZE, |
1278 | .period_bytes_max = CS46XX_MAX_PERIOD_SIZE, | 1278 | .period_bytes_max = CS46XX_MAX_PERIOD_SIZE, |
1279 | .periods_min = CS46XX_FRAGS, | 1279 | .periods_min = CS46XX_FRAGS, |
1280 | .periods_max = 1024, | 1280 | .periods_max = 1024, |
1281 | .fifo_size = 0, | 1281 | .fifo_size = 0, |
1282 | }; | 1282 | }; |
1283 | 1283 | ||
1284 | #ifdef CONFIG_SND_CS46XX_NEW_DSP | 1284 | #ifdef CONFIG_SND_CS46XX_NEW_DSP |
1285 | 1285 | ||
1286 | static unsigned int period_sizes[] = { 32, 64, 128, 256, 512, 1024, 2048 }; | 1286 | static unsigned int period_sizes[] = { 32, 64, 128, 256, 512, 1024, 2048 }; |
1287 | 1287 | ||
1288 | static struct snd_pcm_hw_constraint_list hw_constraints_period_sizes = { | 1288 | static struct snd_pcm_hw_constraint_list hw_constraints_period_sizes = { |
1289 | .count = ARRAY_SIZE(period_sizes), | 1289 | .count = ARRAY_SIZE(period_sizes), |
1290 | .list = period_sizes, | 1290 | .list = period_sizes, |
1291 | .mask = 0 | 1291 | .mask = 0 |
1292 | }; | 1292 | }; |
1293 | 1293 | ||
1294 | #endif | 1294 | #endif |
1295 | 1295 | ||
1296 | static void snd_cs46xx_pcm_free_substream(struct snd_pcm_runtime *runtime) | 1296 | static void snd_cs46xx_pcm_free_substream(struct snd_pcm_runtime *runtime) |
1297 | { | 1297 | { |
1298 | kfree(runtime->private_data); | 1298 | kfree(runtime->private_data); |
1299 | } | 1299 | } |
1300 | 1300 | ||
1301 | static int _cs46xx_playback_open_channel (struct snd_pcm_substream *substream,int pcm_channel_id) | 1301 | static int _cs46xx_playback_open_channel (struct snd_pcm_substream *substream,int pcm_channel_id) |
1302 | { | 1302 | { |
1303 | struct snd_cs46xx *chip = snd_pcm_substream_chip(substream); | 1303 | struct snd_cs46xx *chip = snd_pcm_substream_chip(substream); |
1304 | struct snd_cs46xx_pcm * cpcm; | 1304 | struct snd_cs46xx_pcm * cpcm; |
1305 | struct snd_pcm_runtime *runtime = substream->runtime; | 1305 | struct snd_pcm_runtime *runtime = substream->runtime; |
1306 | 1306 | ||
1307 | cpcm = kzalloc(sizeof(*cpcm), GFP_KERNEL); | 1307 | cpcm = kzalloc(sizeof(*cpcm), GFP_KERNEL); |
1308 | if (cpcm == NULL) | 1308 | if (cpcm == NULL) |
1309 | return -ENOMEM; | 1309 | return -ENOMEM; |
1310 | if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci), | 1310 | if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci), |
1311 | PAGE_SIZE, &cpcm->hw_buf) < 0) { | 1311 | PAGE_SIZE, &cpcm->hw_buf) < 0) { |
1312 | kfree(cpcm); | 1312 | kfree(cpcm); |
1313 | return -ENOMEM; | 1313 | return -ENOMEM; |
1314 | } | 1314 | } |
1315 | 1315 | ||
1316 | runtime->hw = snd_cs46xx_playback; | 1316 | runtime->hw = snd_cs46xx_playback; |
1317 | runtime->private_data = cpcm; | 1317 | runtime->private_data = cpcm; |
1318 | runtime->private_free = snd_cs46xx_pcm_free_substream; | 1318 | runtime->private_free = snd_cs46xx_pcm_free_substream; |
1319 | 1319 | ||
1320 | cpcm->substream = substream; | 1320 | cpcm->substream = substream; |
1321 | #ifdef CONFIG_SND_CS46XX_NEW_DSP | 1321 | #ifdef CONFIG_SND_CS46XX_NEW_DSP |
1322 | down (&chip->spos_mutex); | 1322 | down (&chip->spos_mutex); |
1323 | cpcm->pcm_channel = NULL; | 1323 | cpcm->pcm_channel = NULL; |
1324 | cpcm->pcm_channel_id = pcm_channel_id; | 1324 | cpcm->pcm_channel_id = pcm_channel_id; |
1325 | 1325 | ||
1326 | 1326 | ||
1327 | snd_pcm_hw_constraint_list(runtime, 0, | 1327 | snd_pcm_hw_constraint_list(runtime, 0, |
1328 | SNDRV_PCM_HW_PARAM_PERIOD_BYTES, | 1328 | SNDRV_PCM_HW_PARAM_PERIOD_BYTES, |
1329 | &hw_constraints_period_sizes); | 1329 | &hw_constraints_period_sizes); |
1330 | 1330 | ||
1331 | up (&chip->spos_mutex); | 1331 | up (&chip->spos_mutex); |
1332 | #else | 1332 | #else |
1333 | chip->playback_pcm = cpcm; /* HACK */ | 1333 | chip->playback_pcm = cpcm; /* HACK */ |
1334 | #endif | 1334 | #endif |
1335 | 1335 | ||
1336 | if (chip->accept_valid) | 1336 | if (chip->accept_valid) |
1337 | substream->runtime->hw.info |= SNDRV_PCM_INFO_MMAP_VALID; | 1337 | substream->runtime->hw.info |= SNDRV_PCM_INFO_MMAP_VALID; |
1338 | chip->active_ctrl(chip, 1); | 1338 | chip->active_ctrl(chip, 1); |
1339 | 1339 | ||
1340 | return 0; | 1340 | return 0; |
1341 | } | 1341 | } |
1342 | 1342 | ||
1343 | static int snd_cs46xx_playback_open(struct snd_pcm_substream *substream) | 1343 | static int snd_cs46xx_playback_open(struct snd_pcm_substream *substream) |
1344 | { | 1344 | { |
1345 | snd_printdd("open front channel\n"); | 1345 | snd_printdd("open front channel\n"); |
1346 | return _cs46xx_playback_open_channel(substream,DSP_PCM_MAIN_CHANNEL); | 1346 | return _cs46xx_playback_open_channel(substream,DSP_PCM_MAIN_CHANNEL); |
1347 | } | 1347 | } |
1348 | 1348 | ||
1349 | #ifdef CONFIG_SND_CS46XX_NEW_DSP | 1349 | #ifdef CONFIG_SND_CS46XX_NEW_DSP |
1350 | static int snd_cs46xx_playback_open_rear(struct snd_pcm_substream *substream) | 1350 | static int snd_cs46xx_playback_open_rear(struct snd_pcm_substream *substream) |
1351 | { | 1351 | { |
1352 | snd_printdd("open rear channel\n"); | 1352 | snd_printdd("open rear channel\n"); |
1353 | 1353 | ||
1354 | return _cs46xx_playback_open_channel(substream,DSP_PCM_REAR_CHANNEL); | 1354 | return _cs46xx_playback_open_channel(substream,DSP_PCM_REAR_CHANNEL); |
1355 | } | 1355 | } |
1356 | 1356 | ||
1357 | static int snd_cs46xx_playback_open_clfe(struct snd_pcm_substream *substream) | 1357 | static int snd_cs46xx_playback_open_clfe(struct snd_pcm_substream *substream) |
1358 | { | 1358 | { |
1359 | snd_printdd("open center - LFE channel\n"); | 1359 | snd_printdd("open center - LFE channel\n"); |
1360 | 1360 | ||
1361 | return _cs46xx_playback_open_channel(substream,DSP_PCM_CENTER_LFE_CHANNEL); | 1361 | return _cs46xx_playback_open_channel(substream,DSP_PCM_CENTER_LFE_CHANNEL); |
1362 | } | 1362 | } |
1363 | 1363 | ||
1364 | static int snd_cs46xx_playback_open_iec958(struct snd_pcm_substream *substream) | 1364 | static int snd_cs46xx_playback_open_iec958(struct snd_pcm_substream *substream) |
1365 | { | 1365 | { |
1366 | struct snd_cs46xx *chip = snd_pcm_substream_chip(substream); | 1366 | struct snd_cs46xx *chip = snd_pcm_substream_chip(substream); |
1367 | 1367 | ||
1368 | snd_printdd("open raw iec958 channel\n"); | 1368 | snd_printdd("open raw iec958 channel\n"); |
1369 | 1369 | ||
1370 | down (&chip->spos_mutex); | 1370 | down (&chip->spos_mutex); |
1371 | cs46xx_iec958_pre_open (chip); | 1371 | cs46xx_iec958_pre_open (chip); |
1372 | up (&chip->spos_mutex); | 1372 | up (&chip->spos_mutex); |
1373 | 1373 | ||
1374 | return _cs46xx_playback_open_channel(substream,DSP_IEC958_CHANNEL); | 1374 | return _cs46xx_playback_open_channel(substream,DSP_IEC958_CHANNEL); |
1375 | } | 1375 | } |
1376 | 1376 | ||
1377 | static int snd_cs46xx_playback_close(struct snd_pcm_substream *substream); | 1377 | static int snd_cs46xx_playback_close(struct snd_pcm_substream *substream); |
1378 | 1378 | ||
1379 | static int snd_cs46xx_playback_close_iec958(struct snd_pcm_substream *substream) | 1379 | static int snd_cs46xx_playback_close_iec958(struct snd_pcm_substream *substream) |
1380 | { | 1380 | { |
1381 | int err; | 1381 | int err; |
1382 | struct snd_cs46xx *chip = snd_pcm_substream_chip(substream); | 1382 | struct snd_cs46xx *chip = snd_pcm_substream_chip(substream); |
1383 | 1383 | ||
1384 | snd_printdd("close raw iec958 channel\n"); | 1384 | snd_printdd("close raw iec958 channel\n"); |
1385 | 1385 | ||
1386 | err = snd_cs46xx_playback_close(substream); | 1386 | err = snd_cs46xx_playback_close(substream); |
1387 | 1387 | ||
1388 | down (&chip->spos_mutex); | 1388 | down (&chip->spos_mutex); |
1389 | cs46xx_iec958_post_close (chip); | 1389 | cs46xx_iec958_post_close (chip); |
1390 | up (&chip->spos_mutex); | 1390 | up (&chip->spos_mutex); |
1391 | 1391 | ||
1392 | return err; | 1392 | return err; |
1393 | } | 1393 | } |
1394 | #endif | 1394 | #endif |
1395 | 1395 | ||
1396 | static int snd_cs46xx_capture_open(struct snd_pcm_substream *substream) | 1396 | static int snd_cs46xx_capture_open(struct snd_pcm_substream *substream) |
1397 | { | 1397 | { |
1398 | struct snd_cs46xx *chip = snd_pcm_substream_chip(substream); | 1398 | struct snd_cs46xx *chip = snd_pcm_substream_chip(substream); |
1399 | 1399 | ||
1400 | if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci), | 1400 | if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci), |
1401 | PAGE_SIZE, &chip->capt.hw_buf) < 0) | 1401 | PAGE_SIZE, &chip->capt.hw_buf) < 0) |
1402 | return -ENOMEM; | 1402 | return -ENOMEM; |
1403 | chip->capt.substream = substream; | 1403 | chip->capt.substream = substream; |
1404 | substream->runtime->hw = snd_cs46xx_capture; | 1404 | substream->runtime->hw = snd_cs46xx_capture; |
1405 | 1405 | ||
1406 | if (chip->accept_valid) | 1406 | if (chip->accept_valid) |
1407 | substream->runtime->hw.info |= SNDRV_PCM_INFO_MMAP_VALID; | 1407 | substream->runtime->hw.info |= SNDRV_PCM_INFO_MMAP_VALID; |
1408 | 1408 | ||
1409 | chip->active_ctrl(chip, 1); | 1409 | chip->active_ctrl(chip, 1); |
1410 | 1410 | ||
1411 | #ifdef CONFIG_SND_CS46XX_NEW_DSP | 1411 | #ifdef CONFIG_SND_CS46XX_NEW_DSP |
1412 | snd_pcm_hw_constraint_list(substream->runtime, 0, | 1412 | snd_pcm_hw_constraint_list(substream->runtime, 0, |
1413 | SNDRV_PCM_HW_PARAM_PERIOD_BYTES, | 1413 | SNDRV_PCM_HW_PARAM_PERIOD_BYTES, |
1414 | &hw_constraints_period_sizes); | 1414 | &hw_constraints_period_sizes); |
1415 | #endif | 1415 | #endif |
1416 | return 0; | 1416 | return 0; |
1417 | } | 1417 | } |
1418 | 1418 | ||
1419 | static int snd_cs46xx_playback_close(struct snd_pcm_substream *substream) | 1419 | static int snd_cs46xx_playback_close(struct snd_pcm_substream *substream) |
1420 | { | 1420 | { |
1421 | struct snd_cs46xx *chip = snd_pcm_substream_chip(substream); | 1421 | struct snd_cs46xx *chip = snd_pcm_substream_chip(substream); |
1422 | struct snd_pcm_runtime *runtime = substream->runtime; | 1422 | struct snd_pcm_runtime *runtime = substream->runtime; |
1423 | struct snd_cs46xx_pcm * cpcm; | 1423 | struct snd_cs46xx_pcm * cpcm; |
1424 | 1424 | ||
1425 | cpcm = runtime->private_data; | 1425 | cpcm = runtime->private_data; |
1426 | 1426 | ||
1427 | /* when playback_open fails, then cpcm can be NULL */ | 1427 | /* when playback_open fails, then cpcm can be NULL */ |
1428 | if (!cpcm) return -ENXIO; | 1428 | if (!cpcm) return -ENXIO; |
1429 | 1429 | ||
1430 | #ifdef CONFIG_SND_CS46XX_NEW_DSP | 1430 | #ifdef CONFIG_SND_CS46XX_NEW_DSP |
1431 | down (&chip->spos_mutex); | 1431 | down (&chip->spos_mutex); |
1432 | if (cpcm->pcm_channel) { | 1432 | if (cpcm->pcm_channel) { |
1433 | cs46xx_dsp_destroy_pcm_channel(chip,cpcm->pcm_channel); | 1433 | cs46xx_dsp_destroy_pcm_channel(chip,cpcm->pcm_channel); |
1434 | cpcm->pcm_channel = NULL; | 1434 | cpcm->pcm_channel = NULL; |
1435 | } | 1435 | } |
1436 | up (&chip->spos_mutex); | 1436 | up (&chip->spos_mutex); |
1437 | #else | 1437 | #else |
1438 | chip->playback_pcm = NULL; | 1438 | chip->playback_pcm = NULL; |
1439 | #endif | 1439 | #endif |
1440 | 1440 | ||
1441 | cpcm->substream = NULL; | 1441 | cpcm->substream = NULL; |
1442 | snd_dma_free_pages(&cpcm->hw_buf); | 1442 | snd_dma_free_pages(&cpcm->hw_buf); |
1443 | chip->active_ctrl(chip, -1); | 1443 | chip->active_ctrl(chip, -1); |
1444 | 1444 | ||
1445 | return 0; | 1445 | return 0; |
1446 | } | 1446 | } |
1447 | 1447 | ||
1448 | static int snd_cs46xx_capture_close(struct snd_pcm_substream *substream) | 1448 | static int snd_cs46xx_capture_close(struct snd_pcm_substream *substream) |
1449 | { | 1449 | { |
1450 | struct snd_cs46xx *chip = snd_pcm_substream_chip(substream); | 1450 | struct snd_cs46xx *chip = snd_pcm_substream_chip(substream); |
1451 | 1451 | ||
1452 | chip->capt.substream = NULL; | 1452 | chip->capt.substream = NULL; |
1453 | snd_dma_free_pages(&chip->capt.hw_buf); | 1453 | snd_dma_free_pages(&chip->capt.hw_buf); |
1454 | chip->active_ctrl(chip, -1); | 1454 | chip->active_ctrl(chip, -1); |
1455 | 1455 | ||
1456 | return 0; | 1456 | return 0; |
1457 | } | 1457 | } |
1458 | 1458 | ||
1459 | #ifdef CONFIG_SND_CS46XX_NEW_DSP | 1459 | #ifdef CONFIG_SND_CS46XX_NEW_DSP |
1460 | static struct snd_pcm_ops snd_cs46xx_playback_rear_ops = { | 1460 | static struct snd_pcm_ops snd_cs46xx_playback_rear_ops = { |
1461 | .open = snd_cs46xx_playback_open_rear, | 1461 | .open = snd_cs46xx_playback_open_rear, |
1462 | .close = snd_cs46xx_playback_close, | 1462 | .close = snd_cs46xx_playback_close, |
1463 | .ioctl = snd_pcm_lib_ioctl, | 1463 | .ioctl = snd_pcm_lib_ioctl, |
1464 | .hw_params = snd_cs46xx_playback_hw_params, | 1464 | .hw_params = snd_cs46xx_playback_hw_params, |
1465 | .hw_free = snd_cs46xx_playback_hw_free, | 1465 | .hw_free = snd_cs46xx_playback_hw_free, |
1466 | .prepare = snd_cs46xx_playback_prepare, | 1466 | .prepare = snd_cs46xx_playback_prepare, |
1467 | .trigger = snd_cs46xx_playback_trigger, | 1467 | .trigger = snd_cs46xx_playback_trigger, |
1468 | .pointer = snd_cs46xx_playback_direct_pointer, | 1468 | .pointer = snd_cs46xx_playback_direct_pointer, |
1469 | }; | 1469 | }; |
1470 | 1470 | ||
1471 | static struct snd_pcm_ops snd_cs46xx_playback_indirect_rear_ops = { | 1471 | static struct snd_pcm_ops snd_cs46xx_playback_indirect_rear_ops = { |
1472 | .open = snd_cs46xx_playback_open_rear, | 1472 | .open = snd_cs46xx_playback_open_rear, |
1473 | .close = snd_cs46xx_playback_close, | 1473 | .close = snd_cs46xx_playback_close, |
1474 | .ioctl = snd_pcm_lib_ioctl, | 1474 | .ioctl = snd_pcm_lib_ioctl, |
1475 | .hw_params = snd_cs46xx_playback_hw_params, | 1475 | .hw_params = snd_cs46xx_playback_hw_params, |
1476 | .hw_free = snd_cs46xx_playback_hw_free, | 1476 | .hw_free = snd_cs46xx_playback_hw_free, |
1477 | .prepare = snd_cs46xx_playback_prepare, | 1477 | .prepare = snd_cs46xx_playback_prepare, |
1478 | .trigger = snd_cs46xx_playback_trigger, | 1478 | .trigger = snd_cs46xx_playback_trigger, |
1479 | .pointer = snd_cs46xx_playback_indirect_pointer, | 1479 | .pointer = snd_cs46xx_playback_indirect_pointer, |
1480 | .ack = snd_cs46xx_playback_transfer, | 1480 | .ack = snd_cs46xx_playback_transfer, |
1481 | }; | 1481 | }; |
1482 | 1482 | ||
1483 | static struct snd_pcm_ops snd_cs46xx_playback_clfe_ops = { | 1483 | static struct snd_pcm_ops snd_cs46xx_playback_clfe_ops = { |
1484 | .open = snd_cs46xx_playback_open_clfe, | 1484 | .open = snd_cs46xx_playback_open_clfe, |
1485 | .close = snd_cs46xx_playback_close, | 1485 | .close = snd_cs46xx_playback_close, |
1486 | .ioctl = snd_pcm_lib_ioctl, | 1486 | .ioctl = snd_pcm_lib_ioctl, |
1487 | .hw_params = snd_cs46xx_playback_hw_params, | 1487 | .hw_params = snd_cs46xx_playback_hw_params, |
1488 | .hw_free = snd_cs46xx_playback_hw_free, | 1488 | .hw_free = snd_cs46xx_playback_hw_free, |
1489 | .prepare = snd_cs46xx_playback_prepare, | 1489 | .prepare = snd_cs46xx_playback_prepare, |
1490 | .trigger = snd_cs46xx_playback_trigger, | 1490 | .trigger = snd_cs46xx_playback_trigger, |
1491 | .pointer = snd_cs46xx_playback_direct_pointer, | 1491 | .pointer = snd_cs46xx_playback_direct_pointer, |
1492 | }; | 1492 | }; |
1493 | 1493 | ||
1494 | static struct snd_pcm_ops snd_cs46xx_playback_indirect_clfe_ops = { | 1494 | static struct snd_pcm_ops snd_cs46xx_playback_indirect_clfe_ops = { |
1495 | .open = snd_cs46xx_playback_open_clfe, | 1495 | .open = snd_cs46xx_playback_open_clfe, |
1496 | .close = snd_cs46xx_playback_close, | 1496 | .close = snd_cs46xx_playback_close, |
1497 | .ioctl = snd_pcm_lib_ioctl, | 1497 | .ioctl = snd_pcm_lib_ioctl, |
1498 | .hw_params = snd_cs46xx_playback_hw_params, | 1498 | .hw_params = snd_cs46xx_playback_hw_params, |
1499 | .hw_free = snd_cs46xx_playback_hw_free, | 1499 | .hw_free = snd_cs46xx_playback_hw_free, |
1500 | .prepare = snd_cs46xx_playback_prepare, | 1500 | .prepare = snd_cs46xx_playback_prepare, |
1501 | .trigger = snd_cs46xx_playback_trigger, | 1501 | .trigger = snd_cs46xx_playback_trigger, |
1502 | .pointer = snd_cs46xx_playback_indirect_pointer, | 1502 | .pointer = snd_cs46xx_playback_indirect_pointer, |
1503 | .ack = snd_cs46xx_playback_transfer, | 1503 | .ack = snd_cs46xx_playback_transfer, |
1504 | }; | 1504 | }; |
1505 | 1505 | ||
1506 | static struct snd_pcm_ops snd_cs46xx_playback_iec958_ops = { | 1506 | static struct snd_pcm_ops snd_cs46xx_playback_iec958_ops = { |
1507 | .open = snd_cs46xx_playback_open_iec958, | 1507 | .open = snd_cs46xx_playback_open_iec958, |
1508 | .close = snd_cs46xx_playback_close_iec958, | 1508 | .close = snd_cs46xx_playback_close_iec958, |
1509 | .ioctl = snd_pcm_lib_ioctl, | 1509 | .ioctl = snd_pcm_lib_ioctl, |
1510 | .hw_params = snd_cs46xx_playback_hw_params, | 1510 | .hw_params = snd_cs46xx_playback_hw_params, |
1511 | .hw_free = snd_cs46xx_playback_hw_free, | 1511 | .hw_free = snd_cs46xx_playback_hw_free, |
1512 | .prepare = snd_cs46xx_playback_prepare, | 1512 | .prepare = snd_cs46xx_playback_prepare, |
1513 | .trigger = snd_cs46xx_playback_trigger, | 1513 | .trigger = snd_cs46xx_playback_trigger, |
1514 | .pointer = snd_cs46xx_playback_direct_pointer, | 1514 | .pointer = snd_cs46xx_playback_direct_pointer, |
1515 | }; | 1515 | }; |
1516 | 1516 | ||
1517 | static struct snd_pcm_ops snd_cs46xx_playback_indirect_iec958_ops = { | 1517 | static struct snd_pcm_ops snd_cs46xx_playback_indirect_iec958_ops = { |
1518 | .open = snd_cs46xx_playback_open_iec958, | 1518 | .open = snd_cs46xx_playback_open_iec958, |
1519 | .close = snd_cs46xx_playback_close_iec958, | 1519 | .close = snd_cs46xx_playback_close_iec958, |
1520 | .ioctl = snd_pcm_lib_ioctl, | 1520 | .ioctl = snd_pcm_lib_ioctl, |
1521 | .hw_params = snd_cs46xx_playback_hw_params, | 1521 | .hw_params = snd_cs46xx_playback_hw_params, |
1522 | .hw_free = snd_cs46xx_playback_hw_free, | 1522 | .hw_free = snd_cs46xx_playback_hw_free, |
1523 | .prepare = snd_cs46xx_playback_prepare, | 1523 | .prepare = snd_cs46xx_playback_prepare, |
1524 | .trigger = snd_cs46xx_playback_trigger, | 1524 | .trigger = snd_cs46xx_playback_trigger, |
1525 | .pointer = snd_cs46xx_playback_indirect_pointer, | 1525 | .pointer = snd_cs46xx_playback_indirect_pointer, |
1526 | .ack = snd_cs46xx_playback_transfer, | 1526 | .ack = snd_cs46xx_playback_transfer, |
1527 | }; | 1527 | }; |
1528 | 1528 | ||
1529 | #endif | 1529 | #endif |
1530 | 1530 | ||
1531 | static struct snd_pcm_ops snd_cs46xx_playback_ops = { | 1531 | static struct snd_pcm_ops snd_cs46xx_playback_ops = { |
1532 | .open = snd_cs46xx_playback_open, | 1532 | .open = snd_cs46xx_playback_open, |
1533 | .close = snd_cs46xx_playback_close, | 1533 | .close = snd_cs46xx_playback_close, |
1534 | .ioctl = snd_pcm_lib_ioctl, | 1534 | .ioctl = snd_pcm_lib_ioctl, |
1535 | .hw_params = snd_cs46xx_playback_hw_params, | 1535 | .hw_params = snd_cs46xx_playback_hw_params, |
1536 | .hw_free = snd_cs46xx_playback_hw_free, | 1536 | .hw_free = snd_cs46xx_playback_hw_free, |
1537 | .prepare = snd_cs46xx_playback_prepare, | 1537 | .prepare = snd_cs46xx_playback_prepare, |
1538 | .trigger = snd_cs46xx_playback_trigger, | 1538 | .trigger = snd_cs46xx_playback_trigger, |
1539 | .pointer = snd_cs46xx_playback_direct_pointer, | 1539 | .pointer = snd_cs46xx_playback_direct_pointer, |
1540 | }; | 1540 | }; |
1541 | 1541 | ||
1542 | static struct snd_pcm_ops snd_cs46xx_playback_indirect_ops = { | 1542 | static struct snd_pcm_ops snd_cs46xx_playback_indirect_ops = { |
1543 | .open = snd_cs46xx_playback_open, | 1543 | .open = snd_cs46xx_playback_open, |
1544 | .close = snd_cs46xx_playback_close, | 1544 | .close = snd_cs46xx_playback_close, |
1545 | .ioctl = snd_pcm_lib_ioctl, | 1545 | .ioctl = snd_pcm_lib_ioctl, |
1546 | .hw_params = snd_cs46xx_playback_hw_params, | 1546 | .hw_params = snd_cs46xx_playback_hw_params, |
1547 | .hw_free = snd_cs46xx_playback_hw_free, | 1547 | .hw_free = snd_cs46xx_playback_hw_free, |
1548 | .prepare = snd_cs46xx_playback_prepare, | 1548 | .prepare = snd_cs46xx_playback_prepare, |
1549 | .trigger = snd_cs46xx_playback_trigger, | 1549 | .trigger = snd_cs46xx_playback_trigger, |
1550 | .pointer = snd_cs46xx_playback_indirect_pointer, | 1550 | .pointer = snd_cs46xx_playback_indirect_pointer, |
1551 | .ack = snd_cs46xx_playback_transfer, | 1551 | .ack = snd_cs46xx_playback_transfer, |
1552 | }; | 1552 | }; |
1553 | 1553 | ||
1554 | static struct snd_pcm_ops snd_cs46xx_capture_ops = { | 1554 | static struct snd_pcm_ops snd_cs46xx_capture_ops = { |
1555 | .open = snd_cs46xx_capture_open, | 1555 | .open = snd_cs46xx_capture_open, |
1556 | .close = snd_cs46xx_capture_close, | 1556 | .close = snd_cs46xx_capture_close, |
1557 | .ioctl = snd_pcm_lib_ioctl, | 1557 | .ioctl = snd_pcm_lib_ioctl, |
1558 | .hw_params = snd_cs46xx_capture_hw_params, | 1558 | .hw_params = snd_cs46xx_capture_hw_params, |
1559 | .hw_free = snd_cs46xx_capture_hw_free, | 1559 | .hw_free = snd_cs46xx_capture_hw_free, |
1560 | .prepare = snd_cs46xx_capture_prepare, | 1560 | .prepare = snd_cs46xx_capture_prepare, |
1561 | .trigger = snd_cs46xx_capture_trigger, | 1561 | .trigger = snd_cs46xx_capture_trigger, |
1562 | .pointer = snd_cs46xx_capture_direct_pointer, | 1562 | .pointer = snd_cs46xx_capture_direct_pointer, |
1563 | }; | 1563 | }; |
1564 | 1564 | ||
1565 | static struct snd_pcm_ops snd_cs46xx_capture_indirect_ops = { | 1565 | static struct snd_pcm_ops snd_cs46xx_capture_indirect_ops = { |
1566 | .open = snd_cs46xx_capture_open, | 1566 | .open = snd_cs46xx_capture_open, |
1567 | .close = snd_cs46xx_capture_close, | 1567 | .close = snd_cs46xx_capture_close, |
1568 | .ioctl = snd_pcm_lib_ioctl, | 1568 | .ioctl = snd_pcm_lib_ioctl, |
1569 | .hw_params = snd_cs46xx_capture_hw_params, | 1569 | .hw_params = snd_cs46xx_capture_hw_params, |
1570 | .hw_free = snd_cs46xx_capture_hw_free, | 1570 | .hw_free = snd_cs46xx_capture_hw_free, |
1571 | .prepare = snd_cs46xx_capture_prepare, | 1571 | .prepare = snd_cs46xx_capture_prepare, |
1572 | .trigger = snd_cs46xx_capture_trigger, | 1572 | .trigger = snd_cs46xx_capture_trigger, |
1573 | .pointer = snd_cs46xx_capture_indirect_pointer, | 1573 | .pointer = snd_cs46xx_capture_indirect_pointer, |
1574 | .ack = snd_cs46xx_capture_transfer, | 1574 | .ack = snd_cs46xx_capture_transfer, |
1575 | }; | 1575 | }; |
1576 | 1576 | ||
1577 | #ifdef CONFIG_SND_CS46XX_NEW_DSP | 1577 | #ifdef CONFIG_SND_CS46XX_NEW_DSP |
1578 | #define MAX_PLAYBACK_CHANNELS (DSP_MAX_PCM_CHANNELS - 1) | 1578 | #define MAX_PLAYBACK_CHANNELS (DSP_MAX_PCM_CHANNELS - 1) |
1579 | #else | 1579 | #else |
1580 | #define MAX_PLAYBACK_CHANNELS 1 | 1580 | #define MAX_PLAYBACK_CHANNELS 1 |
1581 | #endif | 1581 | #endif |
1582 | 1582 | ||
1583 | int __devinit snd_cs46xx_pcm(struct snd_cs46xx *chip, int device, struct snd_pcm ** rpcm) | 1583 | int __devinit snd_cs46xx_pcm(struct snd_cs46xx *chip, int device, struct snd_pcm ** rpcm) |
1584 | { | 1584 | { |
1585 | struct snd_pcm *pcm; | 1585 | struct snd_pcm *pcm; |
1586 | int err; | 1586 | int err; |
1587 | 1587 | ||
1588 | if (rpcm) | 1588 | if (rpcm) |
1589 | *rpcm = NULL; | 1589 | *rpcm = NULL; |
1590 | if ((err = snd_pcm_new(chip->card, "CS46xx", device, MAX_PLAYBACK_CHANNELS, 1, &pcm)) < 0) | 1590 | if ((err = snd_pcm_new(chip->card, "CS46xx", device, MAX_PLAYBACK_CHANNELS, 1, &pcm)) < 0) |
1591 | return err; | 1591 | return err; |
1592 | 1592 | ||
1593 | pcm->private_data = chip; | 1593 | pcm->private_data = chip; |
1594 | 1594 | ||
1595 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_cs46xx_playback_ops); | 1595 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_cs46xx_playback_ops); |
1596 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_cs46xx_capture_ops); | 1596 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_cs46xx_capture_ops); |
1597 | 1597 | ||
1598 | /* global setup */ | 1598 | /* global setup */ |
1599 | pcm->info_flags = 0; | 1599 | pcm->info_flags = 0; |
1600 | strcpy(pcm->name, "CS46xx"); | 1600 | strcpy(pcm->name, "CS46xx"); |
1601 | chip->pcm = pcm; | 1601 | chip->pcm = pcm; |
1602 | 1602 | ||
1603 | snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, | 1603 | snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, |
1604 | snd_dma_pci_data(chip->pci), 64*1024, 256*1024); | 1604 | snd_dma_pci_data(chip->pci), 64*1024, 256*1024); |
1605 | 1605 | ||
1606 | if (rpcm) | 1606 | if (rpcm) |
1607 | *rpcm = pcm; | 1607 | *rpcm = pcm; |
1608 | 1608 | ||
1609 | return 0; | 1609 | return 0; |
1610 | } | 1610 | } |
1611 | 1611 | ||
1612 | 1612 | ||
1613 | #ifdef CONFIG_SND_CS46XX_NEW_DSP | 1613 | #ifdef CONFIG_SND_CS46XX_NEW_DSP |
1614 | int __devinit snd_cs46xx_pcm_rear(struct snd_cs46xx *chip, int device, struct snd_pcm ** rpcm) | 1614 | int __devinit snd_cs46xx_pcm_rear(struct snd_cs46xx *chip, int device, struct snd_pcm ** rpcm) |
1615 | { | 1615 | { |
1616 | struct snd_pcm *pcm; | 1616 | struct snd_pcm *pcm; |
1617 | int err; | 1617 | int err; |
1618 | 1618 | ||
1619 | if (rpcm) | 1619 | if (rpcm) |
1620 | *rpcm = NULL; | 1620 | *rpcm = NULL; |
1621 | 1621 | ||
1622 | if ((err = snd_pcm_new(chip->card, "CS46xx - Rear", device, MAX_PLAYBACK_CHANNELS, 0, &pcm)) < 0) | 1622 | if ((err = snd_pcm_new(chip->card, "CS46xx - Rear", device, MAX_PLAYBACK_CHANNELS, 0, &pcm)) < 0) |
1623 | return err; | 1623 | return err; |
1624 | 1624 | ||
1625 | pcm->private_data = chip; | 1625 | pcm->private_data = chip; |
1626 | 1626 | ||
1627 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_cs46xx_playback_rear_ops); | 1627 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_cs46xx_playback_rear_ops); |
1628 | 1628 | ||
1629 | /* global setup */ | 1629 | /* global setup */ |
1630 | pcm->info_flags = 0; | 1630 | pcm->info_flags = 0; |
1631 | strcpy(pcm->name, "CS46xx - Rear"); | 1631 | strcpy(pcm->name, "CS46xx - Rear"); |
1632 | chip->pcm_rear = pcm; | 1632 | chip->pcm_rear = pcm; |
1633 | 1633 | ||
1634 | snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, | 1634 | snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, |
1635 | snd_dma_pci_data(chip->pci), 64*1024, 256*1024); | 1635 | snd_dma_pci_data(chip->pci), 64*1024, 256*1024); |
1636 | 1636 | ||
1637 | if (rpcm) | 1637 | if (rpcm) |
1638 | *rpcm = pcm; | 1638 | *rpcm = pcm; |
1639 | 1639 | ||
1640 | return 0; | 1640 | return 0; |
1641 | } | 1641 | } |
1642 | 1642 | ||
1643 | int __devinit snd_cs46xx_pcm_center_lfe(struct snd_cs46xx *chip, int device, struct snd_pcm ** rpcm) | 1643 | int __devinit snd_cs46xx_pcm_center_lfe(struct snd_cs46xx *chip, int device, struct snd_pcm ** rpcm) |
1644 | { | 1644 | { |
1645 | struct snd_pcm *pcm; | 1645 | struct snd_pcm *pcm; |
1646 | int err; | 1646 | int err; |
1647 | 1647 | ||
1648 | if (rpcm) | 1648 | if (rpcm) |
1649 | *rpcm = NULL; | 1649 | *rpcm = NULL; |
1650 | 1650 | ||
1651 | if ((err = snd_pcm_new(chip->card, "CS46xx - Center LFE", device, MAX_PLAYBACK_CHANNELS, 0, &pcm)) < 0) | 1651 | if ((err = snd_pcm_new(chip->card, "CS46xx - Center LFE", device, MAX_PLAYBACK_CHANNELS, 0, &pcm)) < 0) |
1652 | return err; | 1652 | return err; |
1653 | 1653 | ||
1654 | pcm->private_data = chip; | 1654 | pcm->private_data = chip; |
1655 | 1655 | ||
1656 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_cs46xx_playback_clfe_ops); | 1656 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_cs46xx_playback_clfe_ops); |
1657 | 1657 | ||
1658 | /* global setup */ | 1658 | /* global setup */ |
1659 | pcm->info_flags = 0; | 1659 | pcm->info_flags = 0; |
1660 | strcpy(pcm->name, "CS46xx - Center LFE"); | 1660 | strcpy(pcm->name, "CS46xx - Center LFE"); |
1661 | chip->pcm_center_lfe = pcm; | 1661 | chip->pcm_center_lfe = pcm; |
1662 | 1662 | ||
1663 | snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, | 1663 | snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, |
1664 | snd_dma_pci_data(chip->pci), 64*1024, 256*1024); | 1664 | snd_dma_pci_data(chip->pci), 64*1024, 256*1024); |
1665 | 1665 | ||
1666 | if (rpcm) | 1666 | if (rpcm) |
1667 | *rpcm = pcm; | 1667 | *rpcm = pcm; |
1668 | 1668 | ||
1669 | return 0; | 1669 | return 0; |
1670 | } | 1670 | } |
1671 | 1671 | ||
1672 | int __devinit snd_cs46xx_pcm_iec958(struct snd_cs46xx *chip, int device, struct snd_pcm ** rpcm) | 1672 | int __devinit snd_cs46xx_pcm_iec958(struct snd_cs46xx *chip, int device, struct snd_pcm ** rpcm) |
1673 | { | 1673 | { |
1674 | struct snd_pcm *pcm; | 1674 | struct snd_pcm *pcm; |
1675 | int err; | 1675 | int err; |
1676 | 1676 | ||
1677 | if (rpcm) | 1677 | if (rpcm) |
1678 | *rpcm = NULL; | 1678 | *rpcm = NULL; |
1679 | 1679 | ||
1680 | if ((err = snd_pcm_new(chip->card, "CS46xx - IEC958", device, 1, 0, &pcm)) < 0) | 1680 | if ((err = snd_pcm_new(chip->card, "CS46xx - IEC958", device, 1, 0, &pcm)) < 0) |
1681 | return err; | 1681 | return err; |
1682 | 1682 | ||
1683 | pcm->private_data = chip; | 1683 | pcm->private_data = chip; |
1684 | 1684 | ||
1685 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_cs46xx_playback_iec958_ops); | 1685 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_cs46xx_playback_iec958_ops); |
1686 | 1686 | ||
1687 | /* global setup */ | 1687 | /* global setup */ |
1688 | pcm->info_flags = 0; | 1688 | pcm->info_flags = 0; |
1689 | strcpy(pcm->name, "CS46xx - IEC958"); | 1689 | strcpy(pcm->name, "CS46xx - IEC958"); |
1690 | chip->pcm_rear = pcm; | 1690 | chip->pcm_rear = pcm; |
1691 | 1691 | ||
1692 | snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, | 1692 | snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, |
1693 | snd_dma_pci_data(chip->pci), 64*1024, 256*1024); | 1693 | snd_dma_pci_data(chip->pci), 64*1024, 256*1024); |
1694 | 1694 | ||
1695 | if (rpcm) | 1695 | if (rpcm) |
1696 | *rpcm = pcm; | 1696 | *rpcm = pcm; |
1697 | 1697 | ||
1698 | return 0; | 1698 | return 0; |
1699 | } | 1699 | } |
1700 | #endif | 1700 | #endif |
1701 | 1701 | ||
1702 | /* | 1702 | /* |
1703 | * Mixer routines | 1703 | * Mixer routines |
1704 | */ | 1704 | */ |
1705 | static void snd_cs46xx_mixer_free_ac97_bus(struct snd_ac97_bus *bus) | 1705 | static void snd_cs46xx_mixer_free_ac97_bus(struct snd_ac97_bus *bus) |
1706 | { | 1706 | { |
1707 | struct snd_cs46xx *chip = bus->private_data; | 1707 | struct snd_cs46xx *chip = bus->private_data; |
1708 | 1708 | ||
1709 | chip->ac97_bus = NULL; | 1709 | chip->ac97_bus = NULL; |
1710 | } | 1710 | } |
1711 | 1711 | ||
1712 | static void snd_cs46xx_mixer_free_ac97(struct snd_ac97 *ac97) | 1712 | static void snd_cs46xx_mixer_free_ac97(struct snd_ac97 *ac97) |
1713 | { | 1713 | { |
1714 | struct snd_cs46xx *chip = ac97->private_data; | 1714 | struct snd_cs46xx *chip = ac97->private_data; |
1715 | 1715 | ||
1716 | snd_assert ((ac97 == chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]) || | 1716 | snd_assert ((ac97 == chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]) || |
1717 | (ac97 == chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]), | 1717 | (ac97 == chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]), |
1718 | return); | 1718 | return); |
1719 | 1719 | ||
1720 | if (ac97 == chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]) { | 1720 | if (ac97 == chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]) { |
1721 | chip->ac97[CS46XX_PRIMARY_CODEC_INDEX] = NULL; | 1721 | chip->ac97[CS46XX_PRIMARY_CODEC_INDEX] = NULL; |
1722 | chip->eapd_switch = NULL; | 1722 | chip->eapd_switch = NULL; |
1723 | } | 1723 | } |
1724 | else | 1724 | else |
1725 | chip->ac97[CS46XX_SECONDARY_CODEC_INDEX] = NULL; | 1725 | chip->ac97[CS46XX_SECONDARY_CODEC_INDEX] = NULL; |
1726 | } | 1726 | } |
1727 | 1727 | ||
1728 | static int snd_cs46xx_vol_info(struct snd_kcontrol *kcontrol, | 1728 | static int snd_cs46xx_vol_info(struct snd_kcontrol *kcontrol, |
1729 | struct snd_ctl_elem_info *uinfo) | 1729 | struct snd_ctl_elem_info *uinfo) |
1730 | { | 1730 | { |
1731 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | 1731 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; |
1732 | uinfo->count = 2; | 1732 | uinfo->count = 2; |
1733 | uinfo->value.integer.min = 0; | 1733 | uinfo->value.integer.min = 0; |
1734 | uinfo->value.integer.max = 0x7fff; | 1734 | uinfo->value.integer.max = 0x7fff; |
1735 | return 0; | 1735 | return 0; |
1736 | } | 1736 | } |
1737 | 1737 | ||
1738 | static int snd_cs46xx_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 1738 | static int snd_cs46xx_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
1739 | { | 1739 | { |
1740 | struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol); | 1740 | struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol); |
1741 | int reg = kcontrol->private_value; | 1741 | int reg = kcontrol->private_value; |
1742 | unsigned int val = snd_cs46xx_peek(chip, reg); | 1742 | unsigned int val = snd_cs46xx_peek(chip, reg); |
1743 | ucontrol->value.integer.value[0] = 0xffff - (val >> 16); | 1743 | ucontrol->value.integer.value[0] = 0xffff - (val >> 16); |
1744 | ucontrol->value.integer.value[1] = 0xffff - (val & 0xffff); | 1744 | ucontrol->value.integer.value[1] = 0xffff - (val & 0xffff); |
1745 | return 0; | 1745 | return 0; |
1746 | } | 1746 | } |
1747 | 1747 | ||
1748 | static int snd_cs46xx_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 1748 | static int snd_cs46xx_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
1749 | { | 1749 | { |
1750 | struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol); | 1750 | struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol); |
1751 | int reg = kcontrol->private_value; | 1751 | int reg = kcontrol->private_value; |
1752 | unsigned int val = ((0xffff - ucontrol->value.integer.value[0]) << 16 | | 1752 | unsigned int val = ((0xffff - ucontrol->value.integer.value[0]) << 16 | |
1753 | (0xffff - ucontrol->value.integer.value[1])); | 1753 | (0xffff - ucontrol->value.integer.value[1])); |
1754 | unsigned int old = snd_cs46xx_peek(chip, reg); | 1754 | unsigned int old = snd_cs46xx_peek(chip, reg); |
1755 | int change = (old != val); | 1755 | int change = (old != val); |
1756 | 1756 | ||
1757 | if (change) { | 1757 | if (change) { |
1758 | snd_cs46xx_poke(chip, reg, val); | 1758 | snd_cs46xx_poke(chip, reg, val); |
1759 | } | 1759 | } |
1760 | 1760 | ||
1761 | return change; | 1761 | return change; |
1762 | } | 1762 | } |
1763 | 1763 | ||
1764 | #ifdef CONFIG_SND_CS46XX_NEW_DSP | 1764 | #ifdef CONFIG_SND_CS46XX_NEW_DSP |
1765 | 1765 | ||
1766 | static int snd_cs46xx_vol_dac_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 1766 | static int snd_cs46xx_vol_dac_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
1767 | { | 1767 | { |
1768 | struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol); | 1768 | struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol); |
1769 | 1769 | ||
1770 | ucontrol->value.integer.value[0] = chip->dsp_spos_instance->dac_volume_left; | 1770 | ucontrol->value.integer.value[0] = chip->dsp_spos_instance->dac_volume_left; |
1771 | ucontrol->value.integer.value[1] = chip->dsp_spos_instance->dac_volume_right; | 1771 | ucontrol->value.integer.value[1] = chip->dsp_spos_instance->dac_volume_right; |
1772 | 1772 | ||
1773 | return 0; | 1773 | return 0; |
1774 | } | 1774 | } |
1775 | 1775 | ||
1776 | static int snd_cs46xx_vol_dac_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 1776 | static int snd_cs46xx_vol_dac_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
1777 | { | 1777 | { |
1778 | struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol); | 1778 | struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol); |
1779 | int change = 0; | 1779 | int change = 0; |
1780 | 1780 | ||
1781 | if (chip->dsp_spos_instance->dac_volume_right != ucontrol->value.integer.value[0] || | 1781 | if (chip->dsp_spos_instance->dac_volume_right != ucontrol->value.integer.value[0] || |
1782 | chip->dsp_spos_instance->dac_volume_left != ucontrol->value.integer.value[1]) { | 1782 | chip->dsp_spos_instance->dac_volume_left != ucontrol->value.integer.value[1]) { |
1783 | cs46xx_dsp_set_dac_volume(chip, | 1783 | cs46xx_dsp_set_dac_volume(chip, |
1784 | ucontrol->value.integer.value[0], | 1784 | ucontrol->value.integer.value[0], |
1785 | ucontrol->value.integer.value[1]); | 1785 | ucontrol->value.integer.value[1]); |
1786 | change = 1; | 1786 | change = 1; |
1787 | } | 1787 | } |
1788 | 1788 | ||
1789 | return change; | 1789 | return change; |
1790 | } | 1790 | } |
1791 | 1791 | ||
1792 | #if 0 | 1792 | #if 0 |
1793 | static int snd_cs46xx_vol_iec958_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 1793 | static int snd_cs46xx_vol_iec958_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
1794 | { | 1794 | { |
1795 | struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol); | 1795 | struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol); |
1796 | 1796 | ||
1797 | ucontrol->value.integer.value[0] = chip->dsp_spos_instance->spdif_input_volume_left; | 1797 | ucontrol->value.integer.value[0] = chip->dsp_spos_instance->spdif_input_volume_left; |
1798 | ucontrol->value.integer.value[1] = chip->dsp_spos_instance->spdif_input_volume_right; | 1798 | ucontrol->value.integer.value[1] = chip->dsp_spos_instance->spdif_input_volume_right; |
1799 | return 0; | 1799 | return 0; |
1800 | } | 1800 | } |
1801 | 1801 | ||
1802 | static int snd_cs46xx_vol_iec958_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 1802 | static int snd_cs46xx_vol_iec958_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
1803 | { | 1803 | { |
1804 | struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol); | 1804 | struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol); |
1805 | int change = 0; | 1805 | int change = 0; |
1806 | 1806 | ||
1807 | if (chip->dsp_spos_instance->spdif_input_volume_left != ucontrol->value.integer.value[0] || | 1807 | if (chip->dsp_spos_instance->spdif_input_volume_left != ucontrol->value.integer.value[0] || |
1808 | chip->dsp_spos_instance->spdif_input_volume_right!= ucontrol->value.integer.value[1]) { | 1808 | chip->dsp_spos_instance->spdif_input_volume_right!= ucontrol->value.integer.value[1]) { |
1809 | cs46xx_dsp_set_iec958_volume (chip, | 1809 | cs46xx_dsp_set_iec958_volume (chip, |
1810 | ucontrol->value.integer.value[0], | 1810 | ucontrol->value.integer.value[0], |
1811 | ucontrol->value.integer.value[1]); | 1811 | ucontrol->value.integer.value[1]); |
1812 | change = 1; | 1812 | change = 1; |
1813 | } | 1813 | } |
1814 | 1814 | ||
1815 | return change; | 1815 | return change; |
1816 | } | 1816 | } |
1817 | #endif | 1817 | #endif |
1818 | 1818 | ||
1819 | static int snd_mixer_boolean_info(struct snd_kcontrol *kcontrol, | 1819 | static int snd_mixer_boolean_info(struct snd_kcontrol *kcontrol, |
1820 | struct snd_ctl_elem_info *uinfo) | 1820 | struct snd_ctl_elem_info *uinfo) |
1821 | { | 1821 | { |
1822 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; | 1822 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; |
1823 | uinfo->count = 1; | 1823 | uinfo->count = 1; |
1824 | uinfo->value.integer.min = 0; | 1824 | uinfo->value.integer.min = 0; |
1825 | uinfo->value.integer.max = 1; | 1825 | uinfo->value.integer.max = 1; |
1826 | return 0; | 1826 | return 0; |
1827 | } | 1827 | } |
1828 | 1828 | ||
1829 | static int snd_cs46xx_iec958_get(struct snd_kcontrol *kcontrol, | 1829 | static int snd_cs46xx_iec958_get(struct snd_kcontrol *kcontrol, |
1830 | struct snd_ctl_elem_value *ucontrol) | 1830 | struct snd_ctl_elem_value *ucontrol) |
1831 | { | 1831 | { |
1832 | struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol); | 1832 | struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol); |
1833 | int reg = kcontrol->private_value; | 1833 | int reg = kcontrol->private_value; |
1834 | 1834 | ||
1835 | if (reg == CS46XX_MIXER_SPDIF_OUTPUT_ELEMENT) | 1835 | if (reg == CS46XX_MIXER_SPDIF_OUTPUT_ELEMENT) |
1836 | ucontrol->value.integer.value[0] = (chip->dsp_spos_instance->spdif_status_out & DSP_SPDIF_STATUS_OUTPUT_ENABLED); | 1836 | ucontrol->value.integer.value[0] = (chip->dsp_spos_instance->spdif_status_out & DSP_SPDIF_STATUS_OUTPUT_ENABLED); |
1837 | else | 1837 | else |
1838 | ucontrol->value.integer.value[0] = chip->dsp_spos_instance->spdif_status_in; | 1838 | ucontrol->value.integer.value[0] = chip->dsp_spos_instance->spdif_status_in; |
1839 | 1839 | ||
1840 | return 0; | 1840 | return 0; |
1841 | } | 1841 | } |
1842 | 1842 | ||
1843 | static int snd_cs46xx_iec958_put(struct snd_kcontrol *kcontrol, | 1843 | static int snd_cs46xx_iec958_put(struct snd_kcontrol *kcontrol, |
1844 | struct snd_ctl_elem_value *ucontrol) | 1844 | struct snd_ctl_elem_value *ucontrol) |
1845 | { | 1845 | { |
1846 | struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol); | 1846 | struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol); |
1847 | int change, res; | 1847 | int change, res; |
1848 | 1848 | ||
1849 | switch (kcontrol->private_value) { | 1849 | switch (kcontrol->private_value) { |
1850 | case CS46XX_MIXER_SPDIF_OUTPUT_ELEMENT: | 1850 | case CS46XX_MIXER_SPDIF_OUTPUT_ELEMENT: |
1851 | down (&chip->spos_mutex); | 1851 | down (&chip->spos_mutex); |
1852 | change = (chip->dsp_spos_instance->spdif_status_out & DSP_SPDIF_STATUS_OUTPUT_ENABLED); | 1852 | change = (chip->dsp_spos_instance->spdif_status_out & DSP_SPDIF_STATUS_OUTPUT_ENABLED); |
1853 | if (ucontrol->value.integer.value[0] && !change) | 1853 | if (ucontrol->value.integer.value[0] && !change) |
1854 | cs46xx_dsp_enable_spdif_out(chip); | 1854 | cs46xx_dsp_enable_spdif_out(chip); |
1855 | else if (change && !ucontrol->value.integer.value[0]) | 1855 | else if (change && !ucontrol->value.integer.value[0]) |
1856 | cs46xx_dsp_disable_spdif_out(chip); | 1856 | cs46xx_dsp_disable_spdif_out(chip); |
1857 | 1857 | ||
1858 | res = (change != (chip->dsp_spos_instance->spdif_status_out & DSP_SPDIF_STATUS_OUTPUT_ENABLED)); | 1858 | res = (change != (chip->dsp_spos_instance->spdif_status_out & DSP_SPDIF_STATUS_OUTPUT_ENABLED)); |
1859 | up (&chip->spos_mutex); | 1859 | up (&chip->spos_mutex); |
1860 | break; | 1860 | break; |
1861 | case CS46XX_MIXER_SPDIF_INPUT_ELEMENT: | 1861 | case CS46XX_MIXER_SPDIF_INPUT_ELEMENT: |
1862 | change = chip->dsp_spos_instance->spdif_status_in; | 1862 | change = chip->dsp_spos_instance->spdif_status_in; |
1863 | if (ucontrol->value.integer.value[0] && !change) { | 1863 | if (ucontrol->value.integer.value[0] && !change) { |
1864 | cs46xx_dsp_enable_spdif_in(chip); | 1864 | cs46xx_dsp_enable_spdif_in(chip); |
1865 | /* restore volume */ | 1865 | /* restore volume */ |
1866 | } | 1866 | } |
1867 | else if (change && !ucontrol->value.integer.value[0]) | 1867 | else if (change && !ucontrol->value.integer.value[0]) |
1868 | cs46xx_dsp_disable_spdif_in(chip); | 1868 | cs46xx_dsp_disable_spdif_in(chip); |
1869 | 1869 | ||
1870 | res = (change != chip->dsp_spos_instance->spdif_status_in); | 1870 | res = (change != chip->dsp_spos_instance->spdif_status_in); |
1871 | break; | 1871 | break; |
1872 | default: | 1872 | default: |
1873 | res = -EINVAL; | 1873 | res = -EINVAL; |
1874 | snd_assert(0, (void)0); | 1874 | snd_assert(0, (void)0); |
1875 | } | 1875 | } |
1876 | 1876 | ||
1877 | return res; | 1877 | return res; |
1878 | } | 1878 | } |
1879 | 1879 | ||
1880 | static int snd_cs46xx_adc_capture_get(struct snd_kcontrol *kcontrol, | 1880 | static int snd_cs46xx_adc_capture_get(struct snd_kcontrol *kcontrol, |
1881 | struct snd_ctl_elem_value *ucontrol) | 1881 | struct snd_ctl_elem_value *ucontrol) |
1882 | { | 1882 | { |
1883 | struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol); | 1883 | struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol); |
1884 | struct dsp_spos_instance * ins = chip->dsp_spos_instance; | 1884 | struct dsp_spos_instance * ins = chip->dsp_spos_instance; |
1885 | 1885 | ||
1886 | if (ins->adc_input != NULL) | 1886 | if (ins->adc_input != NULL) |
1887 | ucontrol->value.integer.value[0] = 1; | 1887 | ucontrol->value.integer.value[0] = 1; |
1888 | else | 1888 | else |
1889 | ucontrol->value.integer.value[0] = 0; | 1889 | ucontrol->value.integer.value[0] = 0; |
1890 | 1890 | ||
1891 | return 0; | 1891 | return 0; |
1892 | } | 1892 | } |
1893 | 1893 | ||
1894 | static int snd_cs46xx_adc_capture_put(struct snd_kcontrol *kcontrol, | 1894 | static int snd_cs46xx_adc_capture_put(struct snd_kcontrol *kcontrol, |
1895 | struct snd_ctl_elem_value *ucontrol) | 1895 | struct snd_ctl_elem_value *ucontrol) |
1896 | { | 1896 | { |
1897 | struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol); | 1897 | struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol); |
1898 | struct dsp_spos_instance * ins = chip->dsp_spos_instance; | 1898 | struct dsp_spos_instance * ins = chip->dsp_spos_instance; |
1899 | int change = 0; | 1899 | int change = 0; |
1900 | 1900 | ||
1901 | if (ucontrol->value.integer.value[0] && !ins->adc_input) { | 1901 | if (ucontrol->value.integer.value[0] && !ins->adc_input) { |
1902 | cs46xx_dsp_enable_adc_capture(chip); | 1902 | cs46xx_dsp_enable_adc_capture(chip); |
1903 | change = 1; | 1903 | change = 1; |
1904 | } else if (!ucontrol->value.integer.value[0] && ins->adc_input) { | 1904 | } else if (!ucontrol->value.integer.value[0] && ins->adc_input) { |
1905 | cs46xx_dsp_disable_adc_capture(chip); | 1905 | cs46xx_dsp_disable_adc_capture(chip); |
1906 | change = 1; | 1906 | change = 1; |
1907 | } | 1907 | } |
1908 | return change; | 1908 | return change; |
1909 | } | 1909 | } |
1910 | 1910 | ||
1911 | static int snd_cs46xx_pcm_capture_get(struct snd_kcontrol *kcontrol, | 1911 | static int snd_cs46xx_pcm_capture_get(struct snd_kcontrol *kcontrol, |
1912 | struct snd_ctl_elem_value *ucontrol) | 1912 | struct snd_ctl_elem_value *ucontrol) |
1913 | { | 1913 | { |
1914 | struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol); | 1914 | struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol); |
1915 | struct dsp_spos_instance * ins = chip->dsp_spos_instance; | 1915 | struct dsp_spos_instance * ins = chip->dsp_spos_instance; |
1916 | 1916 | ||
1917 | if (ins->pcm_input != NULL) | 1917 | if (ins->pcm_input != NULL) |
1918 | ucontrol->value.integer.value[0] = 1; | 1918 | ucontrol->value.integer.value[0] = 1; |
1919 | else | 1919 | else |
1920 | ucontrol->value.integer.value[0] = 0; | 1920 | ucontrol->value.integer.value[0] = 0; |
1921 | 1921 | ||
1922 | return 0; | 1922 | return 0; |
1923 | } | 1923 | } |
1924 | 1924 | ||
1925 | 1925 | ||
1926 | static int snd_cs46xx_pcm_capture_put(struct snd_kcontrol *kcontrol, | 1926 | static int snd_cs46xx_pcm_capture_put(struct snd_kcontrol *kcontrol, |
1927 | struct snd_ctl_elem_value *ucontrol) | 1927 | struct snd_ctl_elem_value *ucontrol) |
1928 | { | 1928 | { |
1929 | struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol); | 1929 | struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol); |
1930 | struct dsp_spos_instance * ins = chip->dsp_spos_instance; | 1930 | struct dsp_spos_instance * ins = chip->dsp_spos_instance; |
1931 | int change = 0; | 1931 | int change = 0; |
1932 | 1932 | ||
1933 | if (ucontrol->value.integer.value[0] && !ins->pcm_input) { | 1933 | if (ucontrol->value.integer.value[0] && !ins->pcm_input) { |
1934 | cs46xx_dsp_enable_pcm_capture(chip); | 1934 | cs46xx_dsp_enable_pcm_capture(chip); |
1935 | change = 1; | 1935 | change = 1; |
1936 | } else if (!ucontrol->value.integer.value[0] && ins->pcm_input) { | 1936 | } else if (!ucontrol->value.integer.value[0] && ins->pcm_input) { |
1937 | cs46xx_dsp_disable_pcm_capture(chip); | 1937 | cs46xx_dsp_disable_pcm_capture(chip); |
1938 | change = 1; | 1938 | change = 1; |
1939 | } | 1939 | } |
1940 | 1940 | ||
1941 | return change; | 1941 | return change; |
1942 | } | 1942 | } |
1943 | 1943 | ||
1944 | static int snd_herc_spdif_select_get(struct snd_kcontrol *kcontrol, | 1944 | static int snd_herc_spdif_select_get(struct snd_kcontrol *kcontrol, |
1945 | struct snd_ctl_elem_value *ucontrol) | 1945 | struct snd_ctl_elem_value *ucontrol) |
1946 | { | 1946 | { |
1947 | struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol); | 1947 | struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol); |
1948 | 1948 | ||
1949 | int val1 = snd_cs46xx_peekBA0(chip, BA0_EGPIODR); | 1949 | int val1 = snd_cs46xx_peekBA0(chip, BA0_EGPIODR); |
1950 | 1950 | ||
1951 | if (val1 & EGPIODR_GPOE0) | 1951 | if (val1 & EGPIODR_GPOE0) |
1952 | ucontrol->value.integer.value[0] = 1; | 1952 | ucontrol->value.integer.value[0] = 1; |
1953 | else | 1953 | else |
1954 | ucontrol->value.integer.value[0] = 0; | 1954 | ucontrol->value.integer.value[0] = 0; |
1955 | 1955 | ||
1956 | return 0; | 1956 | return 0; |
1957 | } | 1957 | } |
1958 | 1958 | ||
1959 | /* | 1959 | /* |
1960 | * Game Theatre XP card - EGPIO[0] is used to select SPDIF input optical or coaxial. | 1960 | * Game Theatre XP card - EGPIO[0] is used to select SPDIF input optical or coaxial. |
1961 | */ | 1961 | */ |
1962 | static int snd_herc_spdif_select_put(struct snd_kcontrol *kcontrol, | 1962 | static int snd_herc_spdif_select_put(struct snd_kcontrol *kcontrol, |
1963 | struct snd_ctl_elem_value *ucontrol) | 1963 | struct snd_ctl_elem_value *ucontrol) |
1964 | { | 1964 | { |
1965 | struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol); | 1965 | struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol); |
1966 | int val1 = snd_cs46xx_peekBA0(chip, BA0_EGPIODR); | 1966 | int val1 = snd_cs46xx_peekBA0(chip, BA0_EGPIODR); |
1967 | int val2 = snd_cs46xx_peekBA0(chip, BA0_EGPIOPTR); | 1967 | int val2 = snd_cs46xx_peekBA0(chip, BA0_EGPIOPTR); |
1968 | 1968 | ||
1969 | if (ucontrol->value.integer.value[0]) { | 1969 | if (ucontrol->value.integer.value[0]) { |
1970 | /* optical is default */ | 1970 | /* optical is default */ |
1971 | snd_cs46xx_pokeBA0(chip, BA0_EGPIODR, | 1971 | snd_cs46xx_pokeBA0(chip, BA0_EGPIODR, |
1972 | EGPIODR_GPOE0 | val1); /* enable EGPIO0 output */ | 1972 | EGPIODR_GPOE0 | val1); /* enable EGPIO0 output */ |
1973 | snd_cs46xx_pokeBA0(chip, BA0_EGPIOPTR, | 1973 | snd_cs46xx_pokeBA0(chip, BA0_EGPIOPTR, |
1974 | EGPIOPTR_GPPT0 | val2); /* open-drain on output */ | 1974 | EGPIOPTR_GPPT0 | val2); /* open-drain on output */ |
1975 | } else { | 1975 | } else { |
1976 | /* coaxial */ | 1976 | /* coaxial */ |
1977 | snd_cs46xx_pokeBA0(chip, BA0_EGPIODR, val1 & ~EGPIODR_GPOE0); /* disable */ | 1977 | snd_cs46xx_pokeBA0(chip, BA0_EGPIODR, val1 & ~EGPIODR_GPOE0); /* disable */ |
1978 | snd_cs46xx_pokeBA0(chip, BA0_EGPIOPTR, val2 & ~EGPIOPTR_GPPT0); /* disable */ | 1978 | snd_cs46xx_pokeBA0(chip, BA0_EGPIOPTR, val2 & ~EGPIOPTR_GPPT0); /* disable */ |
1979 | } | 1979 | } |
1980 | 1980 | ||
1981 | /* checking diff from the EGPIO direction register | 1981 | /* checking diff from the EGPIO direction register |
1982 | should be enough */ | 1982 | should be enough */ |
1983 | return (val1 != (int)snd_cs46xx_peekBA0(chip, BA0_EGPIODR)); | 1983 | return (val1 != (int)snd_cs46xx_peekBA0(chip, BA0_EGPIODR)); |
1984 | } | 1984 | } |
1985 | 1985 | ||
1986 | 1986 | ||
1987 | static int snd_cs46xx_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 1987 | static int snd_cs46xx_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) |
1988 | { | 1988 | { |
1989 | uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958; | 1989 | uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958; |
1990 | uinfo->count = 1; | 1990 | uinfo->count = 1; |
1991 | return 0; | 1991 | return 0; |
1992 | } | 1992 | } |
1993 | 1993 | ||
1994 | static int snd_cs46xx_spdif_default_get(struct snd_kcontrol *kcontrol, | 1994 | static int snd_cs46xx_spdif_default_get(struct snd_kcontrol *kcontrol, |
1995 | struct snd_ctl_elem_value *ucontrol) | 1995 | struct snd_ctl_elem_value *ucontrol) |
1996 | { | 1996 | { |
1997 | struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol); | 1997 | struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol); |
1998 | struct dsp_spos_instance * ins = chip->dsp_spos_instance; | 1998 | struct dsp_spos_instance * ins = chip->dsp_spos_instance; |
1999 | 1999 | ||
2000 | down (&chip->spos_mutex); | 2000 | down (&chip->spos_mutex); |
2001 | ucontrol->value.iec958.status[0] = _wrap_all_bits((ins->spdif_csuv_default >> 24) & 0xff); | 2001 | ucontrol->value.iec958.status[0] = _wrap_all_bits((ins->spdif_csuv_default >> 24) & 0xff); |
2002 | ucontrol->value.iec958.status[1] = _wrap_all_bits((ins->spdif_csuv_default >> 16) & 0xff); | 2002 | ucontrol->value.iec958.status[1] = _wrap_all_bits((ins->spdif_csuv_default >> 16) & 0xff); |
2003 | ucontrol->value.iec958.status[2] = 0; | 2003 | ucontrol->value.iec958.status[2] = 0; |
2004 | ucontrol->value.iec958.status[3] = _wrap_all_bits((ins->spdif_csuv_default) & 0xff); | 2004 | ucontrol->value.iec958.status[3] = _wrap_all_bits((ins->spdif_csuv_default) & 0xff); |
2005 | up (&chip->spos_mutex); | 2005 | up (&chip->spos_mutex); |
2006 | 2006 | ||
2007 | return 0; | 2007 | return 0; |
2008 | } | 2008 | } |
2009 | 2009 | ||
2010 | static int snd_cs46xx_spdif_default_put(struct snd_kcontrol *kcontrol, | 2010 | static int snd_cs46xx_spdif_default_put(struct snd_kcontrol *kcontrol, |
2011 | struct snd_ctl_elem_value *ucontrol) | 2011 | struct snd_ctl_elem_value *ucontrol) |
2012 | { | 2012 | { |
2013 | struct snd_cs46xx * chip = snd_kcontrol_chip(kcontrol); | 2013 | struct snd_cs46xx * chip = snd_kcontrol_chip(kcontrol); |
2014 | struct dsp_spos_instance * ins = chip->dsp_spos_instance; | 2014 | struct dsp_spos_instance * ins = chip->dsp_spos_instance; |
2015 | unsigned int val; | 2015 | unsigned int val; |
2016 | int change; | 2016 | int change; |
2017 | 2017 | ||
2018 | down (&chip->spos_mutex); | 2018 | down (&chip->spos_mutex); |
2019 | val = ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[0]) << 24) | | 2019 | val = ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[0]) << 24) | |
2020 | ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[2]) << 16) | | 2020 | ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[2]) << 16) | |
2021 | ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[3])) | | 2021 | ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[3])) | |
2022 | /* left and right validity bit */ | 2022 | /* left and right validity bit */ |
2023 | (1 << 13) | (1 << 12); | 2023 | (1 << 13) | (1 << 12); |
2024 | 2024 | ||
2025 | 2025 | ||
2026 | change = (unsigned int)ins->spdif_csuv_default != val; | 2026 | change = (unsigned int)ins->spdif_csuv_default != val; |
2027 | ins->spdif_csuv_default = val; | 2027 | ins->spdif_csuv_default = val; |
2028 | 2028 | ||
2029 | if ( !(ins->spdif_status_out & DSP_SPDIF_STATUS_PLAYBACK_OPEN) ) | 2029 | if ( !(ins->spdif_status_out & DSP_SPDIF_STATUS_PLAYBACK_OPEN) ) |
2030 | cs46xx_poke_via_dsp (chip,SP_SPDOUT_CSUV,val); | 2030 | cs46xx_poke_via_dsp (chip,SP_SPDOUT_CSUV,val); |
2031 | 2031 | ||
2032 | up (&chip->spos_mutex); | 2032 | up (&chip->spos_mutex); |
2033 | 2033 | ||
2034 | return change; | 2034 | return change; |
2035 | } | 2035 | } |
2036 | 2036 | ||
2037 | static int snd_cs46xx_spdif_mask_get(struct snd_kcontrol *kcontrol, | 2037 | static int snd_cs46xx_spdif_mask_get(struct snd_kcontrol *kcontrol, |
2038 | struct snd_ctl_elem_value *ucontrol) | 2038 | struct snd_ctl_elem_value *ucontrol) |
2039 | { | 2039 | { |
2040 | ucontrol->value.iec958.status[0] = 0xff; | 2040 | ucontrol->value.iec958.status[0] = 0xff; |
2041 | ucontrol->value.iec958.status[1] = 0xff; | 2041 | ucontrol->value.iec958.status[1] = 0xff; |
2042 | ucontrol->value.iec958.status[2] = 0x00; | 2042 | ucontrol->value.iec958.status[2] = 0x00; |
2043 | ucontrol->value.iec958.status[3] = 0xff; | 2043 | ucontrol->value.iec958.status[3] = 0xff; |
2044 | return 0; | 2044 | return 0; |
2045 | } | 2045 | } |
2046 | 2046 | ||
2047 | static int snd_cs46xx_spdif_stream_get(struct snd_kcontrol *kcontrol, | 2047 | static int snd_cs46xx_spdif_stream_get(struct snd_kcontrol *kcontrol, |
2048 | struct snd_ctl_elem_value *ucontrol) | 2048 | struct snd_ctl_elem_value *ucontrol) |
2049 | { | 2049 | { |
2050 | struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol); | 2050 | struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol); |
2051 | struct dsp_spos_instance * ins = chip->dsp_spos_instance; | 2051 | struct dsp_spos_instance * ins = chip->dsp_spos_instance; |
2052 | 2052 | ||
2053 | down (&chip->spos_mutex); | 2053 | down (&chip->spos_mutex); |
2054 | ucontrol->value.iec958.status[0] = _wrap_all_bits((ins->spdif_csuv_stream >> 24) & 0xff); | 2054 | ucontrol->value.iec958.status[0] = _wrap_all_bits((ins->spdif_csuv_stream >> 24) & 0xff); |
2055 | ucontrol->value.iec958.status[1] = _wrap_all_bits((ins->spdif_csuv_stream >> 16) & 0xff); | 2055 | ucontrol->value.iec958.status[1] = _wrap_all_bits((ins->spdif_csuv_stream >> 16) & 0xff); |
2056 | ucontrol->value.iec958.status[2] = 0; | 2056 | ucontrol->value.iec958.status[2] = 0; |
2057 | ucontrol->value.iec958.status[3] = _wrap_all_bits((ins->spdif_csuv_stream) & 0xff); | 2057 | ucontrol->value.iec958.status[3] = _wrap_all_bits((ins->spdif_csuv_stream) & 0xff); |
2058 | up (&chip->spos_mutex); | 2058 | up (&chip->spos_mutex); |
2059 | 2059 | ||
2060 | return 0; | 2060 | return 0; |
2061 | } | 2061 | } |
2062 | 2062 | ||
2063 | static int snd_cs46xx_spdif_stream_put(struct snd_kcontrol *kcontrol, | 2063 | static int snd_cs46xx_spdif_stream_put(struct snd_kcontrol *kcontrol, |
2064 | struct snd_ctl_elem_value *ucontrol) | 2064 | struct snd_ctl_elem_value *ucontrol) |
2065 | { | 2065 | { |
2066 | struct snd_cs46xx * chip = snd_kcontrol_chip(kcontrol); | 2066 | struct snd_cs46xx * chip = snd_kcontrol_chip(kcontrol); |
2067 | struct dsp_spos_instance * ins = chip->dsp_spos_instance; | 2067 | struct dsp_spos_instance * ins = chip->dsp_spos_instance; |
2068 | unsigned int val; | 2068 | unsigned int val; |
2069 | int change; | 2069 | int change; |
2070 | 2070 | ||
2071 | down (&chip->spos_mutex); | 2071 | down (&chip->spos_mutex); |
2072 | val = ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[0]) << 24) | | 2072 | val = ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[0]) << 24) | |
2073 | ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[1]) << 16) | | 2073 | ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[1]) << 16) | |
2074 | ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[3])) | | 2074 | ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[3])) | |
2075 | /* left and right validity bit */ | 2075 | /* left and right validity bit */ |
2076 | (1 << 13) | (1 << 12); | 2076 | (1 << 13) | (1 << 12); |
2077 | 2077 | ||
2078 | 2078 | ||
2079 | change = ins->spdif_csuv_stream != val; | 2079 | change = ins->spdif_csuv_stream != val; |
2080 | ins->spdif_csuv_stream = val; | 2080 | ins->spdif_csuv_stream = val; |
2081 | 2081 | ||
2082 | if ( ins->spdif_status_out & DSP_SPDIF_STATUS_PLAYBACK_OPEN ) | 2082 | if ( ins->spdif_status_out & DSP_SPDIF_STATUS_PLAYBACK_OPEN ) |
2083 | cs46xx_poke_via_dsp (chip,SP_SPDOUT_CSUV,val); | 2083 | cs46xx_poke_via_dsp (chip,SP_SPDOUT_CSUV,val); |
2084 | 2084 | ||
2085 | up (&chip->spos_mutex); | 2085 | up (&chip->spos_mutex); |
2086 | 2086 | ||
2087 | return change; | 2087 | return change; |
2088 | } | 2088 | } |
2089 | 2089 | ||
2090 | #endif /* CONFIG_SND_CS46XX_NEW_DSP */ | 2090 | #endif /* CONFIG_SND_CS46XX_NEW_DSP */ |
2091 | 2091 | ||
2092 | 2092 | ||
2093 | #ifdef CONFIG_SND_CS46XX_DEBUG_GPIO | 2093 | #ifdef CONFIG_SND_CS46XX_DEBUG_GPIO |
2094 | static int snd_cs46xx_egpio_select_info(struct snd_kcontrol *kcontrol, | 2094 | static int snd_cs46xx_egpio_select_info(struct snd_kcontrol *kcontrol, |
2095 | struct snd_ctl_elem_info *uinfo) | 2095 | struct snd_ctl_elem_info *uinfo) |
2096 | { | 2096 | { |
2097 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | 2097 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; |
2098 | uinfo->count = 1; | 2098 | uinfo->count = 1; |
2099 | uinfo->value.integer.min = 0; | 2099 | uinfo->value.integer.min = 0; |
2100 | uinfo->value.integer.max = 8; | 2100 | uinfo->value.integer.max = 8; |
2101 | return 0; | 2101 | return 0; |
2102 | } | 2102 | } |
2103 | 2103 | ||
2104 | static int snd_cs46xx_egpio_select_get(struct snd_kcontrol *kcontrol, | 2104 | static int snd_cs46xx_egpio_select_get(struct snd_kcontrol *kcontrol, |
2105 | struct snd_ctl_elem_value *ucontrol) | 2105 | struct snd_ctl_elem_value *ucontrol) |
2106 | { | 2106 | { |
2107 | struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol); | 2107 | struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol); |
2108 | ucontrol->value.integer.value[0] = chip->current_gpio; | 2108 | ucontrol->value.integer.value[0] = chip->current_gpio; |
2109 | 2109 | ||
2110 | return 0; | 2110 | return 0; |
2111 | } | 2111 | } |
2112 | 2112 | ||
2113 | static int snd_cs46xx_egpio_select_put(struct snd_kcontrol *kcontrol, | 2113 | static int snd_cs46xx_egpio_select_put(struct snd_kcontrol *kcontrol, |
2114 | struct snd_ctl_elem_value *ucontrol) | 2114 | struct snd_ctl_elem_value *ucontrol) |
2115 | { | 2115 | { |
2116 | struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol); | 2116 | struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol); |
2117 | int change = (chip->current_gpio != ucontrol->value.integer.value[0]); | 2117 | int change = (chip->current_gpio != ucontrol->value.integer.value[0]); |
2118 | chip->current_gpio = ucontrol->value.integer.value[0]; | 2118 | chip->current_gpio = ucontrol->value.integer.value[0]; |
2119 | 2119 | ||
2120 | return change; | 2120 | return change; |
2121 | } | 2121 | } |
2122 | 2122 | ||
2123 | 2123 | ||
2124 | static int snd_cs46xx_egpio_get(struct snd_kcontrol *kcontrol, | 2124 | static int snd_cs46xx_egpio_get(struct snd_kcontrol *kcontrol, |
2125 | struct snd_ctl_elem_value *ucontrol) | 2125 | struct snd_ctl_elem_value *ucontrol) |
2126 | { | 2126 | { |
2127 | struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol); | 2127 | struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol); |
2128 | int reg = kcontrol->private_value; | 2128 | int reg = kcontrol->private_value; |
2129 | 2129 | ||
2130 | snd_printdd ("put: reg = %04x, gpio %02x\n",reg,chip->current_gpio); | 2130 | snd_printdd ("put: reg = %04x, gpio %02x\n",reg,chip->current_gpio); |
2131 | ucontrol->value.integer.value[0] = | 2131 | ucontrol->value.integer.value[0] = |
2132 | (snd_cs46xx_peekBA0(chip, reg) & (1 << chip->current_gpio)) ? 1 : 0; | 2132 | (snd_cs46xx_peekBA0(chip, reg) & (1 << chip->current_gpio)) ? 1 : 0; |
2133 | 2133 | ||
2134 | return 0; | 2134 | return 0; |
2135 | } | 2135 | } |
2136 | 2136 | ||
2137 | static int snd_cs46xx_egpio_put(struct snd_kcontrol *kcontrol, | 2137 | static int snd_cs46xx_egpio_put(struct snd_kcontrol *kcontrol, |
2138 | struct snd_ctl_elem_value *ucontrol) | 2138 | struct snd_ctl_elem_value *ucontrol) |
2139 | { | 2139 | { |
2140 | struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol); | 2140 | struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol); |
2141 | int reg = kcontrol->private_value; | 2141 | int reg = kcontrol->private_value; |
2142 | int val = snd_cs46xx_peekBA0(chip, reg); | 2142 | int val = snd_cs46xx_peekBA0(chip, reg); |
2143 | int oldval = val; | 2143 | int oldval = val; |
2144 | snd_printdd ("put: reg = %04x, gpio %02x\n",reg,chip->current_gpio); | 2144 | snd_printdd ("put: reg = %04x, gpio %02x\n",reg,chip->current_gpio); |
2145 | 2145 | ||
2146 | if (ucontrol->value.integer.value[0]) | 2146 | if (ucontrol->value.integer.value[0]) |
2147 | val |= (1 << chip->current_gpio); | 2147 | val |= (1 << chip->current_gpio); |
2148 | else | 2148 | else |
2149 | val &= ~(1 << chip->current_gpio); | 2149 | val &= ~(1 << chip->current_gpio); |
2150 | 2150 | ||
2151 | snd_cs46xx_pokeBA0(chip, reg,val); | 2151 | snd_cs46xx_pokeBA0(chip, reg,val); |
2152 | snd_printdd ("put: val %08x oldval %08x\n",val,oldval); | 2152 | snd_printdd ("put: val %08x oldval %08x\n",val,oldval); |
2153 | 2153 | ||
2154 | return (oldval != val); | 2154 | return (oldval != val); |
2155 | } | 2155 | } |
2156 | #endif /* CONFIG_SND_CS46XX_DEBUG_GPIO */ | 2156 | #endif /* CONFIG_SND_CS46XX_DEBUG_GPIO */ |
2157 | 2157 | ||
2158 | static struct snd_kcontrol_new snd_cs46xx_controls[] __devinitdata = { | 2158 | static struct snd_kcontrol_new snd_cs46xx_controls[] __devinitdata = { |
2159 | { | 2159 | { |
2160 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 2160 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
2161 | .name = "DAC Volume", | 2161 | .name = "DAC Volume", |
2162 | .info = snd_cs46xx_vol_info, | 2162 | .info = snd_cs46xx_vol_info, |
2163 | #ifndef CONFIG_SND_CS46XX_NEW_DSP | 2163 | #ifndef CONFIG_SND_CS46XX_NEW_DSP |
2164 | .get = snd_cs46xx_vol_get, | 2164 | .get = snd_cs46xx_vol_get, |
2165 | .put = snd_cs46xx_vol_put, | 2165 | .put = snd_cs46xx_vol_put, |
2166 | .private_value = BA1_PVOL, | 2166 | .private_value = BA1_PVOL, |
2167 | #else | 2167 | #else |
2168 | .get = snd_cs46xx_vol_dac_get, | 2168 | .get = snd_cs46xx_vol_dac_get, |
2169 | .put = snd_cs46xx_vol_dac_put, | 2169 | .put = snd_cs46xx_vol_dac_put, |
2170 | #endif | 2170 | #endif |
2171 | }, | 2171 | }, |
2172 | 2172 | ||
2173 | { | 2173 | { |
2174 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 2174 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
2175 | .name = "ADC Volume", | 2175 | .name = "ADC Volume", |
2176 | .info = snd_cs46xx_vol_info, | 2176 | .info = snd_cs46xx_vol_info, |
2177 | .get = snd_cs46xx_vol_get, | 2177 | .get = snd_cs46xx_vol_get, |
2178 | .put = snd_cs46xx_vol_put, | 2178 | .put = snd_cs46xx_vol_put, |
2179 | #ifndef CONFIG_SND_CS46XX_NEW_DSP | 2179 | #ifndef CONFIG_SND_CS46XX_NEW_DSP |
2180 | .private_value = BA1_CVOL, | 2180 | .private_value = BA1_CVOL, |
2181 | #else | 2181 | #else |
2182 | .private_value = (VARIDECIMATE_SCB_ADDR + 0xE) << 2, | 2182 | .private_value = (VARIDECIMATE_SCB_ADDR + 0xE) << 2, |
2183 | #endif | 2183 | #endif |
2184 | }, | 2184 | }, |
2185 | #ifdef CONFIG_SND_CS46XX_NEW_DSP | 2185 | #ifdef CONFIG_SND_CS46XX_NEW_DSP |
2186 | { | 2186 | { |
2187 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 2187 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
2188 | .name = "ADC Capture Switch", | 2188 | .name = "ADC Capture Switch", |
2189 | .info = snd_mixer_boolean_info, | 2189 | .info = snd_mixer_boolean_info, |
2190 | .get = snd_cs46xx_adc_capture_get, | 2190 | .get = snd_cs46xx_adc_capture_get, |
2191 | .put = snd_cs46xx_adc_capture_put | 2191 | .put = snd_cs46xx_adc_capture_put |
2192 | }, | 2192 | }, |
2193 | { | 2193 | { |
2194 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 2194 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
2195 | .name = "DAC Capture Switch", | 2195 | .name = "DAC Capture Switch", |
2196 | .info = snd_mixer_boolean_info, | 2196 | .info = snd_mixer_boolean_info, |
2197 | .get = snd_cs46xx_pcm_capture_get, | 2197 | .get = snd_cs46xx_pcm_capture_get, |
2198 | .put = snd_cs46xx_pcm_capture_put | 2198 | .put = snd_cs46xx_pcm_capture_put |
2199 | }, | 2199 | }, |
2200 | { | 2200 | { |
2201 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 2201 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
2202 | .name = SNDRV_CTL_NAME_IEC958("Output ",NONE,SWITCH), | 2202 | .name = SNDRV_CTL_NAME_IEC958("Output ",NONE,SWITCH), |
2203 | .info = snd_mixer_boolean_info, | 2203 | .info = snd_mixer_boolean_info, |
2204 | .get = snd_cs46xx_iec958_get, | 2204 | .get = snd_cs46xx_iec958_get, |
2205 | .put = snd_cs46xx_iec958_put, | 2205 | .put = snd_cs46xx_iec958_put, |
2206 | .private_value = CS46XX_MIXER_SPDIF_OUTPUT_ELEMENT, | 2206 | .private_value = CS46XX_MIXER_SPDIF_OUTPUT_ELEMENT, |
2207 | }, | 2207 | }, |
2208 | { | 2208 | { |
2209 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 2209 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
2210 | .name = SNDRV_CTL_NAME_IEC958("Input ",NONE,SWITCH), | 2210 | .name = SNDRV_CTL_NAME_IEC958("Input ",NONE,SWITCH), |
2211 | .info = snd_mixer_boolean_info, | 2211 | .info = snd_mixer_boolean_info, |
2212 | .get = snd_cs46xx_iec958_get, | 2212 | .get = snd_cs46xx_iec958_get, |
2213 | .put = snd_cs46xx_iec958_put, | 2213 | .put = snd_cs46xx_iec958_put, |
2214 | .private_value = CS46XX_MIXER_SPDIF_INPUT_ELEMENT, | 2214 | .private_value = CS46XX_MIXER_SPDIF_INPUT_ELEMENT, |
2215 | }, | 2215 | }, |
2216 | #if 0 | 2216 | #if 0 |
2217 | /* Input IEC958 volume does not work for the moment. (Benny) */ | 2217 | /* Input IEC958 volume does not work for the moment. (Benny) */ |
2218 | { | 2218 | { |
2219 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 2219 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
2220 | .name = SNDRV_CTL_NAME_IEC958("Input ",NONE,VOLUME), | 2220 | .name = SNDRV_CTL_NAME_IEC958("Input ",NONE,VOLUME), |
2221 | .info = snd_cs46xx_vol_info, | 2221 | .info = snd_cs46xx_vol_info, |
2222 | .get = snd_cs46xx_vol_iec958_get, | 2222 | .get = snd_cs46xx_vol_iec958_get, |
2223 | .put = snd_cs46xx_vol_iec958_put, | 2223 | .put = snd_cs46xx_vol_iec958_put, |
2224 | .private_value = (ASYNCRX_SCB_ADDR + 0xE) << 2, | 2224 | .private_value = (ASYNCRX_SCB_ADDR + 0xE) << 2, |
2225 | }, | 2225 | }, |
2226 | #endif | 2226 | #endif |
2227 | { | 2227 | { |
2228 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, | 2228 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, |
2229 | .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), | 2229 | .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), |
2230 | .info = snd_cs46xx_spdif_info, | 2230 | .info = snd_cs46xx_spdif_info, |
2231 | .get = snd_cs46xx_spdif_default_get, | 2231 | .get = snd_cs46xx_spdif_default_get, |
2232 | .put = snd_cs46xx_spdif_default_put, | 2232 | .put = snd_cs46xx_spdif_default_put, |
2233 | }, | 2233 | }, |
2234 | { | 2234 | { |
2235 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, | 2235 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, |
2236 | .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK), | 2236 | .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK), |
2237 | .info = snd_cs46xx_spdif_info, | 2237 | .info = snd_cs46xx_spdif_info, |
2238 | .get = snd_cs46xx_spdif_mask_get, | 2238 | .get = snd_cs46xx_spdif_mask_get, |
2239 | .access = SNDRV_CTL_ELEM_ACCESS_READ | 2239 | .access = SNDRV_CTL_ELEM_ACCESS_READ |
2240 | }, | 2240 | }, |
2241 | { | 2241 | { |
2242 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, | 2242 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, |
2243 | .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PCM_STREAM), | 2243 | .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PCM_STREAM), |
2244 | .info = snd_cs46xx_spdif_info, | 2244 | .info = snd_cs46xx_spdif_info, |
2245 | .get = snd_cs46xx_spdif_stream_get, | 2245 | .get = snd_cs46xx_spdif_stream_get, |
2246 | .put = snd_cs46xx_spdif_stream_put | 2246 | .put = snd_cs46xx_spdif_stream_put |
2247 | }, | 2247 | }, |
2248 | 2248 | ||
2249 | #endif | 2249 | #endif |
2250 | #ifdef CONFIG_SND_CS46XX_DEBUG_GPIO | 2250 | #ifdef CONFIG_SND_CS46XX_DEBUG_GPIO |
2251 | { | 2251 | { |
2252 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 2252 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
2253 | .name = "EGPIO select", | 2253 | .name = "EGPIO select", |
2254 | .info = snd_cs46xx_egpio_select_info, | 2254 | .info = snd_cs46xx_egpio_select_info, |
2255 | .get = snd_cs46xx_egpio_select_get, | 2255 | .get = snd_cs46xx_egpio_select_get, |
2256 | .put = snd_cs46xx_egpio_select_put, | 2256 | .put = snd_cs46xx_egpio_select_put, |
2257 | .private_value = 0, | 2257 | .private_value = 0, |
2258 | }, | 2258 | }, |
2259 | { | 2259 | { |
2260 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 2260 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
2261 | .name = "EGPIO Input/Output", | 2261 | .name = "EGPIO Input/Output", |
2262 | .info = snd_mixer_boolean_info, | 2262 | .info = snd_mixer_boolean_info, |
2263 | .get = snd_cs46xx_egpio_get, | 2263 | .get = snd_cs46xx_egpio_get, |
2264 | .put = snd_cs46xx_egpio_put, | 2264 | .put = snd_cs46xx_egpio_put, |
2265 | .private_value = BA0_EGPIODR, | 2265 | .private_value = BA0_EGPIODR, |
2266 | }, | 2266 | }, |
2267 | { | 2267 | { |
2268 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 2268 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
2269 | .name = "EGPIO CMOS/Open drain", | 2269 | .name = "EGPIO CMOS/Open drain", |
2270 | .info = snd_mixer_boolean_info, | 2270 | .info = snd_mixer_boolean_info, |
2271 | .get = snd_cs46xx_egpio_get, | 2271 | .get = snd_cs46xx_egpio_get, |
2272 | .put = snd_cs46xx_egpio_put, | 2272 | .put = snd_cs46xx_egpio_put, |
2273 | .private_value = BA0_EGPIOPTR, | 2273 | .private_value = BA0_EGPIOPTR, |
2274 | }, | 2274 | }, |
2275 | { | 2275 | { |
2276 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 2276 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
2277 | .name = "EGPIO On/Off", | 2277 | .name = "EGPIO On/Off", |
2278 | .info = snd_mixer_boolean_info, | 2278 | .info = snd_mixer_boolean_info, |
2279 | .get = snd_cs46xx_egpio_get, | 2279 | .get = snd_cs46xx_egpio_get, |
2280 | .put = snd_cs46xx_egpio_put, | 2280 | .put = snd_cs46xx_egpio_put, |
2281 | .private_value = BA0_EGPIOSR, | 2281 | .private_value = BA0_EGPIOSR, |
2282 | }, | 2282 | }, |
2283 | #endif | 2283 | #endif |
2284 | }; | 2284 | }; |
2285 | 2285 | ||
2286 | #ifdef CONFIG_SND_CS46XX_NEW_DSP | 2286 | #ifdef CONFIG_SND_CS46XX_NEW_DSP |
2287 | /* set primary cs4294 codec into Extended Audio Mode */ | 2287 | /* set primary cs4294 codec into Extended Audio Mode */ |
2288 | static int snd_cs46xx_front_dup_get(struct snd_kcontrol *kcontrol, | 2288 | static int snd_cs46xx_front_dup_get(struct snd_kcontrol *kcontrol, |
2289 | struct snd_ctl_elem_value *ucontrol) | 2289 | struct snd_ctl_elem_value *ucontrol) |
2290 | { | 2290 | { |
2291 | struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol); | 2291 | struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol); |
2292 | unsigned short val; | 2292 | unsigned short val; |
2293 | val = snd_ac97_read(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX], AC97_CSR_ACMODE); | 2293 | val = snd_ac97_read(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX], AC97_CSR_ACMODE); |
2294 | ucontrol->value.integer.value[0] = (val & 0x200) ? 0 : 1; | 2294 | ucontrol->value.integer.value[0] = (val & 0x200) ? 0 : 1; |
2295 | return 0; | 2295 | return 0; |
2296 | } | 2296 | } |
2297 | 2297 | ||
2298 | static int snd_cs46xx_front_dup_put(struct snd_kcontrol *kcontrol, | 2298 | static int snd_cs46xx_front_dup_put(struct snd_kcontrol *kcontrol, |
2299 | struct snd_ctl_elem_value *ucontrol) | 2299 | struct snd_ctl_elem_value *ucontrol) |
2300 | { | 2300 | { |
2301 | struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol); | 2301 | struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol); |
2302 | return snd_ac97_update_bits(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX], | 2302 | return snd_ac97_update_bits(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX], |
2303 | AC97_CSR_ACMODE, 0x200, | 2303 | AC97_CSR_ACMODE, 0x200, |
2304 | ucontrol->value.integer.value[0] ? 0 : 0x200); | 2304 | ucontrol->value.integer.value[0] ? 0 : 0x200); |
2305 | } | 2305 | } |
2306 | 2306 | ||
2307 | static struct snd_kcontrol_new snd_cs46xx_front_dup_ctl = { | 2307 | static struct snd_kcontrol_new snd_cs46xx_front_dup_ctl = { |
2308 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 2308 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
2309 | .name = "Duplicate Front", | 2309 | .name = "Duplicate Front", |
2310 | .info = snd_mixer_boolean_info, | 2310 | .info = snd_mixer_boolean_info, |
2311 | .get = snd_cs46xx_front_dup_get, | 2311 | .get = snd_cs46xx_front_dup_get, |
2312 | .put = snd_cs46xx_front_dup_put, | 2312 | .put = snd_cs46xx_front_dup_put, |
2313 | }; | 2313 | }; |
2314 | #endif | 2314 | #endif |
2315 | 2315 | ||
2316 | #ifdef CONFIG_SND_CS46XX_NEW_DSP | 2316 | #ifdef CONFIG_SND_CS46XX_NEW_DSP |
2317 | /* Only available on the Hercules Game Theater XP soundcard */ | 2317 | /* Only available on the Hercules Game Theater XP soundcard */ |
2318 | static struct snd_kcontrol_new snd_hercules_controls[] __devinitdata = { | 2318 | static struct snd_kcontrol_new snd_hercules_controls[] __devinitdata = { |
2319 | { | 2319 | { |
2320 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 2320 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
2321 | .name = "Optical/Coaxial SPDIF Input Switch", | 2321 | .name = "Optical/Coaxial SPDIF Input Switch", |
2322 | .info = snd_mixer_boolean_info, | 2322 | .info = snd_mixer_boolean_info, |
2323 | .get = snd_herc_spdif_select_get, | 2323 | .get = snd_herc_spdif_select_get, |
2324 | .put = snd_herc_spdif_select_put, | 2324 | .put = snd_herc_spdif_select_put, |
2325 | }, | 2325 | }, |
2326 | }; | 2326 | }; |
2327 | 2327 | ||
2328 | 2328 | ||
2329 | static void snd_cs46xx_codec_reset (struct snd_ac97 * ac97) | 2329 | static void snd_cs46xx_codec_reset (struct snd_ac97 * ac97) |
2330 | { | 2330 | { |
2331 | unsigned long end_time; | 2331 | unsigned long end_time; |
2332 | int err; | 2332 | int err; |
2333 | 2333 | ||
2334 | /* reset to defaults */ | 2334 | /* reset to defaults */ |
2335 | snd_ac97_write(ac97, AC97_RESET, 0); | 2335 | snd_ac97_write(ac97, AC97_RESET, 0); |
2336 | 2336 | ||
2337 | /* set the desired CODEC mode */ | 2337 | /* set the desired CODEC mode */ |
2338 | if (ac97->num == CS46XX_PRIMARY_CODEC_INDEX) { | 2338 | if (ac97->num == CS46XX_PRIMARY_CODEC_INDEX) { |
2339 | snd_printdd("cs46xx: CODOEC1 mode %04x\n",0x0); | 2339 | snd_printdd("cs46xx: CODOEC1 mode %04x\n",0x0); |
2340 | snd_cs46xx_ac97_write(ac97,AC97_CSR_ACMODE,0x0); | 2340 | snd_cs46xx_ac97_write(ac97,AC97_CSR_ACMODE,0x0); |
2341 | } else if (ac97->num == CS46XX_SECONDARY_CODEC_INDEX) { | 2341 | } else if (ac97->num == CS46XX_SECONDARY_CODEC_INDEX) { |
2342 | snd_printdd("cs46xx: CODOEC2 mode %04x\n",0x3); | 2342 | snd_printdd("cs46xx: CODOEC2 mode %04x\n",0x3); |
2343 | snd_cs46xx_ac97_write(ac97,AC97_CSR_ACMODE,0x3); | 2343 | snd_cs46xx_ac97_write(ac97,AC97_CSR_ACMODE,0x3); |
2344 | } else { | 2344 | } else { |
2345 | snd_assert(0); /* should never happen ... */ | 2345 | snd_assert(0); /* should never happen ... */ |
2346 | } | 2346 | } |
2347 | 2347 | ||
2348 | udelay(50); | 2348 | udelay(50); |
2349 | 2349 | ||
2350 | /* it's necessary to wait awhile until registers are accessible after RESET */ | 2350 | /* it's necessary to wait awhile until registers are accessible after RESET */ |
2351 | /* because the PCM or MASTER volume registers can be modified, */ | 2351 | /* because the PCM or MASTER volume registers can be modified, */ |
2352 | /* the REC_GAIN register is used for tests */ | 2352 | /* the REC_GAIN register is used for tests */ |
2353 | end_time = jiffies + HZ; | 2353 | end_time = jiffies + HZ; |
2354 | do { | 2354 | do { |
2355 | unsigned short ext_mid; | 2355 | unsigned short ext_mid; |
2356 | 2356 | ||
2357 | /* use preliminary reads to settle the communication */ | 2357 | /* use preliminary reads to settle the communication */ |
2358 | snd_ac97_read(ac97, AC97_RESET); | 2358 | snd_ac97_read(ac97, AC97_RESET); |
2359 | snd_ac97_read(ac97, AC97_VENDOR_ID1); | 2359 | snd_ac97_read(ac97, AC97_VENDOR_ID1); |
2360 | snd_ac97_read(ac97, AC97_VENDOR_ID2); | 2360 | snd_ac97_read(ac97, AC97_VENDOR_ID2); |
2361 | /* modem? */ | 2361 | /* modem? */ |
2362 | ext_mid = snd_ac97_read(ac97, AC97_EXTENDED_MID); | 2362 | ext_mid = snd_ac97_read(ac97, AC97_EXTENDED_MID); |
2363 | if (ext_mid != 0xffff && (ext_mid & 1) != 0) | 2363 | if (ext_mid != 0xffff && (ext_mid & 1) != 0) |
2364 | return; | 2364 | return; |
2365 | 2365 | ||
2366 | /* test if we can write to the record gain volume register */ | 2366 | /* test if we can write to the record gain volume register */ |
2367 | snd_ac97_write_cache(ac97, AC97_REC_GAIN, 0x8a05); | 2367 | snd_ac97_write_cache(ac97, AC97_REC_GAIN, 0x8a05); |
2368 | if ((err = snd_ac97_read(ac97, AC97_REC_GAIN)) == 0x8a05) | 2368 | if ((err = snd_ac97_read(ac97, AC97_REC_GAIN)) == 0x8a05) |
2369 | return; | 2369 | return; |
2370 | 2370 | ||
2371 | msleep(10); | 2371 | msleep(10); |
2372 | } while (time_after_eq(end_time, jiffies)); | 2372 | } while (time_after_eq(end_time, jiffies)); |
2373 | 2373 | ||
2374 | snd_printk(KERN_ERR "CS46xx secondary codec doesn't respond!\n"); | 2374 | snd_printk(KERN_ERR "CS46xx secondary codec doesn't respond!\n"); |
2375 | } | 2375 | } |
2376 | #endif | 2376 | #endif |
2377 | 2377 | ||
2378 | static int __devinit cs46xx_detect_codec(struct snd_cs46xx *chip, int codec) | 2378 | static int __devinit cs46xx_detect_codec(struct snd_cs46xx *chip, int codec) |
2379 | { | 2379 | { |
2380 | int idx, err; | 2380 | int idx, err; |
2381 | struct snd_ac97_template ac97; | 2381 | struct snd_ac97_template ac97; |
2382 | 2382 | ||
2383 | memset(&ac97, 0, sizeof(ac97)); | 2383 | memset(&ac97, 0, sizeof(ac97)); |
2384 | ac97.private_data = chip; | 2384 | ac97.private_data = chip; |
2385 | ac97.private_free = snd_cs46xx_mixer_free_ac97; | 2385 | ac97.private_free = snd_cs46xx_mixer_free_ac97; |
2386 | ac97.num = codec; | 2386 | ac97.num = codec; |
2387 | if (chip->amplifier_ctrl == amp_voyetra) | 2387 | if (chip->amplifier_ctrl == amp_voyetra) |
2388 | ac97.scaps = AC97_SCAP_INV_EAPD; | 2388 | ac97.scaps = AC97_SCAP_INV_EAPD; |
2389 | 2389 | ||
2390 | if (codec == CS46XX_SECONDARY_CODEC_INDEX) { | 2390 | if (codec == CS46XX_SECONDARY_CODEC_INDEX) { |
2391 | snd_cs46xx_codec_write(chip, AC97_RESET, 0, codec); | 2391 | snd_cs46xx_codec_write(chip, AC97_RESET, 0, codec); |
2392 | udelay(10); | 2392 | udelay(10); |
2393 | if (snd_cs46xx_codec_read(chip, AC97_RESET, codec) & 0x8000) { | 2393 | if (snd_cs46xx_codec_read(chip, AC97_RESET, codec) & 0x8000) { |
2394 | snd_printdd("snd_cs46xx: seconadry codec not present\n"); | 2394 | snd_printdd("snd_cs46xx: seconadry codec not present\n"); |
2395 | return -ENXIO; | 2395 | return -ENXIO; |
2396 | } | 2396 | } |
2397 | } | 2397 | } |
2398 | 2398 | ||
2399 | snd_cs46xx_codec_write(chip, AC97_MASTER, 0x8000, codec); | 2399 | snd_cs46xx_codec_write(chip, AC97_MASTER, 0x8000, codec); |
2400 | for (idx = 0; idx < 100; ++idx) { | 2400 | for (idx = 0; idx < 100; ++idx) { |
2401 | if (snd_cs46xx_codec_read(chip, AC97_MASTER, codec) == 0x8000) { | 2401 | if (snd_cs46xx_codec_read(chip, AC97_MASTER, codec) == 0x8000) { |
2402 | err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97[codec]); | 2402 | err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97[codec]); |
2403 | return err; | 2403 | return err; |
2404 | } | 2404 | } |
2405 | msleep(10); | 2405 | msleep(10); |
2406 | } | 2406 | } |
2407 | snd_printdd("snd_cs46xx: codec %d detection timeout\n", codec); | 2407 | snd_printdd("snd_cs46xx: codec %d detection timeout\n", codec); |
2408 | return -ENXIO; | 2408 | return -ENXIO; |
2409 | } | 2409 | } |
2410 | 2410 | ||
2411 | int __devinit snd_cs46xx_mixer(struct snd_cs46xx *chip, int spdif_device) | 2411 | int __devinit snd_cs46xx_mixer(struct snd_cs46xx *chip, int spdif_device) |
2412 | { | 2412 | { |
2413 | struct snd_card *card = chip->card; | 2413 | struct snd_card *card = chip->card; |
2414 | struct snd_ctl_elem_id id; | 2414 | struct snd_ctl_elem_id id; |
2415 | int err; | 2415 | int err; |
2416 | unsigned int idx; | 2416 | unsigned int idx; |
2417 | static struct snd_ac97_bus_ops ops = { | 2417 | static struct snd_ac97_bus_ops ops = { |
2418 | #ifdef CONFIG_SND_CS46XX_NEW_DSP | 2418 | #ifdef CONFIG_SND_CS46XX_NEW_DSP |
2419 | .reset = snd_cs46xx_codec_reset, | 2419 | .reset = snd_cs46xx_codec_reset, |
2420 | #endif | 2420 | #endif |
2421 | .write = snd_cs46xx_ac97_write, | 2421 | .write = snd_cs46xx_ac97_write, |
2422 | .read = snd_cs46xx_ac97_read, | 2422 | .read = snd_cs46xx_ac97_read, |
2423 | }; | 2423 | }; |
2424 | 2424 | ||
2425 | /* detect primary codec */ | 2425 | /* detect primary codec */ |
2426 | chip->nr_ac97_codecs = 0; | 2426 | chip->nr_ac97_codecs = 0; |
2427 | snd_printdd("snd_cs46xx: detecting primary codec\n"); | 2427 | snd_printdd("snd_cs46xx: detecting primary codec\n"); |
2428 | if ((err = snd_ac97_bus(card, 0, &ops, chip, &chip->ac97_bus)) < 0) | 2428 | if ((err = snd_ac97_bus(card, 0, &ops, chip, &chip->ac97_bus)) < 0) |
2429 | return err; | 2429 | return err; |
2430 | chip->ac97_bus->private_free = snd_cs46xx_mixer_free_ac97_bus; | 2430 | chip->ac97_bus->private_free = snd_cs46xx_mixer_free_ac97_bus; |
2431 | 2431 | ||
2432 | if (cs46xx_detect_codec(chip, CS46XX_PRIMARY_CODEC_INDEX) < 0) | 2432 | if (cs46xx_detect_codec(chip, CS46XX_PRIMARY_CODEC_INDEX) < 0) |
2433 | return -ENXIO; | 2433 | return -ENXIO; |
2434 | chip->nr_ac97_codecs = 1; | 2434 | chip->nr_ac97_codecs = 1; |
2435 | 2435 | ||
2436 | #ifdef CONFIG_SND_CS46XX_NEW_DSP | 2436 | #ifdef CONFIG_SND_CS46XX_NEW_DSP |
2437 | snd_printdd("snd_cs46xx: detecting seconadry codec\n"); | 2437 | snd_printdd("snd_cs46xx: detecting seconadry codec\n"); |
2438 | /* try detect a secondary codec */ | 2438 | /* try detect a secondary codec */ |
2439 | if (! cs46xx_detect_codec(chip, CS46XX_SECONDARY_CODEC_INDEX)) | 2439 | if (! cs46xx_detect_codec(chip, CS46XX_SECONDARY_CODEC_INDEX)) |
2440 | chip->nr_ac97_codecs = 2; | 2440 | chip->nr_ac97_codecs = 2; |
2441 | #endif /* CONFIG_SND_CS46XX_NEW_DSP */ | 2441 | #endif /* CONFIG_SND_CS46XX_NEW_DSP */ |
2442 | 2442 | ||
2443 | /* add cs4630 mixer controls */ | 2443 | /* add cs4630 mixer controls */ |
2444 | for (idx = 0; idx < ARRAY_SIZE(snd_cs46xx_controls); idx++) { | 2444 | for (idx = 0; idx < ARRAY_SIZE(snd_cs46xx_controls); idx++) { |
2445 | struct snd_kcontrol *kctl; | 2445 | struct snd_kcontrol *kctl; |
2446 | kctl = snd_ctl_new1(&snd_cs46xx_controls[idx], chip); | 2446 | kctl = snd_ctl_new1(&snd_cs46xx_controls[idx], chip); |
2447 | if (kctl && kctl->id.iface == SNDRV_CTL_ELEM_IFACE_PCM) | 2447 | if (kctl && kctl->id.iface == SNDRV_CTL_ELEM_IFACE_PCM) |
2448 | kctl->id.device = spdif_device; | 2448 | kctl->id.device = spdif_device; |
2449 | if ((err = snd_ctl_add(card, kctl)) < 0) | 2449 | if ((err = snd_ctl_add(card, kctl)) < 0) |
2450 | return err; | 2450 | return err; |
2451 | } | 2451 | } |
2452 | 2452 | ||
2453 | /* get EAPD mixer switch (for voyetra hack) */ | 2453 | /* get EAPD mixer switch (for voyetra hack) */ |
2454 | memset(&id, 0, sizeof(id)); | 2454 | memset(&id, 0, sizeof(id)); |
2455 | id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; | 2455 | id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; |
2456 | strcpy(id.name, "External Amplifier"); | 2456 | strcpy(id.name, "External Amplifier"); |
2457 | chip->eapd_switch = snd_ctl_find_id(chip->card, &id); | 2457 | chip->eapd_switch = snd_ctl_find_id(chip->card, &id); |
2458 | 2458 | ||
2459 | #ifdef CONFIG_SND_CS46XX_NEW_DSP | 2459 | #ifdef CONFIG_SND_CS46XX_NEW_DSP |
2460 | if (chip->nr_ac97_codecs == 1) { | 2460 | if (chip->nr_ac97_codecs == 1) { |
2461 | unsigned int id2 = chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]->id & 0xffff; | 2461 | unsigned int id2 = chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]->id & 0xffff; |
2462 | if (id2 == 0x592b || id2 == 0x592d) { | 2462 | if (id2 == 0x592b || id2 == 0x592d) { |
2463 | err = snd_ctl_add(card, snd_ctl_new1(&snd_cs46xx_front_dup_ctl, chip)); | 2463 | err = snd_ctl_add(card, snd_ctl_new1(&snd_cs46xx_front_dup_ctl, chip)); |
2464 | if (err < 0) | 2464 | if (err < 0) |
2465 | return err; | 2465 | return err; |
2466 | snd_ac97_write_cache(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX], | 2466 | snd_ac97_write_cache(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX], |
2467 | AC97_CSR_ACMODE, 0x200); | 2467 | AC97_CSR_ACMODE, 0x200); |
2468 | } | 2468 | } |
2469 | } | 2469 | } |
2470 | /* do soundcard specific mixer setup */ | 2470 | /* do soundcard specific mixer setup */ |
2471 | if (chip->mixer_init) { | 2471 | if (chip->mixer_init) { |
2472 | snd_printdd ("calling chip->mixer_init(chip);\n"); | 2472 | snd_printdd ("calling chip->mixer_init(chip);\n"); |
2473 | chip->mixer_init(chip); | 2473 | chip->mixer_init(chip); |
2474 | } | 2474 | } |
2475 | #endif | 2475 | #endif |
2476 | 2476 | ||
2477 | /* turn on amplifier */ | 2477 | /* turn on amplifier */ |
2478 | chip->amplifier_ctrl(chip, 1); | 2478 | chip->amplifier_ctrl(chip, 1); |
2479 | 2479 | ||
2480 | return 0; | 2480 | return 0; |
2481 | } | 2481 | } |
2482 | 2482 | ||
2483 | /* | 2483 | /* |
2484 | * RawMIDI interface | 2484 | * RawMIDI interface |
2485 | */ | 2485 | */ |
2486 | 2486 | ||
2487 | static void snd_cs46xx_midi_reset(struct snd_cs46xx *chip) | 2487 | static void snd_cs46xx_midi_reset(struct snd_cs46xx *chip) |
2488 | { | 2488 | { |
2489 | snd_cs46xx_pokeBA0(chip, BA0_MIDCR, MIDCR_MRST); | 2489 | snd_cs46xx_pokeBA0(chip, BA0_MIDCR, MIDCR_MRST); |
2490 | udelay(100); | 2490 | udelay(100); |
2491 | snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr); | 2491 | snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr); |
2492 | } | 2492 | } |
2493 | 2493 | ||
2494 | static int snd_cs46xx_midi_input_open(struct snd_rawmidi_substream *substream) | 2494 | static int snd_cs46xx_midi_input_open(struct snd_rawmidi_substream *substream) |
2495 | { | 2495 | { |
2496 | struct snd_cs46xx *chip = substream->rmidi->private_data; | 2496 | struct snd_cs46xx *chip = substream->rmidi->private_data; |
2497 | 2497 | ||
2498 | chip->active_ctrl(chip, 1); | 2498 | chip->active_ctrl(chip, 1); |
2499 | spin_lock_irq(&chip->reg_lock); | 2499 | spin_lock_irq(&chip->reg_lock); |
2500 | chip->uartm |= CS46XX_MODE_INPUT; | 2500 | chip->uartm |= CS46XX_MODE_INPUT; |
2501 | chip->midcr |= MIDCR_RXE; | 2501 | chip->midcr |= MIDCR_RXE; |
2502 | chip->midi_input = substream; | 2502 | chip->midi_input = substream; |
2503 | if (!(chip->uartm & CS46XX_MODE_OUTPUT)) { | 2503 | if (!(chip->uartm & CS46XX_MODE_OUTPUT)) { |
2504 | snd_cs46xx_midi_reset(chip); | 2504 | snd_cs46xx_midi_reset(chip); |
2505 | } else { | 2505 | } else { |
2506 | snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr); | 2506 | snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr); |
2507 | } | 2507 | } |
2508 | spin_unlock_irq(&chip->reg_lock); | 2508 | spin_unlock_irq(&chip->reg_lock); |
2509 | return 0; | 2509 | return 0; |
2510 | } | 2510 | } |
2511 | 2511 | ||
2512 | static int snd_cs46xx_midi_input_close(struct snd_rawmidi_substream *substream) | 2512 | static int snd_cs46xx_midi_input_close(struct snd_rawmidi_substream *substream) |
2513 | { | 2513 | { |
2514 | struct snd_cs46xx *chip = substream->rmidi->private_data; | 2514 | struct snd_cs46xx *chip = substream->rmidi->private_data; |
2515 | 2515 | ||
2516 | spin_lock_irq(&chip->reg_lock); | 2516 | spin_lock_irq(&chip->reg_lock); |
2517 | chip->midcr &= ~(MIDCR_RXE | MIDCR_RIE); | 2517 | chip->midcr &= ~(MIDCR_RXE | MIDCR_RIE); |
2518 | chip->midi_input = NULL; | 2518 | chip->midi_input = NULL; |
2519 | if (!(chip->uartm & CS46XX_MODE_OUTPUT)) { | 2519 | if (!(chip->uartm & CS46XX_MODE_OUTPUT)) { |
2520 | snd_cs46xx_midi_reset(chip); | 2520 | snd_cs46xx_midi_reset(chip); |
2521 | } else { | 2521 | } else { |
2522 | snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr); | 2522 | snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr); |
2523 | } | 2523 | } |
2524 | chip->uartm &= ~CS46XX_MODE_INPUT; | 2524 | chip->uartm &= ~CS46XX_MODE_INPUT; |
2525 | spin_unlock_irq(&chip->reg_lock); | 2525 | spin_unlock_irq(&chip->reg_lock); |
2526 | chip->active_ctrl(chip, -1); | 2526 | chip->active_ctrl(chip, -1); |
2527 | return 0; | 2527 | return 0; |
2528 | } | 2528 | } |
2529 | 2529 | ||
2530 | static int snd_cs46xx_midi_output_open(struct snd_rawmidi_substream *substream) | 2530 | static int snd_cs46xx_midi_output_open(struct snd_rawmidi_substream *substream) |
2531 | { | 2531 | { |
2532 | struct snd_cs46xx *chip = substream->rmidi->private_data; | 2532 | struct snd_cs46xx *chip = substream->rmidi->private_data; |
2533 | 2533 | ||
2534 | chip->active_ctrl(chip, 1); | 2534 | chip->active_ctrl(chip, 1); |
2535 | 2535 | ||
2536 | spin_lock_irq(&chip->reg_lock); | 2536 | spin_lock_irq(&chip->reg_lock); |
2537 | chip->uartm |= CS46XX_MODE_OUTPUT; | 2537 | chip->uartm |= CS46XX_MODE_OUTPUT; |
2538 | chip->midcr |= MIDCR_TXE; | 2538 | chip->midcr |= MIDCR_TXE; |
2539 | chip->midi_output = substream; | 2539 | chip->midi_output = substream; |
2540 | if (!(chip->uartm & CS46XX_MODE_INPUT)) { | 2540 | if (!(chip->uartm & CS46XX_MODE_INPUT)) { |
2541 | snd_cs46xx_midi_reset(chip); | 2541 | snd_cs46xx_midi_reset(chip); |
2542 | } else { | 2542 | } else { |
2543 | snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr); | 2543 | snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr); |
2544 | } | 2544 | } |
2545 | spin_unlock_irq(&chip->reg_lock); | 2545 | spin_unlock_irq(&chip->reg_lock); |
2546 | return 0; | 2546 | return 0; |
2547 | } | 2547 | } |
2548 | 2548 | ||
2549 | static int snd_cs46xx_midi_output_close(struct snd_rawmidi_substream *substream) | 2549 | static int snd_cs46xx_midi_output_close(struct snd_rawmidi_substream *substream) |
2550 | { | 2550 | { |
2551 | struct snd_cs46xx *chip = substream->rmidi->private_data; | 2551 | struct snd_cs46xx *chip = substream->rmidi->private_data; |
2552 | 2552 | ||
2553 | spin_lock_irq(&chip->reg_lock); | 2553 | spin_lock_irq(&chip->reg_lock); |
2554 | chip->midcr &= ~(MIDCR_TXE | MIDCR_TIE); | 2554 | chip->midcr &= ~(MIDCR_TXE | MIDCR_TIE); |
2555 | chip->midi_output = NULL; | 2555 | chip->midi_output = NULL; |
2556 | if (!(chip->uartm & CS46XX_MODE_INPUT)) { | 2556 | if (!(chip->uartm & CS46XX_MODE_INPUT)) { |
2557 | snd_cs46xx_midi_reset(chip); | 2557 | snd_cs46xx_midi_reset(chip); |
2558 | } else { | 2558 | } else { |
2559 | snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr); | 2559 | snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr); |
2560 | } | 2560 | } |
2561 | chip->uartm &= ~CS46XX_MODE_OUTPUT; | 2561 | chip->uartm &= ~CS46XX_MODE_OUTPUT; |
2562 | spin_unlock_irq(&chip->reg_lock); | 2562 | spin_unlock_irq(&chip->reg_lock); |
2563 | chip->active_ctrl(chip, -1); | 2563 | chip->active_ctrl(chip, -1); |
2564 | return 0; | 2564 | return 0; |
2565 | } | 2565 | } |
2566 | 2566 | ||
2567 | static void snd_cs46xx_midi_input_trigger(struct snd_rawmidi_substream *substream, int up) | 2567 | static void snd_cs46xx_midi_input_trigger(struct snd_rawmidi_substream *substream, int up) |
2568 | { | 2568 | { |
2569 | unsigned long flags; | 2569 | unsigned long flags; |
2570 | struct snd_cs46xx *chip = substream->rmidi->private_data; | 2570 | struct snd_cs46xx *chip = substream->rmidi->private_data; |
2571 | 2571 | ||
2572 | spin_lock_irqsave(&chip->reg_lock, flags); | 2572 | spin_lock_irqsave(&chip->reg_lock, flags); |
2573 | if (up) { | 2573 | if (up) { |
2574 | if ((chip->midcr & MIDCR_RIE) == 0) { | 2574 | if ((chip->midcr & MIDCR_RIE) == 0) { |
2575 | chip->midcr |= MIDCR_RIE; | 2575 | chip->midcr |= MIDCR_RIE; |
2576 | snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr); | 2576 | snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr); |
2577 | } | 2577 | } |
2578 | } else { | 2578 | } else { |
2579 | if (chip->midcr & MIDCR_RIE) { | 2579 | if (chip->midcr & MIDCR_RIE) { |
2580 | chip->midcr &= ~MIDCR_RIE; | 2580 | chip->midcr &= ~MIDCR_RIE; |
2581 | snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr); | 2581 | snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr); |
2582 | } | 2582 | } |
2583 | } | 2583 | } |
2584 | spin_unlock_irqrestore(&chip->reg_lock, flags); | 2584 | spin_unlock_irqrestore(&chip->reg_lock, flags); |
2585 | } | 2585 | } |
2586 | 2586 | ||
2587 | static void snd_cs46xx_midi_output_trigger(struct snd_rawmidi_substream *substream, int up) | 2587 | static void snd_cs46xx_midi_output_trigger(struct snd_rawmidi_substream *substream, int up) |
2588 | { | 2588 | { |
2589 | unsigned long flags; | 2589 | unsigned long flags; |
2590 | struct snd_cs46xx *chip = substream->rmidi->private_data; | 2590 | struct snd_cs46xx *chip = substream->rmidi->private_data; |
2591 | unsigned char byte; | 2591 | unsigned char byte; |
2592 | 2592 | ||
2593 | spin_lock_irqsave(&chip->reg_lock, flags); | 2593 | spin_lock_irqsave(&chip->reg_lock, flags); |
2594 | if (up) { | 2594 | if (up) { |
2595 | if ((chip->midcr & MIDCR_TIE) == 0) { | 2595 | if ((chip->midcr & MIDCR_TIE) == 0) { |
2596 | chip->midcr |= MIDCR_TIE; | 2596 | chip->midcr |= MIDCR_TIE; |
2597 | /* fill UART FIFO buffer at first, and turn Tx interrupts only if necessary */ | 2597 | /* fill UART FIFO buffer at first, and turn Tx interrupts only if necessary */ |
2598 | while ((chip->midcr & MIDCR_TIE) && | 2598 | while ((chip->midcr & MIDCR_TIE) && |
2599 | (snd_cs46xx_peekBA0(chip, BA0_MIDSR) & MIDSR_TBF) == 0) { | 2599 | (snd_cs46xx_peekBA0(chip, BA0_MIDSR) & MIDSR_TBF) == 0) { |
2600 | if (snd_rawmidi_transmit(substream, &byte, 1) != 1) { | 2600 | if (snd_rawmidi_transmit(substream, &byte, 1) != 1) { |
2601 | chip->midcr &= ~MIDCR_TIE; | 2601 | chip->midcr &= ~MIDCR_TIE; |
2602 | } else { | 2602 | } else { |
2603 | snd_cs46xx_pokeBA0(chip, BA0_MIDWP, byte); | 2603 | snd_cs46xx_pokeBA0(chip, BA0_MIDWP, byte); |
2604 | } | 2604 | } |
2605 | } | 2605 | } |
2606 | snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr); | 2606 | snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr); |
2607 | } | 2607 | } |
2608 | } else { | 2608 | } else { |
2609 | if (chip->midcr & MIDCR_TIE) { | 2609 | if (chip->midcr & MIDCR_TIE) { |
2610 | chip->midcr &= ~MIDCR_TIE; | 2610 | chip->midcr &= ~MIDCR_TIE; |
2611 | snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr); | 2611 | snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr); |
2612 | } | 2612 | } |
2613 | } | 2613 | } |
2614 | spin_unlock_irqrestore(&chip->reg_lock, flags); | 2614 | spin_unlock_irqrestore(&chip->reg_lock, flags); |
2615 | } | 2615 | } |
2616 | 2616 | ||
2617 | static struct snd_rawmidi_ops snd_cs46xx_midi_output = | 2617 | static struct snd_rawmidi_ops snd_cs46xx_midi_output = |
2618 | { | 2618 | { |
2619 | .open = snd_cs46xx_midi_output_open, | 2619 | .open = snd_cs46xx_midi_output_open, |
2620 | .close = snd_cs46xx_midi_output_close, | 2620 | .close = snd_cs46xx_midi_output_close, |
2621 | .trigger = snd_cs46xx_midi_output_trigger, | 2621 | .trigger = snd_cs46xx_midi_output_trigger, |
2622 | }; | 2622 | }; |
2623 | 2623 | ||
2624 | static struct snd_rawmidi_ops snd_cs46xx_midi_input = | 2624 | static struct snd_rawmidi_ops snd_cs46xx_midi_input = |
2625 | { | 2625 | { |
2626 | .open = snd_cs46xx_midi_input_open, | 2626 | .open = snd_cs46xx_midi_input_open, |
2627 | .close = snd_cs46xx_midi_input_close, | 2627 | .close = snd_cs46xx_midi_input_close, |
2628 | .trigger = snd_cs46xx_midi_input_trigger, | 2628 | .trigger = snd_cs46xx_midi_input_trigger, |
2629 | }; | 2629 | }; |
2630 | 2630 | ||
2631 | int __devinit snd_cs46xx_midi(struct snd_cs46xx *chip, int device, struct snd_rawmidi **rrawmidi) | 2631 | int __devinit snd_cs46xx_midi(struct snd_cs46xx *chip, int device, struct snd_rawmidi **rrawmidi) |
2632 | { | 2632 | { |
2633 | struct snd_rawmidi *rmidi; | 2633 | struct snd_rawmidi *rmidi; |
2634 | int err; | 2634 | int err; |
2635 | 2635 | ||
2636 | if (rrawmidi) | 2636 | if (rrawmidi) |
2637 | *rrawmidi = NULL; | 2637 | *rrawmidi = NULL; |
2638 | if ((err = snd_rawmidi_new(chip->card, "CS46XX", device, 1, 1, &rmidi)) < 0) | 2638 | if ((err = snd_rawmidi_new(chip->card, "CS46XX", device, 1, 1, &rmidi)) < 0) |
2639 | return err; | 2639 | return err; |
2640 | strcpy(rmidi->name, "CS46XX"); | 2640 | strcpy(rmidi->name, "CS46XX"); |
2641 | snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_cs46xx_midi_output); | 2641 | snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_cs46xx_midi_output); |
2642 | snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &snd_cs46xx_midi_input); | 2642 | snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &snd_cs46xx_midi_input); |
2643 | rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT | SNDRV_RAWMIDI_INFO_INPUT | SNDRV_RAWMIDI_INFO_DUPLEX; | 2643 | rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT | SNDRV_RAWMIDI_INFO_INPUT | SNDRV_RAWMIDI_INFO_DUPLEX; |
2644 | rmidi->private_data = chip; | 2644 | rmidi->private_data = chip; |
2645 | chip->rmidi = rmidi; | 2645 | chip->rmidi = rmidi; |
2646 | if (rrawmidi) | 2646 | if (rrawmidi) |
2647 | *rrawmidi = NULL; | 2647 | *rrawmidi = NULL; |
2648 | return 0; | 2648 | return 0; |
2649 | } | 2649 | } |
2650 | 2650 | ||
2651 | 2651 | ||
2652 | /* | 2652 | /* |
2653 | * gameport interface | 2653 | * gameport interface |
2654 | */ | 2654 | */ |
2655 | 2655 | ||
2656 | #if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE)) | 2656 | #if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE)) |
2657 | 2657 | ||
2658 | static void snd_cs46xx_gameport_trigger(struct gameport *gameport) | 2658 | static void snd_cs46xx_gameport_trigger(struct gameport *gameport) |
2659 | { | 2659 | { |
2660 | struct snd_cs46xx *chip = gameport_get_port_data(gameport); | 2660 | struct snd_cs46xx *chip = gameport_get_port_data(gameport); |
2661 | 2661 | ||
2662 | snd_assert(chip, return); | 2662 | snd_assert(chip, return); |
2663 | snd_cs46xx_pokeBA0(chip, BA0_JSPT, 0xFF); //outb(gameport->io, 0xFF); | 2663 | snd_cs46xx_pokeBA0(chip, BA0_JSPT, 0xFF); //outb(gameport->io, 0xFF); |
2664 | } | 2664 | } |
2665 | 2665 | ||
2666 | static unsigned char snd_cs46xx_gameport_read(struct gameport *gameport) | 2666 | static unsigned char snd_cs46xx_gameport_read(struct gameport *gameport) |
2667 | { | 2667 | { |
2668 | struct snd_cs46xx *chip = gameport_get_port_data(gameport); | 2668 | struct snd_cs46xx *chip = gameport_get_port_data(gameport); |
2669 | 2669 | ||
2670 | snd_assert(chip, return 0); | 2670 | snd_assert(chip, return 0); |
2671 | return snd_cs46xx_peekBA0(chip, BA0_JSPT); //inb(gameport->io); | 2671 | return snd_cs46xx_peekBA0(chip, BA0_JSPT); //inb(gameport->io); |
2672 | } | 2672 | } |
2673 | 2673 | ||
2674 | static int snd_cs46xx_gameport_cooked_read(struct gameport *gameport, int *axes, int *buttons) | 2674 | static int snd_cs46xx_gameport_cooked_read(struct gameport *gameport, int *axes, int *buttons) |
2675 | { | 2675 | { |
2676 | struct snd_cs46xx *chip = gameport_get_port_data(gameport); | 2676 | struct snd_cs46xx *chip = gameport_get_port_data(gameport); |
2677 | unsigned js1, js2, jst; | 2677 | unsigned js1, js2, jst; |
2678 | 2678 | ||
2679 | snd_assert(chip, return 0); | 2679 | snd_assert(chip, return 0); |
2680 | 2680 | ||
2681 | js1 = snd_cs46xx_peekBA0(chip, BA0_JSC1); | 2681 | js1 = snd_cs46xx_peekBA0(chip, BA0_JSC1); |
2682 | js2 = snd_cs46xx_peekBA0(chip, BA0_JSC2); | 2682 | js2 = snd_cs46xx_peekBA0(chip, BA0_JSC2); |
2683 | jst = snd_cs46xx_peekBA0(chip, BA0_JSPT); | 2683 | jst = snd_cs46xx_peekBA0(chip, BA0_JSPT); |
2684 | 2684 | ||
2685 | *buttons = (~jst >> 4) & 0x0F; | 2685 | *buttons = (~jst >> 4) & 0x0F; |
2686 | 2686 | ||
2687 | axes[0] = ((js1 & JSC1_Y1V_MASK) >> JSC1_Y1V_SHIFT) & 0xFFFF; | 2687 | axes[0] = ((js1 & JSC1_Y1V_MASK) >> JSC1_Y1V_SHIFT) & 0xFFFF; |
2688 | axes[1] = ((js1 & JSC1_X1V_MASK) >> JSC1_X1V_SHIFT) & 0xFFFF; | 2688 | axes[1] = ((js1 & JSC1_X1V_MASK) >> JSC1_X1V_SHIFT) & 0xFFFF; |
2689 | axes[2] = ((js2 & JSC2_Y2V_MASK) >> JSC2_Y2V_SHIFT) & 0xFFFF; | 2689 | axes[2] = ((js2 & JSC2_Y2V_MASK) >> JSC2_Y2V_SHIFT) & 0xFFFF; |
2690 | axes[3] = ((js2 & JSC2_X2V_MASK) >> JSC2_X2V_SHIFT) & 0xFFFF; | 2690 | axes[3] = ((js2 & JSC2_X2V_MASK) >> JSC2_X2V_SHIFT) & 0xFFFF; |
2691 | 2691 | ||
2692 | for(jst=0;jst<4;++jst) | 2692 | for(jst=0;jst<4;++jst) |
2693 | if(axes[jst]==0xFFFF) axes[jst] = -1; | 2693 | if(axes[jst]==0xFFFF) axes[jst] = -1; |
2694 | return 0; | 2694 | return 0; |
2695 | } | 2695 | } |
2696 | 2696 | ||
2697 | static int snd_cs46xx_gameport_open(struct gameport *gameport, int mode) | 2697 | static int snd_cs46xx_gameport_open(struct gameport *gameport, int mode) |
2698 | { | 2698 | { |
2699 | switch (mode) { | 2699 | switch (mode) { |
2700 | case GAMEPORT_MODE_COOKED: | 2700 | case GAMEPORT_MODE_COOKED: |
2701 | return 0; | 2701 | return 0; |
2702 | case GAMEPORT_MODE_RAW: | 2702 | case GAMEPORT_MODE_RAW: |
2703 | return 0; | 2703 | return 0; |
2704 | default: | 2704 | default: |
2705 | return -1; | 2705 | return -1; |
2706 | } | 2706 | } |
2707 | return 0; | 2707 | return 0; |
2708 | } | 2708 | } |
2709 | 2709 | ||
2710 | int __devinit snd_cs46xx_gameport(struct snd_cs46xx *chip) | 2710 | int __devinit snd_cs46xx_gameport(struct snd_cs46xx *chip) |
2711 | { | 2711 | { |
2712 | struct gameport *gp; | 2712 | struct gameport *gp; |
2713 | 2713 | ||
2714 | chip->gameport = gp = gameport_allocate_port(); | 2714 | chip->gameport = gp = gameport_allocate_port(); |
2715 | if (!gp) { | 2715 | if (!gp) { |
2716 | printk(KERN_ERR "cs46xx: cannot allocate memory for gameport\n"); | 2716 | printk(KERN_ERR "cs46xx: cannot allocate memory for gameport\n"); |
2717 | return -ENOMEM; | 2717 | return -ENOMEM; |
2718 | } | 2718 | } |
2719 | 2719 | ||
2720 | gameport_set_name(gp, "CS46xx Gameport"); | 2720 | gameport_set_name(gp, "CS46xx Gameport"); |
2721 | gameport_set_phys(gp, "pci%s/gameport0", pci_name(chip->pci)); | 2721 | gameport_set_phys(gp, "pci%s/gameport0", pci_name(chip->pci)); |
2722 | gameport_set_dev_parent(gp, &chip->pci->dev); | 2722 | gameport_set_dev_parent(gp, &chip->pci->dev); |
2723 | gameport_set_port_data(gp, chip); | 2723 | gameport_set_port_data(gp, chip); |
2724 | 2724 | ||
2725 | gp->open = snd_cs46xx_gameport_open; | 2725 | gp->open = snd_cs46xx_gameport_open; |
2726 | gp->read = snd_cs46xx_gameport_read; | 2726 | gp->read = snd_cs46xx_gameport_read; |
2727 | gp->trigger = snd_cs46xx_gameport_trigger; | 2727 | gp->trigger = snd_cs46xx_gameport_trigger; |
2728 | gp->cooked_read = snd_cs46xx_gameport_cooked_read; | 2728 | gp->cooked_read = snd_cs46xx_gameport_cooked_read; |
2729 | 2729 | ||
2730 | snd_cs46xx_pokeBA0(chip, BA0_JSIO, 0xFF); // ? | 2730 | snd_cs46xx_pokeBA0(chip, BA0_JSIO, 0xFF); // ? |
2731 | snd_cs46xx_pokeBA0(chip, BA0_JSCTL, JSCTL_SP_MEDIUM_SLOW); | 2731 | snd_cs46xx_pokeBA0(chip, BA0_JSCTL, JSCTL_SP_MEDIUM_SLOW); |
2732 | 2732 | ||
2733 | gameport_register_port(gp); | 2733 | gameport_register_port(gp); |
2734 | 2734 | ||
2735 | return 0; | 2735 | return 0; |
2736 | } | 2736 | } |
2737 | 2737 | ||
2738 | static inline void snd_cs46xx_remove_gameport(struct snd_cs46xx *chip) | 2738 | static inline void snd_cs46xx_remove_gameport(struct snd_cs46xx *chip) |
2739 | { | 2739 | { |
2740 | if (chip->gameport) { | 2740 | if (chip->gameport) { |
2741 | gameport_unregister_port(chip->gameport); | 2741 | gameport_unregister_port(chip->gameport); |
2742 | chip->gameport = NULL; | 2742 | chip->gameport = NULL; |
2743 | } | 2743 | } |
2744 | } | 2744 | } |
2745 | #else | 2745 | #else |
2746 | int __devinit snd_cs46xx_gameport(struct snd_cs46xx *chip) { return -ENOSYS; } | 2746 | int __devinit snd_cs46xx_gameport(struct snd_cs46xx *chip) { return -ENOSYS; } |
2747 | static inline void snd_cs46xx_remove_gameport(struct snd_cs46xx *chip) { } | 2747 | static inline void snd_cs46xx_remove_gameport(struct snd_cs46xx *chip) { } |
2748 | #endif /* CONFIG_GAMEPORT */ | 2748 | #endif /* CONFIG_GAMEPORT */ |
2749 | 2749 | ||
2750 | /* | 2750 | /* |
2751 | * proc interface | 2751 | * proc interface |
2752 | */ | 2752 | */ |
2753 | 2753 | ||
2754 | static long snd_cs46xx_io_read(struct snd_info_entry *entry, void *file_private_data, | 2754 | static long snd_cs46xx_io_read(struct snd_info_entry *entry, void *file_private_data, |
2755 | struct file *file, char __user *buf, | 2755 | struct file *file, char __user *buf, |
2756 | unsigned long count, unsigned long pos) | 2756 | unsigned long count, unsigned long pos) |
2757 | { | 2757 | { |
2758 | long size; | 2758 | long size; |
2759 | struct snd_cs46xx_region *region = entry->private_data; | 2759 | struct snd_cs46xx_region *region = entry->private_data; |
2760 | 2760 | ||
2761 | size = count; | 2761 | size = count; |
2762 | if (pos + (size_t)size > region->size) | 2762 | if (pos + (size_t)size > region->size) |
2763 | size = region->size - pos; | 2763 | size = region->size - pos; |
2764 | if (size > 0) { | 2764 | if (size > 0) { |
2765 | if (copy_to_user_fromio(buf, region->remap_addr + pos, size)) | 2765 | if (copy_to_user_fromio(buf, region->remap_addr + pos, size)) |
2766 | return -EFAULT; | 2766 | return -EFAULT; |
2767 | } | 2767 | } |
2768 | return size; | 2768 | return size; |
2769 | } | 2769 | } |
2770 | 2770 | ||
2771 | static struct snd_info_entry_ops snd_cs46xx_proc_io_ops = { | 2771 | static struct snd_info_entry_ops snd_cs46xx_proc_io_ops = { |
2772 | .read = snd_cs46xx_io_read, | 2772 | .read = snd_cs46xx_io_read, |
2773 | }; | 2773 | }; |
2774 | 2774 | ||
2775 | static int __devinit snd_cs46xx_proc_init(struct snd_card *card, struct snd_cs46xx *chip) | 2775 | static int __devinit snd_cs46xx_proc_init(struct snd_card *card, struct snd_cs46xx *chip) |
2776 | { | 2776 | { |
2777 | struct snd_info_entry *entry; | 2777 | struct snd_info_entry *entry; |
2778 | int idx; | 2778 | int idx; |
2779 | 2779 | ||
2780 | for (idx = 0; idx < 5; idx++) { | 2780 | for (idx = 0; idx < 5; idx++) { |
2781 | struct snd_cs46xx_region *region = &chip->region.idx[idx]; | 2781 | struct snd_cs46xx_region *region = &chip->region.idx[idx]; |
2782 | if (! snd_card_proc_new(card, region->name, &entry)) { | 2782 | if (! snd_card_proc_new(card, region->name, &entry)) { |
2783 | entry->content = SNDRV_INFO_CONTENT_DATA; | 2783 | entry->content = SNDRV_INFO_CONTENT_DATA; |
2784 | entry->private_data = chip; | 2784 | entry->private_data = chip; |
2785 | entry->c.ops = &snd_cs46xx_proc_io_ops; | 2785 | entry->c.ops = &snd_cs46xx_proc_io_ops; |
2786 | entry->size = region->size; | 2786 | entry->size = region->size; |
2787 | entry->mode = S_IFREG | S_IRUSR; | 2787 | entry->mode = S_IFREG | S_IRUSR; |
2788 | } | 2788 | } |
2789 | } | 2789 | } |
2790 | #ifdef CONFIG_SND_CS46XX_NEW_DSP | 2790 | #ifdef CONFIG_SND_CS46XX_NEW_DSP |
2791 | cs46xx_dsp_proc_init(card, chip); | 2791 | cs46xx_dsp_proc_init(card, chip); |
2792 | #endif | 2792 | #endif |
2793 | return 0; | 2793 | return 0; |
2794 | } | 2794 | } |
2795 | 2795 | ||
2796 | static int snd_cs46xx_proc_done(struct snd_cs46xx *chip) | 2796 | static int snd_cs46xx_proc_done(struct snd_cs46xx *chip) |
2797 | { | 2797 | { |
2798 | #ifdef CONFIG_SND_CS46XX_NEW_DSP | 2798 | #ifdef CONFIG_SND_CS46XX_NEW_DSP |
2799 | cs46xx_dsp_proc_done(chip); | 2799 | cs46xx_dsp_proc_done(chip); |
2800 | #endif | 2800 | #endif |
2801 | return 0; | 2801 | return 0; |
2802 | } | 2802 | } |
2803 | 2803 | ||
2804 | /* | 2804 | /* |
2805 | * stop the h/w | 2805 | * stop the h/w |
2806 | */ | 2806 | */ |
2807 | static void snd_cs46xx_hw_stop(struct snd_cs46xx *chip) | 2807 | static void snd_cs46xx_hw_stop(struct snd_cs46xx *chip) |
2808 | { | 2808 | { |
2809 | unsigned int tmp; | 2809 | unsigned int tmp; |
2810 | 2810 | ||
2811 | tmp = snd_cs46xx_peek(chip, BA1_PFIE); | 2811 | tmp = snd_cs46xx_peek(chip, BA1_PFIE); |
2812 | tmp &= ~0x0000f03f; | 2812 | tmp &= ~0x0000f03f; |
2813 | tmp |= 0x00000010; | 2813 | tmp |= 0x00000010; |
2814 | snd_cs46xx_poke(chip, BA1_PFIE, tmp); /* playback interrupt disable */ | 2814 | snd_cs46xx_poke(chip, BA1_PFIE, tmp); /* playback interrupt disable */ |
2815 | 2815 | ||
2816 | tmp = snd_cs46xx_peek(chip, BA1_CIE); | 2816 | tmp = snd_cs46xx_peek(chip, BA1_CIE); |
2817 | tmp &= ~0x0000003f; | 2817 | tmp &= ~0x0000003f; |
2818 | tmp |= 0x00000011; | 2818 | tmp |= 0x00000011; |
2819 | snd_cs46xx_poke(chip, BA1_CIE, tmp); /* capture interrupt disable */ | 2819 | snd_cs46xx_poke(chip, BA1_CIE, tmp); /* capture interrupt disable */ |
2820 | 2820 | ||
2821 | /* | 2821 | /* |
2822 | * Stop playback DMA. | 2822 | * Stop playback DMA. |
2823 | */ | 2823 | */ |
2824 | tmp = snd_cs46xx_peek(chip, BA1_PCTL); | 2824 | tmp = snd_cs46xx_peek(chip, BA1_PCTL); |
2825 | snd_cs46xx_poke(chip, BA1_PCTL, tmp & 0x0000ffff); | 2825 | snd_cs46xx_poke(chip, BA1_PCTL, tmp & 0x0000ffff); |
2826 | 2826 | ||
2827 | /* | 2827 | /* |
2828 | * Stop capture DMA. | 2828 | * Stop capture DMA. |
2829 | */ | 2829 | */ |
2830 | tmp = snd_cs46xx_peek(chip, BA1_CCTL); | 2830 | tmp = snd_cs46xx_peek(chip, BA1_CCTL); |
2831 | snd_cs46xx_poke(chip, BA1_CCTL, tmp & 0xffff0000); | 2831 | snd_cs46xx_poke(chip, BA1_CCTL, tmp & 0xffff0000); |
2832 | 2832 | ||
2833 | /* | 2833 | /* |
2834 | * Reset the processor. | 2834 | * Reset the processor. |
2835 | */ | 2835 | */ |
2836 | snd_cs46xx_reset(chip); | 2836 | snd_cs46xx_reset(chip); |
2837 | 2837 | ||
2838 | snd_cs46xx_proc_stop(chip); | 2838 | snd_cs46xx_proc_stop(chip); |
2839 | 2839 | ||
2840 | /* | 2840 | /* |
2841 | * Power down the PLL. | 2841 | * Power down the PLL. |
2842 | */ | 2842 | */ |
2843 | snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, 0); | 2843 | snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, 0); |
2844 | 2844 | ||
2845 | /* | 2845 | /* |
2846 | * Turn off the Processor by turning off the software clock enable flag in | 2846 | * Turn off the Processor by turning off the software clock enable flag in |
2847 | * the clock control register. | 2847 | * the clock control register. |
2848 | */ | 2848 | */ |
2849 | tmp = snd_cs46xx_peekBA0(chip, BA0_CLKCR1) & ~CLKCR1_SWCE; | 2849 | tmp = snd_cs46xx_peekBA0(chip, BA0_CLKCR1) & ~CLKCR1_SWCE; |
2850 | snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, tmp); | 2850 | snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, tmp); |
2851 | } | 2851 | } |
2852 | 2852 | ||
2853 | 2853 | ||
2854 | static int snd_cs46xx_free(struct snd_cs46xx *chip) | 2854 | static int snd_cs46xx_free(struct snd_cs46xx *chip) |
2855 | { | 2855 | { |
2856 | int idx; | 2856 | int idx; |
2857 | 2857 | ||
2858 | snd_assert(chip != NULL, return -EINVAL); | 2858 | snd_assert(chip != NULL, return -EINVAL); |
2859 | 2859 | ||
2860 | if (chip->active_ctrl) | 2860 | if (chip->active_ctrl) |
2861 | chip->active_ctrl(chip, 1); | 2861 | chip->active_ctrl(chip, 1); |
2862 | 2862 | ||
2863 | snd_cs46xx_remove_gameport(chip); | 2863 | snd_cs46xx_remove_gameport(chip); |
2864 | 2864 | ||
2865 | if (chip->amplifier_ctrl) | 2865 | if (chip->amplifier_ctrl) |
2866 | chip->amplifier_ctrl(chip, -chip->amplifier); /* force to off */ | 2866 | chip->amplifier_ctrl(chip, -chip->amplifier); /* force to off */ |
2867 | 2867 | ||
2868 | snd_cs46xx_proc_done(chip); | 2868 | snd_cs46xx_proc_done(chip); |
2869 | 2869 | ||
2870 | if (chip->region.idx[0].resource) | 2870 | if (chip->region.idx[0].resource) |
2871 | snd_cs46xx_hw_stop(chip); | 2871 | snd_cs46xx_hw_stop(chip); |
2872 | 2872 | ||
2873 | for (idx = 0; idx < 5; idx++) { | 2873 | for (idx = 0; idx < 5; idx++) { |
2874 | struct snd_cs46xx_region *region = &chip->region.idx[idx]; | 2874 | struct snd_cs46xx_region *region = &chip->region.idx[idx]; |
2875 | if (region->remap_addr) | 2875 | if (region->remap_addr) |
2876 | iounmap(region->remap_addr); | 2876 | iounmap(region->remap_addr); |
2877 | release_and_free_resource(region->resource); | 2877 | release_and_free_resource(region->resource); |
2878 | } | 2878 | } |
2879 | if (chip->irq >= 0) | 2879 | if (chip->irq >= 0) |
2880 | free_irq(chip->irq, chip); | 2880 | free_irq(chip->irq, chip); |
2881 | 2881 | ||
2882 | if (chip->active_ctrl) | 2882 | if (chip->active_ctrl) |
2883 | chip->active_ctrl(chip, -chip->amplifier); | 2883 | chip->active_ctrl(chip, -chip->amplifier); |
2884 | 2884 | ||
2885 | #ifdef CONFIG_SND_CS46XX_NEW_DSP | 2885 | #ifdef CONFIG_SND_CS46XX_NEW_DSP |
2886 | if (chip->dsp_spos_instance) { | 2886 | if (chip->dsp_spos_instance) { |
2887 | cs46xx_dsp_spos_destroy(chip); | 2887 | cs46xx_dsp_spos_destroy(chip); |
2888 | chip->dsp_spos_instance = NULL; | 2888 | chip->dsp_spos_instance = NULL; |
2889 | } | 2889 | } |
2890 | #endif | 2890 | #endif |
2891 | 2891 | ||
2892 | pci_disable_device(chip->pci); | 2892 | pci_disable_device(chip->pci); |
2893 | kfree(chip); | 2893 | kfree(chip); |
2894 | return 0; | 2894 | return 0; |
2895 | } | 2895 | } |
2896 | 2896 | ||
2897 | static int snd_cs46xx_dev_free(struct snd_device *device) | 2897 | static int snd_cs46xx_dev_free(struct snd_device *device) |
2898 | { | 2898 | { |
2899 | struct snd_cs46xx *chip = device->device_data; | 2899 | struct snd_cs46xx *chip = device->device_data; |
2900 | return snd_cs46xx_free(chip); | 2900 | return snd_cs46xx_free(chip); |
2901 | } | 2901 | } |
2902 | 2902 | ||
2903 | /* | 2903 | /* |
2904 | * initialize chip | 2904 | * initialize chip |
2905 | */ | 2905 | */ |
2906 | static int snd_cs46xx_chip_init(struct snd_cs46xx *chip) | 2906 | static int snd_cs46xx_chip_init(struct snd_cs46xx *chip) |
2907 | { | 2907 | { |
2908 | int timeout; | 2908 | int timeout; |
2909 | 2909 | ||
2910 | /* | 2910 | /* |
2911 | * First, blast the clock control register to zero so that the PLL starts | 2911 | * First, blast the clock control register to zero so that the PLL starts |
2912 | * out in a known state, and blast the master serial port control register | 2912 | * out in a known state, and blast the master serial port control register |
2913 | * to zero so that the serial ports also start out in a known state. | 2913 | * to zero so that the serial ports also start out in a known state. |
2914 | */ | 2914 | */ |
2915 | snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, 0); | 2915 | snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, 0); |
2916 | snd_cs46xx_pokeBA0(chip, BA0_SERMC1, 0); | 2916 | snd_cs46xx_pokeBA0(chip, BA0_SERMC1, 0); |
2917 | 2917 | ||
2918 | /* | 2918 | /* |
2919 | * If we are in AC97 mode, then we must set the part to a host controlled | 2919 | * If we are in AC97 mode, then we must set the part to a host controlled |
2920 | * AC-link. Otherwise, we won't be able to bring up the link. | 2920 | * AC-link. Otherwise, we won't be able to bring up the link. |
2921 | */ | 2921 | */ |
2922 | #ifdef CONFIG_SND_CS46XX_NEW_DSP | 2922 | #ifdef CONFIG_SND_CS46XX_NEW_DSP |
2923 | snd_cs46xx_pokeBA0(chip, BA0_SERACC, SERACC_HSP | SERACC_CHIP_TYPE_2_0 | | 2923 | snd_cs46xx_pokeBA0(chip, BA0_SERACC, SERACC_HSP | SERACC_CHIP_TYPE_2_0 | |
2924 | SERACC_TWO_CODECS); /* 2.00 dual codecs */ | 2924 | SERACC_TWO_CODECS); /* 2.00 dual codecs */ |
2925 | /* snd_cs46xx_pokeBA0(chip, BA0_SERACC, SERACC_HSP | SERACC_CHIP_TYPE_2_0); */ /* 2.00 codec */ | 2925 | /* snd_cs46xx_pokeBA0(chip, BA0_SERACC, SERACC_HSP | SERACC_CHIP_TYPE_2_0); */ /* 2.00 codec */ |
2926 | #else | 2926 | #else |
2927 | snd_cs46xx_pokeBA0(chip, BA0_SERACC, SERACC_HSP | SERACC_CHIP_TYPE_1_03); /* 1.03 codec */ | 2927 | snd_cs46xx_pokeBA0(chip, BA0_SERACC, SERACC_HSP | SERACC_CHIP_TYPE_1_03); /* 1.03 codec */ |
2928 | #endif | 2928 | #endif |
2929 | 2929 | ||
2930 | /* | 2930 | /* |
2931 | * Drive the ARST# pin low for a minimum of 1uS (as defined in the AC97 | 2931 | * Drive the ARST# pin low for a minimum of 1uS (as defined in the AC97 |
2932 | * spec) and then drive it high. This is done for non AC97 modes since | 2932 | * spec) and then drive it high. This is done for non AC97 modes since |
2933 | * there might be logic external to the CS461x that uses the ARST# line | 2933 | * there might be logic external to the CS461x that uses the ARST# line |
2934 | * for a reset. | 2934 | * for a reset. |
2935 | */ | 2935 | */ |
2936 | snd_cs46xx_pokeBA0(chip, BA0_ACCTL, 0); | 2936 | snd_cs46xx_pokeBA0(chip, BA0_ACCTL, 0); |
2937 | #ifdef CONFIG_SND_CS46XX_NEW_DSP | 2937 | #ifdef CONFIG_SND_CS46XX_NEW_DSP |
2938 | snd_cs46xx_pokeBA0(chip, BA0_ACCTL2, 0); | 2938 | snd_cs46xx_pokeBA0(chip, BA0_ACCTL2, 0); |
2939 | #endif | 2939 | #endif |
2940 | udelay(50); | 2940 | udelay(50); |
2941 | snd_cs46xx_pokeBA0(chip, BA0_ACCTL, ACCTL_RSTN); | 2941 | snd_cs46xx_pokeBA0(chip, BA0_ACCTL, ACCTL_RSTN); |
2942 | #ifdef CONFIG_SND_CS46XX_NEW_DSP | 2942 | #ifdef CONFIG_SND_CS46XX_NEW_DSP |
2943 | snd_cs46xx_pokeBA0(chip, BA0_ACCTL2, ACCTL_RSTN); | 2943 | snd_cs46xx_pokeBA0(chip, BA0_ACCTL2, ACCTL_RSTN); |
2944 | #endif | 2944 | #endif |
2945 | 2945 | ||
2946 | /* | 2946 | /* |
2947 | * The first thing we do here is to enable sync generation. As soon | 2947 | * The first thing we do here is to enable sync generation. As soon |
2948 | * as we start receiving bit clock, we'll start producing the SYNC | 2948 | * as we start receiving bit clock, we'll start producing the SYNC |
2949 | * signal. | 2949 | * signal. |
2950 | */ | 2950 | */ |
2951 | snd_cs46xx_pokeBA0(chip, BA0_ACCTL, ACCTL_ESYN | ACCTL_RSTN); | 2951 | snd_cs46xx_pokeBA0(chip, BA0_ACCTL, ACCTL_ESYN | ACCTL_RSTN); |
2952 | #ifdef CONFIG_SND_CS46XX_NEW_DSP | 2952 | #ifdef CONFIG_SND_CS46XX_NEW_DSP |
2953 | snd_cs46xx_pokeBA0(chip, BA0_ACCTL2, ACCTL_ESYN | ACCTL_RSTN); | 2953 | snd_cs46xx_pokeBA0(chip, BA0_ACCTL2, ACCTL_ESYN | ACCTL_RSTN); |
2954 | #endif | 2954 | #endif |
2955 | 2955 | ||
2956 | /* | 2956 | /* |
2957 | * Now wait for a short while to allow the AC97 part to start | 2957 | * Now wait for a short while to allow the AC97 part to start |
2958 | * generating bit clock (so we don't try to start the PLL without an | 2958 | * generating bit clock (so we don't try to start the PLL without an |
2959 | * input clock). | 2959 | * input clock). |
2960 | */ | 2960 | */ |
2961 | mdelay(10); | 2961 | mdelay(10); |
2962 | 2962 | ||
2963 | /* | 2963 | /* |
2964 | * Set the serial port timing configuration, so that | 2964 | * Set the serial port timing configuration, so that |
2965 | * the clock control circuit gets its clock from the correct place. | 2965 | * the clock control circuit gets its clock from the correct place. |
2966 | */ | 2966 | */ |
2967 | snd_cs46xx_pokeBA0(chip, BA0_SERMC1, SERMC1_PTC_AC97); | 2967 | snd_cs46xx_pokeBA0(chip, BA0_SERMC1, SERMC1_PTC_AC97); |
2968 | 2968 | ||
2969 | /* | 2969 | /* |
2970 | * Write the selected clock control setup to the hardware. Do not turn on | 2970 | * Write the selected clock control setup to the hardware. Do not turn on |
2971 | * SWCE yet (if requested), so that the devices clocked by the output of | 2971 | * SWCE yet (if requested), so that the devices clocked by the output of |
2972 | * PLL are not clocked until the PLL is stable. | 2972 | * PLL are not clocked until the PLL is stable. |
2973 | */ | 2973 | */ |
2974 | snd_cs46xx_pokeBA0(chip, BA0_PLLCC, PLLCC_LPF_1050_2780_KHZ | PLLCC_CDR_73_104_MHZ); | 2974 | snd_cs46xx_pokeBA0(chip, BA0_PLLCC, PLLCC_LPF_1050_2780_KHZ | PLLCC_CDR_73_104_MHZ); |
2975 | snd_cs46xx_pokeBA0(chip, BA0_PLLM, 0x3a); | 2975 | snd_cs46xx_pokeBA0(chip, BA0_PLLM, 0x3a); |
2976 | snd_cs46xx_pokeBA0(chip, BA0_CLKCR2, CLKCR2_PDIVS_8); | 2976 | snd_cs46xx_pokeBA0(chip, BA0_CLKCR2, CLKCR2_PDIVS_8); |
2977 | 2977 | ||
2978 | /* | 2978 | /* |
2979 | * Power up the PLL. | 2979 | * Power up the PLL. |
2980 | */ | 2980 | */ |
2981 | snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, CLKCR1_PLLP); | 2981 | snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, CLKCR1_PLLP); |
2982 | 2982 | ||
2983 | /* | 2983 | /* |
2984 | * Wait until the PLL has stabilized. | 2984 | * Wait until the PLL has stabilized. |
2985 | */ | 2985 | */ |
2986 | msleep(100); | 2986 | msleep(100); |
2987 | 2987 | ||
2988 | /* | 2988 | /* |
2989 | * Turn on clocking of the core so that we can setup the serial ports. | 2989 | * Turn on clocking of the core so that we can setup the serial ports. |
2990 | */ | 2990 | */ |
2991 | snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, CLKCR1_PLLP | CLKCR1_SWCE); | 2991 | snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, CLKCR1_PLLP | CLKCR1_SWCE); |
2992 | 2992 | ||
2993 | /* | 2993 | /* |
2994 | * Enable FIFO Host Bypass | 2994 | * Enable FIFO Host Bypass |
2995 | */ | 2995 | */ |
2996 | snd_cs46xx_pokeBA0(chip, BA0_SERBCF, SERBCF_HBP); | 2996 | snd_cs46xx_pokeBA0(chip, BA0_SERBCF, SERBCF_HBP); |
2997 | 2997 | ||
2998 | /* | 2998 | /* |
2999 | * Fill the serial port FIFOs with silence. | 2999 | * Fill the serial port FIFOs with silence. |
3000 | */ | 3000 | */ |
3001 | snd_cs46xx_clear_serial_FIFOs(chip); | 3001 | snd_cs46xx_clear_serial_FIFOs(chip); |
3002 | 3002 | ||
3003 | /* | 3003 | /* |
3004 | * Set the serial port FIFO pointer to the first sample in the FIFO. | 3004 | * Set the serial port FIFO pointer to the first sample in the FIFO. |
3005 | */ | 3005 | */ |
3006 | /* snd_cs46xx_pokeBA0(chip, BA0_SERBSP, 0); */ | 3006 | /* snd_cs46xx_pokeBA0(chip, BA0_SERBSP, 0); */ |
3007 | 3007 | ||
3008 | /* | 3008 | /* |
3009 | * Write the serial port configuration to the part. The master | 3009 | * Write the serial port configuration to the part. The master |
3010 | * enable bit is not set until all other values have been written. | 3010 | * enable bit is not set until all other values have been written. |
3011 | */ | 3011 | */ |
3012 | snd_cs46xx_pokeBA0(chip, BA0_SERC1, SERC1_SO1F_AC97 | SERC1_SO1EN); | 3012 | snd_cs46xx_pokeBA0(chip, BA0_SERC1, SERC1_SO1F_AC97 | SERC1_SO1EN); |
3013 | snd_cs46xx_pokeBA0(chip, BA0_SERC2, SERC2_SI1F_AC97 | SERC1_SO1EN); | 3013 | snd_cs46xx_pokeBA0(chip, BA0_SERC2, SERC2_SI1F_AC97 | SERC1_SO1EN); |
3014 | snd_cs46xx_pokeBA0(chip, BA0_SERMC1, SERMC1_PTC_AC97 | SERMC1_MSPE); | 3014 | snd_cs46xx_pokeBA0(chip, BA0_SERMC1, SERMC1_PTC_AC97 | SERMC1_MSPE); |
3015 | 3015 | ||
3016 | 3016 | ||
3017 | #ifdef CONFIG_SND_CS46XX_NEW_DSP | 3017 | #ifdef CONFIG_SND_CS46XX_NEW_DSP |
3018 | snd_cs46xx_pokeBA0(chip, BA0_SERC7, SERC7_ASDI2EN); | 3018 | snd_cs46xx_pokeBA0(chip, BA0_SERC7, SERC7_ASDI2EN); |
3019 | snd_cs46xx_pokeBA0(chip, BA0_SERC3, 0); | 3019 | snd_cs46xx_pokeBA0(chip, BA0_SERC3, 0); |
3020 | snd_cs46xx_pokeBA0(chip, BA0_SERC4, 0); | 3020 | snd_cs46xx_pokeBA0(chip, BA0_SERC4, 0); |
3021 | snd_cs46xx_pokeBA0(chip, BA0_SERC5, 0); | 3021 | snd_cs46xx_pokeBA0(chip, BA0_SERC5, 0); |
3022 | snd_cs46xx_pokeBA0(chip, BA0_SERC6, 1); | 3022 | snd_cs46xx_pokeBA0(chip, BA0_SERC6, 1); |
3023 | #endif | 3023 | #endif |
3024 | 3024 | ||
3025 | mdelay(5); | 3025 | mdelay(5); |
3026 | 3026 | ||
3027 | 3027 | ||
3028 | /* | 3028 | /* |
3029 | * Wait for the codec ready signal from the AC97 codec. | 3029 | * Wait for the codec ready signal from the AC97 codec. |
3030 | */ | 3030 | */ |
3031 | timeout = 150; | 3031 | timeout = 150; |
3032 | while (timeout-- > 0) { | 3032 | while (timeout-- > 0) { |
3033 | /* | 3033 | /* |
3034 | * Read the AC97 status register to see if we've seen a CODEC READY | 3034 | * Read the AC97 status register to see if we've seen a CODEC READY |
3035 | * signal from the AC97 codec. | 3035 | * signal from the AC97 codec. |
3036 | */ | 3036 | */ |
3037 | if (snd_cs46xx_peekBA0(chip, BA0_ACSTS) & ACSTS_CRDY) | 3037 | if (snd_cs46xx_peekBA0(chip, BA0_ACSTS) & ACSTS_CRDY) |
3038 | goto ok1; | 3038 | goto ok1; |
3039 | msleep(10); | 3039 | msleep(10); |
3040 | } | 3040 | } |
3041 | 3041 | ||
3042 | 3042 | ||
3043 | snd_printk(KERN_ERR "create - never read codec ready from AC'97\n"); | 3043 | snd_printk(KERN_ERR "create - never read codec ready from AC'97\n"); |
3044 | snd_printk(KERN_ERR "it is not probably bug, try to use CS4236 driver\n"); | 3044 | snd_printk(KERN_ERR "it is not probably bug, try to use CS4236 driver\n"); |
3045 | return -EIO; | 3045 | return -EIO; |
3046 | ok1: | 3046 | ok1: |
3047 | #ifdef CONFIG_SND_CS46XX_NEW_DSP | 3047 | #ifdef CONFIG_SND_CS46XX_NEW_DSP |
3048 | { | 3048 | { |
3049 | int count; | 3049 | int count; |
3050 | for (count = 0; count < 150; count++) { | 3050 | for (count = 0; count < 150; count++) { |
3051 | /* First, we want to wait for a short time. */ | 3051 | /* First, we want to wait for a short time. */ |
3052 | udelay(25); | 3052 | udelay(25); |
3053 | 3053 | ||
3054 | if (snd_cs46xx_peekBA0(chip, BA0_ACSTS2) & ACSTS_CRDY) | 3054 | if (snd_cs46xx_peekBA0(chip, BA0_ACSTS2) & ACSTS_CRDY) |
3055 | break; | 3055 | break; |
3056 | } | 3056 | } |
3057 | 3057 | ||
3058 | /* | 3058 | /* |
3059 | * Make sure CODEC is READY. | 3059 | * Make sure CODEC is READY. |
3060 | */ | 3060 | */ |
3061 | if (!(snd_cs46xx_peekBA0(chip, BA0_ACSTS2) & ACSTS_CRDY)) | 3061 | if (!(snd_cs46xx_peekBA0(chip, BA0_ACSTS2) & ACSTS_CRDY)) |
3062 | snd_printdd("cs46xx: never read card ready from secondary AC'97\n"); | 3062 | snd_printdd("cs46xx: never read card ready from secondary AC'97\n"); |
3063 | } | 3063 | } |
3064 | #endif | 3064 | #endif |
3065 | 3065 | ||
3066 | /* | 3066 | /* |
3067 | * Assert the vaid frame signal so that we can start sending commands | 3067 | * Assert the vaid frame signal so that we can start sending commands |
3068 | * to the AC97 codec. | 3068 | * to the AC97 codec. |
3069 | */ | 3069 | */ |
3070 | snd_cs46xx_pokeBA0(chip, BA0_ACCTL, ACCTL_VFRM | ACCTL_ESYN | ACCTL_RSTN); | 3070 | snd_cs46xx_pokeBA0(chip, BA0_ACCTL, ACCTL_VFRM | ACCTL_ESYN | ACCTL_RSTN); |
3071 | #ifdef CONFIG_SND_CS46XX_NEW_DSP | 3071 | #ifdef CONFIG_SND_CS46XX_NEW_DSP |
3072 | snd_cs46xx_pokeBA0(chip, BA0_ACCTL2, ACCTL_VFRM | ACCTL_ESYN | ACCTL_RSTN); | 3072 | snd_cs46xx_pokeBA0(chip, BA0_ACCTL2, ACCTL_VFRM | ACCTL_ESYN | ACCTL_RSTN); |
3073 | #endif | 3073 | #endif |
3074 | 3074 | ||
3075 | 3075 | ||
3076 | /* | 3076 | /* |
3077 | * Wait until we've sampled input slots 3 and 4 as valid, meaning that | 3077 | * Wait until we've sampled input slots 3 and 4 as valid, meaning that |
3078 | * the codec is pumping ADC data across the AC-link. | 3078 | * the codec is pumping ADC data across the AC-link. |
3079 | */ | 3079 | */ |
3080 | timeout = 150; | 3080 | timeout = 150; |
3081 | while (timeout-- > 0) { | 3081 | while (timeout-- > 0) { |
3082 | /* | 3082 | /* |
3083 | * Read the input slot valid register and see if input slots 3 and | 3083 | * Read the input slot valid register and see if input slots 3 and |
3084 | * 4 are valid yet. | 3084 | * 4 are valid yet. |
3085 | */ | 3085 | */ |
3086 | if ((snd_cs46xx_peekBA0(chip, BA0_ACISV) & (ACISV_ISV3 | ACISV_ISV4)) == (ACISV_ISV3 | ACISV_ISV4)) | 3086 | if ((snd_cs46xx_peekBA0(chip, BA0_ACISV) & (ACISV_ISV3 | ACISV_ISV4)) == (ACISV_ISV3 | ACISV_ISV4)) |
3087 | goto ok2; | 3087 | goto ok2; |
3088 | msleep(10); | 3088 | msleep(10); |
3089 | } | 3089 | } |
3090 | 3090 | ||
3091 | #ifndef CONFIG_SND_CS46XX_NEW_DSP | 3091 | #ifndef CONFIG_SND_CS46XX_NEW_DSP |
3092 | snd_printk(KERN_ERR "create - never read ISV3 & ISV4 from AC'97\n"); | 3092 | snd_printk(KERN_ERR "create - never read ISV3 & ISV4 from AC'97\n"); |
3093 | return -EIO; | 3093 | return -EIO; |
3094 | #else | 3094 | #else |
3095 | /* This may happen on a cold boot with a Terratec SiXPack 5.1. | 3095 | /* This may happen on a cold boot with a Terratec SiXPack 5.1. |
3096 | Reloading the driver may help, if there's other soundcards | 3096 | Reloading the driver may help, if there's other soundcards |
3097 | with the same problem I would like to know. (Benny) */ | 3097 | with the same problem I would like to know. (Benny) */ |
3098 | 3098 | ||
3099 | snd_printk(KERN_ERR "ERROR: snd-cs46xx: never read ISV3 & ISV4 from AC'97\n"); | 3099 | snd_printk(KERN_ERR "ERROR: snd-cs46xx: never read ISV3 & ISV4 from AC'97\n"); |
3100 | snd_printk(KERN_ERR " Try reloading the ALSA driver, if you find something\n"); | 3100 | snd_printk(KERN_ERR " Try reloading the ALSA driver, if you find something\n"); |
3101 | snd_printk(KERN_ERR " broken or not working on your soundcard upon\n"); | 3101 | snd_printk(KERN_ERR " broken or not working on your soundcard upon\n"); |
3102 | snd_printk(KERN_ERR " this message please report to alsa-devel@lists.sourceforge.net\n"); | 3102 | snd_printk(KERN_ERR " this message please report to alsa-devel@lists.sourceforge.net\n"); |
3103 | 3103 | ||
3104 | return -EIO; | 3104 | return -EIO; |
3105 | #endif | 3105 | #endif |
3106 | ok2: | 3106 | ok2: |
3107 | 3107 | ||
3108 | /* | 3108 | /* |
3109 | * Now, assert valid frame and the slot 3 and 4 valid bits. This will | 3109 | * Now, assert valid frame and the slot 3 and 4 valid bits. This will |
3110 | * commense the transfer of digital audio data to the AC97 codec. | 3110 | * commense the transfer of digital audio data to the AC97 codec. |
3111 | */ | 3111 | */ |
3112 | 3112 | ||
3113 | snd_cs46xx_pokeBA0(chip, BA0_ACOSV, ACOSV_SLV3 | ACOSV_SLV4); | 3113 | snd_cs46xx_pokeBA0(chip, BA0_ACOSV, ACOSV_SLV3 | ACOSV_SLV4); |
3114 | 3114 | ||
3115 | 3115 | ||
3116 | /* | 3116 | /* |
3117 | * Power down the DAC and ADC. We will power them up (if) when we need | 3117 | * Power down the DAC and ADC. We will power them up (if) when we need |
3118 | * them. | 3118 | * them. |
3119 | */ | 3119 | */ |
3120 | /* snd_cs46xx_pokeBA0(chip, BA0_AC97_POWERDOWN, 0x300); */ | 3120 | /* snd_cs46xx_pokeBA0(chip, BA0_AC97_POWERDOWN, 0x300); */ |
3121 | 3121 | ||
3122 | /* | 3122 | /* |
3123 | * Turn off the Processor by turning off the software clock enable flag in | 3123 | * Turn off the Processor by turning off the software clock enable flag in |
3124 | * the clock control register. | 3124 | * the clock control register. |
3125 | */ | 3125 | */ |
3126 | /* tmp = snd_cs46xx_peekBA0(chip, BA0_CLKCR1) & ~CLKCR1_SWCE; */ | 3126 | /* tmp = snd_cs46xx_peekBA0(chip, BA0_CLKCR1) & ~CLKCR1_SWCE; */ |
3127 | /* snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, tmp); */ | 3127 | /* snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, tmp); */ |
3128 | 3128 | ||
3129 | return 0; | 3129 | return 0; |
3130 | } | 3130 | } |
3131 | 3131 | ||
3132 | /* | 3132 | /* |
3133 | * start and load DSP | 3133 | * start and load DSP |
3134 | */ | 3134 | */ |
3135 | int __devinit snd_cs46xx_start_dsp(struct snd_cs46xx *chip) | 3135 | int __devinit snd_cs46xx_start_dsp(struct snd_cs46xx *chip) |
3136 | { | 3136 | { |
3137 | unsigned int tmp; | 3137 | unsigned int tmp; |
3138 | /* | 3138 | /* |
3139 | * Reset the processor. | 3139 | * Reset the processor. |
3140 | */ | 3140 | */ |
3141 | snd_cs46xx_reset(chip); | 3141 | snd_cs46xx_reset(chip); |
3142 | /* | 3142 | /* |
3143 | * Download the image to the processor. | 3143 | * Download the image to the processor. |
3144 | */ | 3144 | */ |
3145 | #ifdef CONFIG_SND_CS46XX_NEW_DSP | 3145 | #ifdef CONFIG_SND_CS46XX_NEW_DSP |
3146 | #if 0 | 3146 | #if 0 |
3147 | if (cs46xx_dsp_load_module(chip, &cwcemb80_module) < 0) { | 3147 | if (cs46xx_dsp_load_module(chip, &cwcemb80_module) < 0) { |
3148 | snd_printk(KERN_ERR "image download error\n"); | 3148 | snd_printk(KERN_ERR "image download error\n"); |
3149 | return -EIO; | 3149 | return -EIO; |
3150 | } | 3150 | } |
3151 | #endif | 3151 | #endif |
3152 | 3152 | ||
3153 | if (cs46xx_dsp_load_module(chip, &cwc4630_module) < 0) { | 3153 | if (cs46xx_dsp_load_module(chip, &cwc4630_module) < 0) { |
3154 | snd_printk(KERN_ERR "image download error [cwc4630]\n"); | 3154 | snd_printk(KERN_ERR "image download error [cwc4630]\n"); |
3155 | return -EIO; | 3155 | return -EIO; |
3156 | } | 3156 | } |
3157 | 3157 | ||
3158 | if (cs46xx_dsp_load_module(chip, &cwcasync_module) < 0) { | 3158 | if (cs46xx_dsp_load_module(chip, &cwcasync_module) < 0) { |
3159 | snd_printk(KERN_ERR "image download error [cwcasync]\n"); | 3159 | snd_printk(KERN_ERR "image download error [cwcasync]\n"); |
3160 | return -EIO; | 3160 | return -EIO; |
3161 | } | 3161 | } |
3162 | 3162 | ||
3163 | if (cs46xx_dsp_load_module(chip, &cwcsnoop_module) < 0) { | 3163 | if (cs46xx_dsp_load_module(chip, &cwcsnoop_module) < 0) { |
3164 | snd_printk(KERN_ERR "image download error [cwcsnoop]\n"); | 3164 | snd_printk(KERN_ERR "image download error [cwcsnoop]\n"); |
3165 | return -EIO; | 3165 | return -EIO; |
3166 | } | 3166 | } |
3167 | 3167 | ||
3168 | if (cs46xx_dsp_load_module(chip, &cwcbinhack_module) < 0) { | 3168 | if (cs46xx_dsp_load_module(chip, &cwcbinhack_module) < 0) { |
3169 | snd_printk(KERN_ERR "image download error [cwcbinhack]\n"); | 3169 | snd_printk(KERN_ERR "image download error [cwcbinhack]\n"); |
3170 | return -EIO; | 3170 | return -EIO; |
3171 | } | 3171 | } |
3172 | 3172 | ||
3173 | if (cs46xx_dsp_load_module(chip, &cwcdma_module) < 0) { | 3173 | if (cs46xx_dsp_load_module(chip, &cwcdma_module) < 0) { |
3174 | snd_printk(KERN_ERR "image download error [cwcdma]\n"); | 3174 | snd_printk(KERN_ERR "image download error [cwcdma]\n"); |
3175 | return -EIO; | 3175 | return -EIO; |
3176 | } | 3176 | } |
3177 | 3177 | ||
3178 | if (cs46xx_dsp_scb_and_task_init(chip) < 0) | 3178 | if (cs46xx_dsp_scb_and_task_init(chip) < 0) |
3179 | return -EIO; | 3179 | return -EIO; |
3180 | #else | 3180 | #else |
3181 | /* old image */ | 3181 | /* old image */ |
3182 | if (snd_cs46xx_download_image(chip) < 0) { | 3182 | if (snd_cs46xx_download_image(chip) < 0) { |
3183 | snd_printk(KERN_ERR "image download error\n"); | 3183 | snd_printk(KERN_ERR "image download error\n"); |
3184 | return -EIO; | 3184 | return -EIO; |
3185 | } | 3185 | } |
3186 | 3186 | ||
3187 | /* | 3187 | /* |
3188 | * Stop playback DMA. | 3188 | * Stop playback DMA. |
3189 | */ | 3189 | */ |
3190 | tmp = snd_cs46xx_peek(chip, BA1_PCTL); | 3190 | tmp = snd_cs46xx_peek(chip, BA1_PCTL); |
3191 | chip->play_ctl = tmp & 0xffff0000; | 3191 | chip->play_ctl = tmp & 0xffff0000; |
3192 | snd_cs46xx_poke(chip, BA1_PCTL, tmp & 0x0000ffff); | 3192 | snd_cs46xx_poke(chip, BA1_PCTL, tmp & 0x0000ffff); |
3193 | #endif | 3193 | #endif |
3194 | 3194 | ||
3195 | /* | 3195 | /* |
3196 | * Stop capture DMA. | 3196 | * Stop capture DMA. |
3197 | */ | 3197 | */ |
3198 | tmp = snd_cs46xx_peek(chip, BA1_CCTL); | 3198 | tmp = snd_cs46xx_peek(chip, BA1_CCTL); |
3199 | chip->capt.ctl = tmp & 0x0000ffff; | 3199 | chip->capt.ctl = tmp & 0x0000ffff; |
3200 | snd_cs46xx_poke(chip, BA1_CCTL, tmp & 0xffff0000); | 3200 | snd_cs46xx_poke(chip, BA1_CCTL, tmp & 0xffff0000); |
3201 | 3201 | ||
3202 | mdelay(5); | 3202 | mdelay(5); |
3203 | 3203 | ||
3204 | snd_cs46xx_set_play_sample_rate(chip, 8000); | 3204 | snd_cs46xx_set_play_sample_rate(chip, 8000); |
3205 | snd_cs46xx_set_capture_sample_rate(chip, 8000); | 3205 | snd_cs46xx_set_capture_sample_rate(chip, 8000); |
3206 | 3206 | ||
3207 | snd_cs46xx_proc_start(chip); | 3207 | snd_cs46xx_proc_start(chip); |
3208 | 3208 | ||
3209 | /* | 3209 | /* |
3210 | * Enable interrupts on the part. | 3210 | * Enable interrupts on the part. |
3211 | */ | 3211 | */ |
3212 | snd_cs46xx_pokeBA0(chip, BA0_HICR, HICR_IEV | HICR_CHGM); | 3212 | snd_cs46xx_pokeBA0(chip, BA0_HICR, HICR_IEV | HICR_CHGM); |
3213 | 3213 | ||
3214 | tmp = snd_cs46xx_peek(chip, BA1_PFIE); | 3214 | tmp = snd_cs46xx_peek(chip, BA1_PFIE); |
3215 | tmp &= ~0x0000f03f; | 3215 | tmp &= ~0x0000f03f; |
3216 | snd_cs46xx_poke(chip, BA1_PFIE, tmp); /* playback interrupt enable */ | 3216 | snd_cs46xx_poke(chip, BA1_PFIE, tmp); /* playback interrupt enable */ |
3217 | 3217 | ||
3218 | tmp = snd_cs46xx_peek(chip, BA1_CIE); | 3218 | tmp = snd_cs46xx_peek(chip, BA1_CIE); |
3219 | tmp &= ~0x0000003f; | 3219 | tmp &= ~0x0000003f; |
3220 | tmp |= 0x00000001; | 3220 | tmp |= 0x00000001; |
3221 | snd_cs46xx_poke(chip, BA1_CIE, tmp); /* capture interrupt enable */ | 3221 | snd_cs46xx_poke(chip, BA1_CIE, tmp); /* capture interrupt enable */ |
3222 | 3222 | ||
3223 | #ifndef CONFIG_SND_CS46XX_NEW_DSP | 3223 | #ifndef CONFIG_SND_CS46XX_NEW_DSP |
3224 | /* set the attenuation to 0dB */ | 3224 | /* set the attenuation to 0dB */ |
3225 | snd_cs46xx_poke(chip, BA1_PVOL, 0x80008000); | 3225 | snd_cs46xx_poke(chip, BA1_PVOL, 0x80008000); |
3226 | snd_cs46xx_poke(chip, BA1_CVOL, 0x80008000); | 3226 | snd_cs46xx_poke(chip, BA1_CVOL, 0x80008000); |
3227 | #endif | 3227 | #endif |
3228 | 3228 | ||
3229 | return 0; | 3229 | return 0; |
3230 | } | 3230 | } |
3231 | 3231 | ||
3232 | 3232 | ||
3233 | /* | 3233 | /* |
3234 | * AMP control - null AMP | 3234 | * AMP control - null AMP |
3235 | */ | 3235 | */ |
3236 | 3236 | ||
3237 | static void amp_none(struct snd_cs46xx *chip, int change) | 3237 | static void amp_none(struct snd_cs46xx *chip, int change) |
3238 | { | 3238 | { |
3239 | } | 3239 | } |
3240 | 3240 | ||
3241 | #ifdef CONFIG_SND_CS46XX_NEW_DSP | 3241 | #ifdef CONFIG_SND_CS46XX_NEW_DSP |
3242 | static int voyetra_setup_eapd_slot(struct snd_cs46xx *chip) | 3242 | static int voyetra_setup_eapd_slot(struct snd_cs46xx *chip) |
3243 | { | 3243 | { |
3244 | 3244 | ||
3245 | u32 idx, valid_slots,tmp,powerdown = 0; | 3245 | u32 idx, valid_slots,tmp,powerdown = 0; |
3246 | u16 modem_power,pin_config,logic_type; | 3246 | u16 modem_power,pin_config,logic_type; |
3247 | 3247 | ||
3248 | snd_printdd ("cs46xx: cs46xx_setup_eapd_slot()+\n"); | 3248 | snd_printdd ("cs46xx: cs46xx_setup_eapd_slot()+\n"); |
3249 | 3249 | ||
3250 | /* | 3250 | /* |
3251 | * See if the devices are powered down. If so, we must power them up first | 3251 | * See if the devices are powered down. If so, we must power them up first |
3252 | * or they will not respond. | 3252 | * or they will not respond. |
3253 | */ | 3253 | */ |
3254 | tmp = snd_cs46xx_peekBA0(chip, BA0_CLKCR1); | 3254 | tmp = snd_cs46xx_peekBA0(chip, BA0_CLKCR1); |
3255 | 3255 | ||
3256 | if (!(tmp & CLKCR1_SWCE)) { | 3256 | if (!(tmp & CLKCR1_SWCE)) { |
3257 | snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, tmp | CLKCR1_SWCE); | 3257 | snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, tmp | CLKCR1_SWCE); |
3258 | powerdown = 1; | 3258 | powerdown = 1; |
3259 | } | 3259 | } |
3260 | 3260 | ||
3261 | /* | 3261 | /* |
3262 | * Clear PRA. The Bonzo chip will be used for GPIO not for modem | 3262 | * Clear PRA. The Bonzo chip will be used for GPIO not for modem |
3263 | * stuff. | 3263 | * stuff. |
3264 | */ | 3264 | */ |
3265 | if(chip->nr_ac97_codecs != 2) { | 3265 | if(chip->nr_ac97_codecs != 2) { |
3266 | snd_printk (KERN_ERR "cs46xx: cs46xx_setup_eapd_slot() - no secondary codec configured\n"); | 3266 | snd_printk (KERN_ERR "cs46xx: cs46xx_setup_eapd_slot() - no secondary codec configured\n"); |
3267 | return -EINVAL; | 3267 | return -EINVAL; |
3268 | } | 3268 | } |
3269 | 3269 | ||
3270 | modem_power = snd_cs46xx_codec_read (chip, | 3270 | modem_power = snd_cs46xx_codec_read (chip, |
3271 | AC97_EXTENDED_MSTATUS, | 3271 | AC97_EXTENDED_MSTATUS, |
3272 | CS46XX_SECONDARY_CODEC_INDEX); | 3272 | CS46XX_SECONDARY_CODEC_INDEX); |
3273 | modem_power &=0xFEFF; | 3273 | modem_power &=0xFEFF; |
3274 | 3274 | ||
3275 | snd_cs46xx_codec_write(chip, | 3275 | snd_cs46xx_codec_write(chip, |
3276 | AC97_EXTENDED_MSTATUS, modem_power, | 3276 | AC97_EXTENDED_MSTATUS, modem_power, |
3277 | CS46XX_SECONDARY_CODEC_INDEX); | 3277 | CS46XX_SECONDARY_CODEC_INDEX); |
3278 | 3278 | ||
3279 | /* | 3279 | /* |
3280 | * Set GPIO pin's 7 and 8 so that they are configured for output. | 3280 | * Set GPIO pin's 7 and 8 so that they are configured for output. |
3281 | */ | 3281 | */ |
3282 | pin_config = snd_cs46xx_codec_read (chip, | 3282 | pin_config = snd_cs46xx_codec_read (chip, |
3283 | AC97_GPIO_CFG, | 3283 | AC97_GPIO_CFG, |
3284 | CS46XX_SECONDARY_CODEC_INDEX); | 3284 | CS46XX_SECONDARY_CODEC_INDEX); |
3285 | pin_config &=0x27F; | 3285 | pin_config &=0x27F; |
3286 | 3286 | ||
3287 | snd_cs46xx_codec_write(chip, | 3287 | snd_cs46xx_codec_write(chip, |
3288 | AC97_GPIO_CFG, pin_config, | 3288 | AC97_GPIO_CFG, pin_config, |
3289 | CS46XX_SECONDARY_CODEC_INDEX); | 3289 | CS46XX_SECONDARY_CODEC_INDEX); |
3290 | 3290 | ||
3291 | /* | 3291 | /* |
3292 | * Set GPIO pin's 7 and 8 so that they are compatible with CMOS logic. | 3292 | * Set GPIO pin's 7 and 8 so that they are compatible with CMOS logic. |
3293 | */ | 3293 | */ |
3294 | 3294 | ||
3295 | logic_type = snd_cs46xx_codec_read(chip, AC97_GPIO_POLARITY, | 3295 | logic_type = snd_cs46xx_codec_read(chip, AC97_GPIO_POLARITY, |
3296 | CS46XX_SECONDARY_CODEC_INDEX); | 3296 | CS46XX_SECONDARY_CODEC_INDEX); |
3297 | logic_type &=0x27F; | 3297 | logic_type &=0x27F; |
3298 | 3298 | ||
3299 | snd_cs46xx_codec_write (chip, AC97_GPIO_POLARITY, logic_type, | 3299 | snd_cs46xx_codec_write (chip, AC97_GPIO_POLARITY, logic_type, |
3300 | CS46XX_SECONDARY_CODEC_INDEX); | 3300 | CS46XX_SECONDARY_CODEC_INDEX); |
3301 | 3301 | ||
3302 | valid_slots = snd_cs46xx_peekBA0(chip, BA0_ACOSV); | 3302 | valid_slots = snd_cs46xx_peekBA0(chip, BA0_ACOSV); |
3303 | valid_slots |= 0x200; | 3303 | valid_slots |= 0x200; |
3304 | snd_cs46xx_pokeBA0(chip, BA0_ACOSV, valid_slots); | 3304 | snd_cs46xx_pokeBA0(chip, BA0_ACOSV, valid_slots); |
3305 | 3305 | ||
3306 | if ( cs46xx_wait_for_fifo(chip,1) ) { | 3306 | if ( cs46xx_wait_for_fifo(chip,1) ) { |
3307 | snd_printdd("FIFO is busy\n"); | 3307 | snd_printdd("FIFO is busy\n"); |
3308 | 3308 | ||
3309 | return -EINVAL; | 3309 | return -EINVAL; |
3310 | } | 3310 | } |
3311 | 3311 | ||
3312 | /* | 3312 | /* |
3313 | * Fill slots 12 with the correct value for the GPIO pins. | 3313 | * Fill slots 12 with the correct value for the GPIO pins. |
3314 | */ | 3314 | */ |
3315 | for(idx = 0x90; idx <= 0x9F; idx++) { | 3315 | for(idx = 0x90; idx <= 0x9F; idx++) { |
3316 | /* | 3316 | /* |
3317 | * Initialize the fifo so that bits 7 and 8 are on. | 3317 | * Initialize the fifo so that bits 7 and 8 are on. |
3318 | * | 3318 | * |
3319 | * Remember that the GPIO pins in bonzo are shifted by 4 bits to | 3319 | * Remember that the GPIO pins in bonzo are shifted by 4 bits to |
3320 | * the left. 0x1800 corresponds to bits 7 and 8. | 3320 | * the left. 0x1800 corresponds to bits 7 and 8. |
3321 | */ | 3321 | */ |
3322 | snd_cs46xx_pokeBA0(chip, BA0_SERBWP, 0x1800); | 3322 | snd_cs46xx_pokeBA0(chip, BA0_SERBWP, 0x1800); |
3323 | 3323 | ||
3324 | /* | 3324 | /* |
3325 | * Wait for command to complete | 3325 | * Wait for command to complete |
3326 | */ | 3326 | */ |
3327 | if ( cs46xx_wait_for_fifo(chip,200) ) { | 3327 | if ( cs46xx_wait_for_fifo(chip,200) ) { |
3328 | snd_printdd("failed waiting for FIFO at addr (%02X)\n",idx); | 3328 | snd_printdd("failed waiting for FIFO at addr (%02X)\n",idx); |
3329 | 3329 | ||
3330 | return -EINVAL; | 3330 | return -EINVAL; |
3331 | } | 3331 | } |
3332 | 3332 | ||
3333 | /* | 3333 | /* |
3334 | * Write the serial port FIFO index. | 3334 | * Write the serial port FIFO index. |
3335 | */ | 3335 | */ |
3336 | snd_cs46xx_pokeBA0(chip, BA0_SERBAD, idx); | 3336 | snd_cs46xx_pokeBA0(chip, BA0_SERBAD, idx); |
3337 | 3337 | ||
3338 | /* | 3338 | /* |
3339 | * Tell the serial port to load the new value into the FIFO location. | 3339 | * Tell the serial port to load the new value into the FIFO location. |
3340 | */ | 3340 | */ |
3341 | snd_cs46xx_pokeBA0(chip, BA0_SERBCM, SERBCM_WRC); | 3341 | snd_cs46xx_pokeBA0(chip, BA0_SERBCM, SERBCM_WRC); |
3342 | } | 3342 | } |
3343 | 3343 | ||
3344 | /* wait for last command to complete */ | 3344 | /* wait for last command to complete */ |
3345 | cs46xx_wait_for_fifo(chip,200); | 3345 | cs46xx_wait_for_fifo(chip,200); |
3346 | 3346 | ||
3347 | /* | 3347 | /* |
3348 | * Now, if we powered up the devices, then power them back down again. | 3348 | * Now, if we powered up the devices, then power them back down again. |
3349 | * This is kinda ugly, but should never happen. | 3349 | * This is kinda ugly, but should never happen. |
3350 | */ | 3350 | */ |
3351 | if (powerdown) | 3351 | if (powerdown) |
3352 | snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, tmp); | 3352 | snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, tmp); |
3353 | 3353 | ||
3354 | return 0; | 3354 | return 0; |
3355 | } | 3355 | } |
3356 | #endif | 3356 | #endif |
3357 | 3357 | ||
3358 | /* | 3358 | /* |
3359 | * Crystal EAPD mode | 3359 | * Crystal EAPD mode |
3360 | */ | 3360 | */ |
3361 | 3361 | ||
3362 | static void amp_voyetra(struct snd_cs46xx *chip, int change) | 3362 | static void amp_voyetra(struct snd_cs46xx *chip, int change) |
3363 | { | 3363 | { |
3364 | /* Manage the EAPD bit on the Crystal 4297 | 3364 | /* Manage the EAPD bit on the Crystal 4297 |
3365 | and the Analog AD1885 */ | 3365 | and the Analog AD1885 */ |
3366 | 3366 | ||
3367 | #ifdef CONFIG_SND_CS46XX_NEW_DSP | 3367 | #ifdef CONFIG_SND_CS46XX_NEW_DSP |
3368 | int old = chip->amplifier; | 3368 | int old = chip->amplifier; |
3369 | #endif | 3369 | #endif |
3370 | int oval, val; | 3370 | int oval, val; |
3371 | 3371 | ||
3372 | chip->amplifier += change; | 3372 | chip->amplifier += change; |
3373 | oval = snd_cs46xx_codec_read(chip, AC97_POWERDOWN, | 3373 | oval = snd_cs46xx_codec_read(chip, AC97_POWERDOWN, |
3374 | CS46XX_PRIMARY_CODEC_INDEX); | 3374 | CS46XX_PRIMARY_CODEC_INDEX); |
3375 | val = oval; | 3375 | val = oval; |
3376 | if (chip->amplifier) { | 3376 | if (chip->amplifier) { |
3377 | /* Turn the EAPD amp on */ | 3377 | /* Turn the EAPD amp on */ |
3378 | val |= 0x8000; | 3378 | val |= 0x8000; |
3379 | } else { | 3379 | } else { |
3380 | /* Turn the EAPD amp off */ | 3380 | /* Turn the EAPD amp off */ |
3381 | val &= ~0x8000; | 3381 | val &= ~0x8000; |
3382 | } | 3382 | } |
3383 | if (val != oval) { | 3383 | if (val != oval) { |
3384 | snd_cs46xx_codec_write(chip, AC97_POWERDOWN, val, | 3384 | snd_cs46xx_codec_write(chip, AC97_POWERDOWN, val, |
3385 | CS46XX_PRIMARY_CODEC_INDEX); | 3385 | CS46XX_PRIMARY_CODEC_INDEX); |
3386 | if (chip->eapd_switch) | 3386 | if (chip->eapd_switch) |
3387 | snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, | 3387 | snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, |
3388 | &chip->eapd_switch->id); | 3388 | &chip->eapd_switch->id); |
3389 | } | 3389 | } |
3390 | 3390 | ||
3391 | #ifdef CONFIG_SND_CS46XX_NEW_DSP | 3391 | #ifdef CONFIG_SND_CS46XX_NEW_DSP |
3392 | if (chip->amplifier && !old) { | 3392 | if (chip->amplifier && !old) { |
3393 | voyetra_setup_eapd_slot(chip); | 3393 | voyetra_setup_eapd_slot(chip); |
3394 | } | 3394 | } |
3395 | #endif | 3395 | #endif |
3396 | } | 3396 | } |
3397 | 3397 | ||
3398 | static void hercules_init(struct snd_cs46xx *chip) | 3398 | static void hercules_init(struct snd_cs46xx *chip) |
3399 | { | 3399 | { |
3400 | /* default: AMP off, and SPDIF input optical */ | 3400 | /* default: AMP off, and SPDIF input optical */ |
3401 | snd_cs46xx_pokeBA0(chip, BA0_EGPIODR, EGPIODR_GPOE0); | 3401 | snd_cs46xx_pokeBA0(chip, BA0_EGPIODR, EGPIODR_GPOE0); |
3402 | snd_cs46xx_pokeBA0(chip, BA0_EGPIOPTR, EGPIODR_GPOE0); | 3402 | snd_cs46xx_pokeBA0(chip, BA0_EGPIOPTR, EGPIODR_GPOE0); |
3403 | } | 3403 | } |
3404 | 3404 | ||
3405 | 3405 | ||
3406 | /* | 3406 | /* |
3407 | * Game Theatre XP card - EGPIO[2] is used to enable the external amp. | 3407 | * Game Theatre XP card - EGPIO[2] is used to enable the external amp. |
3408 | */ | 3408 | */ |
3409 | static void amp_hercules(struct snd_cs46xx *chip, int change) | 3409 | static void amp_hercules(struct snd_cs46xx *chip, int change) |
3410 | { | 3410 | { |
3411 | int old = chip->amplifier; | 3411 | int old = chip->amplifier; |
3412 | int val1 = snd_cs46xx_peekBA0(chip, BA0_EGPIODR); | 3412 | int val1 = snd_cs46xx_peekBA0(chip, BA0_EGPIODR); |
3413 | int val2 = snd_cs46xx_peekBA0(chip, BA0_EGPIOPTR); | 3413 | int val2 = snd_cs46xx_peekBA0(chip, BA0_EGPIOPTR); |
3414 | 3414 | ||
3415 | chip->amplifier += change; | 3415 | chip->amplifier += change; |
3416 | if (chip->amplifier && !old) { | 3416 | if (chip->amplifier && !old) { |
3417 | snd_printdd ("Hercules amplifier ON\n"); | 3417 | snd_printdd ("Hercules amplifier ON\n"); |
3418 | 3418 | ||
3419 | snd_cs46xx_pokeBA0(chip, BA0_EGPIODR, | 3419 | snd_cs46xx_pokeBA0(chip, BA0_EGPIODR, |
3420 | EGPIODR_GPOE2 | val1); /* enable EGPIO2 output */ | 3420 | EGPIODR_GPOE2 | val1); /* enable EGPIO2 output */ |
3421 | snd_cs46xx_pokeBA0(chip, BA0_EGPIOPTR, | 3421 | snd_cs46xx_pokeBA0(chip, BA0_EGPIOPTR, |
3422 | EGPIOPTR_GPPT2 | val2); /* open-drain on output */ | 3422 | EGPIOPTR_GPPT2 | val2); /* open-drain on output */ |
3423 | } else if (old && !chip->amplifier) { | 3423 | } else if (old && !chip->amplifier) { |
3424 | snd_printdd ("Hercules amplifier OFF\n"); | 3424 | snd_printdd ("Hercules amplifier OFF\n"); |
3425 | snd_cs46xx_pokeBA0(chip, BA0_EGPIODR, val1 & ~EGPIODR_GPOE2); /* disable */ | 3425 | snd_cs46xx_pokeBA0(chip, BA0_EGPIODR, val1 & ~EGPIODR_GPOE2); /* disable */ |
3426 | snd_cs46xx_pokeBA0(chip, BA0_EGPIOPTR, val2 & ~EGPIOPTR_GPPT2); /* disable */ | 3426 | snd_cs46xx_pokeBA0(chip, BA0_EGPIOPTR, val2 & ~EGPIOPTR_GPPT2); /* disable */ |
3427 | } | 3427 | } |
3428 | } | 3428 | } |
3429 | 3429 | ||
3430 | static void voyetra_mixer_init (struct snd_cs46xx *chip) | 3430 | static void voyetra_mixer_init (struct snd_cs46xx *chip) |
3431 | { | 3431 | { |
3432 | snd_printdd ("initializing Voyetra mixer\n"); | 3432 | snd_printdd ("initializing Voyetra mixer\n"); |
3433 | 3433 | ||
3434 | /* Enable SPDIF out */ | 3434 | /* Enable SPDIF out */ |
3435 | snd_cs46xx_pokeBA0(chip, BA0_EGPIODR, EGPIODR_GPOE0); | 3435 | snd_cs46xx_pokeBA0(chip, BA0_EGPIODR, EGPIODR_GPOE0); |
3436 | snd_cs46xx_pokeBA0(chip, BA0_EGPIOPTR, EGPIODR_GPOE0); | 3436 | snd_cs46xx_pokeBA0(chip, BA0_EGPIOPTR, EGPIODR_GPOE0); |
3437 | } | 3437 | } |
3438 | 3438 | ||
3439 | static void hercules_mixer_init (struct snd_cs46xx *chip) | 3439 | static void hercules_mixer_init (struct snd_cs46xx *chip) |
3440 | { | 3440 | { |
3441 | #ifdef CONFIG_SND_CS46XX_NEW_DSP | 3441 | #ifdef CONFIG_SND_CS46XX_NEW_DSP |
3442 | unsigned int idx; | 3442 | unsigned int idx; |
3443 | int err; | 3443 | int err; |
3444 | struct snd_card *card = chip->card; | 3444 | struct snd_card *card = chip->card; |
3445 | #endif | 3445 | #endif |
3446 | 3446 | ||
3447 | /* set EGPIO to default */ | 3447 | /* set EGPIO to default */ |
3448 | hercules_init(chip); | 3448 | hercules_init(chip); |
3449 | 3449 | ||
3450 | snd_printdd ("initializing Hercules mixer\n"); | 3450 | snd_printdd ("initializing Hercules mixer\n"); |
3451 | 3451 | ||
3452 | #ifdef CONFIG_SND_CS46XX_NEW_DSP | 3452 | #ifdef CONFIG_SND_CS46XX_NEW_DSP |
3453 | for (idx = 0 ; idx < ARRAY_SIZE(snd_hercules_controls); idx++) { | 3453 | for (idx = 0 ; idx < ARRAY_SIZE(snd_hercules_controls); idx++) { |
3454 | struct snd_kcontrol *kctl; | 3454 | struct snd_kcontrol *kctl; |
3455 | 3455 | ||
3456 | kctl = snd_ctl_new1(&snd_hercules_controls[idx], chip); | 3456 | kctl = snd_ctl_new1(&snd_hercules_controls[idx], chip); |
3457 | if ((err = snd_ctl_add(card, kctl)) < 0) { | 3457 | if ((err = snd_ctl_add(card, kctl)) < 0) { |
3458 | printk (KERN_ERR "cs46xx: failed to initialize Hercules mixer (%d)\n",err); | 3458 | printk (KERN_ERR "cs46xx: failed to initialize Hercules mixer (%d)\n",err); |
3459 | break; | 3459 | break; |
3460 | } | 3460 | } |
3461 | } | 3461 | } |
3462 | #endif | 3462 | #endif |
3463 | } | 3463 | } |
3464 | 3464 | ||
3465 | 3465 | ||
3466 | #if 0 | 3466 | #if 0 |
3467 | /* | 3467 | /* |
3468 | * Untested | 3468 | * Untested |
3469 | */ | 3469 | */ |
3470 | 3470 | ||
3471 | static void amp_voyetra_4294(struct snd_cs46xx *chip, int change) | 3471 | static void amp_voyetra_4294(struct snd_cs46xx *chip, int change) |
3472 | { | 3472 | { |
3473 | chip->amplifier += change; | 3473 | chip->amplifier += change; |
3474 | 3474 | ||
3475 | if (chip->amplifier) { | 3475 | if (chip->amplifier) { |
3476 | /* Switch the GPIO pins 7 and 8 to open drain */ | 3476 | /* Switch the GPIO pins 7 and 8 to open drain */ |
3477 | snd_cs46xx_codec_write(chip, 0x4C, | 3477 | snd_cs46xx_codec_write(chip, 0x4C, |
3478 | snd_cs46xx_codec_read(chip, 0x4C) & 0xFE7F); | 3478 | snd_cs46xx_codec_read(chip, 0x4C) & 0xFE7F); |
3479 | snd_cs46xx_codec_write(chip, 0x4E, | 3479 | snd_cs46xx_codec_write(chip, 0x4E, |
3480 | snd_cs46xx_codec_read(chip, 0x4E) | 0x0180); | 3480 | snd_cs46xx_codec_read(chip, 0x4E) | 0x0180); |
3481 | /* Now wake the AMP (this might be backwards) */ | 3481 | /* Now wake the AMP (this might be backwards) */ |
3482 | snd_cs46xx_codec_write(chip, 0x54, | 3482 | snd_cs46xx_codec_write(chip, 0x54, |
3483 | snd_cs46xx_codec_read(chip, 0x54) & ~0x0180); | 3483 | snd_cs46xx_codec_read(chip, 0x54) & ~0x0180); |
3484 | } else { | 3484 | } else { |
3485 | snd_cs46xx_codec_write(chip, 0x54, | 3485 | snd_cs46xx_codec_write(chip, 0x54, |
3486 | snd_cs46xx_codec_read(chip, 0x54) | 0x0180); | 3486 | snd_cs46xx_codec_read(chip, 0x54) | 0x0180); |
3487 | } | 3487 | } |
3488 | } | 3488 | } |
3489 | #endif | 3489 | #endif |
3490 | 3490 | ||
3491 | 3491 | ||
3492 | /* | 3492 | /* |
3493 | * Handle the CLKRUN on a thinkpad. We must disable CLKRUN support | 3493 | * Handle the CLKRUN on a thinkpad. We must disable CLKRUN support |
3494 | * whenever we need to beat on the chip. | 3494 | * whenever we need to beat on the chip. |
3495 | * | 3495 | * |
3496 | * The original idea and code for this hack comes from David Kaiser at | 3496 | * The original idea and code for this hack comes from David Kaiser at |
3497 | * Linuxcare. Perhaps one day Crystal will document their chips well | 3497 | * Linuxcare. Perhaps one day Crystal will document their chips well |
3498 | * enough to make them useful. | 3498 | * enough to make them useful. |
3499 | */ | 3499 | */ |
3500 | 3500 | ||
3501 | static void clkrun_hack(struct snd_cs46xx *chip, int change) | 3501 | static void clkrun_hack(struct snd_cs46xx *chip, int change) |
3502 | { | 3502 | { |
3503 | u16 control, nval; | 3503 | u16 control, nval; |
3504 | 3504 | ||
3505 | if (!chip->acpi_port) | 3505 | if (!chip->acpi_port) |
3506 | return; | 3506 | return; |
3507 | 3507 | ||
3508 | chip->amplifier += change; | 3508 | chip->amplifier += change; |
3509 | 3509 | ||
3510 | /* Read ACPI port */ | 3510 | /* Read ACPI port */ |
3511 | nval = control = inw(chip->acpi_port + 0x10); | 3511 | nval = control = inw(chip->acpi_port + 0x10); |
3512 | 3512 | ||
3513 | /* Flip CLKRUN off while running */ | 3513 | /* Flip CLKRUN off while running */ |
3514 | if (! chip->amplifier) | 3514 | if (! chip->amplifier) |
3515 | nval |= 0x2000; | 3515 | nval |= 0x2000; |
3516 | else | 3516 | else |
3517 | nval &= ~0x2000; | 3517 | nval &= ~0x2000; |
3518 | if (nval != control) | 3518 | if (nval != control) |
3519 | outw(nval, chip->acpi_port + 0x10); | 3519 | outw(nval, chip->acpi_port + 0x10); |
3520 | } | 3520 | } |
3521 | 3521 | ||
3522 | 3522 | ||
3523 | /* | 3523 | /* |
3524 | * detect intel piix4 | 3524 | * detect intel piix4 |
3525 | */ | 3525 | */ |
3526 | static void clkrun_init(struct snd_cs46xx *chip) | 3526 | static void clkrun_init(struct snd_cs46xx *chip) |
3527 | { | 3527 | { |
3528 | struct pci_dev *pdev; | 3528 | struct pci_dev *pdev; |
3529 | u8 pp; | 3529 | u8 pp; |
3530 | 3530 | ||
3531 | chip->acpi_port = 0; | 3531 | chip->acpi_port = 0; |
3532 | 3532 | ||
3533 | pdev = pci_get_device(PCI_VENDOR_ID_INTEL, | 3533 | pdev = pci_get_device(PCI_VENDOR_ID_INTEL, |
3534 | PCI_DEVICE_ID_INTEL_82371AB_3, NULL); | 3534 | PCI_DEVICE_ID_INTEL_82371AB_3, NULL); |
3535 | if (pdev == NULL) | 3535 | if (pdev == NULL) |
3536 | return; /* Not a thinkpad thats for sure */ | 3536 | return; /* Not a thinkpad thats for sure */ |
3537 | 3537 | ||
3538 | /* Find the control port */ | 3538 | /* Find the control port */ |
3539 | pci_read_config_byte(pdev, 0x41, &pp); | 3539 | pci_read_config_byte(pdev, 0x41, &pp); |
3540 | chip->acpi_port = pp << 8; | 3540 | chip->acpi_port = pp << 8; |
3541 | pci_dev_put(pdev); | 3541 | pci_dev_put(pdev); |
3542 | } | 3542 | } |
3543 | 3543 | ||
3544 | 3544 | ||
3545 | /* | 3545 | /* |
3546 | * Card subid table | 3546 | * Card subid table |
3547 | */ | 3547 | */ |
3548 | 3548 | ||
3549 | struct cs_card_type | 3549 | struct cs_card_type |
3550 | { | 3550 | { |
3551 | u16 vendor; | 3551 | u16 vendor; |
3552 | u16 id; | 3552 | u16 id; |
3553 | char *name; | 3553 | char *name; |
3554 | void (*init)(struct snd_cs46xx *); | 3554 | void (*init)(struct snd_cs46xx *); |
3555 | void (*amp)(struct snd_cs46xx *, int); | 3555 | void (*amp)(struct snd_cs46xx *, int); |
3556 | void (*active)(struct snd_cs46xx *, int); | 3556 | void (*active)(struct snd_cs46xx *, int); |
3557 | void (*mixer_init)(struct snd_cs46xx *); | 3557 | void (*mixer_init)(struct snd_cs46xx *); |
3558 | }; | 3558 | }; |
3559 | 3559 | ||
3560 | static struct cs_card_type __devinitdata cards[] = { | 3560 | static struct cs_card_type __devinitdata cards[] = { |
3561 | { | 3561 | { |
3562 | .vendor = 0x1489, | 3562 | .vendor = 0x1489, |
3563 | .id = 0x7001, | 3563 | .id = 0x7001, |
3564 | .name = "Genius Soundmaker 128 value", | 3564 | .name = "Genius Soundmaker 128 value", |
3565 | /* nothing special */ | 3565 | /* nothing special */ |
3566 | }, | 3566 | }, |
3567 | { | 3567 | { |
3568 | .vendor = 0x5053, | 3568 | .vendor = 0x5053, |
3569 | .id = 0x3357, | 3569 | .id = 0x3357, |
3570 | .name = "Voyetra", | 3570 | .name = "Voyetra", |
3571 | .amp = amp_voyetra, | 3571 | .amp = amp_voyetra, |
3572 | .mixer_init = voyetra_mixer_init, | 3572 | .mixer_init = voyetra_mixer_init, |
3573 | }, | 3573 | }, |
3574 | { | 3574 | { |
3575 | .vendor = 0x1071, | 3575 | .vendor = 0x1071, |
3576 | .id = 0x6003, | 3576 | .id = 0x6003, |
3577 | .name = "Mitac MI6020/21", | 3577 | .name = "Mitac MI6020/21", |
3578 | .amp = amp_voyetra, | 3578 | .amp = amp_voyetra, |
3579 | }, | 3579 | }, |
3580 | { | 3580 | { |
3581 | .vendor = 0x14AF, | 3581 | .vendor = 0x14AF, |
3582 | .id = 0x0050, | 3582 | .id = 0x0050, |
3583 | .name = "Hercules Game Theatre XP", | 3583 | .name = "Hercules Game Theatre XP", |
3584 | .amp = amp_hercules, | 3584 | .amp = amp_hercules, |
3585 | .mixer_init = hercules_mixer_init, | 3585 | .mixer_init = hercules_mixer_init, |
3586 | }, | 3586 | }, |
3587 | { | 3587 | { |
3588 | .vendor = 0x1681, | 3588 | .vendor = 0x1681, |
3589 | .id = 0x0050, | 3589 | .id = 0x0050, |
3590 | .name = "Hercules Game Theatre XP", | 3590 | .name = "Hercules Game Theatre XP", |
3591 | .amp = amp_hercules, | 3591 | .amp = amp_hercules, |
3592 | .mixer_init = hercules_mixer_init, | 3592 | .mixer_init = hercules_mixer_init, |
3593 | }, | 3593 | }, |
3594 | { | 3594 | { |
3595 | .vendor = 0x1681, | 3595 | .vendor = 0x1681, |
3596 | .id = 0x0051, | 3596 | .id = 0x0051, |
3597 | .name = "Hercules Game Theatre XP", | 3597 | .name = "Hercules Game Theatre XP", |
3598 | .amp = amp_hercules, | 3598 | .amp = amp_hercules, |
3599 | .mixer_init = hercules_mixer_init, | 3599 | .mixer_init = hercules_mixer_init, |
3600 | 3600 | ||
3601 | }, | 3601 | }, |
3602 | { | 3602 | { |
3603 | .vendor = 0x1681, | 3603 | .vendor = 0x1681, |
3604 | .id = 0x0052, | 3604 | .id = 0x0052, |
3605 | .name = "Hercules Game Theatre XP", | 3605 | .name = "Hercules Game Theatre XP", |
3606 | .amp = amp_hercules, | 3606 | .amp = amp_hercules, |
3607 | .mixer_init = hercules_mixer_init, | 3607 | .mixer_init = hercules_mixer_init, |
3608 | }, | 3608 | }, |
3609 | { | 3609 | { |
3610 | .vendor = 0x1681, | 3610 | .vendor = 0x1681, |
3611 | .id = 0x0053, | 3611 | .id = 0x0053, |
3612 | .name = "Hercules Game Theatre XP", | 3612 | .name = "Hercules Game Theatre XP", |
3613 | .amp = amp_hercules, | 3613 | .amp = amp_hercules, |
3614 | .mixer_init = hercules_mixer_init, | 3614 | .mixer_init = hercules_mixer_init, |
3615 | }, | 3615 | }, |
3616 | { | 3616 | { |
3617 | .vendor = 0x1681, | 3617 | .vendor = 0x1681, |
3618 | .id = 0x0054, | 3618 | .id = 0x0054, |
3619 | .name = "Hercules Game Theatre XP", | 3619 | .name = "Hercules Game Theatre XP", |
3620 | .amp = amp_hercules, | 3620 | .amp = amp_hercules, |
3621 | .mixer_init = hercules_mixer_init, | 3621 | .mixer_init = hercules_mixer_init, |
3622 | }, | 3622 | }, |
3623 | /* Teratec */ | 3623 | /* Teratec */ |
3624 | { | 3624 | { |
3625 | .vendor = 0x153b, | 3625 | .vendor = 0x153b, |
3626 | .id = 0x1136, | 3626 | .id = 0x1136, |
3627 | .name = "Terratec SiXPack 5.1", | 3627 | .name = "Terratec SiXPack 5.1", |
3628 | }, | 3628 | }, |
3629 | /* Not sure if the 570 needs the clkrun hack */ | 3629 | /* Not sure if the 570 needs the clkrun hack */ |
3630 | { | 3630 | { |
3631 | .vendor = PCI_VENDOR_ID_IBM, | 3631 | .vendor = PCI_VENDOR_ID_IBM, |
3632 | .id = 0x0132, | 3632 | .id = 0x0132, |
3633 | .name = "Thinkpad 570", | 3633 | .name = "Thinkpad 570", |
3634 | .init = clkrun_init, | 3634 | .init = clkrun_init, |
3635 | .active = clkrun_hack, | 3635 | .active = clkrun_hack, |
3636 | }, | 3636 | }, |
3637 | { | 3637 | { |
3638 | .vendor = PCI_VENDOR_ID_IBM, | 3638 | .vendor = PCI_VENDOR_ID_IBM, |
3639 | .id = 0x0153, | 3639 | .id = 0x0153, |
3640 | .name = "Thinkpad 600X/A20/T20", | 3640 | .name = "Thinkpad 600X/A20/T20", |
3641 | .init = clkrun_init, | 3641 | .init = clkrun_init, |
3642 | .active = clkrun_hack, | 3642 | .active = clkrun_hack, |
3643 | }, | 3643 | }, |
3644 | { | 3644 | { |
3645 | .vendor = PCI_VENDOR_ID_IBM, | 3645 | .vendor = PCI_VENDOR_ID_IBM, |
3646 | .id = 0x1010, | 3646 | .id = 0x1010, |
3647 | .name = "Thinkpad 600E (unsupported)", | 3647 | .name = "Thinkpad 600E (unsupported)", |
3648 | }, | 3648 | }, |
3649 | {} /* terminator */ | 3649 | {} /* terminator */ |
3650 | }; | 3650 | }; |
3651 | 3651 | ||
3652 | 3652 | ||
3653 | /* | 3653 | /* |
3654 | * APM support | 3654 | * APM support |
3655 | */ | 3655 | */ |
3656 | #ifdef CONFIG_PM | 3656 | #ifdef CONFIG_PM |
3657 | static int snd_cs46xx_suspend(struct snd_card *card, pm_message_t state) | 3657 | int snd_cs46xx_suspend(struct pci_dev *pci, pm_message_t state) |
3658 | { | 3658 | { |
3659 | struct snd_cs46xx *chip = card->pm_private_data; | 3659 | struct snd_card *card = pci_get_drvdata(pci); |
3660 | struct snd_cs46xx *chip = card->private_data; | ||
3660 | int amp_saved; | 3661 | int amp_saved; |
3661 | 3662 | ||
3663 | snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); | ||
3662 | snd_pcm_suspend_all(chip->pcm); | 3664 | snd_pcm_suspend_all(chip->pcm); |
3663 | // chip->ac97_powerdown = snd_cs46xx_codec_read(chip, AC97_POWER_CONTROL); | 3665 | // chip->ac97_powerdown = snd_cs46xx_codec_read(chip, AC97_POWER_CONTROL); |
3664 | // chip->ac97_general_purpose = snd_cs46xx_codec_read(chip, BA0_AC97_GENERAL_PURPOSE); | 3666 | // chip->ac97_general_purpose = snd_cs46xx_codec_read(chip, BA0_AC97_GENERAL_PURPOSE); |
3665 | 3667 | ||
3666 | snd_ac97_suspend(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]); | 3668 | snd_ac97_suspend(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]); |
3667 | if (chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]) | 3669 | snd_ac97_suspend(chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]); |
3668 | snd_ac97_suspend(chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]); | ||
3669 | 3670 | ||
3670 | amp_saved = chip->amplifier; | 3671 | amp_saved = chip->amplifier; |
3671 | /* turn off amp */ | 3672 | /* turn off amp */ |
3672 | chip->amplifier_ctrl(chip, -chip->amplifier); | 3673 | chip->amplifier_ctrl(chip, -chip->amplifier); |
3673 | snd_cs46xx_hw_stop(chip); | 3674 | snd_cs46xx_hw_stop(chip); |
3674 | /* disable CLKRUN */ | 3675 | /* disable CLKRUN */ |
3675 | chip->active_ctrl(chip, -chip->amplifier); | 3676 | chip->active_ctrl(chip, -chip->amplifier); |
3676 | chip->amplifier = amp_saved; /* restore the status */ | 3677 | chip->amplifier = amp_saved; /* restore the status */ |
3677 | pci_disable_device(chip->pci); | 3678 | pci_disable_device(pci); |
3679 | pci_save_state(pci); | ||
3678 | return 0; | 3680 | return 0; |
3679 | } | 3681 | } |
3680 | 3682 | ||
3681 | static int snd_cs46xx_resume(struct snd_card *card) | 3683 | int snd_cs46xx_resume(struct pci_dev *pci) |
3682 | { | 3684 | { |
3683 | struct snd_cs46xx *chip = card->pm_private_data; | 3685 | struct snd_card *card = pci_get_drvdata(pci); |
3686 | struct snd_cs46xx *chip = card->private_data; | ||
3684 | int amp_saved; | 3687 | int amp_saved; |
3685 | 3688 | ||
3686 | pci_enable_device(chip->pci); | 3689 | pci_restore_state(pci); |
3687 | pci_set_master(chip->pci); | 3690 | pci_enable_device(pci); |
3691 | pci_set_master(pci); | ||
3688 | amp_saved = chip->amplifier; | 3692 | amp_saved = chip->amplifier; |
3689 | chip->amplifier = 0; | 3693 | chip->amplifier = 0; |
3690 | chip->active_ctrl(chip, 1); /* force to on */ | 3694 | chip->active_ctrl(chip, 1); /* force to on */ |
3691 | 3695 | ||
3692 | snd_cs46xx_chip_init(chip); | 3696 | snd_cs46xx_chip_init(chip); |
3693 | 3697 | ||
3694 | #if 0 | 3698 | #if 0 |
3695 | snd_cs46xx_codec_write(chip, BA0_AC97_GENERAL_PURPOSE, | 3699 | snd_cs46xx_codec_write(chip, BA0_AC97_GENERAL_PURPOSE, |
3696 | chip->ac97_general_purpose); | 3700 | chip->ac97_general_purpose); |
3697 | snd_cs46xx_codec_write(chip, AC97_POWER_CONTROL, | 3701 | snd_cs46xx_codec_write(chip, AC97_POWER_CONTROL, |
3698 | chip->ac97_powerdown); | 3702 | chip->ac97_powerdown); |
3699 | mdelay(10); | 3703 | mdelay(10); |
3700 | snd_cs46xx_codec_write(chip, BA0_AC97_POWERDOWN, | 3704 | snd_cs46xx_codec_write(chip, BA0_AC97_POWERDOWN, |
3701 | chip->ac97_powerdown); | 3705 | chip->ac97_powerdown); |
3702 | mdelay(5); | 3706 | mdelay(5); |
3703 | #endif | 3707 | #endif |
3704 | 3708 | ||
3705 | snd_ac97_resume(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]); | 3709 | snd_ac97_resume(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]); |
3706 | if (chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]) | 3710 | snd_ac97_resume(chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]); |
3707 | snd_ac97_resume(chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]); | ||
3708 | 3711 | ||
3709 | if (amp_saved) | 3712 | if (amp_saved) |
3710 | chip->amplifier_ctrl(chip, 1); /* turn amp on */ | 3713 | chip->amplifier_ctrl(chip, 1); /* turn amp on */ |
3711 | else | 3714 | else |
3712 | chip->active_ctrl(chip, -1); /* disable CLKRUN */ | 3715 | chip->active_ctrl(chip, -1); /* disable CLKRUN */ |
3713 | chip->amplifier = amp_saved; | 3716 | chip->amplifier = amp_saved; |
3717 | snd_power_change_state(card, SNDRV_CTL_POWER_D0); | ||
3714 | return 0; | 3718 | return 0; |
3715 | } | 3719 | } |
3716 | #endif /* CONFIG_PM */ | 3720 | #endif /* CONFIG_PM */ |
3717 | 3721 | ||
3718 | 3722 | ||
3719 | /* | 3723 | /* |
3720 | */ | 3724 | */ |
3721 | 3725 | ||
3722 | int __devinit snd_cs46xx_create(struct snd_card *card, | 3726 | int __devinit snd_cs46xx_create(struct snd_card *card, |
3723 | struct pci_dev * pci, | 3727 | struct pci_dev * pci, |
3724 | int external_amp, int thinkpad, | 3728 | int external_amp, int thinkpad, |
3725 | struct snd_cs46xx ** rchip) | 3729 | struct snd_cs46xx ** rchip) |
3726 | { | 3730 | { |
3727 | struct snd_cs46xx *chip; | 3731 | struct snd_cs46xx *chip; |
3728 | int err, idx; | 3732 | int err, idx; |
3729 | struct snd_cs46xx_region *region; | 3733 | struct snd_cs46xx_region *region; |
3730 | struct cs_card_type *cp; | 3734 | struct cs_card_type *cp; |
3731 | u16 ss_card, ss_vendor; | 3735 | u16 ss_card, ss_vendor; |
3732 | static struct snd_device_ops ops = { | 3736 | static struct snd_device_ops ops = { |
3733 | .dev_free = snd_cs46xx_dev_free, | 3737 | .dev_free = snd_cs46xx_dev_free, |
3734 | }; | 3738 | }; |
3735 | 3739 | ||
3736 | *rchip = NULL; | 3740 | *rchip = NULL; |
3737 | 3741 | ||
3738 | /* enable PCI device */ | 3742 | /* enable PCI device */ |
3739 | if ((err = pci_enable_device(pci)) < 0) | 3743 | if ((err = pci_enable_device(pci)) < 0) |
3740 | return err; | 3744 | return err; |
3741 | 3745 | ||
3742 | chip = kzalloc(sizeof(*chip), GFP_KERNEL); | 3746 | chip = kzalloc(sizeof(*chip), GFP_KERNEL); |
3743 | if (chip == NULL) { | 3747 | if (chip == NULL) { |
3744 | pci_disable_device(pci); | 3748 | pci_disable_device(pci); |
3745 | return -ENOMEM; | 3749 | return -ENOMEM; |
3746 | } | 3750 | } |
3747 | spin_lock_init(&chip->reg_lock); | 3751 | spin_lock_init(&chip->reg_lock); |
3748 | #ifdef CONFIG_SND_CS46XX_NEW_DSP | 3752 | #ifdef CONFIG_SND_CS46XX_NEW_DSP |
3749 | init_MUTEX(&chip->spos_mutex); | 3753 | init_MUTEX(&chip->spos_mutex); |
3750 | #endif | 3754 | #endif |
3751 | chip->card = card; | 3755 | chip->card = card; |
3752 | chip->pci = pci; | 3756 | chip->pci = pci; |
3753 | chip->irq = -1; | 3757 | chip->irq = -1; |
3754 | chip->ba0_addr = pci_resource_start(pci, 0); | 3758 | chip->ba0_addr = pci_resource_start(pci, 0); |
3755 | chip->ba1_addr = pci_resource_start(pci, 1); | 3759 | chip->ba1_addr = pci_resource_start(pci, 1); |
3756 | if (chip->ba0_addr == 0 || chip->ba0_addr == (unsigned long)~0 || | 3760 | if (chip->ba0_addr == 0 || chip->ba0_addr == (unsigned long)~0 || |
3757 | chip->ba1_addr == 0 || chip->ba1_addr == (unsigned long)~0) { | 3761 | chip->ba1_addr == 0 || chip->ba1_addr == (unsigned long)~0) { |
3758 | snd_printk(KERN_ERR "wrong address(es) - ba0 = 0x%lx, ba1 = 0x%lx\n", | 3762 | snd_printk(KERN_ERR "wrong address(es) - ba0 = 0x%lx, ba1 = 0x%lx\n", |
3759 | chip->ba0_addr, chip->ba1_addr); | 3763 | chip->ba0_addr, chip->ba1_addr); |
3760 | snd_cs46xx_free(chip); | 3764 | snd_cs46xx_free(chip); |
3761 | return -ENOMEM; | 3765 | return -ENOMEM; |
3762 | } | 3766 | } |
3763 | 3767 | ||
3764 | region = &chip->region.name.ba0; | 3768 | region = &chip->region.name.ba0; |
3765 | strcpy(region->name, "CS46xx_BA0"); | 3769 | strcpy(region->name, "CS46xx_BA0"); |
3766 | region->base = chip->ba0_addr; | 3770 | region->base = chip->ba0_addr; |
3767 | region->size = CS46XX_BA0_SIZE; | 3771 | region->size = CS46XX_BA0_SIZE; |
3768 | 3772 | ||
3769 | region = &chip->region.name.data0; | 3773 | region = &chip->region.name.data0; |
3770 | strcpy(region->name, "CS46xx_BA1_data0"); | 3774 | strcpy(region->name, "CS46xx_BA1_data0"); |
3771 | region->base = chip->ba1_addr + BA1_SP_DMEM0; | 3775 | region->base = chip->ba1_addr + BA1_SP_DMEM0; |
3772 | region->size = CS46XX_BA1_DATA0_SIZE; | 3776 | region->size = CS46XX_BA1_DATA0_SIZE; |
3773 | 3777 | ||
3774 | region = &chip->region.name.data1; | 3778 | region = &chip->region.name.data1; |
3775 | strcpy(region->name, "CS46xx_BA1_data1"); | 3779 | strcpy(region->name, "CS46xx_BA1_data1"); |
3776 | region->base = chip->ba1_addr + BA1_SP_DMEM1; | 3780 | region->base = chip->ba1_addr + BA1_SP_DMEM1; |
3777 | region->size = CS46XX_BA1_DATA1_SIZE; | 3781 | region->size = CS46XX_BA1_DATA1_SIZE; |
3778 | 3782 | ||
3779 | region = &chip->region.name.pmem; | 3783 | region = &chip->region.name.pmem; |
3780 | strcpy(region->name, "CS46xx_BA1_pmem"); | 3784 | strcpy(region->name, "CS46xx_BA1_pmem"); |
3781 | region->base = chip->ba1_addr + BA1_SP_PMEM; | 3785 | region->base = chip->ba1_addr + BA1_SP_PMEM; |
3782 | region->size = CS46XX_BA1_PRG_SIZE; | 3786 | region->size = CS46XX_BA1_PRG_SIZE; |
3783 | 3787 | ||
3784 | region = &chip->region.name.reg; | 3788 | region = &chip->region.name.reg; |
3785 | strcpy(region->name, "CS46xx_BA1_reg"); | 3789 | strcpy(region->name, "CS46xx_BA1_reg"); |
3786 | region->base = chip->ba1_addr + BA1_SP_REG; | 3790 | region->base = chip->ba1_addr + BA1_SP_REG; |
3787 | region->size = CS46XX_BA1_REG_SIZE; | 3791 | region->size = CS46XX_BA1_REG_SIZE; |
3788 | 3792 | ||
3789 | /* set up amp and clkrun hack */ | 3793 | /* set up amp and clkrun hack */ |
3790 | pci_read_config_word(pci, PCI_SUBSYSTEM_VENDOR_ID, &ss_vendor); | 3794 | pci_read_config_word(pci, PCI_SUBSYSTEM_VENDOR_ID, &ss_vendor); |
3791 | pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &ss_card); | 3795 | pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &ss_card); |
3792 | 3796 | ||
3793 | for (cp = &cards[0]; cp->name; cp++) { | 3797 | for (cp = &cards[0]; cp->name; cp++) { |
3794 | if (cp->vendor == ss_vendor && cp->id == ss_card) { | 3798 | if (cp->vendor == ss_vendor && cp->id == ss_card) { |
3795 | snd_printdd ("hack for %s enabled\n", cp->name); | 3799 | snd_printdd ("hack for %s enabled\n", cp->name); |
3796 | 3800 | ||
3797 | chip->amplifier_ctrl = cp->amp; | 3801 | chip->amplifier_ctrl = cp->amp; |
3798 | chip->active_ctrl = cp->active; | 3802 | chip->active_ctrl = cp->active; |
3799 | chip->mixer_init = cp->mixer_init; | 3803 | chip->mixer_init = cp->mixer_init; |
3800 | 3804 | ||
3801 | if (cp->init) | 3805 | if (cp->init) |
3802 | cp->init(chip); | 3806 | cp->init(chip); |
3803 | break; | 3807 | break; |
3804 | } | 3808 | } |
3805 | } | 3809 | } |
3806 | 3810 | ||
3807 | if (external_amp) { | 3811 | if (external_amp) { |
3808 | snd_printk(KERN_INFO "Crystal EAPD support forced on.\n"); | 3812 | snd_printk(KERN_INFO "Crystal EAPD support forced on.\n"); |
3809 | chip->amplifier_ctrl = amp_voyetra; | 3813 | chip->amplifier_ctrl = amp_voyetra; |
3810 | } | 3814 | } |
3811 | 3815 | ||
3812 | if (thinkpad) { | 3816 | if (thinkpad) { |
3813 | snd_printk(KERN_INFO "Activating CLKRUN hack for Thinkpad.\n"); | 3817 | snd_printk(KERN_INFO "Activating CLKRUN hack for Thinkpad.\n"); |
3814 | chip->active_ctrl = clkrun_hack; | 3818 | chip->active_ctrl = clkrun_hack; |
3815 | clkrun_init(chip); | 3819 | clkrun_init(chip); |
3816 | } | 3820 | } |
3817 | 3821 | ||
3818 | if (chip->amplifier_ctrl == NULL) | 3822 | if (chip->amplifier_ctrl == NULL) |
3819 | chip->amplifier_ctrl = amp_none; | 3823 | chip->amplifier_ctrl = amp_none; |
3820 | if (chip->active_ctrl == NULL) | 3824 | if (chip->active_ctrl == NULL) |
3821 | chip->active_ctrl = amp_none; | 3825 | chip->active_ctrl = amp_none; |
3822 | 3826 | ||
3823 | chip->active_ctrl(chip, 1); /* enable CLKRUN */ | 3827 | chip->active_ctrl(chip, 1); /* enable CLKRUN */ |
3824 | 3828 | ||
3825 | pci_set_master(pci); | 3829 | pci_set_master(pci); |
3826 | 3830 | ||
3827 | for (idx = 0; idx < 5; idx++) { | 3831 | for (idx = 0; idx < 5; idx++) { |
3828 | region = &chip->region.idx[idx]; | 3832 | region = &chip->region.idx[idx]; |
3829 | if ((region->resource = request_mem_region(region->base, region->size, | 3833 | if ((region->resource = request_mem_region(region->base, region->size, |
3830 | region->name)) == NULL) { | 3834 | region->name)) == NULL) { |
3831 | snd_printk(KERN_ERR "unable to request memory region 0x%lx-0x%lx\n", | 3835 | snd_printk(KERN_ERR "unable to request memory region 0x%lx-0x%lx\n", |
3832 | region->base, region->base + region->size - 1); | 3836 | region->base, region->base + region->size - 1); |
3833 | snd_cs46xx_free(chip); | 3837 | snd_cs46xx_free(chip); |
3834 | return -EBUSY; | 3838 | return -EBUSY; |
3835 | } | 3839 | } |
3836 | region->remap_addr = ioremap_nocache(region->base, region->size); | 3840 | region->remap_addr = ioremap_nocache(region->base, region->size); |
3837 | if (region->remap_addr == NULL) { | 3841 | if (region->remap_addr == NULL) { |
3838 | snd_printk(KERN_ERR "%s ioremap problem\n", region->name); | 3842 | snd_printk(KERN_ERR "%s ioremap problem\n", region->name); |
3839 | snd_cs46xx_free(chip); | 3843 | snd_cs46xx_free(chip); |
3840 | return -ENOMEM; | 3844 | return -ENOMEM; |
3841 | } | 3845 | } |
3842 | } | 3846 | } |
3843 | 3847 | ||
3844 | if (request_irq(pci->irq, snd_cs46xx_interrupt, SA_INTERRUPT|SA_SHIRQ, | 3848 | if (request_irq(pci->irq, snd_cs46xx_interrupt, SA_INTERRUPT|SA_SHIRQ, |
3845 | "CS46XX", chip)) { | 3849 | "CS46XX", chip)) { |
3846 | snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq); | 3850 | snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq); |
3847 | snd_cs46xx_free(chip); | 3851 | snd_cs46xx_free(chip); |
3848 | return -EBUSY; | 3852 | return -EBUSY; |
3849 | } | 3853 | } |
3850 | chip->irq = pci->irq; | 3854 | chip->irq = pci->irq; |
3851 | 3855 | ||
3852 | #ifdef CONFIG_SND_CS46XX_NEW_DSP | 3856 | #ifdef CONFIG_SND_CS46XX_NEW_DSP |
3853 | chip->dsp_spos_instance = cs46xx_dsp_spos_create(chip); | 3857 | chip->dsp_spos_instance = cs46xx_dsp_spos_create(chip); |
3854 | if (chip->dsp_spos_instance == NULL) { | 3858 | if (chip->dsp_spos_instance == NULL) { |
3855 | snd_cs46xx_free(chip); | 3859 | snd_cs46xx_free(chip); |
3856 | return -ENOMEM; | 3860 | return -ENOMEM; |
3857 | } | 3861 | } |
3858 | #endif | 3862 | #endif |
3859 | 3863 | ||
3860 | err = snd_cs46xx_chip_init(chip); | 3864 | err = snd_cs46xx_chip_init(chip); |
3861 | if (err < 0) { | 3865 | if (err < 0) { |
3862 | snd_cs46xx_free(chip); | 3866 | snd_cs46xx_free(chip); |
3863 | return err; | 3867 | return err; |
3864 | } | 3868 | } |
3865 | 3869 | ||
3866 | if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) { | 3870 | if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) { |
3867 | snd_cs46xx_free(chip); | 3871 | snd_cs46xx_free(chip); |
3868 | return err; | 3872 | return err; |
3869 | } | 3873 | } |
3870 | 3874 | ||
3871 | snd_cs46xx_proc_init(card, chip); | 3875 | snd_cs46xx_proc_init(card, chip); |
3872 | |||
3873 | snd_card_set_pm_callback(card, snd_cs46xx_suspend, snd_cs46xx_resume, chip); | ||
3874 | 3876 | ||
3875 | chip->active_ctrl(chip, -1); /* disable CLKRUN */ | 3877 | chip->active_ctrl(chip, -1); /* disable CLKRUN */ |
3876 | 3878 | ||
3877 | snd_card_set_dev(card, &pci->dev); | 3879 | snd_card_set_dev(card, &pci->dev); |
3878 | 3880 |