Subversion Repositories Kolibri OS

Rev

Rev 4324 | 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
4324 Asper 16
    mov    ebx, [nid]
3083 leency 17
    shl    ebx, 20
18
    or     eax, ebx
4324 Asper 19
    mov    ebx, [verb]
3083 leency 20
    shl    ebx, 8
21
    or     eax, ebx
4324 Asper 22
    mov    ebx, [parm]
3083 leency 23
    or     eax, ebx
4324 Asper 24
    pop    ebx
3083 leency 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
4324 Asper 35
    mov    ebx, [cmd]
3083 leency 36
    cmp    ebx, -1
37
    jne    @f
38
    pop    edx  ebx
4324 Asper 39
    mov    eax, -1
3083 leency 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
4324 Asper 64
    push   eax esi
3083 leency 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
4324 Asper 83
3083 leency 84
 
85
    jz     @f
4324 Asper 86
3083 leency 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
 
4324 Asper 104
    ret
3083 leency 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
4324 Asper 166
    movzx    ecx, word [esi] ; NID
3496 Asper 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
4324 Asper 195
3083 leency 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 ?
4324 Asper 220
       conn_len      dd ?
3083 leency 221
       conns         dd 0
4324 Asper 222
       shift         db 8
223
       num_elements  dd 4
3083 leency 224
       mask          dd 0x7F
4324 Asper 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.
3083 leency 227
    endl
228
229
 
230
    mov      edi, [conn_list]
231
    test     edi, edi
232
    jz       .err_out
4324 Asper 233
    mov      ecx, [max_conns]
3083 leency 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
4324 Asper 244
    test     ebx, AC_WCAP_CONN_LIST
3083 leency 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
 
4324 Asper 259
    mov      [parm], eax
3083 leency 260
261
 
262
    jz       @f
4324 Asper 263
    ; long form
3083 leency 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
4324 Asper 271
3083 leency 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
4324 Asper 303
    sub      eax, edx
3083 leency 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
4324 Asper 363
    ; ranges between the previous and this one
3083 leency 364
    movzx    esi, word [prev_nid]
365
    test     esi, esi
366
    jz       .l2
4324 Asper 367
    cmp      esi, eax
3083 leency 368
    jl       @f
4324 Asper 369
  .l2:
3083 leency 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
4324 Asper 397
 if DEBUG
3083 leency 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
4324 Asper 425
 if DEBUG
3083 leency 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
4324 Asper 447
3083 leency 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
 
4324 Asper 515
  if DEBUG
516
     push    esi
517
     mov     esi, msgNoAFGFound
518
     call    SysMsgBoardStr
519
     pop     esi
520
  end  if
521
     push    ecx
522
     inc     eax
523
     mov     ecx, [codec.addr]
524
     shl     eax, cl
525
     pop     ecx
526
     cmp     eax, [ctrl.codec_mask]
527
     jl      .skip_codec
528
     ;Asper+]
529
530
 
3083 leency 531
     test    eax, eax
532
     jnz     @f
533
  if DEBUG
534
     push    esi
535
     mov     esi, emsgNoAFGorMFGFound
536
     call    SysMsgBoardStr
537
     pop     esi
538
  end  if
539
  .skip_codec:
4324 Asper 540
     mov     eax, -1
3083 leency 541
     ret
542
  @@:
543
544
 
545
     push    ebx
546
     stdcall read_widget_caps, eax
547
548
 
549
     jge     @f
550
  if DEBUG
551
     push    esi
552
     mov     esi, emsgNoMem
553
     call    SysMsgBoardStr
554
     pop     esi
555
  end  if
556
     pop     ebx
557
     mov     eax, -1
558
     ret
559
  @@:
560
561
 
562
563
 
564
     jge     @f
565
     pop     ebx
566
     mov     eax, -1
567
     ret
568
  @@:
569
     mov     eax, [codec.subsystem_id]
570
     test    eax, eax
571
     jnz     @f
572
     stdcall snd_hda_codec_read, ebx, 0, AC_VERB_GET_SUBSYSTEM_ID, 0
