Subversion Repositories Kolibri OS

Rev

Rev 4555 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
3083 leency 1
 
2
proc make_codec_cmd stdcall, nid:dword, direct:dword, verb:dword, parm:dword
3
	push	ebx
5048 Asper 4
3083 leency 5
 
5048 Asper 6
	and	dword [direct], 1
7
	and	dword [nid], 0x7F
8
	and	dword [verb], 0xFFF
9
	and	dword [parm], 0xFFFF
10
3083 leency 11
 
5048 Asper 12
	shl	eax, 28
13
	mov	ebx, [direct]
14
	shl	ebx, 27
15
	or	eax, ebx
16
	mov	ebx, [nid]
17
	shl	ebx, 20
18
	or	eax, ebx
19
	mov	ebx, [verb]
20
	shl	ebx, 8
21
	or	eax, ebx
22
	mov	ebx, [parm]
23
	or	eax, ebx
24
	pop	ebx
25
	ret
26
.err:
27
	pop	ebx
28
	mov	eax, -1
29
	ret
30
endp
3083 leency 31
32
 
33
proc codec_exec_verb stdcall, cmd:dword;, res:dword <- returned in eax
5048 Asper 34
	push	ebx  edx
35
	mov	ebx, [cmd]
36
	cmp	ebx, -1
37
	jne	@f
38
	pop	edx  ebx
39
	mov	eax, -1
40
	ret
41
@@:
42
if  FDEBUG
43
	push	eax esi
44
	mov	esi, msgVerbQuery
45
	invoke	SysMsgBoardStr
46
	mov	eax, ebx
47
	stdcall fdword2str, 2
48
	invoke	SysMsgBoardStr
49
	pop	esi eax
50
end if
51
3083 leency 52
 
5048 Asper 53
.again:
54
	;call   snd_hda_power_up
55
	stdcall azx_send_cmd, ebx
56
	mov	ebx, eax
57
	test	ebx, ebx
58
	jnz	@f
59
	call	azx_get_response
60
	mov	edx, eax
61
if  FDEBUG
62
	test	edx, edx
63
	jz	.end_debug
64
	push	eax esi
65
	mov	esi, msgVerbAnswer
66
	invoke	SysMsgBoardStr
67
	mov	eax, edx
68
	stdcall fdword2str, 2
69
	invoke	SysMsgBoardStr
70
	pop	esi eax
71
.end_debug:
72
end if
73
3083 leency 74
 
5048 Asper 75
	;call   snd_hda_power_down
76
	cmp	edx, -1
77
	jne	.l1
78
3083 leency 79
 
5048 Asper 80
	test	eax, eax
81
	jz	.l1
82
3083 leency 83
 
5048 Asper 84
	jz	@f
85
3083 leency 86
 
5048 Asper 87
	push	esi
88
	mov	esi, emsgBusResetFatalComm
89
	invoke	SysMsgBoardStr
90
	pop	esi
91
end if
92
	call	azx_bus_reset
93
@@:
94
.l1:
95
	;; clear reset-flag when the communication gets recovered
96
	test	ebx, ebx
97
	jnz	@f
98
	mov	[ctrl.response_reset], 0
99
@@:
100
	mov	eax, edx
101
3083 leency 102
 
5048 Asper 103
	ret
104
endp
3083 leency 105
106
 
107
 
108
;; snd_hda_codec_read - send a command and get the response
109
;; @nid: NID to send the command
110
;; @direct: direct flag
111
;; @verb: the verb to send
112
;; @parm: the parameter for the verb
113
;;
114
;; Send a single command and read the corresponding response.
115
;;
116
;; Returns the obtained response value, or -1 for an error.
117
;;
118
proc snd_hda_codec_read stdcall, nid:dword, direct:dword, verb:dword, parm:dword
5048 Asper 119
	stdcall make_codec_cmd, [nid], [direct], [verb], [parm]
120
	stdcall codec_exec_verb, eax
121
	ret
122
endp
3083 leency 123
124
 
125
 
126
;; snd_hda_codec_write - send a single command without waiting for response
127
;; @nid: NID to send the command
128
;; @direct: direct flag
129
;; @verb: the verb to send
130
;; @parm: the parameter for the verb
131
;;
132
;; Send a single command without waiting for response.
133
;;
134
;; Returns 0 if successful, or a negative error code.
135
;;
136
proc snd_hda_codec_write stdcall, nid:dword, direct:dword, verb:dword, parm:dword
5048 Asper 137
	; Do we need to support a sync write?
138
	stdcall make_codec_cmd, [nid], [direct], [verb], [parm]
139
	stdcall codec_exec_verb, eax
140
	ret
141
endp
3083 leency 142
143
 
144
 
145
;; snd_hda_sequence_write - sequence writes
146
;; @seq: VERB array to send
147
;;
148
;; Send the commands sequentially from the given array.
149
;; The array must be terminated with NID=0.
150
;;
151
proc snd_hda_sequence_write stdcall, seq:dword
5048 Asper 152
	push	eax  ebx  ecx  esi
153
	mov	esi, [seq]
154
@@:
155
	;mov     ecx, [esi + hda_verb.nid]
156
	;mov     ebx, [esi + hda_verb.verb]
157
	;mov     eax, [esi + hda_verb.param]
158
	;stdcall snd_hda_codec_write, ecx, 0, ebx, eax
159
	;add     esi, hda_verb.sizeof
160
	;test    ecx, ecx
161
	;jnz     @b
162
	;______________________________________
163
	cmp	dword [esi], 0
164
	je	.out
165
	movzx	ecx, word [esi] ; NID
166
	movzx	ebx, word [esi+2] ; verb
167
	and	bx, 0x0FFF
168
	movzx	eax, word [esi + 4] ; sizeof(param) = 4 bytes
169
	stdcall snd_hda_codec_write, ecx, 0, ebx, eax
170
	add	esi, 6
171
	jmp	@b
172
.out:
173
	pop	esi  ecx  ebx  eax
174
	ret
175
endp
3083 leency 176
177
 
178
 
5048 Asper 179
{
3083 leency 180
	stdcall snd_hda_codec_read, nid, 0, AC_VERB_PARAMETERS, param
5048 Asper 181
}
3083 leency 182
183
 
