Subversion Repositories Kolibri OS

Rev

Rev 4321 | Rev 4555 | 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     edi, eax
836
     ;Asper ]
837
838
 
839
   push   eax esi
840
   mov    esi, msgPinCfgs
4324 Asper 841
   call   SysMsgBoardStr
3083 leency 842
   pop    esi eax
4324 Asper 843
end if
3083 leency 844
845
 
846
 
847
     stdcall get_wcaps, ebx
848
     and  eax, AC_WCAP_TYPE
849
     shr  eax, AC_WCAP_TYPE_SHIFT
850
851
 
852
     jne     .continue
853
854
 
855
     stdcall snd_hda_codec_read, ebx, 0, AC_VERB_GET_CONFIG_DEFAULT, 0
856
     mov     [edi + HDA_PINCFG.cfg], eax
857
858
 
859
     add     edi, HDA_PINCFG.sizeof
860
     inc     ebx
861
     dec     ecx
862
     jnz     .next_node
863
864
 
865
     and     ebx, 0xFFFF
866
     sub     bx, [codec.start_nid]
867
     mov     [codec.num_pins], ebx
868
;Asper ]
869
870
 
871
     xor     eax, eax
872
     ret
873
  .err_out:
874
     pop     edi edx ecx ebx
875
     xor     eax, eax
876
     dec     eax
877
     ret
878
endp
879
880
 
881
 
882
 
883
proc  look_up_pincfg stdcall, array:dword, nid:dword
884
     push    ebx ecx edx
885
     mov     ecx, [codec.num_pins]
886
     mov     eax, [array]
887
     mov     ebx, [nid]
888
  .next_pin:
889
     mov     dx,  [eax + HDA_PINCFG.nid]
890
     cmp     dx,  bx
891
     je      .out
892
  .continue:
893
     add     eax, HDA_PINCFG.sizeof
894
     dec     ecx
895
     jnz     .next_pin
896
897
 
898
  .out:
899
     pop     edx ecx ebx
900
     ret
901
endp
902
903
 
904
proc  set_pincfg stdcall, nid:dword, cfg:dword
905
     push    eax  ebx  ecx  edx
906
     mov     eax, [cfg]
907
     xor     ebx, ebx
908
     mov     edx, AC_VERB_SET_CONFIG_DEFAULT_BYTES_0
909
     mov     ecx, 4
910
  @@:
911
     mov     bl,  al
912
     stdcall snd_hda_codec_write, [nid], 0, edx, ebx
913
     shr     eax, 8
914
     inc     edx
915
     dec     ecx
916
     jnz     @b
917
  .l1:
918
     pop     edx  ecx  ebx  eax
919
     ret
920
endp
921
922
 
923
 
924
;; snd_hda_codec_get_pincfg - Obtain a pin-default configuration
925
;; @codec: the HDA codec
926
;; @nid: NID to get the pin config
927
;;
928
;; Get the current pin config value of the given pin NID.
929
;; If the pincfg value is cached or overridden via sysfs or driver,
930
;; returns the cached value.
931
;;
932
proc  snd_hda_codec_get_pincfg stdcall, nid:dword
933
     push    edi
934
     stdcall look_up_pincfg, [codec.init_pins], [nid]
935
     test    eax, eax
936
     jz      @f
937
     mov     edi, eax
938
     mov     eax, [edi + HDA_PINCFG.cfg]
939
  @@:
940
     pop     edi
941
     ret
942
endp
943
944
 
945
946
 
947
;; snd_hda_codec_setup_stream - set up the codec for streaming
948
;; @nid: the NID to set up
949
;; @stream_tag: stream tag to pass, it's between 0x1 and 0xf.
950
;; @channel_id: channel id to pass, zero based.
951
;; @format: stream format.
952
;;
953
proc hda_codec_setup_stream stdcall, nid:dword, stream_tag:dword, channel_id:dword, format:dword
954
     push    eax
955
     mov     eax, [nid]
956
     test    eax, eax
957
     jnz     @f
958
     pop     eax
959
     ret
960
  @@:
961
  if DEBUG
962
     push    esi
963
     mov     esi, msgHDACodecSetupStream
964
     call    SysMsgBoardStr
965
     stdcall fdword2str, 3