573
574
 
575
576
 
577
     stdcall snd_hda_set_power_state, ebx, AC_PWRST_D0
3496 Asper 578
3083 leency 579
 
4324 Asper 580
     pop     ebx
3083 leency 581
     ret
582
endp
583
584
 
585
 
586
;; snd_hda_codec_configure - (Re-)configure the HD-audio codec
587
;;
588
;; Start parsing of the given codec tree and (re-)initialize the whole
589
;; patch instance.
590
;;
591
;; Returns 0 if successful or a negative error code.
592
;;
593
proc  snd_hda_codec_configure
594
     call    get_codec_name
595
  @@:
596
     ; call the default parser
597
     stdcall snd_hda_parse_generic_codec  ;entry point to generic tree parser!!!
598
3496 Asper 599
 
3083 leency 600
     jz      @f
601
  if DEBUG
602
     push    esi
603
     mov     esi, emsgNoParserAvailable
604
     call    SysMsgBoardStr
605
     pop     esi
606
  end if
607
  @@:
608
  .out:
609
     ret
610
endp
611
612
 
613
 
614
proc  get_codec_name
615
     push    eax  ebx  edi  esi
616
     mov     eax, [codec.ac_vendor_ids]
617
     test    eax, eax
618
     jnz     .get_chip_name
619
     mov     ax, [codec.vendor_id]
620
     mov     edi, hda_vendor_ids
621
622
 
623
     mov     ebx, [edi]
624
     test    ebx, ebx
625
     jz      .unknown
626
627
 
628
     jne     .next
629
     mov     eax, [edi+4]
630
     mov     [codec.ac_vendor_ids], eax
631
     mov     esi, eax
632
     call    SysMsgBoardStr
633
  .get_chip_name:
634
     stdcall detect_chip, [edi+8]
635
     pop     esi  edi  ebx  eax
636
     ret
637
  .next:
638
     add     edi, 12
639
     jmp     @b
640
  .unknown:
641
     mov     [codec.ac_vendor_ids], ac_unknown
642
     mov     [codec.chip_ids], chip_unknown
643
644
 
645
     call    SysMsgBoardStr
646
     movzx   eax, [codec.chip_id]
647
     stdcall fdword2str, 2
648
     call    SysMsgBoardStr
649
     pop     esi  edi  ebx  eax
650
     ret
651
endp
652
653
 
654
 
655
proc detect_chip stdcall, chip_tab:dword
656
657
 
658
     mov     ax, [codec.chip_id]
659
660
 
661
@@:
662
     mov     ebx, [edi]
663
     cmp     ebx, 0xFF
664
     je      .unknown
665
666
 
667
     jne     .next
668
     mov     eax, [edi+4]
669
     mov     [codec.chip_ids], eax
670
     mov     esi, eax
671
     call    SysMsgBoardStr
672
     pop     esi  edi  ebx  eax
673
     ret
674
.next:
675
     add     edi, 8
676
     jmp     @b
677
.unknown:
678
     mov     [codec.chip_ids], chip_unknown
679
     mov     esi, chip_unknown
680
     call    SysMsgBoardStr
681
     movzx   eax, [codec.chip_id]
682
     stdcall fdword2str, 2
683
     call    SysMsgBoardStr
684
     pop     esi  edi  ebx  eax
685
     ret
686
endp
687
688
 
689
 
690
proc setup_fg_nodes
691
     push    eax  ebx  ecx
692
     stdcall snd_hda_get_sub_nodes, AC_NODE_ROOT
693
     mov     ecx, eax
694
     and     ecx, 0x7FFF ; total_nodes
695
     mov     ebx, eax
696
     shr     ebx, 16
697
     and     ebx, 0x7FFF ; nid
698
699
 
700
     push    eax esi
701
     mov     esi, msgSETUP_FG_NODES
702
     call    SysMsgBoardStr
703
     mov     eax, ebx
704
     stdcall fdword2str, 1
705
     call    SysMsgBoardStr
706
707
 
708
     call    SysMsgBoardStr