184
;; snd_hda_get_sub_nodes - get the range of sub nodes
185
;; @codec: the HDA codec
186
;; @nid: NID to parse
187
;; @start_id: the pointer to store the start NID
188
;;
189
;; Parse the NID and store the start NID of its sub-nodes.
190
;; Returns the number of sub-nodes.
191
;;
192
proc snd_hda_get_sub_nodes stdcall, nid:dword;, start_id:dword  <- returned in upper word of eax
5048 Asper 193
	snd_hda_param_read  [nid], AC_PAR_NODE_COUNT
194
3083 leency 195
 
5048 Asper 196
	jne	@f
197
	inc	eax
198
@@:
199
	and	eax, 0x7FFF7FFF
200
	ret
201
endp
3083 leency 202
203
 
204
;; snd_hda_get_connections - get connection list
205
;; @codec: the HDA codec
206
;; @nid: NID to parse
207
;; @conn_list: connection list array
208
;; @max_conns: max. number of connections to store
209
;;
210
;; Parses the connection list of the given widget and stores the list
211
;; of NIDs.
212
;;
213
;; Returns the number of connections, or a negative error code.
214
;;
215
proc snd_hda_get_connections stdcall, nid:dword, conn_list:dword, max_conns:dword   ;Asper: Complete translation!
5048 Asper 216
locals
217
	parm	      dd ?
218
	conn_len      dd ?
219
	conns	      dd 0
220
	shift	      db 8
221
	num_elements  dd 4
222
	mask	      dd 0x7F
223
	wcaps	      dd ?
224
	prev_nid      dw 1 ;Asper: Hmm.. Probably ALSA bug that it isn't initialized. I suppose to init it with 1.
225
endl
226
3083 leency 227
 
5048 Asper 228
	mov	edi, [conn_list]
229
	test	edi, edi
230
	jz	.err_out
231
	mov	ecx, [max_conns]
232
	cmp	ecx, 0
233
	jle	.err_out
234
3083 leency 235
 
236
 
5048 Asper 237
	mov	ebx, eax
238
	mov	[wcaps], eax
239
	stdcall get_wcaps_type, ebx
240
	cmp	eax, AC_WID_VOL_KNB
241
	je	.conn_list_ok
242
	test	ebx, AC_WCAP_CONN_LIST
243
	jnz	.conn_list_ok
244
if DEBUG
245
	mov	esi, emsgConnListNotAvailable
246
	invoke	SysMsgBoardStr
247
	mov	eax, [nid]
248
	stdcall fdword2str, 3
249
	invoke	SysMsgBoardStr
250
end if
251
	xor	eax, eax
252
	dec	eax
253
	jmp	.out
254
.conn_list_ok:
255
3083 leency 256
 
5048 Asper 257
	mov	[parm], eax
258
3083 leency 259
 
5048 Asper 260
	jz	@f
261
	; long form
262
	mov	[shift], 16
263
	mov	[num_elements], 2
264
	mov	[mask], 0x7FFF ;Asper+
265
@@:
266
	and	eax, AC_CLIST_LENGTH
267
	test	eax, eax
268
	jz	.out ; no connection
269
3083 leency 270
 
5048 Asper 271
	cmp	eax, 1
272
	jne	.multi_conns
273
	; single connection
274
	stdcall snd_hda_codec_read, [nid], 0, AC_VERB_GET_CONNECT_LIST, 0
275
	mov	[parm], eax
276
	cmp	[parm], -1
277
	jne	@f
278
	cmp	[ctrl.rirb_error], 0
279
	jne	@f
280
	xor	eax, eax
281
	dec	eax
282
	jmp	.out
283
@@:
284
3083 leency 285
 
5048 Asper 286
	and	eax, [mask]
287
	stosd
288
	xor	eax, eax
289
	inc	eax
290
	jmp	.out
291
.multi_conns:
292
3083 leency 293
 
5048 Asper 294
	xor	ecx, ecx
295
	mov	edx, [num_elements]
296
.next_conn:
297
	mov	eax, ecx
298
.mod:
299
	cmp	eax, edx
300
	jl	.mod_counted
301
	sub	eax, edx
302
	jmp	.mod
303
.mod_counted:
304
3083 leency 305
 
5048 Asper 306
	jnz	.l1
307
	stdcall snd_hda_codec_read, [nid], 0, AC_VERB_GET_CONNECT_LIST, ecx
308
	mov	[parm], eax
309
3083 leency 310
 
5048 Asper 311
	jne	.l1
312
	cmp	[ctrl.rirb_error], 0
313
	jne	.err_out
314
.l1:
315
3083 leency 316
 
5048 Asper 317
	push	ecx
318
	mov	cl, [shift]
319
	dec	cl
320
	shl	eax, cl
321
	and	eax, [parm]
322
	pop	ecx
323
	mov	ebx, eax  ;ranges
324
3083 leency 325
 
5048 Asper 326
	and	eax, [mask] ;val
327
3083 leency 328
 
5048 Asper 329
	jnz	@f
330
if DEBUG
331
	push	eax esi
332
	mov	esi, emsgInvConnList
333
	invoke	SysMsgBoardStr
334
	mov	eax, [nid]
335
	stdcall fdword2str, 1
336
	invoke	SysMsgBoardStr
337
3083 leency 338
 
5048 Asper 339
	invoke	SysMsgBoardStr
340
	mov	eax, ecx
341
	stdcall fdword2str, 0
342
	invoke	SysMsgBoardStr
343
3083 leency 344
 
5048 Asper 345
	invoke	SysMsgBoardStr
346
	mov	eax, [parm]
347
	stdcall fdword2str, 2
348
	invoke	SysMsgBoardStr
349
	pop	esi eax
350
end if
351
	xor	eax, eax
352
	jmp	.out
353
@@:
354
	push	ecx
355
	mov	cl, [shift]
356
	shr	[parm], cl
357
	pop	ecx
358
3083 leency 359
 
5048 Asper 360
	jz	.range_zero
361
	; ranges between the previous and this one
362
	movzx	esi, word [prev_nid]
363
	test	esi, esi
364
	jz	.l2
365
	cmp	esi, eax
366
	jl	@f
367
.l2:
368
if DEBUG
369
	push	eax esi
370
	push	esi
371
	mov	esi, emsgInvDepRangeVal