966
     call    SysMsgBoardStr
967
968
 
969
     call    SysMsgBoardStr
970
     mov     eax, [stream_tag]
971
     stdcall fdword2str, 3
972
     call    SysMsgBoardStr
973
974
 
975
     call    SysMsgBoardStr
976
     mov     eax, [channel_id]
977
     stdcall fdword2str, 3
978
     call    SysMsgBoardStr
979
980
 
981
     call    SysMsgBoardStr
982
     mov     eax, [format]
983
     stdcall fdword2str, 3
984
     call    SysMsgBoardStr
985
     pop     esi
986
  end if
987
     mov     eax, [stream_tag]
988
     shl     eax, 4
989
     or      eax, [channel_id]
990
     stdcall snd_hda_codec_write, [nid], 0, AC_VERB_SET_CHANNEL_STREAMID, eax
991
992
 
4324 Asper 993
     call    StallExec
3083 leency 994
995
 
996
     pop     eax
997
     ret
998
endp
999
1000
 
1001
 
1002
     push    eax
1003
     mov     eax, [nid]
1004
     test    eax, eax
1005
     jz      @f
1006
     pop     eax
1007
     ret
1008
  @@:
1009
  if DEBUG
1010
     push    esi
1011
     mov     esi, msgHDACodecCleanupStream
1012
     call    SysMsgBoardStr
1013
     stdcall fdword2str, 3
1014
     call    SysMsgBoardStr
1015
     pop     esi
1016
  end if
1017
     stdcall snd_hda_codec_write, [nid], 0, AC_VERB_SET_CHANNEL_STREAMID, 0
1018
  if 0  ; keep the format
4324 Asper 1019
     mov     eax, 1000000  ; wait 100 ms
3083 leency 1020
     call    StallExec
1021
     stdcall snd_hda_codec_write, [nid], 0, AC_VERB_SET_STREAM_FORMAT, 0
1022
  end if
1023
     pop     eax
1024
     ret
1025
endp
1026
1027
 
1028
 
1029
     snd_hda_param_read  [nid], AC_PAR_PIN_CAP
1030
     ret
1031
endp
1032
1033
 
1034
 
1035
proc get_volume_mute stdcall, nid:dword, ch:dword, direction:dword, index:dword
1036
     push    ebx
1037
     mov     ebx, AC_AMP_GET_LEFT
1038
     mov     eax, [ch]
1039
     test    eax, eax
1040
     jz      @f
1041
     mov     ebx, AC_AMP_GET_RIGHT
1042
  @@:
1043
     mov     eax, [direction]
1044
     cmp     eax, HDA_OUTPUT
1045
     jne     @f
1046
     or      ebx, AC_AMP_GET_OUTPUT
1047
     jmp     .l1
1048
  @@:
1049
     or      ebx, AC_AMP_GET_INPUT
1050
  .l1:
1051
     or      ebx, [index]
1052
     stdcall snd_hda_codec_read, [nid], 0, AC_VERB_GET_AMP_GAIN_MUTE, ebx
1053
     and     eax, 0xFF
1054
     pop     ebx
1055
     ret
1056
endp
1057
1058
 
1059
 
1060
proc put_volume_mute stdcall, nid:dword, ch:dword, direction:dword, index:dword, val:dword
1061
     push    eax  ebx
1062
     mov     ebx, AC_AMP_SET_LEFT
1063
     mov     eax, [ch]
1064
     test    eax, eax
1065
     jz      @f
1066
     mov     ebx, AC_AMP_SET_RIGHT
1067
  @@:
1068
     mov     eax, [direction]
1069
     cmp     eax, HDA_OUTPUT
1070
     jne     @f
1071
     or      ebx, AC_AMP_SET_OUTPUT
1072
     jmp     .l1
1073
  @@:
1074
     or      ebx, AC_AMP_SET_INPUT
1075
  .l1:
1076
     mov     eax, [index]
1077
     shl     eax, AC_AMP_SET_INDEX_SHIFT
1078
     or      ebx, eax
1079
     or      ebx, [val]
1080
     stdcall snd_hda_codec_write, [nid], 0, AC_VERB_SET_AMP_GAIN_MUTE, ebx
1081
     pop     ebx  eax