709
     mov     eax, ecx
710
     stdcall fdword2str, 3
711
     call    SysMsgBoardStr
712
     pop     esi eax
713
end if
714
715
 
716
     test    ecx, ecx
717
     jz      .l1
718
     snd_hda_param_read  ebx, AC_PAR_FUNCTION_TYPE
719
     and     eax, 0xFF
720
721
 
722
     push    eax esi
723
     mov     esi, msgFG_TYPE
724
     call    SysMsgBoardStr
725
     stdcall fdword2str, 3
726
     call    SysMsgBoardStr
727
     pop     esi eax
728
end if
729
730
 
731
     jne     @f
732
733
 
734
     mov     [codec.function_id], eax
735
     jmp     .continue
736
  @@:
737
     cmp     eax, AC_GRP_MODEM_FUNCTION
738
     jne     @f
739
740
 
741
     mov     [codec.function_id], eax
742
     jmp     .continue
743
  @@:
744
  .continue:
745
     inc     ebx
746
     dec     ecx
747
     jnz     .next
748
  .l1:
749
     pop     ecx  ebx  eax
750
     ret
751
endp
752
753
 
754
 
755
; read widget caps for each widget and store in cache
756
proc  read_widget_caps stdcall, fg_node:dword
757
     push    ebx ecx edx edi
758
759
 
760
     mov     ecx, eax
761
     and     ecx, 0x7FFF ; total_nodes
762
     mov     [codec.num_nodes], cx
763
     mov     ebx, eax
764
     shr     ebx, 16
765
     and     ebx, 0x7FFF ; nid
766
     mov     [codec.start_nid], bx
767
768
 
769
     push    eax esi
770
     mov     esi, msgSETUP_FG_NODES
771
     call    SysMsgBoardStr
772
     mov     eax, ebx
773
     stdcall fdword2str, 1
774
     call    SysMsgBoardStr
775
776
 
777
     call    SysMsgBoardStr
778
     mov     eax, ecx
779
     stdcall fdword2str, 3
780
     call    SysMsgBoardStr
781
     pop     esi eax
782
end if
783
784
 
785
     push    esi
786
     mov     esi, msgWCaps
787
     call    SysMsgBoardStr
788
     pop     esi
789
end if
790
791
 
792
     shl     eax, 2
793
     push    ebx ecx
794
     call    Kmalloc
795
     pop     ecx ebx
796
     test    eax, eax
797
     jz      .err_out
798
     mov     [codec.wcaps], eax
799
800
 
801
  .next_node:
802
803
 
804
     stosd
805
     inc     ebx
806
     dec     ecx
807
     jnz     .next_node
808
     pop     edi edx ecx ebx
809
     xor     eax, eax
810
     ret
811
  .err_out:
812
     pop     edi edx ecx ebx
813
     xor     eax, eax
814
     dec     eax
815
     ret
816
endp
817
818
 
819
 
820
proc  read_pin_defaults
821
     push    ebx ecx edx edi
822
823
 
824
     movzx   ecx, [codec.num_nodes]
825
826
 
827
     mov     eax, HDA_PINCFG.sizeof
828
     mul     cl
829
     push    ebx ecx
830
     call    Kmalloc
831
     pop     ecx ebx
832
     test    eax, eax
833
     jz      .err_out
834
     mov     [codec.init_pins], eax
835
     mov     [codec.num_pins], 0
4555 clevermous 836
     mov     edi, eax
3083 leency 837
     ;Asper ]
838
839
 
840
   push   eax esi
841
   mov    esi, msgPinCfgs
4324 Asper 842
   call   SysMsgBoardStr
3083 leency 843
   pop    esi eax
4324 Asper 844
end if
3083 leency 845
846
 
847
 
848
     stdcall get_wcaps, ebx
849
     and  eax, AC_WCAP_TYPE
850
     shr  eax, AC_WCAP_TYPE_SHIFT
851
852
 
853
     jne     .continue
854
855
 
856
     stdcall snd_hda_codec_read, ebx, 0, AC_VERB_GET_CONFIG_DEFAULT, 0