372
	invoke	SysMsgBoardStr
373
	pop	esi
374
	push	eax
375
	mov	eax, esi
376
	stdcall fdword2str, 0
377
	invoke	SysMsgBoardStr
378
3083 leency 379
 
5048 Asper 380
	invoke	SysMsgBoardStr
381
	pop	eax
382
	stdcall fdword2str, 2
383
	invoke	SysMsgBoardStr
384
	pop	esi eax
385
end if
386
	jmp	.continue
387
@@:
388
	push	ecx
389
	mov	ecx, esi
390
	inc	ecx
391
	mov	ebx, [conns]
392
.next_conn2:
393
	cmp	ebx, [max_conns]
394
	jl	@f
395
if DEBUG
396
	push	esi
397
	mov	esi, emsgTooManyConns
398
	invoke	SysMsgBoardStr
399
	pop	esi
400
end if
401
	pop	ecx
402
	jmp	.err_out
403
@@:
404
	shl	ebx, 1
405
	push	edi
406
	add	edi, ebx
407
	mov	word [edi], cx
408
	pop	edi
409
	shr	ebx, 1
410
	inc	ebx
411
	inc	ecx
412
	cmp	ecx, eax
413
	jle	.next_conn2
414
3083 leency 415
 
5048 Asper 416
	pop	ecx
417
	jmp	.end_range_test
418
.range_zero:
419
3083 leency 420
 
5048 Asper 421
	cmp	ebx, [max_conns]
422
	jl	@f
423
if DEBUG
424
	push	esi
425
	mov	esi, emsgTooManyConns
426
	invoke	SysMsgBoardStr
427
	pop	esi
428
end if
429
	jmp	.err_out
430
@@:
431
	shl	ebx, 1
432
	push	edi
433
	add	edi, ebx
434
	mov	word [edi], ax
435
	pop	edi
436
	shr	ebx, 1
437
	inc	ebx
438
	mov	[conns], ebx
439
.end_range_test:
440
	mov	[prev_nid], ax
441
.continue:
442
	inc	ecx
443
	cmp	ecx, [conn_len]
444
	jl	.next_conn
445
3083 leency 446
 
5048 Asper 447
.out:
448
	pop	esi edi edx ecx ebx
449
	ret
450
.err_out:
451
	pop	esi edi edx ecx ebx
452
	mov	eax, -1
453
	ret
454
endp
3083 leency 455
456
 
457
 
458
;proc snd_hda_queue_unsol_events stdcall, res:dword, res_ex:dword
5048 Asper 459
;        push    ebx  edi  esi
460
;        ...
461
;        pop     esi  edi  ebx
462
;        ret
463
;endp
3083 leency 464
465
 
466
;proc process_unsol_events stdcall, work:dword
5048 Asper 467
;proc init_usol_queue stdcall, bus:dword
468
3083 leency 469
 
470
;; snd_hda_bus_new - create a HDA bus
471
;; @card: the card entry
472
;; @temp: the template for hda_bus information
473
;; @busp: the pointer to store the created bus instance
474
;;
475
;; Returns 0 if successful, or a negative error code.
476
;;
477
;proc snd_hda_bus_new
5048 Asper 478
	; if we want to support unsolicited events, we have to solve this
479
	;    bus->workq = create_singlethread_workqueue(bus->workq_name);
480
	; (...)
481
;        xor   eax, eax
482
;        ret
483
;endp
3083 leency 484
485
 
486
;; snd_hda_codec_init - initialize a HDA codec
487
;;
488
;; Returns 0 if successful, or a negative error code.
489
;;
490
proc snd_hda_codec_init    ; We use just one codec (the first found)
5048 Asper 491
	snd_hda_param_read  AC_NODE_ROOT, AC_PAR_VENDOR_ID
492
	cmp	eax, -1
493
	jne	@f
494
	snd_hda_param_read  AC_NODE_ROOT, AC_PAR_VENDOR_ID
495
@@:
496
	mov	[codec.chip_id], ax
497
	shr	eax, 16
498
	mov	[codec.vendor_id], ax
499
3083 leency 500
 
5048 Asper 501
	mov	[codec.subsystem_id], eax
502
3083 leency 503
 
5048 Asper 504
	mov	[codec.revision_id], eax
505
3083 leency 506
 
5048 Asper 507
3083 leency 508
 
5048 Asper 509
	test	eax, eax
510
	jnz	@f
511
	;Asper+: try to use another codec if possible [
512
if DEBUG
513
	push	esi
514
	mov	esi, msgNoAFGFound
515
	invoke	SysMsgBoardStr
516
	pop	esi
517
end  if
518
	push	ecx
519
	inc	eax
520
	mov	ecx, [codec.addr]
521
	shl	eax, cl
522
	pop	ecx
523
	cmp	eax, [ctrl.codec_mask]
524
	jl	.skip_codec
525
	;Asper+]
526
3083 leency 527
 
5048 Asper 528
	test	eax, eax
529
	jnz	@f
530
if DEBUG
531
	push	esi
532
	mov	esi, emsgNoAFGorMFGFound
533
	invoke	SysMsgBoardStr
534
	pop	esi
535
end  if
536
.skip_codec:
537
	mov	eax, -1
538
	ret
539
@@:
540
4324 Asper 541
 
5048 Asper 542
	push	ebx
543
	stdcall read_widget_caps, eax
544
3083 leency 545
 
5048 Asper 546
	jge	@f
547
if DEBUG
548
	push	esi
549
	mov	esi, emsgNoMem
550
	invoke	SysMsgBoardStr
551
	pop	esi
552
end  if
553
	pop	ebx
554
	mov	eax, -1
555
	ret
556
@@:
557
3083 leency 558
 
5048 Asper 559
3083 leency 560
 
5048 Asper 561
	jge	@f
562
	pop	ebx
563
	mov	eax, -1
564
	ret
565
@@:
566
	mov	eax, [codec.subsystem_id]
567
	test	eax, eax
568
	jnz	@f
569
	stdcall snd_hda_codec_read, ebx, 0, AC_VERB_GET_SUBSYSTEM_ID, 0
570
@@:
571
	; power up all before initialization
572
	stdcall snd_hda_set_power_state, ebx, AC_PWRST_D0
