Subversion Repositories Kolibri OS

Rev

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