Subversion Repositories Kolibri OS

Rev

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