857
     mov     [edi + HDA_PINCFG.cfg], eax
858
     add     edi, HDA_PINCFG.sizeof
4555 clevermous 859
     inc     [codec.num_pins]
860
3083 leency 861
 
862
     inc     ebx
863
     dec     ecx
864
     jnz     .next_node
865
866
 
867
     xor     eax, eax
868
     ret
869
  .err_out:
870
     pop     edi edx ecx ebx
871
     xor     eax, eax
872
     dec     eax
873
     ret
874
endp
875
876
 
877
 
878
 
879
proc  look_up_pincfg stdcall, array:dword, nid:dword
880
     push    ebx ecx edx
881
     mov     ecx, [codec.num_pins]
882
     mov     eax, [array]
883
     mov     ebx, [nid]
884
  .next_pin:
885
     mov     dx,  [eax + HDA_PINCFG.nid]
886
     cmp     dx,  bx
887
     je      .out
888
  .continue:
889
     add     eax, HDA_PINCFG.sizeof
890
     dec     ecx
891
     jnz     .next_pin
892
893
 
894
  .out:
895
     pop     edx ecx ebx
896
     ret
897
endp
898
899
 
900
proc  set_pincfg stdcall, nid:dword, cfg:dword
901
     push    eax  ebx  ecx  edx
902
     mov     eax, [cfg]
903
     xor     ebx, ebx
904
     mov     edx, AC_VERB_SET_CONFIG_DEFAULT_BYTES_0
905
     mov     ecx, 4
906
  @@:
907
     mov     bl,  al
908
     stdcall snd_hda_codec_write, [nid], 0, edx, ebx
909
     shr     eax, 8
910
     inc     edx
911
     dec     ecx
912
     jnz     @b
913
  .l1:
914
     pop     edx  ecx  ebx  eax
915
     ret
916
endp
917
918
 
919
 
920
;; snd_hda_codec_get_pincfg - Obtain a pin-default configuration
921
;; @codec: the HDA codec
922
;; @nid: NID to get the pin config
923
;;
924
;; Get the current pin config value of the given pin NID.
925
;; If the pincfg value is cached or overridden via sysfs or driver,
926
;; returns the cached value.
927
;;
928
proc  snd_hda_codec_get_pincfg stdcall, nid:dword
929
     push    edi
930
     stdcall look_up_pincfg, [codec.init_pins], [nid]
931
     test    eax, eax
932
     jz      @f
933
     mov     edi, eax
934
     mov     eax, [edi + HDA_PINCFG.cfg]
935
  @@:
936
     pop     edi
937
     ret
938
endp
939
940
 
941
942
 
943
;; snd_hda_codec_setup_stream - set up the codec for streaming
944
;; @nid: the NID to set up
945
;; @stream_tag: stream tag to pass, it's between 0x1 and 0xf.
946
;; @channel_id: channel id to pass, zero based.
947
;; @format: stream format.
948
;;
949
proc hda_codec_setup_stream stdcall, nid:dword, stream_tag:dword, channel_id:dword, format:dword
950
     push    eax
951
     mov     eax, [nid]
952
     test    eax, eax
953
     jnz     @f
954
     pop     eax
955
     ret
956
  @@:
957
  if DEBUG
958
     push    esi
959
     mov     esi, msgHDACodecSetupStream
960
     call    SysMsgBoardStr
961
     stdcall fdword2str, 3
962
     call    SysMsgBoardStr
963
964
 
965
     call    SysMsgBoardStr
966
     mov     eax, [stream_tag]
967
     stdcall fdword2str, 3
968
     call    SysMsgBoardStr
969
970
 
971
     call    SysMsgBoardStr
972
     mov     eax, [channel_id]
973
     stdcall fdword2str, 3
974
     call    SysMsgBoardStr
975
976
 
977
     call    SysMsgBoardStr
978
     mov     eax, [format]
979
     stdcall fdword2str, 3
980
     call    SysMsgBoardStr
981
     pop     esi
982
  end if
983
     mov     eax, [stream_tag]
