Subversion Repositories Kolibri OS

Rev

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