573
3083 leency 574
 
5048 Asper 575
	pop	ebx
576
	ret
577
endp
3083 leency 578
579
 
580
 
581
;; snd_hda_codec_configure - (Re-)configure the HD-audio codec
582
;;
583
;; Start parsing of the given codec tree and (re-)initialize the whole
584
;; patch instance.
585
;;
586
;; Returns 0 if successful or a negative error code.
587
;;
588
proc snd_hda_codec_configure
5048 Asper 589
	call	get_codec_name
590
@@:
591
	; call the default parser
592
	stdcall snd_hda_parse_generic_codec  ;entry point to generic tree parser!!!
593
3496 Asper 594
 
5048 Asper 595
	jz	@f
596
if DEBUG
597
	push	esi
598
	mov	esi, emsgNoParserAvailable
599
	invoke	SysMsgBoardStr
600
	pop	esi
601
end if
602
@@:
603
.out:
604
	ret
605
endp
3083 leency 606
607
 
608
 
609
proc get_codec_name
5048 Asper 610
	push	eax ebx edi esi
611
	mov	eax, [codec.ac_vendor_ids]
612
	test	eax, eax
613
	jnz	.get_chip_name
614
	mov	ax, [codec.vendor_id]
615
	mov	edi, hda_vendor_ids
616
3083 leency 617
 
5048 Asper 618
	mov	ebx, [edi]
619
	test	ebx, ebx
620
	jz	.unknown
621
3083 leency 622
 
5048 Asper 623
	jne	.next
624
	mov	eax, [edi+4]
625
	mov	[codec.ac_vendor_ids], eax
626
	mov	esi, eax
627
	invoke	SysMsgBoardStr
628
.get_chip_name:
629
	stdcall detect_chip, [edi+8]
630
	pop	esi  edi  ebx  eax
631
	ret
632
.next:
633
	add	edi, 12
634
	jmp	@b
635
.unknown:
636
	mov	[codec.ac_vendor_ids], ac_unknown
637
	mov	[codec.chip_ids], chip_unknown
638
3083 leency 639
 
5048 Asper 640
	invoke	SysMsgBoardStr
641
	movzx	eax, [codec.chip_id]
642
	stdcall fdword2str, 2
643
	invoke	SysMsgBoardStr
644
	pop	esi edi ebx eax
645
	ret
646
endp
3083 leency 647
648
 
649
 
650
proc detect_chip stdcall, chip_tab:dword
651
	push	eax ebx edi esi
5048 Asper 652
	mov	ax, [codec.chip_id]
653
3083 leency 654
 
5048 Asper 655
@@:
3083 leency 656
	mov	ebx, [edi]
5048 Asper 657
	cmp	ebx, 0xFF
658
	je	.unknown
659
3083 leency 660
 
5048 Asper 661
	jne	.next
662
	mov	eax, [edi+4]
663
	mov	[codec.chip_ids], eax
664
	mov	esi, eax
665
	invoke	SysMsgBoardStr
666
	pop	esi  edi  ebx  eax
667
	ret
668
.next:
3083 leency 669
	add	edi, 8
5048 Asper 670
	jmp	@b
671
.unknown:
3083 leency 672
	mov	[codec.chip_ids], chip_unknown
5048 Asper 673
	mov	esi, chip_unknown
674
	invoke	SysMsgBoardStr
675
	movzx	eax, [codec.chip_id]
676
	stdcall fdword2str, 2
677
	invoke	SysMsgBoardStr
678
	pop	esi edi ebx eax
679
	ret
680
endp
3083 leency 681
682
 
683
 
684
proc setup_fg_nodes
685
	push	eax  ebx  ecx
5048 Asper 686
	stdcall snd_hda_get_sub_nodes, AC_NODE_ROOT
687
	mov	ecx, eax
688
	and	ecx, 0x7FFF ; total_nodes
689
	mov	ebx, eax
690
	shr	ebx, 16
691
	and	ebx, 0x7FFF ; nid
692
3083 leency 693
 
5048 Asper 694
	push	eax esi
695
	mov	esi, msgSETUP_FG_NODES
696
	invoke	SysMsgBoardStr
697
	mov	eax, ebx
698
	stdcall fdword2str, 1
699
	invoke	SysMsgBoardStr
700
3083 leency 701
 
5048 Asper 702
	invoke	SysMsgBoardStr
703
	mov	eax, ecx
704
	stdcall fdword2str, 3
705
	invoke	SysMsgBoardStr
706
	pop	esi eax
707
end if
3083 leency 708
709
 
5048 Asper 710
	test	ecx, ecx
711
	jz	.l1
712
	snd_hda_param_read  ebx, AC_PAR_FUNCTION_TYPE
713
	and	eax, 0xFF
714
3083 leency 715
 
5048 Asper 716
	push	eax esi
717
	mov	esi, msgFG_TYPE
718
	invoke	SysMsgBoardStr
719
	stdcall fdword2str, 3
720
	invoke	SysMsgBoardStr
721
	pop	esi eax
722
end if
3083 leency 723
724
 
5048 Asper 725
	jne	@f
726
3083 leency 727
 
5048 Asper 728
	mov	[codec.function_id], eax
729
	jmp	.continue
730
@@:
731
	cmp	eax, AC_GRP_MODEM_FUNCTION
732
	jne	@f
733
3083 leency 734
 
5048 Asper 735
	mov	[codec.function_id], eax
736
	jmp	.continue
737
@@:
738
.continue:
739
	inc	ebx
740
	dec	ecx
741
	jnz	.next
742
.l1:
743
	pop	ecx  ebx  eax
744
	ret
745
endp
3083 leency 746
747
 
748
 
749
; read widget caps for each widget and store in cache
750
proc read_widget_caps stdcall, fg_node:dword
5048 Asper 751
	push	ebx ecx edx edi
752
3083 leency 753
 
5048 Asper 754
	mov	ecx, eax
755
	and	ecx, 0x7FFF ; total_nodes
756
	mov	[codec.num_nodes], cx
757
	mov	ebx, eax
758
	shr	ebx, 16
759
	and	ebx, 0x7FFF ; nid
760
	mov	[codec.start_nid], bx
761
3083 leency 762
 
5048 Asper 763
	push	eax esi
764
	mov	esi, msgSETUP_FG_NODES