984
     shl     eax, 4
985
     or      eax, [channel_id]
986
     stdcall snd_hda_codec_write, [nid], 0, AC_VERB_SET_CHANNEL_STREAMID, eax
987
988
 
4324 Asper 989
     call    StallExec
3083 leency 990
991
 
992
     pop     eax
993
     ret
994
endp
995
996
 
997
 
998
     push    eax
999
     mov     eax, [nid]
1000
     test    eax, eax
1001
     jz      @f
1002
     pop     eax
1003
     ret
1004
  @@:
1005
  if DEBUG
1006
     push    esi
1007
     mov     esi, msgHDACodecCleanupStream
1008
     call    SysMsgBoardStr
1009
     stdcall fdword2str, 3
1010
     call    SysMsgBoardStr
1011
     pop     esi
1012
  end if
1013
     stdcall snd_hda_codec_write, [nid], 0, AC_VERB_SET_CHANNEL_STREAMID, 0
1014
  if 0  ; keep the format
4324 Asper 1015
     mov     eax, 1000000  ; wait 100 ms
3083 leency 1016
     call    StallExec
1017
     stdcall snd_hda_codec_write, [nid], 0, AC_VERB_SET_STREAM_FORMAT, 0
1018
  end if
1019
     pop     eax
1020
     ret
1021
endp
1022
1023
 
1024
 
1025
     snd_hda_param_read  [nid], AC_PAR_PIN_CAP
1026
     ret
1027
endp
1028
1029
 
1030
 
1031
proc get_volume_mute stdcall, nid:dword, ch:dword, direction:dword, index:dword
1032
     push    ebx
1033
     mov     ebx, AC_AMP_GET_LEFT
1034
     mov     eax, [ch]
1035
     test    eax, eax
1036
     jz      @f
1037
     mov     ebx, AC_AMP_GET_RIGHT
1038
  @@:
1039
     mov     eax, [direction]
1040
     cmp     eax, HDA_OUTPUT
1041
     jne     @f
1042
     or      ebx, AC_AMP_GET_OUTPUT
1043
     jmp     .l1
1044
  @@:
1045
     or      ebx, AC_AMP_GET_INPUT
1046
  .l1:
1047
     or      ebx, [index]
1048
     stdcall snd_hda_codec_read, [nid], 0, AC_VERB_GET_AMP_GAIN_MUTE, ebx
1049
     and     eax, 0xFF
1050
     pop     ebx
1051
     ret
1052
endp
1053
1054
 
1055
 
1056
proc put_volume_mute stdcall, nid:dword, ch:dword, direction:dword, index:dword, val:dword
1057
     push    eax  ebx
1058
     mov     ebx, AC_AMP_SET_LEFT
1059
     mov     eax, [ch]
1060
     test    eax, eax
1061
     jz      @f
1062
     mov     ebx, AC_AMP_SET_RIGHT
1063
  @@:
1064
     mov     eax, [direction]
1065
     cmp     eax, HDA_OUTPUT
1066
     jne     @f
1067
     or      ebx, AC_AMP_SET_OUTPUT
1068
     jmp     .l1
1069
  @@:
1070
     or      ebx, AC_AMP_SET_INPUT
1071
  .l1:
1072
     mov     eax, [index]
1073
     shl     eax, AC_AMP_SET_INDEX_SHIFT
1074
     or      ebx, eax
1075
     or      ebx, [val]
1076
     stdcall snd_hda_codec_write, [nid], 0, AC_VERB_SET_AMP_GAIN_MUTE, ebx
1077
     pop     ebx  eax
1078
     ret
1079
endp
1080
1081
 
1082
 
