Rev 3083 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 3083 | Rev 5048 | ||
---|---|---|---|
1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
2 | ; Universal Interface for Intel High Definition Audio Codec ; |
2 | ; Universal Interface for Intel High Definition Audio Codec ; |
3 | ; ; |
3 | ; ; |
4 | ; Generic widget tree parser ; |
4 | ; Generic widget tree parser ; |
5 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
5 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
6 | 6 | ||
7 | ; widget node for parsing |
7 | ; widget node for parsing |
8 | struc HDA_GNODE |
8 | struc HDA_GNODE |
9 | { |
9 | { |
10 | .nid dw ? ;NID of this widget |
10 | .nid dw ? ;NID of this widget |
11 | .nconns dw ? ;number of input connections |
11 | .nconns dw ? ;number of input connections |
12 | .conn_list dd ? |
12 | .conn_list dd ? |
13 | .slist dw ? ;temporary list |
13 | .slist dw ? ;temporary list |
14 | dw ? |
14 | dw ? |
15 | 15 | ||
16 | .wid_caps dd ? ;widget capabilities |
16 | .wid_caps dd ? ;widget capabilities |
17 | .type db ? ;widget type |
17 | .type db ? ;widget type |
18 | .pin_ctl db ? ;pin controls |
18 | .pin_ctl db ? ;pin controls |
19 | .checked db ? ;the flag indicates that the node is already parsed |
19 | .checked db ? ;the flag indicates that the node is already parsed |
20 | .pin_caps dd ? ;pin widget capabilities |
20 | .pin_caps dd ? ;pin widget capabilities |
21 | .def_cfg dd ? ;default configuration |
21 | .def_cfg dd ? ;default configuration |
22 | .amp_out_caps dd ? ;AMP out capabilities |
22 | .amp_out_caps dd ? ;AMP out capabilities |
23 | .amp_in_caps dd ? ;AMP in capabilities |
23 | .amp_in_caps dd ? ;AMP in capabilities |
24 | .next dd ? ; struct list_head list |
24 | .next dd ? ; struct list_head list |
25 | .sizeof: |
25 | .sizeof: |
26 | } |
26 | } |
27 | 27 | ||
28 | virtual at 0 |
28 | virtual at 0 |
29 | HDA_GNODE HDA_GNODE |
29 | HDA_GNODE HDA_GNODE |
30 | end virtual |
30 | end virtual |
31 | 31 | ||
32 | struc HDA_GSPEC |
32 | struc HDA_GSPEC |
33 | { |
33 | { |
34 | .dac_node dd ? ;DAC node |
34 | .dac_node dd ? ;DAC node |
35 | dd ? |
35 | dd ? |
36 | .out_pin_node dd ? ;Output pin (Line-Out) node |
36 | .out_pin_node dd ? ;Output pin (Line-Out) node |
37 | dd ? |
37 | dd ? |
38 | 38 | ||
39 | .def_amp_in_caps dd ? |
39 | .def_amp_in_caps dd ? |
40 | .def_amp_out_caps dd ? |
40 | .def_amp_out_caps dd ? |
41 | 41 | ||
42 | ; .pcm_rec dd ? ;PCM information |
42 | ; .pcm_rec dd ? ;PCM information |
43 | .nid_list dd 0 ;list of widgets |
43 | .nid_list dd 0 ;list of widgets |
44 | } |
44 | } |
45 | 45 | ||
46 | struc VOLUME_CTL |
46 | struc VOLUME_CTL |
47 | { |
47 | { |
48 | .out_amp_node dd 0 ;Asper+ : To get/set volume |
48 | .out_amp_node dd 0 ;Asper+ : To get/set volume |
49 | .num_steps db ? ; num_steps=NumSteps+1 |
49 | .num_steps db ? ; num_steps=NumSteps+1 |
50 | .step_size db ? ; step_size=StepSize+1 |
50 | .step_size db ? ; step_size=StepSize+1 |
51 | .maxDb dd ? ; Max volume in Db. maxDb=(num_steps*step_size/4*100) |
51 | .maxDb dd ? ; Max volume in Db. maxDb=(num_steps*step_size/4*100) |
52 | } |
52 | } |
53 | 53 | ||
54 | ; retrieve the default device type from the default config value |
54 | ; retrieve the default device type from the default config value |
55 | - | ||
56 | proc defcfg_type stdcall, node:dword |
55 | proc defcfg_type stdcall, node:dword |
57 | push edx |
56 | push edx |
58 | mov edx, [node] |
57 | mov edx, [node] |
59 | mov eax, [edx + HDA_GNODE.def_cfg] |
58 | mov eax, [edx + HDA_GNODE.def_cfg] |
60 | and eax, AC_DEFCFG_DEVICE |
59 | and eax, AC_DEFCFG_DEVICE |
61 | shr eax, AC_DEFCFG_DEVICE_SHIFT |
60 | shr eax, AC_DEFCFG_DEVICE_SHIFT |
62 | pop edx |
61 | pop edx |
63 | ret |
62 | ret |
64 | endp |
63 | endp |
65 | 64 | ||
66 | proc defcfg_location stdcall, node:dword |
65 | proc defcfg_location stdcall, node:dword |
67 | push edx |
66 | push edx |
68 | mov edx, [node] |
67 | mov edx, [node] |
69 | mov eax, [edx + HDA_GNODE.def_cfg] |
68 | mov eax, [edx + HDA_GNODE.def_cfg] |
70 | and eax, AC_DEFCFG_LOCATION |
69 | and eax, AC_DEFCFG_LOCATION |
71 | shr eax, AC_DEFCFG_LOCATION_SHIFT |
70 | shr eax, AC_DEFCFG_LOCATION_SHIFT |
72 | pop edx |
71 | pop edx |
73 | ret |
72 | ret |
74 | endp |
73 | endp |
75 | 74 | ||
76 | proc defcfg_port_conn stdcall, node:dword |
75 | proc defcfg_port_conn stdcall, node:dword |
77 | push edx |
76 | push edx |
78 | mov edx, [node] |
77 | mov edx, [node] |
79 | mov eax, [edx + HDA_GNODE.def_cfg] |
78 | mov eax, [edx + HDA_GNODE.def_cfg] |
80 | and eax, AC_DEFCFG_PORT_CONN |
79 | and eax, AC_DEFCFG_PORT_CONN |
81 | shr eax, AC_DEFCFG_PORT_CONN_SHIFT |
80 | shr eax, AC_DEFCFG_PORT_CONN_SHIFT |
82 | pop edx |
81 | pop edx |
83 | ret |
82 | ret |
84 | endp |
83 | endp |
85 | 84 | ||
86 | proc defcfg_color stdcall, node:dword |
85 | proc defcfg_color stdcall, node:dword |
87 | push edx |
86 | push edx |
88 | mov edx, [node] |
87 | mov edx, [node] |
89 | mov eax, [edx + HDA_GNODE.def_cfg] |
88 | mov eax, [edx + HDA_GNODE.def_cfg] |
90 | and eax, AC_DEFCFG_COLOR |
89 | and eax, AC_DEFCFG_COLOR |
91 | shr eax, AC_DEFCFG_COLOR_SHIFT |
90 | shr eax, AC_DEFCFG_COLOR_SHIFT |
92 | pop edx |
91 | pop edx |
93 | ret |
92 | ret |
94 | endp |
93 | endp |
95 | - | ||
96 | 94 | ||
97 | ; destructor |
95 | ; destructor |
98 | proc snd_hda_generic_free |
96 | proc snd_hda_generic_free |
99 | push eax ebx edx edi |
97 | push eax ebx edx edi |
100 | ; free all widgets |
98 | ; free all widgets |
101 | mov ebx, [spec.nid_list] ; ebx = 1st node address |
99 | mov ebx, [spec.nid_list] ; ebx = 1st node address |
102 | test ebx, ebx |
100 | test ebx, ebx |
103 | jz .out |
101 | jz .out |
104 | mov edx, [ebx + HDA_GNODE.next] ;edx = 2nd node address |
102 | mov edx, [ebx + HDA_GNODE.next] ;edx = 2nd node address |
105 | 103 | ||
106 | .next: |
104 | .next: |
107 | test edx, edx |
105 | test edx, edx |
108 | jz .free_head |
106 | jz .free_head |
109 | 107 | ||
110 | mov eax, [edx + HDA_GNODE.conn_list] |
108 | mov eax, [edx + HDA_GNODE.conn_list] |
111 | lea edi, [edx + HDA_GNODE.slist] |
109 | lea edi, [edx + HDA_GNODE.slist] |
112 | cmp eax, edi |
110 | cmp eax, edi |
113 | je @f |
111 | je @f |
114 | pusha |
112 | pusha |
115 | call Kfree ;free conn_list |
113 | invoke Kfree ;free conn_list |
116 | popa |
114 | popa |
117 | @@: |
115 | @@: |
118 | mov eax, edx |
116 | mov eax, edx |
119 | mov edx, [edx + HDA_GNODE.next] |
117 | mov edx, [edx + HDA_GNODE.next] |
120 | pusha |
118 | pusha |
121 | call Kfree ;free node |
119 | invoke Kfree ;free node |
122 | popa |
120 | popa |
123 | jmp .next |
121 | jmp .next |
124 | .free_head: |
122 | .free_head: |
125 | mov eax, [spec.nid_list] |
123 | mov eax, [spec.nid_list] |
126 | pusha |
124 | pusha |
127 | call Kfree ;free the very 1st node in the list |
125 | invoke Kfree ;free the very 1st node in the list |
128 | popa |
126 | popa |
129 | mov [spec.nid_list], 0 |
127 | mov [spec.nid_list], 0 |
130 | .out: |
128 | .out: |
131 | pop edi edx ebx eax |
129 | pop edi edx ebx eax |
132 | ret |
130 | ret |
133 | endp |
131 | endp |
134 | 132 | ||
135 | 133 | ||
136 | ; add a new widget node and read its attributes |
134 | ; add a new widget node and read its attributes |
137 | proc add_new_node stdcall, nid:dword |
135 | proc add_new_node stdcall, nid:dword |
138 | push ebx ecx edx edi esi |
136 | push ebx ecx edx edi esi |
139 | 137 | ||
140 | mov eax, HDA_GNODE.sizeof |
138 | mov eax, HDA_GNODE.sizeof |
141 | call Kmalloc |
139 | invoke Kmalloc |
142 | test eax, eax |
140 | test eax, eax |
143 | jz .err_out ; Not enough memory |
141 | jz .err_out ; Not enough memory |
144 | 142 | ||
145 | mov edx, eax |
143 | mov edx, eax |
146 | ;Asper+ [ |
144 | ;Asper+ [ |
147 | mov edi, edx |
145 | mov edi, edx |
148 | xor eax, eax |
146 | xor eax, eax |
149 | mov ecx, HDA_GNODE.sizeof |
147 | mov ecx, HDA_GNODE.sizeof |
150 | rep stosb |
148 | rep stosb |
151 | ;Asper+ ] |
149 | ;Asper+ ] |
152 | 150 | ||
153 | mov eax, [nid] |
151 | mov eax, [nid] |
154 | mov word [edx + HDA_GNODE.nid], ax |
152 | mov word [edx + HDA_GNODE.nid], ax |
155 | stdcall get_wcaps, eax |
153 | stdcall get_wcaps, eax |
156 | mov [edx + HDA_GNODE.wid_caps], eax |
154 | mov [edx + HDA_GNODE.wid_caps], eax |
157 | mov ebx, eax |
155 | mov ebx, eax |
158 | stdcall get_wcaps_type, eax |
156 | stdcall get_wcaps_type, eax |
159 | mov byte [edx + HDA_GNODE.type], al |
157 | mov byte [edx + HDA_GNODE.type], al |
160 | 158 | ||
161 | mov eax, HDA_MAX_CONNECTIONS*2 ;HDA_MAX_CONNECTIONS * sizeof(word) |
159 | mov eax, HDA_MAX_CONNECTIONS*2 ;HDA_MAX_CONNECTIONS * sizeof(word) |
162 | push ebx ecx edx |
160 | push ebx ecx edx |
163 | call Kmalloc ;malloc temporary conn_list |
161 | invoke Kmalloc ;malloc temporary conn_list |
164 | pop edx ecx ebx |
162 | pop edx ecx ebx |
165 | mov edi, eax |
163 | mov edi, eax |
166 | 164 | ||
167 | test ebx, AC_WCAP_CONN_LIST |
165 | test ebx, AC_WCAP_CONN_LIST |
168 | jz .no_conn_list |
166 | jz .no_conn_list |
169 | 167 | ||
170 | stdcall snd_hda_get_connections, [nid], edi, HDA_MAX_CONNECTIONS |
168 | stdcall snd_hda_get_connections, [nid], edi, HDA_MAX_CONNECTIONS |
171 | mov ecx, eax |
169 | mov ecx, eax |
172 | cmp ecx, 0 |
170 | cmp ecx, 0 |
173 | jge @f |
171 | jge @f |
174 | 172 | ||
175 | mov eax, edx |
173 | mov eax, edx |
176 | pusha |
174 | pusha |
177 | call Kfree ;free node |
175 | invoke Kfree ;free node |
178 | popa |
176 | popa |
179 | mov eax, ecx |
177 | mov eax, ecx |
180 | jmp .out |
178 | jmp .out |
181 | .no_conn_list: |
179 | .no_conn_list: |
182 | 180 | ||
183 | xor ecx, ecx |
181 | xor ecx, ecx |
184 | @@: |
182 | @@: |
185 | cmp ecx, 2 ;nconns <= ARRAY_SIZE(node->slist) ? |
183 | cmp ecx, 2 ;nconns <= ARRAY_SIZE(node->slist) ? |
186 | jg @f |
184 | jg @f |
187 | 185 | ||
188 | lea eax, [edx + HDA_GNODE.slist] |
186 | lea eax, [edx + HDA_GNODE.slist] |
189 | mov [edx + HDA_GNODE.conn_list], eax |
187 | mov [edx + HDA_GNODE.conn_list], eax |
190 | jmp .set_conn_list |
188 | jmp .set_conn_list |
191 | @@: |
189 | @@: |
192 | mov eax, ecx |
190 | mov eax, ecx |
193 | shl ecx, 1 |
191 | shl ecx, 1 |
194 | push ebx ecx edx edi |
192 | push ebx ecx edx edi |
195 | call Kmalloc ;malloc conn_list |
193 | invoke Kmalloc ;malloc conn_list |
196 | pop edi edx ecx ebx |
194 | pop edi edx ecx ebx |
197 | shr ecx, 1 |
195 | shr ecx, 1 |
198 | test eax, eax |
196 | test eax, eax |
199 | jnz @f |
197 | jnz @f |
200 | 198 | ||
201 | mov eax, edi |
199 | mov eax, edi |
202 | pusha |
200 | pusha |
203 | call Kfree ;free temporary conn_list |
201 | invoke Kfree ;free temporary conn_list |
204 | popa |
202 | popa |
205 | jmp .err_out |
203 | jmp .err_out |
206 | @@: |
204 | @@: |
207 | mov [edx + HDA_GNODE.conn_list], eax |
205 | mov [edx + HDA_GNODE.conn_list], eax |
208 | .set_conn_list: |
206 | .set_conn_list: |
209 | mov [edx + HDA_GNODE.nconns], cx |
207 | mov [edx + HDA_GNODE.nconns], cx |
210 | push edi |
208 | push edi |
211 | mov esi, edi |
209 | mov esi, edi |
212 | mov edi, eax |
210 | mov edi, eax |
213 | rep movsw |
211 | rep movsw |
214 | pop edi |
212 | pop edi |
215 | 213 | ||
216 | 214 | ||
217 | mov al, byte [edx + HDA_GNODE.type] |
215 | mov al, byte [edx + HDA_GNODE.type] |
218 | test al, AC_WID_PIN |
216 | test al, AC_WID_PIN |
219 | jz @f |
217 | jz @f |
220 | ;Asper+ [ |
218 | ;Asper+ [ |
221 | cmp al, AC_WID_VENDOR |
219 | cmp al, AC_WID_VENDOR |
222 | je @f |
220 | je @f |
223 | ;Asper+ ] |
221 | ;Asper+ ] |
224 | 222 | ||
225 | 223 | ||
226 | stdcall read_pin_cap, [nid] |
224 | stdcall read_pin_cap, [nid] |
227 | mov [edx + HDA_GNODE.pin_caps], eax |
225 | mov [edx + HDA_GNODE.pin_caps], eax |
228 | stdcall snd_hda_codec_read, [nid], 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0 |
226 | stdcall snd_hda_codec_read, [nid], 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0 |
229 | mov byte [edx + HDA_GNODE.pin_ctl], al |
227 | mov byte [edx + HDA_GNODE.pin_ctl], al |
230 | stdcall snd_hda_codec_get_pincfg, [nid] |
228 | stdcall snd_hda_codec_get_pincfg, [nid] |
231 | mov [edx + HDA_GNODE.def_cfg], eax |
229 | mov [edx + HDA_GNODE.def_cfg], eax |
232 | @@: |
230 | @@: |
233 | 231 | ||
234 | xor eax, eax |
232 | xor eax, eax |
235 | test ebx, AC_WCAP_OUT_AMP |
233 | test ebx, AC_WCAP_OUT_AMP |
236 | jz .no_out_amp |
234 | jz .no_out_amp |
237 | test ebx, AC_WCAP_AMP_OVRD |
235 | test ebx, AC_WCAP_AMP_OVRD |
238 | jz @f |
236 | jz @f |
239 | snd_hda_param_read [nid], AC_PAR_AMP_OUT_CAP |
237 | snd_hda_param_read [nid], AC_PAR_AMP_OUT_CAP |
240 | @@: |
238 | @@: |
241 | test eax, eax |
239 | test eax, eax |
242 | jnz @f |
240 | jnz @f |
243 | mov eax, [spec.def_amp_out_caps] |
241 | mov eax, [spec.def_amp_out_caps] |
244 | @@: |
242 | @@: |
245 | mov [edx + HDA_GNODE.amp_out_caps], eax |
243 | mov [edx + HDA_GNODE.amp_out_caps], eax |
246 | .no_out_amp: |
244 | .no_out_amp: |
247 | 245 | ||
248 | ;;Asper+: Beeper [ |
246 | ;;Asper+: Beeper [ |
249 | ; pusha |
247 | ; pusha |
250 | ; mov bl, byte [edx + HDA_GNODE.type] |
248 | ; mov bl, byte [edx + HDA_GNODE.type] |
251 | ; cmp bl, AC_WID_BEEP |
249 | ; cmp bl, AC_WID_BEEP |
252 | ; jne .not_beeper |
250 | ; jne .not_beeper |
253 | ; |
251 | ; |
254 | ; mov ebx, [nid] |
252 | ; mov ebx, [nid] |
255 | ; mov [codec.beeper_nid], bx |
253 | ; mov [codec.beeper_nid], bx |
256 | ; |
254 | ; |
257 | ; test eax, eax |
255 | ; test eax, eax |
258 | ; jz .no_beeper_amp |
256 | ; jz .no_beeper_amp |
259 | ; ;set beep amplifier here |
257 | ; ;set beep amplifier here |
260 | ; stdcall unmute_output, edx |
258 | ; stdcall unmute_output, edx |
261 | ; .no_beeper_amp: |
259 | ;.no_beeper_amp: |
262 | ; ;try to beep here |
260 | ; ;try to beep here |
263 | ; stdcall snd_hda_codec_read, [nid], 0, AC_VERB_GET_BEEP_CONTROL, 0 ;eax |
261 | ; stdcall snd_hda_codec_read, [nid], 0, AC_VERB_GET_BEEP_CONTROL, 0 ;eax |
264 | ; if DEBUG |
262 | ;if DEBUG |
265 | ; push eax esi |
263 | ; push eax esi |
266 | ; mov esi, msgBeeperNid |
264 | ; mov esi, msgBeeperNid |
267 | ; call SysMsgBoardStr |
265 | ; invoke SysMsgBoardStr |
268 | ; push eax |
266 | ; push eax |
269 | ; mov eax, [nid] |
267 | ; mov eax, [nid] |
270 | ; stdcall fdword2str, 2 |
268 | ; stdcall fdword2str, 2 |
271 | ; call SysMsgBoardStr |
269 | ; invoke SysMsgBoardStr |
272 | ; |
270 | ; |
273 | ; mov esi, msgBeeperValue |
271 | ; mov esi, msgBeeperValue |
274 | ; call SysMsgBoardStr |
272 | ; invoke SysMsgBoardStr |
275 | ; pop eax |
273 | ; pop eax |
276 | ; stdcall fdword2str, 2 |
274 | ; stdcall fdword2str, 2 |
277 | ; call SysMsgBoardStr |
275 | ; invoke SysMsgBoardStr |
278 | ; |
276 | ; |
279 | ; mov esi, msgBeepNow |
277 | ; mov esi, msgBeepNow |
280 | ; call SysMsgBoardStr |
278 | ; invoke SysMsgBoardStr |
281 | ; pop esi eax |
279 | ; pop esi eax |
282 | ; end if |
280 | ;end if |
283 | ; mov ecx, 256*1 |
281 | ; mov ecx, 256*1 |
284 | ; .next_tone: |
282 | ;.next_tone: |
285 | ; dec ecx |
283 | ; dec ecx |
286 | ; movzx ebx, [esi + HDA_GNODE.nid] |
284 | ; movzx ebx, [esi + HDA_GNODE.nid] |
287 | ; stdcall snd_hda_codec_write, [nid], 0, AC_VERB_SET_BEEP_CONTROL, ecx |
285 | ; stdcall snd_hda_codec_write, [nid], 0, AC_VERB_SET_BEEP_CONTROL, ecx |
288 | ; ;mov eax, 0x8000 |
286 | ; ;mov eax, 0x8000 |
289 | ; ;stdcall StallExec |
287 | ; ;stdcall StallExec |
290 | ; test ecx, ecx |
288 | ; test ecx, ecx |
291 | ; jnz .next_tone |
289 | ; jnz .next_tone |
292 | ; .end_beep: |
290 | ;.end_beep: |
293 | ; stdcall snd_hda_codec_read, [nid], 0, AC_VERB_GET_BEEP_CONTROL, 0 ;eax |
291 | ; stdcall snd_hda_codec_read, [nid], 0, AC_VERB_GET_BEEP_CONTROL, 0 ;eax |
294 | ; if DEBUG |
292 | ;if DEBUG |
295 | ; ;push eax esi |
293 | ; ;push eax esi |
296 | ; mov esi, msgBeeperValue |
294 | ; mov esi, msgBeeperValue |
297 | ; call SysMsgBoardStr |
295 | ; invoke SysMsgBoardStr |
298 | ; stdcall fdword2str, 2 |
296 | ; stdcall fdword2str, 2 |
299 | ; call SysMsgBoardStr |
297 | ; invoke SysMsgBoardStr |
300 | ; ;pop esi eax |
298 | ; ;pop esi eax |
301 | ; end if |
299 | ;end if |
302 | ; .not_beeper: |
300 | ;.not_beeper: |
303 | ; popa |
301 | ; popa |
304 | ;;Asper+: Beeper ] |
302 | ;;Asper+: Beeper ] |
305 | 303 | ||
306 | xor eax, eax |
304 | xor eax, eax |
307 | test ebx, AC_WCAP_IN_AMP |
305 | test ebx, AC_WCAP_IN_AMP |
308 | jz .no_in_amp |
306 | jz .no_in_amp |
309 | test ebx, AC_WCAP_AMP_OVRD |
307 | test ebx, AC_WCAP_AMP_OVRD |
310 | jz @f |
308 | jz @f |
311 | snd_hda_param_read [nid], AC_PAR_AMP_IN_CAP |
309 | snd_hda_param_read [nid], AC_PAR_AMP_IN_CAP |
312 | @@: |
310 | @@: |
313 | test eax, eax |
311 | test eax, eax |
314 | jnz @f |
312 | jnz @f |
315 | mov eax, [spec.def_amp_in_caps] |
313 | mov eax, [spec.def_amp_in_caps] |
316 | @@: |
314 | @@: |
317 | mov [edx + HDA_GNODE.amp_in_caps], eax |
315 | mov [edx + HDA_GNODE.amp_in_caps], eax |
318 | .no_in_amp: |
316 | .no_in_amp: |
319 | 317 | ||
320 | mov esi, [spec.nid_list] |
318 | mov esi, [spec.nid_list] |
321 | test esi, esi |
319 | test esi, esi |
322 | jnz @f |
320 | jnz @f |
323 | mov [spec.nid_list], edx |
321 | mov [spec.nid_list], edx |
324 | jmp .out |
322 | jmp .out |
325 | @@: |
323 | @@: |
326 | 324 | ||
327 | ;Asper+: Sort pins by DA:Sequence during tree building [ |
325 | ;Asper+: Sort pins by DA:Sequence during tree building [ |
328 | mov ecx, esi |
326 | mov ecx, esi |
329 | movzx ebx, byte [edx + HDA_GNODE.def_cfg] |
327 | movzx ebx, byte [edx + HDA_GNODE.def_cfg] |
330 | push edi |
328 | push edi |
331 | .next_node: |
329 | .next_node: |
332 | cmp [esi + HDA_GNODE.type], AC_WID_PIN |
330 | cmp [esi + HDA_GNODE.type], AC_WID_PIN |
333 | jne @f |
331 | jne @f |
334 | cmp [edx + HDA_GNODE.type], AC_WID_PIN |
332 | cmp [edx + HDA_GNODE.type], AC_WID_PIN |
335 | je .pin |
333 | je .pin |
336 | 334 | ||
337 | mov edi, [spec.nid_list] |
335 | mov edi, [spec.nid_list] |
338 | cmp [edi + HDA_GNODE.type], AC_WID_PIN |
336 | cmp [edi + HDA_GNODE.type], AC_WID_PIN |
339 | jne .not_pin |
337 | jne .not_pin |
340 | mov [edx + HDA_GNODE.next], edi |
338 | mov [edx + HDA_GNODE.next], edi |
341 | .head: ;CleverMouse+ |
339 | .head: ;CleverMouse+ |
342 | mov [spec.nid_list], edx |
340 | mov [spec.nid_list], edx |
343 | pop edi |
341 | pop edi |
344 | jmp .out |
342 | jmp .out |
345 | .pin: |
343 | .pin: |
346 | movzx edi, byte [esi + HDA_GNODE.def_cfg] |
344 | movzx edi, byte [esi + HDA_GNODE.def_cfg] |
347 | cmp edi, ebx |
345 | cmp edi, ebx |
348 | jle @f |
346 | jle @f |
349 | .not_pin: |
347 | .not_pin: |
350 | mov [edx + HDA_GNODE.next], esi |
348 | mov [edx + HDA_GNODE.next], esi |
351 | cmp esi, [spec.nid_list] ;CleverMouse+ |
349 | cmp esi, [spec.nid_list] ;CleverMouse+ |
352 | jz .head ;CleverMouse+ |
350 | jz .head ;CleverMouse+ |
353 | mov esi, ecx |
351 | mov esi, ecx |
354 | jmp .insert |
352 | jmp .insert |
355 | @@: |
353 | @@: |
356 | mov eax, [esi + HDA_GNODE.next] |
354 | mov eax, [esi + HDA_GNODE.next] |
357 | test eax, eax |
355 | test eax, eax |
358 | jz .insert |
356 | jz .insert |
359 | mov ecx, esi |
357 | mov ecx, esi |
360 | mov esi, eax |
358 | mov esi, eax |
361 | jmp .next_node |
359 | jmp .next_node |
362 | .insert: |
360 | .insert: |
363 | mov [esi + HDA_GNODE.next], edx |
361 | mov [esi + HDA_GNODE.next], edx |
364 | pop edi |
362 | pop edi |
365 | ;Asper+ ] |
363 | ;Asper+ ] |
366 | 364 | ||
367 | .out: |
365 | .out: |
368 | mov eax, edi |
366 | mov eax, edi |
369 | pusha |
367 | pusha |
370 | call Kfree ;free temporary conn_list |
368 | invoke Kfree ;free temporary conn_list |
371 | popa |
369 | popa |
372 | xor eax, eax |
370 | xor eax, eax |
373 | pop esi edi edx ecx ebx |
371 | pop esi edi edx ecx ebx |
374 | ret |
372 | ret |
375 | 373 | ||
376 | .err_out: |
374 | .err_out: |
377 | mov eax, edx |
375 | mov eax, edx |
378 | pusha |
376 | pusha |
379 | call Kfree ;free node |
377 | invoke Kfree ;free node |
380 | popa |
378 | popa |
381 | xor eax, eax |
379 | xor eax, eax |
382 | dec eax |
380 | dec eax |
383 | pop esi edi edx ecx ebx |
381 | pop esi edi edx ecx ebx |
384 | ret |
382 | ret |
385 | endp |
383 | endp |
386 | 384 | ||
387 | 385 | ||
388 | 386 | ||
389 | ; build the AFG subtree |
387 | ; build the AFG subtree |
390 | proc build_afg_tree |
388 | proc build_afg_tree |
391 | push ebx ecx edx |
389 | push ebx ecx edx |
392 | 390 | ||
393 | mov ebx, [codec.afg] |
391 | mov ebx, [codec.afg] |
394 | snd_hda_param_read ebx, AC_PAR_AMP_OUT_CAP |
392 | snd_hda_param_read ebx, AC_PAR_AMP_OUT_CAP |
395 | 393 | ||
396 | mov [spec.def_amp_out_caps], eax |
394 | mov [spec.def_amp_out_caps], eax |
397 | snd_hda_param_read ebx, AC_PAR_AMP_IN_CAP |
395 | snd_hda_param_read ebx, AC_PAR_AMP_IN_CAP |
398 | mov [spec.def_amp_in_caps], eax |
396 | mov [spec.def_amp_in_caps], eax |
399 | 397 | ||
400 | stdcall snd_hda_get_sub_nodes, ebx |
398 | stdcall snd_hda_get_sub_nodes, ebx |
401 | mov ecx, eax |
399 | mov ecx, eax |
402 | and ecx, 0xFFFF ;ecx = nodes number |
400 | and ecx, 0xFFFF ;ecx = nodes number |
403 | mov edx, eax |
401 | mov edx, eax |
404 | shr edx, 16 ;eax = address of the first nid |
402 | shr edx, 16 ;eax = address of the first nid |
405 | 403 | ||
406 | test edx, edx |
404 | test edx, edx |
407 | jz @f |
405 | jz @f |
408 | cmp ecx, 0 |
406 | cmp ecx, 0 |
409 | jge .nid_ok |
407 | jge .nid_ok |
410 | @@: |
408 | @@: |
411 | if FDEBUG |
409 | if FDEBUG |
412 | push esi |
410 | push esi |
413 | mov esi, emsgInvalidAFGSubtree |
411 | mov esi, emsgInvalidAFGSubtree |
414 | call SysMsgBoardStr |
412 | invoke SysMsgBoardStr |
415 | pop esi |
413 | pop esi |
416 | end if |
414 | end if |
417 | xor eax, eax |
415 | xor eax, eax |
418 | dec eax |
416 | dec eax |
419 | jmp .out |
417 | jmp .out |
420 | .nid_ok: |
418 | .nid_ok: |
421 | 419 | ||
422 | ; parse all nodes belonging to the AFG |
420 | ; parse all nodes belonging to the AFG |
423 | .next_node: |
421 | .next_node: |
424 | test ecx, ecx |
422 | test ecx, ecx |
425 | jz .build_done |
423 | jz .build_done |
426 | 424 | ||
427 | stdcall add_new_node, edx |
425 | stdcall add_new_node, edx |
428 | test eax, eax |
426 | test eax, eax |
429 | jnz .out |
427 | jnz .out |
430 | inc edx |
428 | inc edx |
431 | dec ecx |
429 | dec ecx |
432 | jmp .next_node |
430 | jmp .next_node |
433 | .build_done: |
431 | .build_done: |
434 | xor eax, eax |
432 | xor eax, eax |
435 | .out: |
433 | .out: |
436 | pop edx ecx ebx |
434 | pop edx ecx ebx |
437 | ret |
435 | ret |
438 | endp |
436 | endp |
- | 437 | ||
- | 438 | ;Asper+[ |
|
- | 439 | proc print_afg_tree_nodes |
|
- | 440 | push eax esi edi |
|
- | 441 | mov esi, msgNodeSeq |
|
- | 442 | invoke SysMsgBoardStr |
|
- | 443 | ||
- | 444 | mov edi, [spec.nid_list] |
|
- | 445 | test edi, edi |
|
- | 446 | jz .out |
|
- | 447 | .next_node: |
|
- | 448 | movzx eax, word [edi + HDA_GNODE.nid] |
|
- | 449 | mov esi, msgNID |
|
- | 450 | invoke SysMsgBoardStr |
|
- | 451 | stdcall fdword2str, 3 |
|
- | 452 | invoke SysMsgBoardStr |
|
- | 453 | ||
- | 454 | mov eax, [edi + HDA_GNODE.next] |
|
- | 455 | test eax, eax |
|
- | 456 | jz .out |
|
- | 457 | ||
- | 458 | mov edi, eax |
|
- | 459 | jmp .next_node |
|
- | 460 | .out: |
|
- | 461 | pop edi esi eax |
|
- | 462 | ret |
|
- | 463 | endp |
|
439 | 464 | ;Asper+] |
|
440 | 465 | ||
441 | ; look for the node record for the given NID |
466 | ; look for the node record for the given NID |
442 | proc hda_get_node stdcall, nid:dword |
467 | proc hda_get_node stdcall, nid:dword |
443 | push ebx edx esi |
468 | push ebx edx esi |
444 | movzx ebx, word [nid] |
469 | movzx ebx, word [nid] |
445 | mov esi, [spec.nid_list] |
470 | mov esi, [spec.nid_list] |
446 | test esi, esi |
471 | test esi, esi |
447 | jz .out |
472 | jz .out |
448 | 473 | ||
449 | .next_node: |
474 | .next_node: |
450 | mov edx, [esi + HDA_GNODE.next] |
475 | mov edx, [esi + HDA_GNODE.next] |
451 | test edx, edx ;Asper+ |
476 | test edx, edx ;Asper+ |
452 | jz .not_found ;Asper+ |
477 | jz .not_found ;Asper+ |
453 | mov ax, word [esi + HDA_GNODE.nid] |
478 | mov ax, word [esi + HDA_GNODE.nid] |
454 | cmp ax, bx |
479 | cmp ax, bx |
455 | je .out |
480 | je .out |
456 | mov esi, edx |
481 | mov esi, edx |
457 | jmp .next_node |
482 | jmp .next_node |
458 | 483 | ||
459 | .not_found: ;Asper+ |
484 | .not_found: ;Asper+ |
460 | xor esi, esi |
485 | xor esi, esi |
461 | .out: |
486 | .out: |
462 | mov eax, esi |
487 | mov eax, esi |
463 | pop esi edx ebx |
488 | pop esi edx ebx |
464 | ret |
489 | ret |
465 | endp |
490 | endp |
466 | 491 | ||
467 | ;Asper+[ |
492 | ;Asper+[ |
468 | proc set_eapd stdcall, node:dword ;nid:dword, on:dword |
493 | proc set_eapd stdcall, node:dword ;nid:dword, on:dword |
469 | push eax ebx esi |
494 | push eax ebx esi |
470 | mov esi, [node] |
495 | mov esi, [node] |
471 | cmp [esi + HDA_GNODE.type], AC_WID_PIN |
496 | cmp [esi + HDA_GNODE.type], AC_WID_PIN |
472 | jne .out |
497 | jne .out |
473 | ; eapd capable? |
498 | ; eapd capable? |
474 | test [esi + HDA_GNODE.pin_caps], AC_PINCAP_EAPD |
499 | test [esi + HDA_GNODE.pin_caps], AC_PINCAP_EAPD |
475 | jz .out |
500 | jz .out |
476 | ;stdcall snd_hda_codec_read, ebx, 0, AC_VERB_GET_EAPD_BTLENABLE, AC_EAPDBTL_EAPD |
501 | ;stdcall snd_hda_codec_read, ebx, 0, AC_VERB_GET_EAPD_BTLENABLE, AC_EAPDBTL_EAPD |
477 | ;or eax, AC_EAPDBTL_EAPD |
502 | ;or eax, AC_EAPDBTL_EAPD |
478 | movzx ebx, [esi + HDA_GNODE.nid] |
503 | movzx ebx, [esi + HDA_GNODE.nid] |
479 | stdcall snd_hda_codec_write, ebx, 0, AC_VERB_SET_EAPD_BTLENABLE, AC_EAPDBTL_EAPD ;eax |
504 | stdcall snd_hda_codec_write, ebx, 0, AC_VERB_SET_EAPD_BTLENABLE, AC_EAPDBTL_EAPD ;eax |
480 | if DEBUG |
505 | if DEBUG |
481 | push eax esi |
506 | push eax esi |
482 | mov esi, msgEnableEAPD |
507 | mov esi, msgEnableEAPD |
483 | call SysMsgBoardStr |
508 | invoke SysMsgBoardStr |
484 | mov eax, ebx |
509 | mov eax, ebx |
485 | stdcall fdword2str, 3 |
510 | stdcall fdword2str, 3 |
486 | call SysMsgBoardStr |
511 | invoke SysMsgBoardStr |
487 | pop esi eax |
512 | pop esi eax |
488 | end if |
513 | end if |
489 | .out: |
514 | .out: |
490 | pop esi ebx eax |
515 | pop esi ebx eax |
491 | ret |
516 | ret |
492 | endp |
517 | endp |
493 | ;Asper+] |
518 | ;Asper+] |
494 | 519 | ||
495 | ; unmute (and set max vol) the output amplifier |
520 | ; unmute (and set max vol) the output amplifier |
496 | proc unmute_output stdcall, node:dword |
521 | proc unmute_output stdcall, node:dword |
497 | - | ||
498 | push ebx ecx edx esi |
522 | push ebx ecx edx esi |
499 | mov esi, [node] |
523 | mov esi, [node] |
500 | test [esi + HDA_GNODE.wid_caps], AC_WCAP_OUT_AMP |
524 | test [esi + HDA_GNODE.wid_caps], AC_WCAP_OUT_AMP |
501 | jz .out |
525 | jz .out |
502 | movzx eax, word [esi + HDA_GNODE.nid] |
526 | movzx eax, word [esi + HDA_GNODE.nid] |
503 | if DEBUG |
527 | if DEBUG |
504 | push esi |
528 | push esi |
505 | mov esi, msgUnmuteOut |
529 | mov esi, msgUnmuteOut |
506 | call SysMsgBoardStr |
530 | invoke SysMsgBoardStr |
507 | stdcall fdword2str, 3 |
531 | stdcall fdword2str, 3 |
508 | call SysMsgBoardStr |
532 | invoke SysMsgBoardStr |
509 | pop esi |
533 | pop esi |
510 | end if |
534 | end if |
511 | 535 | ||
512 | stdcall set_eapd, esi ;Asper+: set EAPD if exist |
536 | stdcall set_eapd, esi ;Asper+: set EAPD if exist |
513 | 537 | ||
514 | mov ebx, eax |
538 | mov ebx, eax |
515 | mov eax, [esi + HDA_GNODE.amp_out_caps] |
539 | mov eax, [esi + HDA_GNODE.amp_out_caps] |
516 | mov ecx, eax |
540 | mov ecx, eax |
517 | 541 | ||
518 | and eax, AC_AMPCAP_NUM_STEPS |
542 | and eax, AC_AMPCAP_NUM_STEPS |
519 | shr eax, AC_AMPCAP_NUM_STEPS_SHIFT |
543 | shr eax, AC_AMPCAP_NUM_STEPS_SHIFT |
520 | 544 | ||
521 | stdcall snd_hda_codec_amp_stereo, ebx, HDA_OUTPUT, 0, 0xFF, eax |
545 | stdcall snd_hda_codec_amp_stereo, ebx, HDA_OUTPUT, 0, 0xFF, eax |
522 | 546 | ||
523 | and ecx, AC_AMPCAP_STEP_SIZE |
547 | and ecx, AC_AMPCAP_STEP_SIZE |
524 | shr ecx, AC_AMPCAP_STEP_SIZE_SHIFT |
548 | shr ecx, AC_AMPCAP_STEP_SIZE_SHIFT |
525 | 549 | ||
526 | test al, al |
550 | test al, al |
527 | jz .out |
551 | jz .out |
528 | if DEBUG |
552 | if DEBUG |
529 | push eax esi |
553 | push eax esi |
530 | mov esi, msgAmpVal |
554 | mov esi, msgAmpVal |
531 | call SysMsgBoardStr |
555 | invoke SysMsgBoardStr |
532 | stdcall fdword2str, 1 |
556 | stdcall fdword2str, 1 |
533 | call SysMsgBoardStr |
557 | invoke SysMsgBoardStr |
534 | 558 | ||
535 | mov esi, strSemicolon |
559 | mov esi, strSemicolon |
536 | call SysMsgBoardStr |
560 | invoke SysMsgBoardStr |
537 | mov eax, ecx |
561 | mov eax, ecx |
538 | stdcall fdword2str, 3 |
562 | stdcall fdword2str, 3 |
539 | call SysMsgBoardStr |
563 | invoke SysMsgBoardStr |
540 | pop esi eax |
564 | pop esi eax |
541 | end if |
565 | end if |
542 | mov [volume.out_amp_node], esi |
566 | mov [volume.out_amp_node], esi |
543 | inc al |
- | |
544 | mov [volume.num_steps], al |
567 | mov [volume.num_steps], al |
545 | inc cl |
- | |
546 | mov [volume.step_size], cl |
568 | mov [volume.step_size], cl |
547 | mul cl |
569 | mul cl |
548 | shr eax, 2 |
- | |
549 | imul eax, 100 |
570 | imul eax, (100/4) |
550 | mov [volume.maxDb], eax |
571 | mov [volume.maxDb], eax |
551 | - | ||
552 | .out: |
572 | .out: |
553 | xor eax, eax |
573 | xor eax, eax |
554 | pop esi edx ecx ebx |
574 | pop esi edx ecx ebx |
555 | ret |
575 | ret |
556 | endp |
576 | endp |
557 | 577 | ||
558 | ; unmute (and set max vol) the input amplifier |
578 | ; unmute (and set max vol) the input amplifier |
559 | proc unmute_input stdcall, node:dword, index:dword |
579 | proc unmute_input stdcall, node:dword, index:dword |
560 | push ecx edx esi |
580 | push ecx edx esi |
561 | test [esi + HDA_GNODE.wid_caps], AC_WCAP_IN_AMP |
581 | test [esi + HDA_GNODE.wid_caps], AC_WCAP_IN_AMP |
562 | jz .out |
582 | jz .out |
563 | and [index], 0xF ;Asper+ : Ranger |
583 | and [index], 0xF ;Asper+ : Ranger |
564 | mov esi, [node] |
584 | mov esi, [node] |
565 | movzx eax, word [esi + HDA_GNODE.nid] |
585 | movzx eax, word [esi + HDA_GNODE.nid] |
566 | if DEBUG |
586 | if DEBUG |
567 | push eax esi |
587 | push eax esi |
568 | mov esi, msgUnmuteIn |
588 | mov esi, msgUnmuteIn |
569 | call SysMsgBoardStr |
589 | invoke SysMsgBoardStr |
570 | stdcall fdword2str, 3 |
590 | stdcall fdword2str, 3 |
571 | call SysMsgBoardStr |
591 | invoke SysMsgBoardStr |
572 | mov esi, msgIdx |
592 | mov esi, msgIdx |
573 | call SysMsgBoardStr |
593 | invoke SysMsgBoardStr |
574 | mov eax, [index] |
594 | mov eax, [index] |
575 | stdcall fdword2str, 3 |
595 | stdcall fdword2str, 3 |
576 | call SysMsgBoardStr |
596 | invoke SysMsgBoardStr |
577 | pop esi eax |
597 | pop esi eax |
578 | end if |
598 | end if |
579 | 599 | ||
580 | mov edx, [esi + HDA_GNODE.amp_in_caps] |
600 | mov edx, [esi + HDA_GNODE.amp_in_caps] |
581 | mov ecx, edx |
601 | mov ecx, edx |
582 | 602 | ||
583 | and edx, AC_AMPCAP_NUM_STEPS |
603 | and edx, AC_AMPCAP_NUM_STEPS |
584 | shr edx, AC_AMPCAP_NUM_STEPS_SHIFT |
604 | shr edx, AC_AMPCAP_NUM_STEPS_SHIFT |
585 | 605 | ||
586 | stdcall snd_hda_codec_amp_stereo, eax, HDA_INPUT, [index], 0xFF, edx |
606 | stdcall snd_hda_codec_amp_stereo, eax, HDA_INPUT, [index], 0xFF, edx |
587 | .out: |
607 | .out: |
588 | xor eax, eax |
608 | xor eax, eax |
589 | pop esi edx ecx |
609 | pop esi edx ecx |
590 | ret |
610 | ret |
591 | endp |
611 | endp |
592 | 612 | ||
593 | 613 | ||
594 | ; select the input connection of the given node. |
614 | ; select the input connection of the given node. |
595 | proc select_input_connection stdcall, node:dword, index:dword |
615 | proc select_input_connection stdcall, node:dword, index:dword |
596 | push ebx esi |
616 | push ebx esi |
597 | mov esi, [node] |
617 | mov esi, [node] |
598 | movzx eax, word [esi + HDA_GNODE.nid] |
618 | movzx eax, word [esi + HDA_GNODE.nid] |
599 | mov ebx, [index] |
619 | mov ebx, [index] |
600 | if DEBUG |
620 | if DEBUG |
601 | mov esi, msgConnect |
621 | mov esi, msgConnect |
602 | call SysMsgBoardStr |
622 | invoke SysMsgBoardStr |
603 | stdcall fdword2str, 3 |
623 | stdcall fdword2str, 3 |
604 | call SysMsgBoardStr |
624 | invoke SysMsgBoardStr |
605 | 625 | ||
606 | mov esi, msgIdx |
626 | mov esi, msgIdx |
607 | call SysMsgBoardStr |
627 | invoke SysMsgBoardStr |
608 | push eax |
628 | push eax |
609 | mov eax, ebx |
629 | mov eax, ebx |
610 | stdcall fdword2str, 3 |
630 | stdcall fdword2str, 3 |
611 | call SysMsgBoardStr |
631 | invoke SysMsgBoardStr |
612 | pop eax |
632 | pop eax |
613 | end if |
633 | end if |
614 | stdcall snd_hda_codec_write, eax, 0, AC_VERB_SET_CONNECT_SEL, ebx |
634 | stdcall snd_hda_codec_write, eax, 0, AC_VERB_SET_CONNECT_SEL, ebx |
615 | pop esi ebx |
635 | pop esi ebx |
616 | ret |
636 | ret |
617 | endp |
637 | endp |
618 | 638 | ||
619 | 639 | ||
620 | ; clear checked flag of each node in the node list |
640 | ; clear checked flag of each node in the node list |
621 | proc clear_check_flags |
641 | proc clear_check_flags |
622 | push eax esi |
642 | push eax esi |
623 | mov esi, [spec.nid_list] |
643 | mov esi, [spec.nid_list] |
624 | test esi, esi |
644 | test esi, esi |
625 | jz .out |
645 | jz .out |
626 | .next_node: |
646 | .next_node: |
627 | mov byte [esi + HDA_GNODE.checked], 0 |
647 | mov byte [esi + HDA_GNODE.checked], 0 |
628 | mov eax, [esi + HDA_GNODE.next] |
648 | mov eax, [esi + HDA_GNODE.next] |
629 | test eax, eax |
649 | test eax, eax |
630 | jz .out |
650 | jz .out |
631 | mov esi, eax |
651 | mov esi, eax |
632 | jmp .next_node |
652 | jmp .next_node |
633 | - | ||
634 | .out: |
653 | .out: |
635 | pop esi eax |
654 | pop esi eax |
636 | ret |
655 | ret |
637 | endp |
656 | endp |
638 | 657 | ||
639 | ; |
658 | ; |
640 | ; parse the output path recursively until reach to an audio output widget |
659 | ; parse the output path recursively until reach to an audio output widget |
641 | ; |
660 | ; |
642 | ; returns 0 if not found, 1 if found, or a negative error code. |
661 | ; returns 0 if not found, 1 if found, or a negative error code. |
643 | ; |
662 | ; |
644 | proc parse_output_path stdcall, node:dword, dac_idx:dword |
663 | proc parse_output_path stdcall, node:dword, dac_idx:dword |
645 | push ebx ecx edx esi |
664 | push ebx ecx edx esi |
646 | mov esi, [node] |
665 | mov esi, [node] |
647 | mov al, byte [esi + HDA_GNODE.checked] |
666 | mov al, byte [esi + HDA_GNODE.checked] |
648 | test al, al |
667 | test al, al |
649 | jnz .ret_zero |
668 | jnz .ret_zero |
650 | 669 | ||
651 | mov byte [esi + HDA_GNODE.checked], 1 |
670 | mov byte [esi + HDA_GNODE.checked], 1 |
652 | 671 | ||
653 | mov al, byte [esi + HDA_GNODE.type] |
672 | mov al, byte [esi + HDA_GNODE.type] |
654 | cmp al, AC_WID_AUD_OUT |
673 | cmp al, AC_WID_AUD_OUT |
655 | jne .not_wid_aud_out |
674 | jne .not_wid_aud_out |
656 | 675 | ||
657 | movzx eax, word [esi + HDA_GNODE.nid] |
676 | movzx eax, word [esi + HDA_GNODE.nid] |
658 | mov ebx, [esi + HDA_GNODE.wid_caps] |
677 | mov ebx, [esi + HDA_GNODE.wid_caps] |
659 | test ebx, AC_WCAP_DIGITAL |
678 | test ebx, AC_WCAP_DIGITAL |
660 | jz @f |
679 | jz @f |
661 | if DEBUG |
680 | if DEBUG |
662 | push esi |
681 | push esi |
663 | mov esi, msgSkipDigitalOutNode |
682 | mov esi, msgSkipDigitalOutNode |
664 | call SysMsgBoardStr |
683 | invoke SysMsgBoardStr |
665 | stdcall fdword2str, 3 |
684 | stdcall fdword2str, 3 |
666 | call SysMsgBoardStr |
685 | invoke SysMsgBoardStr |
667 | pop esi |
686 | pop esi |
668 | end if |
687 | end if |
669 | jmp .ret_zero |
688 | jmp .ret_zero |
670 | @@: |
689 | @@: |
671 | if DEBUG |
690 | if DEBUG |
672 | push eax esi |
691 | push eax esi |
673 | mov esi, msgAudOutFound |
692 | mov esi, msgAudOutFound |
674 | call SysMsgBoardStr |
693 | invoke SysMsgBoardStr |
675 | stdcall fdword2str, 3 |
694 | stdcall fdword2str, 3 |
676 | call SysMsgBoardStr |
695 | invoke SysMsgBoardStr |
677 | pop esi eax |
696 | pop esi eax |
678 | end if |
697 | end if |
679 | 698 | ||
680 | push eax |
699 | push eax |
681 | stdcall unmute_output, esi ;Asper+ |
700 | stdcall unmute_output, esi ;Asper+ |
682 | pop eax |
701 | pop eax |
683 | mov ecx, [dac_idx] |
702 | mov ecx, [dac_idx] |
684 | shl ecx, 2 |
703 | shl ecx, 2 |
685 | push eax |
704 | push eax |
686 | mov eax, [spec.dac_node+ecx] |
705 | mov eax, [spec.dac_node+ecx] |
687 | test eax, eax |
706 | test eax, eax |
688 | pop eax |
707 | pop eax |
689 | jz @f |
708 | jz @f |
690 | ; already DAC node is assigned, just unmute & connect |
709 | ; already DAC node is assigned, just unmute & connect |
691 | cmp eax, [node] |
710 | cmp eax, [node] |
692 | je .ret_one |
711 | je .ret_one |
693 | jmp .ret_zero |
712 | jmp .ret_zero |
694 | @@: |
713 | @@: |
695 | mov ecx, [dac_idx] |
714 | mov ecx, [dac_idx] |
696 | shl ecx, 2 |
715 | shl ecx, 2 |
697 | mov [spec.dac_node+ecx], eax |
716 | mov [spec.dac_node+ecx], eax |
698 | jmp .ret_one ;found |
717 | jmp .ret_one ;found |
699 | .not_wid_aud_out: |
718 | .not_wid_aud_out: |
700 | movzx ebx, [esi + HDA_GNODE.nconns] |
719 | movzx ebx, [esi + HDA_GNODE.nconns] |
701 | xor ecx, ecx |
720 | xor ecx, ecx |
702 | mov edx, [esi + HDA_GNODE.conn_list] |
721 | mov edx, [esi + HDA_GNODE.conn_list] |
703 | test ebx, ebx |
722 | test ebx, ebx |
704 | jz .ret_zero |
723 | jz .ret_zero |
705 | .next_node: |
724 | .next_node: |
706 | stdcall hda_get_node, [edx] |
725 | stdcall hda_get_node, [edx] |
707 | test eax, eax |
726 | test eax, eax |
708 | jz .continue |
727 | jz .continue |
709 | 728 | ||
710 | stdcall parse_output_path, eax, [dac_idx] |
729 | stdcall parse_output_path, eax, [dac_idx] |
711 | 730 | ||
712 | cmp [esi + HDA_GNODE.nconns], 1 |
731 | cmp [esi + HDA_GNODE.nconns], 1 |
713 | jle @f |
732 | jle @f |
714 | stdcall select_input_connection, esi, ecx |
733 | stdcall select_input_connection, esi, ecx |
715 | @@: |
734 | @@: |
716 | ;UNSUPPORTED YET! stdcall unmute_input, esi, ecx |
735 | ;UNSUPPORTED YET! stdcall unmute_input, esi, ecx |
717 | stdcall unmute_output, esi |
736 | stdcall unmute_output, esi |
718 | jmp .ret_one |
737 | jmp .ret_one |
719 | 738 | ||
720 | .continue: |
739 | .continue: |
721 | add edx, 2 |
740 | add edx, 2 |
722 | inc ecx |
741 | inc ecx |
723 | cmp ecx, ebx |
742 | cmp ecx, ebx |
724 | jl .next_node |
743 | jl .next_node |
725 | .ret_zero: |
744 | .ret_zero: |
726 | xor eax, eax |
745 | xor eax, eax |
727 | pop esi edx ecx ebx |
746 | pop esi edx ecx ebx |
728 | ret |
747 | ret |
729 | .ret_one: |
748 | .ret_one: |
730 | xor eax, eax |
749 | xor eax, eax |
731 | inc eax |
750 | inc eax |
732 | .ret: ;Asper+ |
751 | .ret: ;Asper+ |
733 | pop esi edx ecx ebx |
752 | pop esi edx ecx ebx |
734 | ret |
753 | ret |
735 | endp |
754 | endp |
736 | 755 | ||
737 | ; Look for the output PIN widget with the given jack type |
756 | ; Look for the output PIN widget with the given jack type |
738 | ; and parse the output path to that PIN. |
757 | ; and parse the output path to that PIN. |
739 | ; |
758 | ; |
740 | ; Returns the PIN node when the path to DAC is established. |
759 | ; Returns the PIN node when the path to DAC is established. |
741 | proc parse_output_jack stdcall, jack_type:dword |
760 | proc parse_output_jack stdcall, jack_type:dword |
742 | push edx esi |
761 | push edx esi |
743 | 762 | ||
744 | mov esi, [spec.nid_list] |
763 | mov esi, [spec.nid_list] |
745 | test esi, esi |
764 | test esi, esi |
746 | jz .ret_zero |
765 | jz .ret_zero |
747 | .next_pin: |
766 | .next_pin: |
748 | cmp [esi + HDA_GNODE.type], AC_WID_PIN |
767 | cmp [esi + HDA_GNODE.type], AC_WID_PIN |
749 | jne .continue |
768 | jne .continue |
750 | 769 | ||
751 | ; output capable? |
770 | ; output capable? |
752 | mov eax, [esi + HDA_GNODE.pin_caps] |
771 | mov eax, [esi + HDA_GNODE.pin_caps] |
753 | test eax, AC_PINCAP_OUT |
772 | test eax, AC_PINCAP_OUT |
754 | jz .continue |
773 | jz .continue |
755 | 774 | ||
756 | stdcall defcfg_port_conn, esi |
775 | stdcall defcfg_port_conn, esi |
757 | cmp eax, AC_JACK_PORT_NONE |
776 | cmp eax, AC_JACK_PORT_NONE |
758 | je .continue ;unconnected |
777 | je .continue ;unconnected |
759 | 778 | ||
760 | mov edx, [jack_type] |
779 | mov edx, [jack_type] |
761 | cmp edx, 0 |
780 | cmp edx, 0 |
762 | jl @f |
781 | jl @f |
763 | 782 | ||
764 | stdcall defcfg_type, esi |
783 | stdcall defcfg_type, esi |
765 | cmp edx, eax |
784 | cmp edx, eax |
766 | jne .continue |
785 | jne .continue |
767 | 786 | ||
768 | test [esi + HDA_GNODE.wid_caps], AC_WCAP_DIGITAL |
787 | test [esi + HDA_GNODE.wid_caps], AC_WCAP_DIGITAL |
769 | jnz .continue ; skip SPDIF |
788 | jnz .continue ; skip SPDIF |
770 | @@: |
789 | @@: |
771 | ; output as default? |
790 | push eax |
- | 791 | movzx eax, [esi + HDA_GNODE.nid] |
|
- | 792 | stdcall snd_hda_enable_pin_sense, eax, eax ;Asper+: enable unsolicited events for the output pin |
|
- | 793 | pop eax |
|
- | 794 | ||
772 | if DEBUG |
795 | if DEBUG |
773 | pusha |
796 | pusha |
774 | ; push esi |
797 | ; push esi |
775 | ; mov esi, msgPin_Nid |
798 | ; mov esi, msgPin_Nid |
776 | ; call SysMsgBoardStr |
799 | ; invoke SysMsgBoardStr |
777 | ; pop esi |
800 | ; pop esi |
778 | movzx eax, [esi + HDA_GNODE.nid] |
801 | movzx eax, [esi + HDA_GNODE.nid] |
779 | movzx ebx, [esi + HDA_GNODE.pin_ctl] |
802 | movzx ebx, [esi + HDA_GNODE.pin_ctl] |
780 | mov ecx, [esi + HDA_GNODE.pin_caps] |
803 | mov ecx, [esi + HDA_GNODE.pin_caps] |
781 | mov edx, [esi + HDA_GNODE.def_cfg] |
804 | mov edx, [esi + HDA_GNODE.def_cfg] |
782 | mov edi, [esi + HDA_GNODE.amp_out_caps] |
805 | mov edi, [esi + HDA_GNODE.amp_out_caps] |
783 | mov esi, msgPin_Nid |
806 | mov esi, msgPin_Nid |
784 | call SysMsgBoardStr |
807 | invoke SysMsgBoardStr |
785 | stdcall fdword2str, 3 |
808 | stdcall fdword2str, 3 |
786 | call SysMsgBoardStr |
809 | invoke SysMsgBoardStr |
787 | 810 | ||
788 | mov esi, msgPin_Ctl |
811 | mov esi, msgPin_Ctl |
789 | call SysMsgBoardStr |
812 | invoke SysMsgBoardStr |
790 | mov eax, ebx |
813 | mov eax, ebx |
791 | stdcall fdword2str, 2 |
814 | stdcall fdword2str, 2 |
792 | call SysMsgBoardStr |
815 | invoke SysMsgBoardStr |
793 | 816 | ||
794 | mov esi, msgPin_Caps |
817 | mov esi, msgPin_Caps |
795 | call SysMsgBoardStr |
818 | invoke SysMsgBoardStr |
796 | mov eax, ecx |
819 | mov eax, ecx |
797 | stdcall fdword2str, 2 |
820 | stdcall fdword2str, 2 |
798 | call SysMsgBoardStr |
821 | invoke SysMsgBoardStr |
799 | 822 | ||
800 | mov esi, msgDef_Cfg |
823 | mov esi, msgDef_Cfg |
801 | call SysMsgBoardStr |
824 | invoke SysMsgBoardStr |
802 | mov eax, edx |
825 | mov eax, edx |
803 | stdcall fdword2str, 2 |
826 | stdcall fdword2str, 2 |
804 | call SysMsgBoardStr |
827 | invoke SysMsgBoardStr |
805 | 828 | ||
806 | mov esi, msgAmp_Out_Caps |
829 | mov esi, msgAmp_Out_Caps |
807 | call SysMsgBoardStr |
- | |
808 | mov eax, edi |
830 | invoke SysMsgBoardStr |
809 | stdcall fdword2str, 2 |
831 | mov eax, edi |
- | 832 | stdcall fdword2str, 2 |
|
810 | call SysMsgBoardStr |
833 | invoke SysMsgBoardStr |
811 | 834 | popa |
|
- | 835 | end if |
|
- | 836 | ; output as default? |
|
- | 837 | ; test [esi + HDA_GNODE.pin_ctl], AC_PINCTL_OUT_EN |
|
- | 838 | ; jz .continue |
|
812 | popa |
839 | .use_dac0: |
813 | end if |
840 | cmp [spec.dac_node], 0 |
814 | ; test [esi + HDA_GNODE.pin_ctl], AC_PINCTL_OUT_EN |
841 | jne .use_dac1 |
815 | ; jz .continue |
842 | |
816 | stdcall clear_check_flags |
843 | stdcall clear_check_flags |
817 | stdcall parse_output_path, esi, 0 |
844 | stdcall parse_output_path, esi, 0 |
818 | 845 | ||
819 | test eax, eax |
846 | test eax, eax |
820 | jnz @f |
847 | jnz @f |
821 | mov edx, [spec.out_pin_node] |
848 | mov edx, [spec.out_pin_node] |
822 | test edx, edx |
849 | test edx, edx |
823 | jz @f |
850 | jz @f |
- | 851 | .use_dac1: |
|
824 | stdcall clear_check_flags |
852 | stdcall clear_check_flags |
825 | stdcall parse_output_path, esi, 1 |
853 | stdcall parse_output_path, esi, 1 |
826 | @@: |
854 | @@: |
827 | cmp eax, 0 |
855 | cmp eax, 0 |
828 | jle .l1 |
856 | jle .l1 |
829 | 857 | ||
830 | ; unmute the PIN output |
858 | ; unmute the PIN output |
831 | stdcall unmute_output, esi |
859 | stdcall unmute_output, esi |
832 | ; set PIN-Out enable |
860 | ; set PIN-Out enable |
833 | xor edx, edx |
861 | xor edx, edx |
834 | test [esi + HDA_GNODE.pin_caps], AC_PINCAP_HP_DRV |
862 | test [esi + HDA_GNODE.pin_caps], AC_PINCAP_HP_DRV |
835 | jz @f |
863 | jz @f |
836 | mov edx, AC_PINCTL_HP_EN |
864 | mov edx, AC_PINCTL_HP_EN |
837 | @@: |
865 | @@: |
838 | or edx, AC_PINCTL_OUT_EN |
866 | or edx, AC_PINCTL_OUT_EN |
839 | movzx eax, [esi + HDA_GNODE.nid] |
867 | movzx eax, [esi + HDA_GNODE.nid] |
840 | stdcall snd_hda_codec_write, eax, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, edx |
868 | stdcall snd_hda_codec_write, eax, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, edx |
841 | mov eax, esi |
869 | mov eax, esi |
842 | jmp .out |
870 | jmp .out |
843 | .l1: |
871 | .l1: |
844 | .continue: |
872 | .continue: |
845 | mov edx, [esi + HDA_GNODE.next] |
873 | mov edx, [esi + HDA_GNODE.next] |
846 | test edx, edx |
874 | test edx, edx |
847 | jz .ret_zero |
875 | jz .ret_zero |
848 | mov esi, edx |
876 | mov esi, edx |
849 | jmp .next_pin |
877 | jmp .next_pin |
850 | .ret_zero: |
878 | .ret_zero: |
851 | xor eax, eax |
879 | xor eax, eax |
852 | .out: |
880 | .out: |
853 | pop esi edx |
881 | pop esi edx |
854 | ret |
882 | ret |
855 | endp |
883 | endp |
856 | 884 | ||
857 | 885 | ||
858 | ; parse outputs |
886 | ; parse outputs |
859 | proc parse_output |
887 | proc parse_output |
860 | push edx |
888 | push edx |
861 | ; Look for the output PIN widget |
889 | ; Look for the output PIN widget |
862 | ; |
890 | ; |
863 | ; first, look for the line-out pin |
891 | ; first, look for the line-out pin |
864 | stdcall parse_output_jack, AC_JACK_LINE_OUT |
892 | stdcall parse_output_jack, AC_JACK_LINE_OUT |
865 | test eax, eax |
893 | test eax, eax |
866 | jz @f |
894 | jz @f |
867 | mov [spec.out_pin_node], eax ; found, remember the PIN node |
895 | mov [spec.out_pin_node], eax ; found, remember the PIN node |
868 | jmp .l1 |
896 | jmp .l1 |
869 | @@: |
897 | @@: |
870 | ; if no line-out is found, try speaker out |
898 | ; if no line-out is found, try speaker out |
871 | stdcall parse_output_jack, AC_JACK_SPEAKER |
899 | stdcall parse_output_jack, AC_JACK_SPEAKER |
872 | test eax, eax |
900 | test eax, eax |
873 | jz .l1 |
901 | jz .l1 |
874 | mov [spec.out_pin_node], eax ; found, remember the PIN node |
902 | mov [spec.out_pin_node], eax ; found, remember the PIN node |
875 | .l1: |
903 | .l1: |
876 | ; look for the HP-out pin |
904 | ; look for the HP-out pin |
877 | stdcall parse_output_jack, AC_JACK_HP_OUT |
905 | stdcall parse_output_jack, AC_JACK_HP_OUT |
878 | test eax, eax |
906 | test eax, eax |
879 | jz .l2 |
907 | jz .l2 |
880 | 908 | ||
881 | mov edx, [spec.out_pin_node] |
909 | mov edx, [spec.out_pin_node] |
882 | test edx, edx |
910 | test edx, edx |
883 | jnz @f |
911 | jnz @f |
884 | mov [spec.out_pin_node], eax |
912 | mov [spec.out_pin_node], eax |
885 | jmp .l2 |
913 | jmp .l2 |
886 | @@: |
914 | @@: |
887 | mov [spec.out_pin_node+4], eax |
915 | mov [spec.out_pin_node+4], eax |
888 | .l2: |
916 | .l2: |
889 | mov edx, [spec.out_pin_node] |
917 | mov edx, [spec.out_pin_node] |
890 | test edx, edx |
918 | test edx, edx |
891 | jnz @f |
919 | jnz @f |
892 | ; no line-out or HP pins found, |
920 | ; no line-out or HP pins found, |
893 | ; then choose for the first output pin |
921 | ; then choose for the first output pin |
894 | stdcall parse_output_jack, -1 |
922 | stdcall parse_output_jack, -1 |
895 | 923 | ||
896 | mov [spec.out_pin_node], eax |
924 | mov [spec.out_pin_node], eax |
897 | test eax, eax |
925 | test eax, eax |
898 | jnz @f |
926 | jnz @f |
899 | if DEBUG |
927 | if DEBUG |
900 | push esi |
928 | push esi |
901 | mov esi, emsgNoProperOutputPathFound |
929 | mov esi, emsgNoProperOutputPathFound |
902 | call SysMsgBoardStr |
930 | invoke SysMsgBoardStr |
903 | pop esi |
931 | pop esi |
904 | end if |
932 | end if |
905 | @@: |
933 | @@: |
906 | pop edx |
934 | pop edx |
907 | xor eax, eax |
935 | xor eax, eax |
908 | ret |
936 | ret |
909 | endp |
937 | endp |
910 | 938 | ||
911 | 939 | ||
912 | ;(...) Skip functions for the input (capture is not supported). |
940 | ;(...) Skip functions for the input (capture is not supported). |
913 | 941 | ||
914 | ; the generic parser |
942 | ; the generic parser |
915 | proc snd_hda_parse_generic_codec |
943 | proc snd_hda_parse_generic_codec |
916 | mov eax, [codec.afg] |
944 | mov eax, [codec.afg] |
917 | test eax, eax |
945 | test eax, eax |
918 | jz .out |
946 | jz .out |
919 | 947 | ||
920 | stdcall build_afg_tree |
948 | stdcall build_afg_tree |
921 | cmp eax, 0 |
949 | cmp eax, 0 |
922 | jl .error |
950 | jl .error |
- | 951 | ||
- | 952 | if FDEBUG |
|
- | 953 | stdcall print_afg_tree_nodes ;Asper+ |
|
- | 954 | end if |
|
923 | 955 | ||
924 | stdcall parse_output |
956 | stdcall parse_output |
925 | xor eax, eax |
957 | xor eax, eax |
926 | .out: |
958 | .out: |
927 | ret |
959 | ret |
928 | .error: |
960 | .error: |
929 | stdcall snd_hda_generic_free |
961 | stdcall snd_hda_generic_free |
930 | ret |
962 | ret |
931 | endp |
963 | endp |
932 | 964 | ||
933 | 965 | ||
934 | ; some data |
966 | ; some data |
935 | spec HDA_GSPEC |
967 | spec HDA_GSPEC |
936 | volume VOLUME_CTL=> |
968 | volume VOLUME_CTL=> |