765
	invoke	SysMsgBoardStr
766
	mov	eax, ebx
767
	stdcall fdword2str, 1
768
	invoke	SysMsgBoardStr
769
3083 leency 770
 
5048 Asper 771
	invoke	SysMsgBoardStr
772
	mov	eax, ecx
773
	stdcall fdword2str, 3
774
	invoke	SysMsgBoardStr
775
	pop	esi eax
776
end if
3083 leency 777
778
 
5048 Asper 779
	push	esi
780
	mov	esi, msgWCaps
781
	invoke	SysMsgBoardStr
782
	pop	esi
783
end if
3083 leency 784
785
 
5048 Asper 786
	shl	eax, 2
787
	push	ebx ecx
788
	invoke	Kmalloc
789
	pop	ecx ebx
790
	test	eax, eax
791
	jz	.err_out
792
	mov	[codec.wcaps], eax
793
3083 leency 794
 
5048 Asper 795
.next_node:
796
3083 leency 797
 
5048 Asper 798
	stosd
799
	inc	ebx
800
	dec	ecx
801
	jnz	.next_node
802
	pop	edi edx ecx ebx
803
	xor	eax, eax
804
	ret
805
.err_out:
806
	pop	edi edx ecx ebx
807
	xor	eax, eax
808
	dec	eax
809
	ret
810
endp
3083 leency 811
812
 
813
 
814
proc  read_pin_defaults
815
	push	ebx ecx edx edi
5048 Asper 816
3083 leency 817
 
5048 Asper 818
	movzx	ecx, [codec.num_nodes]
819
3083 leency 820
 
5048 Asper 821
	mov	eax, HDA_PINCFG.sizeof
822
	mul	cl
823
	push	ebx ecx
824
	invoke	Kmalloc
825
	pop	ecx ebx
826
	test	eax, eax
827
	jz	.err_out
828
	mov	[codec.init_pins], eax
829
	mov	[codec.num_pins], 0
830
	mov	edi, eax
831
	;Asper ]
832
3083 leency 833
 
834
	push	eax esi
5048 Asper 835
	mov	esi, msgPinCfgs
836
	invoke	SysMsgBoardStr
837
	pop	esi eax
838
end if
3083 leency 839
840
 
841
 
5048 Asper 842
	stdcall get_wcaps, ebx
843
	and	eax, AC_WCAP_TYPE
844
	shr	eax, AC_WCAP_TYPE_SHIFT
845
3083 leency 846
 
5048 Asper 847
	jne	.continue
848
3083 leency 849
 
5048 Asper 850
	stdcall snd_hda_codec_read, ebx, 0, AC_VERB_GET_CONFIG_DEFAULT, 0
851
	mov	[edi + HDA_PINCFG.cfg], eax
852
	add	edi, HDA_PINCFG.sizeof
853
	inc	[codec.num_pins]
854
3083 leency 855
 
5048 Asper 856
	inc	ebx
857
	dec	ecx
858
	jnz	.next_node
859
3083 leency 860
 
5048 Asper 861
	xor	eax, eax
862
	ret
863
.err_out:
864
	pop	edi edx ecx ebx
865
	xor	eax, eax
866
	dec	eax
867
	ret
868
endp
3083 leency 869
870
 
871
 
872
 
873
proc look_up_pincfg stdcall, array:dword, nid:dword
5048 Asper 874
	push	ebx ecx edx
875
	mov	ecx, [codec.num_pins]
876
	mov	eax, [array]
877
	mov	ebx, [nid]
878
.next_pin:
879
	mov	dx,  [eax + HDA_PINCFG.nid]
880
	cmp	dx,  bx
881
	je	.out
882
.continue:
883
	add	eax, HDA_PINCFG.sizeof
884
	dec	ecx
885
	jnz	.next_pin
886
3083 leency 887
 
5048 Asper 888
.out:
889
	pop	edx ecx ebx
890
	ret
891
endp
3083 leency 892
893
 
894
proc set_pincfg stdcall, nid:dword, cfg:dword
5048 Asper 895
	push	eax  ebx  ecx  edx
896
	mov	eax, [cfg]
897
	xor	ebx, ebx
898
	mov	edx, AC_VERB_SET_CONFIG_DEFAULT_BYTES_0
899
	mov	ecx, 4
900
@@:
901
	mov	bl,  al
902
	stdcall snd_hda_codec_write, [nid], 0, edx, ebx
903
	shr	eax, 8
904
	inc	edx
905
	dec	ecx
906
	jnz	@b
907
.l1:
908
	pop	edx  ecx  ebx  eax
909
	ret
910
endp
3083 leency 911
912
 
913
 
914
;; snd_hda_codec_get_pincfg - Obtain a pin-default configuration
915
;; @codec: the HDA codec
916
;; @nid: NID to get the pin config
917
;;
918
;; Get the current pin config value of the given pin NID.
919
;; If the pincfg value is cached or overridden via sysfs or driver,
920
;; returns the cached value.
921
;;
922
proc snd_hda_codec_get_pincfg stdcall, nid:dword
5048 Asper 923
	push	edi
924
	stdcall look_up_pincfg, [codec.init_pins], [nid]
925
	test	eax, eax
926
	jz	@f
927
	mov	edi, eax
928
	mov	eax, [edi + HDA_PINCFG.cfg]
929
@@:
930
	pop	edi
931
	ret
932
endp
3083 leency 933
934
 
935
936
 
937
;; snd_hda_codec_setup_stream - set up the codec for streaming
938
;; @nid: the NID to set up
939
;; @stream_tag: stream tag to pass, it's between 0x1 and 0xf.
940
;; @channel_id: channel id to pass, zero based.
941
;; @format: stream format.
942
;;
943
proc hda_codec_setup_stream stdcall, nid:dword, stream_tag:dword, channel_id:dword, format:dword
944
	push	eax
5048 Asper 945
	mov	eax, [nid]
946
	test	eax, eax
947
	jnz	@f
948
	pop	eax
949
	ret
950
@@:
951
if DEBUG
952
	push	esi
953
	mov	esi, msgHDACodecSetupStream
954
	invoke	SysMsgBoardStr
955
	stdcall fdword2str, 3
956
	invoke	SysMsgBoardStr
957
3083 leency 958
 