1083
;; snd_hda_codec_amp_update - update the AMP value
1084
;; @nid: NID to read the AMP value
1085
;; @ch: channel (left=0 or right=1)
1086
;; @direction: #HDA_INPUT or #HDA_OUTPUT
1087
;; @idx: the index value (only for input direction)
1088
;; @mask: bit mask to set
1089
;; @val: the bits value to set
1090
;;
1091
;; Update the AMP value with a bit mask.
1092
;; Returns 0 if the value is unchanged, 1 if changed.
1093
;;
1094
;-proc snd_hda_codec_amp_update stdcall, nid:dword, ch:dword, direction:dword, idx:dword, mask:dword, val:dword
1095
;-     push    ebx  edx
1096
;-     mov     eax, [mask]
1097
;-     mov     ebx, [val]
1098
;-     and     ebx, eax
1099
;-     xor     eax, -1
1100
;-     mov     edx, eax
1101
;-     stdcall get_volume_mute, [nid], [ch], [direction], [idx]
1102
;-     and     eax, edx
1103
;-     or      ebx, eax
1104
;-
1105
;-     stdcall put_volume_mute, [nid], [ch], [direction], [idx], ebx
1106
;-     xor     eax, eax
1107
;-     inc     eax
1108
;-     pop     edx  ebx
1109
;-     ret
1110
;-endp
1111
1112
 
1113
 
1114
;; snd_hda_codec_amp_stereo - update the AMP stereo values
1115
;; @nid: NID to read the AMP value
1116
;; @direction: #HDA_INPUT or #HDA_OUTPUT
1117
;; @idx: the index value (only for input direction)
1118
;; @mask: bit mask to set
1119
;; @val: the bits value to set
1120
;;
1121
;; Update the AMP values like snd_hda_codec_amp_update(), but for a
1122
;; stereo widget with the same mask and value.
1123
;;
1124
proc snd_hda_codec_amp_stereo stdcall, nid:dword, direction:dword, idx:dword, mask:dword, val:dword
1125
     push    ebx edx
1126
     mov     ebx, [val]
1127
     mov     edx, [mask]
1128
     and     ebx, edx
1129
     stdcall put_volume_mute, [nid], 0, [direction], [idx], ebx
1130
     stdcall put_volume_mute, [nid], 1, [direction], [idx], ebx
1131
     pop     edx  ebx
1132
     ret
1133
endp
1134
1135
 
1136
 
1137
proc snd_hda_set_power_state stdcall, fg:dword, power_state:dword
1138
     push    eax ebx ecx edx
1139
     ; this delay seems necessary to avoid click noise at power down
1140
     mov     ebx, [power_state]
1141
     cmp     ebx, AC_PWRST_D3
1142
     jne     @f
1143
     mov     eax, 100000
1144
     call    StallExec
1145
  @@:
1146
     stdcall snd_hda_codec_read, [fg], 0, AC_VERB_SET_POWER_STATE, ebx
1147
     ;partial workaround for "azx_get_response timeout"
1148
     cmp     ebx, AC_PWRST_D0
1149
     jne     @f
1150
1151
 
1152
     cmp     dx, 0x14F1
1153
1154
 
1155
     mov     eax, 10000
1156
     call    StallExec
1157
  @@:
1158
     movzx   ecx, [codec.num_nodes]
1159
     movzx   edx, [codec.start_nid]
1160
  .next_nid:
1161
     stdcall get_wcaps, edx
1162
     test    eax, AC_WCAP_POWER
1163
     jz      .skip_nid
1164
1165
 
1166
     cmp     ebx, AC_PWRST_D3
1167
     jne     .l1
1168
     cmp     eax, AC_WID_PIN
1169
     jne     .l1
1170
     ;don't power down the widget if it controls
1171
     ;eapd and EAPD_BTLENABLE is set.
1172
     stdcall  read_pin_cap, edx
1173
     test    eax, AC_PINCAP_EAPD
1174
     jz      .l2
1175
1176
 
1177
     and     eax, 0x02
1178
     test    eax, eax
1179
     jnz     .skip_nid
1180
  .l2:
1181
  .l1:
1182
     stdcall snd_hda_codec_write, edx, 0, AC_VERB_SET_POWER_STATE, ebx
1183
  .skip_nid:
1184
     inc     edx
1185
     dec     ecx
1186
     jnz     .next_nid
1187
1188
 
1189
     jne     .out
1190
     ;wait until codec reaches to D0
1191
     mov     ecx, 500