1082
     ret
1083
endp
1084
1085
 
1086
 
1087
;; snd_hda_codec_amp_update - update the AMP value
1088
;; @nid: NID to read the AMP value
1089
;; @ch: channel (left=0 or right=1)
1090
;; @direction: #HDA_INPUT or #HDA_OUTPUT
1091
;; @idx: the index value (only for input direction)
1092
;; @mask: bit mask to set
1093
;; @val: the bits value to set
1094
;;
1095
;; Update the AMP value with a bit mask.
1096
;; Returns 0 if the value is unchanged, 1 if changed.
1097
;;
1098
;-proc snd_hda_codec_amp_update stdcall, nid:dword, ch:dword, direction:dword, idx:dword, mask:dword, val:dword
1099
;-     push    ebx  edx
1100
;-     mov     eax, [mask]
1101
;-     mov     ebx, [val]
1102
;-     and     ebx, eax
1103
;-     xor     eax, -1
1104
;-     mov     edx, eax
1105
;-     stdcall get_volume_mute, [nid], [ch], [direction], [idx]
1106
;-     and     eax, edx
1107
;-     or      ebx, eax
1108
;-
1109
;-     stdcall put_volume_mute, [nid], [ch], [direction], [idx], ebx
1110
;-     xor     eax, eax
1111
;-     inc     eax
1112
;-     pop     edx  ebx
1113
;-     ret
1114
;-endp
1115
1116
 
1117
 
1118
;; snd_hda_codec_amp_stereo - update the AMP stereo values
1119
;; @nid: NID to read the AMP value
1120
;; @direction: #HDA_INPUT or #HDA_OUTPUT
1121
;; @idx: the index value (only for input direction)
1122
;; @mask: bit mask to set
1123
;; @val: the bits value to set
1124
;;
1125
;; Update the AMP values like snd_hda_codec_amp_update(), but for a
1126
;; stereo widget with the same mask and value.
1127
;;
1128
proc snd_hda_codec_amp_stereo stdcall, nid:dword, direction:dword, idx:dword, mask:dword, val:dword
1129
     push    ebx edx
1130
     mov     ebx, [val]
1131
     mov     edx, [mask]
1132
     and     ebx, edx
1133
     stdcall put_volume_mute, [nid], 0, [direction], [idx], ebx
1134
     stdcall put_volume_mute, [nid], 1, [direction], [idx], ebx
1135
     pop     edx  ebx
1136
     ret
1137
endp
1138
1139
 
1140
 
1141
proc snd_hda_set_power_state stdcall, fg:dword, power_state:dword
1142
     push    eax ebx ecx edx
1143
     ; this delay seems necessary to avoid click noise at power down
1144
     mov     ebx, [power_state]
1145
     cmp     ebx, AC_PWRST_D3
1146
     jne     @f
1147
     mov     eax, 100000
1148
     call    StallExec
1149
  @@:
1150
     stdcall snd_hda_codec_read, [fg], 0, AC_VERB_SET_POWER_STATE, ebx
1151
     ;partial workaround for "azx_get_response timeout"
1152
     cmp     ebx, AC_PWRST_D0
1153
     jne     @f
1154
1155
 
1156
     cmp     dx, 0x14F1
1157
1158
 
1159
     mov     eax, 10000
1160
     call    StallExec
1161
  @@:
1162
     movzx   ecx, [codec.num_nodes]
1163
     movzx   edx, [codec.start_nid]
1164
  .next_nid:
1165
     stdcall get_wcaps, edx
1166
     test    eax, AC_WCAP_POWER
1167
     jz      .skip_nid
1168
1169
 
1170
     cmp     ebx, AC_PWRST_D3
1171
     jne     .l1
1172
     cmp     eax, AC_WID_PIN
1173
     jne     .l1
1174
     ;don't power down the widget if it controls
1175
     ;eapd and EAPD_BTLENABLE is set.
1176
     stdcall  read_pin_cap, edx
1177
     test    eax, AC_PINCAP_EAPD
1178
     jz      .l2
1179
1180
 
1181
     and     eax, 0x02
1182
     test    eax, eax
1183
     jnz     .skip_nid
1184
  .l2:
1185
  .l1:
1186
     stdcall snd_hda_codec_write, edx, 0, AC_VERB_SET_POWER_STATE, ebx
1187
  .skip_nid:
1188
     inc     edx
1189
     dec     ecx
1190
     jnz     .next_nid
1191
1192
 
1193
     jne     .out
1194
     ;wait until codec reaches to D0
1195
     mov     ecx, 500
1196
  .wait_D0:
1197
     stdcall snd_hda_codec_read, [fg], 0, AC_VERB_GET_POWER_STATE, 0
1198
     cmp     eax, ebx
1199
     je      .out
1200
     mov     eax, 1000  ; msleep(1);
4324 Asper 1201
     call    StallExec
3083 leency 1202
     dec     ecx
1203
     jnz     .wait_D0
1204
  .out:
1205
     pop     edx ecx ebx eax
1206
     ret
1207
endp
1208
1209
 
1210
 
1211
1212
 
1213
align 16
1214
msg_Cirrus       db 'Cirrus Logic ',0
4324 Asper 1215
msg_Motorola       db 'Motorola ',0
1216
msg_SiliconImage     db 'Silicon Image ',0
3083 leency 1217
msg_Realtek       db 'Realtek ',0
4324 Asper 1218
msg_Creative       db 'Creative ',0
1219
msg_IDT        db 'IDT ',0
1220
msg_LSI        db 'LSI ',0
1221
msg_AnalogDevices    db 'Analog Devices ',0
3083 leency 1222
msg_CMedia       db 'C-Media ',0
4324 Asper 1223
msg_Conexant       db 'Conexant ',0
1224
msg_Chrontel       db 'Chrontel ',0
1225
msg_LG         db 'LG ',0
1226
msg_Wolfson       db 'Wolfson Microelectronics ',0
1227
msg_Qumranet       db 'Qumranet ',0
1228
msg_SigmaTel       db 'SigmaTel ',0
1229
ac_unknown     db 'unknown manufacturer ',0
3083 leency 1230
1231
 
1232
1233
 
1234
 
1235
align 4
1236
hda_vendor_ids:
1237
     dd    0x1002, msg_ATI, chips_ATI
1238
     dd    0x1013, msg_Cirrus, chips_Cirrus
1239
     dd    0x1057, msg_Motorola, chips_Motorola
1240
     dd    0x1095, msg_SiliconImage, chips_SiliconImage
1241
     dd    0x10de, msg_NVidia, chips_NVidia
1242
     dd    0x10ec, msg_Realtek, chips_Realtek
1243
     dd    0x1102, msg_Creative, chips_Creative
1244
     dd    0x1106, msg_VIA, chips_VIA
1245
     dd    0x111d, msg_IDT, chips_IDT
1246
     dd    0x11c1, msg_LSI, chips_LSI
1247
     dd    0x11d4, msg_AnalogDevices, chips_Analog
1248
     dd    0x13f6, msg_CMedia, chips_CMedia
1249
     dd    0x14f1, msg_Conexant, chips_Conexant
1250
     dd    0x17e8, msg_Chrontel, chips_Chrontel
1251
     dd    0x1854, msg_LG, chips_LG
1252
     dd    0x1aec, msg_Wolfson, chips_Wolfson
1253
     dd    0x1af4, msg_Qumranet, chips_Qumranet   ; Qemu 0.14
1254
     dd    0x434d, msg_CMedia, chips_CMedia
1255
     dd    0x8086, msg_Intel, chips_Intel
1256
     dd    0x8384, msg_SigmaTel, chips_SigmaTel
1257
     dd    0 ; terminator
1258
1259
 
4324 Asper 1260
chips_ATI            dd 0xAA01, chip_ATIR6XX
1261
                     dd 0xFF
1262
3083 leency 1263
 
4324 Asper 1264
chips_Motorola       dd 0xFF
1265
3083 leency 1266
 
1267
                     dd 0xFF
4324 Asper 1268
3083 leency 1269
 
4324 Asper 1270
                     dd 0xFF
1271
3083 leency 1272
 
4324 Asper 1273
                     dd 0x0268, chip_ALC268
1274
                     dd 0x0269, chip_ALC269
1275
                     dd 0x0272, chip_ALC272