5048 Asper 959
	invoke	SysMsgBoardStr
960
	mov	eax, [stream_tag]
961
	stdcall fdword2str, 3
962
	invoke	SysMsgBoardStr
963
3083 leency 964
 
5048 Asper 965
	invoke	SysMsgBoardStr
966
	mov	eax, [channel_id]
967
	stdcall fdword2str, 3
968
	invoke	SysMsgBoardStr
969
3083 leency 970
 
5048 Asper 971
	invoke	SysMsgBoardStr
972
	mov	eax, [format]
973
	stdcall fdword2str, 3
974
	invoke	SysMsgBoardStr
975
	pop	esi
976
end if
977
	mov	eax, [stream_tag]
978
	shl	eax, 4
979
	or	eax, [channel_id]
980
	stdcall snd_hda_codec_write, [nid], 0, AC_VERB_SET_CHANNEL_STREAMID, eax
981
3083 leency 982
 
5048 Asper 983
	call	StallExec
984
3083 leency 985
 
5048 Asper 986
	pop	eax
987
	ret
988
endp
3083 leency 989
990
 
991
 
992
	push	eax
5048 Asper 993
	mov	eax, [nid]
994
	test	eax, eax
995
	jz	@f
996
	pop	eax
997
	ret
998
@@:
999
if DEBUG
1000
	push	esi
1001
	mov	esi, msgHDACodecCleanupStream
1002
	invoke	SysMsgBoardStr
1003
	stdcall fdword2str, 3
1004
	invoke	SysMsgBoardStr
1005
	pop	esi
1006
end if
1007
	stdcall snd_hda_codec_write, [nid], 0, AC_VERB_SET_CHANNEL_STREAMID, 0
1008
if 0  ; keep the format
1009
	mov	eax, 1000000  ; wait 100 ms
1010
	call	StallExec
1011
	stdcall snd_hda_codec_write, [nid], 0, AC_VERB_SET_STREAM_FORMAT, 0
1012
end if
1013
	pop	eax
1014
	ret
1015
endp
3083 leency 1016
1017
 
1018
 
5048 Asper 1019
	snd_hda_param_read  [nid], AC_PAR_PIN_CAP
1020
	ret
1021
endp
3083 leency 1022
1023
 
1024
 
1025
proc get_volume_mute stdcall, nid:dword, ch:dword, direction:dword, index:dword
1026
	push	ebx
5048 Asper 1027
	mov	ebx, AC_AMP_GET_LEFT
1028
	mov	eax, [ch]
1029
	test	eax, eax
1030
	jz	@f
1031
	mov	ebx, AC_AMP_GET_RIGHT
1032
@@:
1033
	mov	eax, [direction]
1034
	cmp	eax, HDA_OUTPUT
1035
	jne	@f
1036
	or	ebx, AC_AMP_GET_OUTPUT
1037
	jmp	.l1
1038
@@:
1039
	or	ebx, AC_AMP_GET_INPUT
1040
.l1:
1041
	or	ebx, [index]
1042
	stdcall snd_hda_codec_read, [nid], 0, AC_VERB_GET_AMP_GAIN_MUTE, ebx
1043
	and	eax, 0xFF
1044
	pop	ebx
1045
	ret
1046
endp
3083 leency 1047
1048
 
1049
 
1050
proc put_volume_mute stdcall, nid:dword, ch:dword, direction:dword, index:dword, val:dword
1051
	push	eax  ebx
5048 Asper 1052
	mov	ebx, AC_AMP_SET_LEFT
1053
	mov	eax, [ch]
1054
	test	eax, eax
1055
	jz	@f
1056
	mov	ebx, AC_AMP_SET_RIGHT
1057
@@:
1058
	mov	eax, [direction]
1059
	cmp	eax, HDA_OUTPUT
1060
	jne	@f
1061
	or	ebx, AC_AMP_SET_OUTPUT
1062
	jmp	.l1
1063
@@:
1064
	or	ebx, AC_AMP_SET_INPUT
1065
.l1:
1066
	mov	eax, [index]
1067
	shl	eax, AC_AMP_SET_INDEX_SHIFT
1068
	or	ebx, eax
1069
	or	ebx, [val]
1070
	stdcall snd_hda_codec_write, [nid], 0, AC_VERB_SET_AMP_GAIN_MUTE, ebx
1071
	pop	ebx  eax
1072
	ret
1073
endp
3083 leency 1074
1075
 
1076
 
1077
;; snd_hda_codec_amp_update - update the AMP value
1078
;; @nid: NID to read the AMP value
1079
;; @ch: channel (left=0 or right=1)
1080
;; @direction: #HDA_INPUT or #HDA_OUTPUT
1081
;; @idx: the index value (only for input direction)
1082
;; @mask: bit mask to set
1083
;; @val: the bits value to set
1084
;;
1085
;; Update the AMP value with a bit mask.
1086
;; Returns 0 if the value is unchanged, 1 if changed.
1087
;;
1088
;-proc snd_hda_codec_amp_update stdcall, nid:dword, ch:dword, direction:dword, idx:dword, mask:dword, val:dword
1089
;-        push    ebx  edx
5048 Asper 1090
;-        mov     eax, [mask]
1091
;-        mov     ebx, [val]
1092
;-        and     ebx, eax
1093
;-        xor     eax, -1
1094
;-        mov     edx, eax
1095
;-        stdcall get_volume_mute, [nid], [ch], [direction], [idx]
1096
;-        and     eax, edx
1097
;-        or      ebx, eax
1098
;-
3083 leency 1099
;-        stdcall put_volume_mute, [nid], [ch], [direction], [idx], ebx
5048 Asper 1100
;-        xor     eax, eax
1101
;-        inc     eax
1102
;-        pop     edx  ebx
1103
;-        ret
1104
;-endp
3083 leency 1105
1106
 
1107
 
1108
;; snd_hda_codec_amp_stereo - update the AMP stereo values
1109
;; @nid: NID to read the AMP value
1110
;; @direction: #HDA_INPUT or #HDA_OUTPUT
1111
;; @idx: the index value (only for input direction)
1112
;; @mask: bit mask to set
1113
;; @val: the bits value to set
1114
;;
1115
;; Update the AMP values like snd_hda_codec_amp_update(), but for a
1116
;; stereo widget with the same mask and value.
1117
;;
1118
proc snd_hda_codec_amp_stereo stdcall, nid:dword, direction:dword, idx:dword, mask:dword, val:dword
1119
	push	ebx edx