1192
  .wait_D0:
1193
     stdcall snd_hda_codec_read, [fg], 0, AC_VERB_GET_POWER_STATE, 0
1194
     cmp     eax, ebx
1195
     je      .out
1196
     mov     eax, 1000  ; msleep(1);
4324 Asper 1197
     call    StallExec
3083 leency 1198
     dec     ecx
1199
     jnz     .wait_D0
1200
  .out:
1201
     pop     edx ecx ebx eax
1202
     ret
1203
endp
1204
1205
 
1206
 
1207
1208
 
1209
align 16
1210
msg_Cirrus       db 'Cirrus Logic ',0
4324 Asper 1211
msg_Motorola       db 'Motorola ',0
1212
msg_SiliconImage     db 'Silicon Image ',0
3083 leency 1213
msg_Realtek       db 'Realtek ',0
4324 Asper 1214
msg_Creative       db 'Creative ',0
1215
msg_IDT        db 'IDT ',0
1216
msg_LSI        db 'LSI ',0
1217
msg_AnalogDevices    db 'Analog Devices ',0
3083 leency 1218
msg_CMedia       db 'C-Media ',0
4324 Asper 1219
msg_Conexant       db 'Conexant ',0
1220
msg_Chrontel       db 'Chrontel ',0
1221
msg_LG         db 'LG ',0
1222
msg_Wolfson       db 'Wolfson Microelectronics ',0
1223
msg_Qumranet       db 'Qumranet ',0
1224
msg_SigmaTel       db 'SigmaTel ',0
1225
ac_unknown     db 'unknown manufacturer ',0
3083 leency 1226
1227
 
1228
1229
 
1230
 
1231
align 4
1232
hda_vendor_ids:
1233
     dd    0x1002, msg_ATI, chips_ATI
1234
     dd    0x1013, msg_Cirrus, chips_Cirrus
1235
     dd    0x1057, msg_Motorola, chips_Motorola
1236
     dd    0x1095, msg_SiliconImage, chips_SiliconImage
1237
     dd    0x10de, msg_NVidia, chips_NVidia
1238
     dd    0x10ec, msg_Realtek, chips_Realtek
1239
     dd    0x1102, msg_Creative, chips_Creative
1240
     dd    0x1106, msg_VIA, chips_VIA
1241
     dd    0x111d, msg_IDT, chips_IDT
1242
     dd    0x11c1, msg_LSI, chips_LSI
1243
     dd    0x11d4, msg_AnalogDevices, chips_Analog
1244
     dd    0x13f6, msg_CMedia, chips_CMedia
1245
     dd    0x14f1, msg_Conexant, chips_Conexant
1246
     dd    0x17e8, msg_Chrontel, chips_Chrontel
1247
     dd    0x1854, msg_LG, chips_LG
1248
     dd    0x1aec, msg_Wolfson, chips_Wolfson
1249
     dd    0x1af4, msg_Qumranet, chips_Qumranet   ; Qemu 0.14
1250
     dd    0x434d, msg_CMedia, chips_CMedia
1251
     dd    0x8086, msg_Intel, chips_Intel
1252
     dd    0x8384, msg_SigmaTel, chips_SigmaTel
1253
     dd    0 ; terminator
1254
1255
 
4324 Asper 1256
chips_ATI            dd 0xAA01, chip_ATIR6XX
1257
                     dd 0xFF
1258
3083 leency 1259
 
4324 Asper 1260
chips_Motorola       dd 0xFF
1261
3083 leency 1262
 
1263
                     dd 0xFF
4324 Asper 1264
3083 leency 1265
 
4324 Asper 1266
                     dd 0xFF
1267
3083 leency 1268
 
4324 Asper 1269
                     dd 0x0268, chip_ALC268
1270
                     dd 0x0269, chip_ALC269
1271
                     dd 0x0272, chip_ALC272
1272
                     dd 0x0662, chip_ALC662
1273
                     dd 0x0663, chip_ALC663
1274
                     dd 0x0883, chip_ALC883
1275
                     dd 0x0887, chip_ALC887