1276
                     dd 0x0662, chip_ALC662
1277
                     dd 0x0663, chip_ALC663
1278
                     dd 0x0883, chip_ALC883
1279
                     dd 0x0887, chip_ALC887
1280
                     dd 0x0888, chip_ALC888
1281
                     dd 0x0889, chip_ALC889
1282
                     dd 0xFF
1283
3083 leency 1284
 
4324 Asper 1285
3083 leency 1286
 
4324 Asper 1287
                     dd 0x0397, chip_VT17085_0
1288
                     dd 0xFF
1289
3083 leency 1290
 
4324 Asper 1291
3083 leency 1292
 
4324 Asper 1293
                     dd 0x1040, chip_LSI1040
1294
                     dd 0x3026, chip_LSI3026
1295
                     dd 0x3055, chip_LSI3055
1296
                     dd 0xFF
1297
4320 yogev_ezra 1298
 
4324 Asper 1299
                     dd 0x198B, chip_AD198B
1300
                     dd 0xFF
1301
3083 leency 1302
 
4324 Asper 1303
3083 leency 1304
 
4324 Asper 1305
                     dd 0x5051, chip_CX20561
1306
                     dd 0xFF
1307
3083 leency 1308
 
4324 Asper 1309
chips_LG             dd 0xFF
1310
chips_Wolfson        dd 0xFF
1311
chips_Intel          dd 0xFF
1312
3083 leency 1313
 
4324 Asper 1314
                     dd 0x0020, chip_HDA_DUPLEX
1315
                     dd 0xFF
1316
3083 leency 1317
 
4324 Asper 1318
                     dd 0x7682, chip_STAC9221_A2
1319
                     dd 0xFF
1320
3083 leency 1321
 
1322
;AnalogDevices
1323
chip_AD1986A         db 'AD1986A',13,10,0
4324 Asper 1324
chip_AD198B          db 'AD198B',13,10,0
1325
3083 leency 1326
 
1327
chip_ATIR6XX         db 'ATIR6XX',13,10,0
4324 Asper 1328
3083 leency 1329
 
1330
chip_SI1392          db 'SI1392',13,10,0
4324 Asper 1331
3083 leency 1332
 
1333
chip_MCP78           db 'MCP78',13,10,0
4324 Asper 1334
3083 leency 1335
 
1336
chip_ALC262          db 'ALC262',13,10,0
4324 Asper 1337
chip_ALC268          db 'ALC268',13,10,0
1338
chip_ALC269          db 'ALC269',13,10,0
1339
chip_ALC272          db 'ALC272',13,10,0
1340
chip_ALC662          db 'ALC662',13,10,0
1341
chip_ALC663          db 'ALC663',13,10,0
1342
chip_ALC883          db 'ALC883',13,10,0
1343
chip_ALC887          db 'ALC887',13,10,0
1344
chip_ALC888          db 'ALC888',13,10,0
1345
chip_ALC889          db 'ALC889',13,10,0
1346
3083 leency 1347
 
1348
chip_STAC9221        db 'STAC9221',13,10,0
4324 Asper 1349
chip_STAC9221_A2     db 'STAC9221_A2',13,10,0
3083 leency 1350
1351
 
1352
chip_VT1708B_1       db 'VT1708B_1',13,10,0
4324 Asper 1353
chip_VT17085_0       db 'VT17085_0',13,10,0
1354
3083 leency 1355
 
1356
chip_CX20549         db 'CX20549',13,10,0
4324 Asper 1357
chip_CX20561         db 'CX20561',13,10,0
1358
3083 leency 1359
 
1360
chip_HDA_OUTPUT      db 'HDA-OUTPUT',13,10,0
1361
chip_HDA_DUPLEX      db 'HDA-DUPLEX',13,10,0
1362
1363
 
4320 yogev_ezra 1364
chip_LSI1039         db '1039 (Agere Systems HDA Modem)',13,10,0
4321 yogev_ezra 1365
chip_LSI1040         db '1040 (Agere Systems HDA Modem)',13,10,0
1366
chip_LSI3026         db '3026 (Agere Systems HDA Modem)',13,10,0
1367
chip_LSI3055         db '3055 (Agere Systems HDA Modem)',13,10,0
4324 Asper 1368