5048 Asper 1120
	mov	ebx, [val]
1121
	mov	edx, [mask]
1122
	and	ebx, edx
1123
	stdcall put_volume_mute, [nid], 0, [direction], [idx], ebx
1124
	stdcall put_volume_mute, [nid], 1, [direction], [idx], ebx
1125
	pop	edx  ebx
1126
	ret
1127
endp
3083 leency 1128
1129
 
5048 Asper 1130
proc snd_hda_read_pin_sense stdcall, nid:dword, trigger_sense:dword
1131
	mov	eax, [trigger_sense]
1132
	test	eax, eax
1133
	jz	.no_trigger_sense
1134
3083 leency 1135
 
5048 Asper 1136
	test	eax, AC_PINCAP_TRIG_REQ ;need trigger?
1137
	jz	.no_trigger_sense
1138
1139
 
1140
.no_trigger_sense:
1141
	stdcall snd_hda_codec_read, [nid], 0, AC_VERB_GET_PIN_SENSE, 0
1142
	ret
1143
endp
1144
1145
 
1146
	stdcall read_pin_cap, [nid]
1147
	test	eax, AC_PINCAP_PRES_DETECT
1148
	jz	.no
1149
1150
 
1151
	test	eax, AC_WCAP_UNSOL_CAP
1152
	jz	.no
1153
.yes:
1154
	xor	eax, eax
1155
	inc	eax
1156
	ret
1157
.no:
1158
	xor	eax, eax
1159
	ret
1160
endp
1161
1162
 
1163
	push	eax
1164
	stdcall is_jack_detectable, [nid]
1165
	test	eax, eax
1166
	jz	@f
1167
	mov	eax, [jacktag]
1168
	or	eax, AC_USRSP_EN
1169
	stdcall snd_hda_codec_write, [nid], 0, AC_VERB_SET_UNSOLICITED_ENABLE, eax
1170
@@:
1171
	pop	eax
1172
	ret
1173
endp
1174
1175
 
3083 leency 1176
proc snd_hda_set_power_state stdcall, fg:dword, power_state:dword
1177
	push	eax ebx ecx edx
5048 Asper 1178
	; this delay seems necessary to avoid click noise at power down
1179
	mov	ebx, [power_state]
1180
	cmp	ebx, AC_PWRST_D3
1181
	jne	@f
1182
	mov	eax, 100000
1183
	call	StallExec
1184
@@:
1185
	stdcall snd_hda_codec_read, [fg], 0, AC_VERB_SET_POWER_STATE, ebx
1186
	;partial workaround for "azx_get_response timeout"
1187
	cmp	ebx, AC_PWRST_D0
1188
	jne	@f
1189
3083 leency 1190
 
5048 Asper 1191
	cmp	dx, 0x14F1
1192
	jne	@f
1193
	mov	eax, 10000
1194
	call	StallExec
1195
@@:
1196
	movzx	ecx, [codec.num_nodes]
1197
	movzx	edx, [codec.start_nid]
1198
.next_nid:
1199
	stdcall get_wcaps, edx
1200
	test	eax, AC_WCAP_POWER
1201
	jz	.skip_nid
1202
3083 leency 1203
 
5048 Asper 1204
	cmp	ebx, AC_PWRST_D3
1205
	jne	.l1
1206
	cmp	eax, AC_WID_PIN
1207
	jne	.l1
1208
	;don't power down the widget if it controls
1209
	;eapd and EAPD_BTLENABLE is set.
1210
	stdcall read_pin_cap, edx
1211
	test	eax, AC_PINCAP_EAPD
1212
	jz	.l2
1213
3083 leency 1214
 
5048 Asper 1215
	and	eax, 0x02
1216
	test	eax, eax
1217
	jnz	.skip_nid
1218
.l2:
1219
.l1:
1220
	stdcall snd_hda_codec_write, edx, 0, AC_VERB_SET_POWER_STATE, ebx
1221
.skip_nid:
1222
	inc	edx
1223
	dec	ecx
1224
	jnz	.next_nid
1225
3083 leency 1226
 
5048 Asper 1227
	jne	.out
1228
	;wait until codec reaches to D0
1229
	mov	ecx, 500
1230
.wait_D0:
1231
	stdcall snd_hda_codec_read, [fg], 0, AC_VERB_GET_POWER_STATE, 0
1232
	cmp	eax, ebx
1233
	je	.out
1234
	mov	eax, 1000  ; msleep(1);
1235
	call	StallExec
1236
	dec	ecx
1237
	jnz	.wait_D0
1238
.out:
1239
	pop	edx ecx ebx eax
1240
	ret
1241
endp
3083 leency 1242
1243
 
1244
 
1245
1246
 
1247
align 16
1248
msg_Cirrus	     db 'Cirrus Logic ',0
5048 Asper 1249
msg_Motorola	     db 'Motorola ',0
1250
msg_SiliconImage     db 'Silicon Image ',0
3083 leency 1251
msg_Realtek	     db 'Realtek ',0
5048 Asper 1252
msg_Creative	     db 'Creative ',0
1253
msg_IDT 	     db 'IDT ',0
1254
msg_LSI 	     db 'LSI ',0
1255
msg_AnalogDevices    db 'Analog Devices ',0
3083 leency 1256
msg_CMedia	     db 'C-Media ',0
5048 Asper 1257
msg_Conexant	     db 'Conexant ',0
1258
msg_Chrontel	     db 'Chrontel ',0
1259
msg_LG		     db 'LG ',0
1260
msg_Wolfson	     db 'Wolfson Microelectronics ',0
1261
msg_Qumranet	     db 'Qumranet ',0
1262
msg_SigmaTel	     db 'SigmaTel ',0
1263
ac_unknown     db 'unknown manufacturer ',0
3083 leency 1264
1265
 
1266
1267
 
1268
 
1269
align 4
1270
hda_vendor_ids:
1271
	dd    0x1002, msg_ATI, chips_ATI
5048 Asper 1272
	dd    0x1013, msg_Cirrus, chips_Cirrus