1276
                     dd 0x0888, chip_ALC888
1277
                     dd 0x0889, chip_ALC889
1278
                     dd 0xFF
1279
3083 leency 1280
 
4324 Asper 1281
3083 leency 1282
 
4324 Asper 1283
                     dd 0x0397, chip_VT17085_0
1284
                     dd 0xFF
1285
3083 leency 1286
 
4324 Asper 1287
3083 leency 1288
 
4324 Asper 1289
                     dd 0x1040, chip_LSI1040
1290
                     dd 0x3026, chip_LSI3026
1291
                     dd 0x3055, chip_LSI3055
1292
                     dd 0xFF
1293
4320 yogev_ezra 1294
 
4324 Asper 1295
                     dd 0x198B, chip_AD198B
1296
                     dd 0xFF
1297
3083 leency 1298
 
4324 Asper 1299
3083 leency 1300
 
4324 Asper 1301
                     dd 0x5051, chip_CX20561
1302
                     dd 0xFF
1303
3083 leency 1304
 
4324 Asper 1305
chips_LG             dd 0xFF
1306
chips_Wolfson        dd 0xFF
1307
chips_Intel          dd 0xFF
1308
3083 leency 1309
 
4324 Asper 1310
                     dd 0x0020, chip_HDA_DUPLEX
1311
                     dd 0xFF
1312
3083 leency 1313
 
4324 Asper 1314
                     dd 0x7682, chip_STAC9221_A2
1315
                     dd 0xFF
1316
3083 leency 1317
 
1318
;AnalogDevices
1319
chip_AD1986A         db 'AD1986A',13,10,0
4324 Asper 1320
chip_AD198B          db 'AD198B',13,10,0
1321
3083 leency 1322
 
1323
chip_ATIR6XX         db 'ATIR6XX',13,10,0
4324 Asper 1324
3083 leency 1325
 
1326
chip_SI1392          db 'SI1392',13,10,0
4324 Asper 1327
3083 leency 1328
 
1329
chip_MCP78           db 'MCP78',13,10,0
4324 Asper 1330
3083 leency 1331
 
1332
chip_ALC262          db 'ALC262',13,10,0
4324 Asper 1333
chip_ALC268          db 'ALC268',13,10,0
1334
chip_ALC269          db 'ALC269',13,10,0
1335
chip_ALC272          db 'ALC272',13,10,0
1336
chip_ALC662          db 'ALC662',13,10,0
1337
chip_ALC663          db 'ALC663',13,10,0
1338
chip_ALC883          db 'ALC883',13,10,0
1339
chip_ALC887          db 'ALC887',13,10,0
1340
chip_ALC888          db 'ALC888',13,10,0
1341
chip_ALC889          db 'ALC889',13,10,0
1342
3083 leency 1343
 
1344
chip_STAC9221        db 'STAC9221',13,10,0
4324 Asper 1345
chip_STAC9221_A2     db 'STAC9221_A2',13,10,0
3083 leency 1346
1347
 
1348
chip_VT1708B_1       db 'VT1708B_1',13,10,0
4324 Asper 1349
chip_VT17085_0       db 'VT17085_0',13,10,0
1350
3083 leency 1351
 
1352
chip_CX20549         db 'CX20549',13,10,0
4324 Asper 1353
chip_CX20561         db 'CX20561',13,10,0
1354
3083 leency 1355
 
1356
chip_HDA_OUTPUT      db 'HDA-OUTPUT',13,10,0
1357
chip_HDA_DUPLEX      db 'HDA-DUPLEX',13,10,0
1358
1359
 
4320 yogev_ezra 1360
chip_LSI1039         db '1039 (Agere Systems HDA Modem)',13,10,0
4321 yogev_ezra 1361
chip_LSI1040         db '1040 (Agere Systems HDA Modem)',13,10,0
1362
chip_LSI3026         db '3026 (Agere Systems HDA Modem)',13,10,0
1363
chip_LSI3055         db '3055 (Agere Systems HDA Modem)',13,10,0
4324 Asper 1364