1273
	dd    0x1057, msg_Motorola, chips_Motorola
1274
	dd    0x1095, msg_SiliconImage, chips_SiliconImage
1275
	dd    0x10de, msg_NVidia, chips_NVidia
1276
	dd    0x10ec, msg_Realtek, chips_Realtek
1277
	dd    0x1102, msg_Creative, chips_Creative
1278
	dd    0x1106, msg_VIA, chips_VIA
1279
	dd    0x111d, msg_IDT, chips_IDT
1280
	dd    0x11c1, msg_LSI, chips_LSI
1281
	dd    0x11d4, msg_AnalogDevices, chips_Analog
1282
	dd    0x13f6, msg_CMedia, chips_CMedia
1283
	dd    0x14f1, msg_Conexant, chips_Conexant
1284
	dd    0x17e8, msg_Chrontel, chips_Chrontel
1285
	dd    0x1854, msg_LG, chips_LG
1286
	dd    0x1aec, msg_Wolfson, chips_Wolfson
1287
	dd    0x1af4, msg_Qumranet, chips_Qumranet   ; Qemu 0.14
1288
	dd    0x434d, msg_CMedia, chips_CMedia
1289
	dd    0x8086, msg_Intel, chips_Intel
1290
	dd    0x8384, msg_SigmaTel, chips_SigmaTel
1291
	dd    0 ; terminator
1292
3083 leency 1293
 
5048 Asper 1294
chips_ATI	     dd 0xAA01, chip_ATIR6XX
1295
		     dd 0xFF
1296
3083 leency 1297
 
5048 Asper 1298
chips_Motorola	     dd 0xFF
1299
3083 leency 1300
 
1301
		     dd 0xFF
5048 Asper 1302
3083 leency 1303
 
5048 Asper 1304
		     dd 0xFF
1305
3083 leency 1306
 
5048 Asper 1307
		     dd 0x0268, chip_ALC268
1308
		     dd 0x0269, chip_ALC269
1309
		     dd 0x0272, chip_ALC272
1310
		     dd 0x0662, chip_ALC662
1311
		     dd 0x0663, chip_ALC663
1312
		     dd 0x0883, chip_ALC883
1313
		     dd 0x0887, chip_ALC887
1314
		     dd 0x0888, chip_ALC888
1315
		     dd 0x0889, chip_ALC889
1316
		     dd 0xFF
1317
3083 leency 1318
 
5048 Asper 1319
3083 leency 1320
 
5048 Asper 1321
		     dd 0x0397, chip_VT17085_0
1322
		     dd 0xFF
1323
3083 leency 1324
 
5048 Asper 1325
chips_LSI	     dd 0x1039, chip_LSI1039
1326
		     dd 0x1040, chip_LSI1040
1327
		     dd 0x3026, chip_LSI3026
1328
		     dd 0x3055, chip_LSI3055
1329
		     dd 0xFF
1330
3083 leency 1331
 
5048 Asper 1332
		     dd 0x198B, chip_AD198B
1333
		     dd 0xFF
1334
4320 yogev_ezra 1335
 
5048 Asper 1336
3083 leency 1337
 
5048 Asper 1338
		     dd 0x5051, chip_CX20561
1339
		     dd 0xFF
1340
3083 leency 1341
 
5048 Asper 1342
chips_LG	     dd 0xFF
1343
chips_Wolfson	     dd 0xFF
1344
chips_Intel	     dd 0xFF
1345
3083 leency 1346
 
5048 Asper 1347
		     dd 0x0020, chip_HDA_DUPLEX
1348
		     dd 0xFF
1349
3083 leency 1350
 
5048 Asper 1351
		     dd 0x7682, chip_STAC9221_A2
1352
		     dd 0xFF
1353
3083 leency 1354
 
1355
;AnalogDevices
1356
chip_AD1986A	     db 'AD1986A',13,10,0
5048 Asper 1357
chip_AD198B	     db 'AD198B',13,10,0
1358
3083 leency 1359
 
1360
chip_ATIR6XX	     db 'ATIR6XX',13,10,0
5048 Asper 1361
3083 leency 1362
 
1363
chip_SI1392	     db 'SI1392',13,10,0
5048 Asper 1364
3083 leency 1365
 
1366
chip_MCP78	     db 'MCP78',13,10,0
5048 Asper 1367
3083 leency 1368
 
1369
chip_ALC262	     db 'ALC262',13,10,0
5048 Asper 1370
chip_ALC268	     db 'ALC268',13,10,0
1371
chip_ALC269	     db 'ALC269',13,10,0
1372
chip_ALC272	     db 'ALC272',13,10,0
1373
chip_ALC662	     db 'ALC662',13,10,0
1374
chip_ALC663	     db 'ALC663',13,10,0
1375
chip_ALC883	     db 'ALC883',13,10,0
1376
chip_ALC887	     db 'ALC887',13,10,0
1377
chip_ALC888	     db 'ALC888',13,10,0
1378
chip_ALC889	     db 'ALC889',13,10,0
1379
3083 leency 1380
 
1381
chip_STAC9221	     db 'STAC9221',13,10,0
5048 Asper 1382
chip_STAC9221_A2     db 'STAC9221_A2',13,10,0
3083 leency 1383
1384
 
1385
chip_VT1708B_1	     db 'VT1708B_1',13,10,0
5048 Asper 1386
chip_VT17085_0	     db 'VT17085_0',13,10,0
1387
3083 leency 1388
 
1389
chip_CX20549	     db 'CX20549',13,10,0
5048 Asper 1390
chip_CX20561	     db 'CX20561',13,10,0
1391
3083 leency 1392
 
1393
chip_HDA_OUTPUT      db 'HDA-OUTPUT',13,10,0
1394
chip_HDA_DUPLEX      db 'HDA-DUPLEX',13,10,0
1395
1396
 
4320 yogev_ezra 1397
chip_LSI1039	     db '1039 (Agere Systems HDA Modem)',13,10,0
5048 Asper 1398
chip_LSI1040	     db '1040 (Agere Systems HDA Modem)',13,10,0
1399
chip_LSI3026	     db '3026 (Agere Systems HDA Modem)',13,10,0
1400
chip_LSI3055	     db '3055 (Agere Systems HDA Modem)',13,10,0
1401