Subversion Repositories Kolibri OS

Rev

Rev 425 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
431 serge 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
3
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
4
;; Distributed under terms of the GNU General Public License    ;;
5
;;                                                              ;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
168 serge 7
 
8
format MS COFF
9
 
10
include 'proc32.inc'
281 serge 11
include 'imports.inc'
168 serge 12
 
13
DEBUG	    equ 1
14
 
15
CPU_FREQ    equ  2000d	 ;cpu freq in MHz
16
 
17
BIT0  EQU 0x00000001
18
BIT1  EQU 0x00000002
19
BIT2  EQU 0x00000004
20
BIT3  EQU 0x00000008
21
BIT4  EQU 0x00000010
22
BIT5  EQU 0x00000020
23
BIT6  EQU 0x00000040
24
BIT7  EQU 0x00000080
25
BIT8  EQU 0x00000100
26
BIT9  EQU 0x00000200
27
BIT10 EQU 0x00000400
28
BIT11 EQU 0x00000800
29
BIT12 EQU 0x00001000
30
BIT13 EQU 0x00002000
31
BIT14 EQU 0x00004000
32
BIT15 EQU 0x00008000
33
BIT16 EQU 0x00010000
34
BIT17 EQU 0x00020000
35
BIT18 EQU 0x00040000
36
BIT19 EQU 0x00080000
37
BIT20 EQU 0x00100000
38
BIT21 EQU 0x00200000
39
BIT22 EQU 0x00400000
40
BIT23 EQU 0x00800000
41
BIT24 EQU 0x00100000
42
BIT25 EQU 0x02000000
43
BIT26 EQU 0x04000000
44
BIT27 EQU 0x08000000
45
BIT28 EQU 0x10000000
46
BIT29 EQU 0x20000000
47
BIT30 EQU 0x40000000
48
BIT31 EQU 0x80000000
49
 
50
VID_SIS           equ 0x1039
51
CTRL_SIS          equ 0x7012
52
 
378 serge 53
PCM_OUT_BDL       equ  0x10  ; PCM out buffer descriptors list
54
PCM_OUT_CR_REG    equ  0x1b  ; PCM out Control Register
168 serge 55
PCM_OUT_LVI_REG   equ  0x15	 ; PCM last valid index
378 serge 56
PCM_OUT_SR_REG    equ  0x18  ; PCM out Status register
168 serge 57
PCM_OUT_PIV_REG   equ  0x1a	 ; PCM out prefetched index
58
PCM_OUT_CIV_REG   equ  0x14      ; PCM out current index
59
 
60
PCM_IN_CR_REG     equ  0x0b      ; PCM in Control Register
378 serge 61
MC_IN_CR_REG      equ  0x2b  ; MIC in Control Register
168 serge 62
RR		  equ  BIT1	 ; reset registers.  Nukes all regs
63
 
64
CODEC_MASTER_VOL_REG            equ     0x02
65
CODEC_AUX_VOL                   equ     0x04    ;
66
CODEC_PCM_OUT_REG		equ	18h	; PCM output volume
67
CODEC_EXT_AUDIO_REG		equ	28h	; extended audio
68
CODEC_EXT_AUDIO_CTRL_REG	equ	2ah	; extended audio control
69
CODEC_PCM_FRONT_DACRATE_REG	equ	2ch	; PCM out sample rate
70
CODEC_PCM_SURND_DACRATE_REG	equ	2eh	; surround sound sample rate
71
CODEC_PCM_LFE_DACRATE_REG	equ	30h	; LFE sample rate
72
 
73
 
378 serge 74
GLOB_CTRL         equ  0x2C        ;   Global Control
75
CTRL_STAT         equ  0x30        ;   Global Status
76
CTRL_CAS          equ  0x34        ;   Codec Access Semiphore
168 serge 77
 
378 serge 78
CAS_FLAG          equ  0x01        ;   Codec Access Semiphore Bit
168 serge 79
 
378 serge 80
CTRL_ST_CREADY    equ  BIT8+BIT9+BIT28 ;   Primary Codec Ready
168 serge 81
 
378 serge 82
CTRL_ST_RCS       equ  0x00008000  ;   Read Completion Status
168 serge 83
 
378 serge 84
CTRL_CNT_CRIE     equ  BIT4+BIT5+BIT6  ;   Codecs Resume Interrupt Enable
85
CTRL_CNT_AC_OFF   equ  0x00000008  ;   ACLINK Off
86
CTRL_CNT_WARM     equ  0x00000004  ;   AC97 Warm Reset
87
CTRL_CNT_COLD     equ  0x00000002  ;   AC97 Cold Reset
88
CTRL_CNT_GIE      equ  0x00000001  ;   GPI Interrupt Enable
168 serge 89
 
90
CODEC_REG_POWERDOWN   equ 0x26
378 serge 91
CODEC_REG_ST          equ 0x26
168 serge 92
 
93
 
94
DEV_PLAY              equ  1
95
DEV_STOP              equ  2
96
DEV_CALLBACK          equ  3
97
DEV_SET_BUFF          equ  4
98
DEV_NOTIFY            equ  5
99
DEV_SET_MASTERVOL     equ  6
100
DEV_GET_MASTERVOL     equ  7
101
DEV_GET_INFO          equ  8
102
 
103
struc AC_CNTRL		    ;AC controller base class
188 serge 104
{ .bus                dd ?
105
  .devfn              dd ?
168 serge 106
 
188 serge 107
  .vendor             dd ?
108
  .dev_id             dd ?
109
  .pci_cmd            dd ?
110
  .pci_stat           dd ?
168 serge 111
 
188 serge 112
  .codec_io_base      dd ?
113
  .codec_mem_base     dd ?
168 serge 114
 
188 serge 115
  .ctrl_io_base       dd ?
116
  .ctrl_mem_base      dd ?
117
  .cfg_reg            dd ?
118
  .int_line           dd ?
168 serge 119
 
188 serge 120
  .vendor_ids         dd ?    ;vendor id string
121
  .ctrl_ids           dd ?    ;hub id string
168 serge 122
 
188 serge 123
  .buffer             dd ?
168 serge 124
 
188 serge 125
  .notify_pos         dd ?
126
  .notify_task        dd ?
168 serge 127
 
188 serge 128
  .lvi_reg            dd ?
129
  .ctrl_setup         dd ?
130
  .user_callback      dd ?
131
  .codec_read16       dd ?
132
  .codec_write16      dd ?
168 serge 133
 
188 serge 134
  .ctrl_read8         dd ?
135
  .ctrl_read16        dd ?
136
  .ctrl_read32        dd ?
168 serge 137
 
188 serge 138
  .ctrl_write8        dd ?
139
  .ctrl_write16       dd ?
140
  .ctrl_write32       dd ?
168 serge 141
}
142
 
143
struc CODEC		   ;Audio Chip base class
144
{
188 serge 145
  .chip_id            dd ?
146
  .flags              dd ?
147
  .status             dd ?
168 serge 148
 
188 serge 149
  .ac_vendor_ids      dd ?    ;ac vendor id string
150
  .chip_ids           dd ?    ;chip model string
168 serge 151
 
188 serge 152
  .shadow_flag        dd ?
153
                      dd ?
168 serge 154
 
188 serge 155
  .regs               dw ?     ; codec registers
156
  .reg_master_vol     dw ?     ;0x02
157
  .reg_aux_out_vol    dw ?     ;0x04
158
  .reg_mone_vol       dw ?     ;0x06
159
  .reg_master_tone    dw ?     ;0x08
160
  .reg_beep_vol       dw ?     ;0x0A
161
  .reg_phone_vol      dw ?     ;0x0C
162
  .reg_mic_vol        dw ?     ;0x0E
163
  .reg_line_in_vol    dw ?     ;0x10
164
  .reg_cd_vol         dw ?     ;0x12
165
  .reg_video_vol      dw ?     ;0x14
166
  .reg_aux_in_vol     dw ?     ;0x16
167
  .reg_pcm_out_vol    dw ?     ;0x18
168
  .reg_rec_select     dw ?     ;0x1A
169
  .reg_rec_gain       dw ?     ;0x1C
170
  .reg_rec_gain_mic   dw ?     ;0x1E
171
  .reg_gen            dw ?     ;0x20
172
  .reg_3d_ctrl        dw ?     ;0X22
173
  .reg_page           dw ?     ;0X24
174
  .reg_powerdown      dw ?     ;0x26
175
  .reg_ext_audio      dw ?     ;0x28
176
  .reg_ext_st         dw ?     ;0x2a
177
  .reg_pcm_front_rate dw ?     ;0x2c
178
  .reg_pcm_surr_rate  dw ?     ;0x2e
179
  .reg_lfe_rate       dw ?     ;0x30
180
  .reg_pcm_in_rate    dw ?     ;0x32
181
                      dw ?     ;0x34
182
  .reg_cent_lfe_vol   dw ?     ;0x36
183
  .reg_surr_vol       dw ?     ;0x38
184
  .reg_spdif_ctrl     dw ?     ;0x3A
185
                      dw ?     ;0x3C
186
                      dw ?     ;0x3E
187
                      dw ?     ;0x40
188
                      dw ?     ;0x42
189
                      dw ?     ;0x44
190
                      dw ?     ;0x46
191
                      dw ?     ;0x48
192
                      dw ?     ;0x4A
193
                      dw ?     ;0x4C
194
                      dw ?     ;0x4E
195
                      dw ?     ;0x50
196
                      dw ?     ;0x52
197
                      dw ?     ;0x54
198
                      dw ?     ;0x56
199
                      dw ?     ;0x58
200
                      dw ?     ;0x5A
201
                      dw ?     ;0x5C
202
                      dw ?     ;0x5E
203
  .reg_page_0         dw ?     ;0x60
204
  .reg_page_1         dw ?     ;0x62
205
  .reg_page_2         dw ?     ;0x64
206
  .reg_page_3         dw ?     ;0x66
207
  .reg_page_4         dw ?     ;0x68
208
  .reg_page_5         dw ?     ;0x6A
209
  .reg_page_6         dw ?     ;0x6C
210
  .reg_page_7         dw ?     ;0x6E
211
                      dw ?     ;0x70
212
                      dw ?     ;0x72
213
                      dw ?     ;0x74
214
                      dw ?     ;0x76
215
                      dw ?     ;0x78
216
                      dw ?     ;0x7A
217
  .reg_vendor_id_1    dw ?     ;0x7C
218
  .reg_vendor_id_2    dw ?     ;0x7E
168 serge 219
 
220
 
188 serge 221
  .reset              dd ?    ;virual
222
  .set_master_vol     dd ?
168 serge 223
}
224
 
225
struc CTRL_INFO
378 serge 226
{   .pci_cmd          dd ?
227
    .irq              dd ?
228
    .glob_cntrl       dd ?
229
    .glob_sta         dd ?
230
    .codec_io_base    dd ?
231
    .ctrl_io_base     dd ?
232
    .codec_mem_base   dd ?
233
    .ctrl_mem_base    dd ?
234
    .codec_id         dd ?
168 serge 235
}
236
 
237
struc IOCTL
378 serge 238
{  .handle            dd ?
239
   .io_code           dd ?
240
   .input             dd ?
241
   .inp_size          dd ?
242
   .output            dd ?
243
   .out_size          dd ?
168 serge 244
}
245
 
246
virtual at 0
247
  IOCTL IOCTL
248
end virtual
249
 
250
EVENT_NOTIFY	      equ 0x00000200
251
 
378 serge 252
OS_BASE            equ 0;  0x80400000
380 serge 253
SLOT_BASE          equ OS_BASE+0x0080000
378 serge 254
new_app_base       equ 0x80000000
168 serge 255
 
188 serge 256
public START
168 serge 257
public service_proc
227 serge 258
public version
168 serge 259
 
188 serge 260
section '.flat' code readable align 16
261
 
214 serge 262
proc START stdcall, state:dword
263
 
227 serge 264
           cmp [state], 1
265
           jne .stop
266
 
168 serge 267
     if DEBUG
227 serge 268
           mov esi, msgInit
188 serge 269
           call SysMsgBoardStr
168 serge 270
     end if
271
 
227 serge 272
           call detect_controller
273
           test eax, eax
274
           jz .fail
168 serge 275
 
276
     if DEBUG
277
           mov esi,[ctrl.vendor_ids]
188 serge 278
           call SysMsgBoardStr
168 serge 279
           mov  esi, [ctrl.ctrl_ids]
188 serge 280
           call SysMsgBoardStr
168 serge 281
     end if
282
 
227 serge 283
           call init_controller
284
           test eax, eax
285
           jz .fail
168 serge 286
 
287
     if DEBUG
288
           mov esi, msgInitCodec
188 serge 289
           call SysMsgBoardStr
168 serge 290
     end if
291
 
292
	   call init_codec
293
           test eax, eax
294
           jz .fail
295
 
296
     if DEBUG
227 serge 297
           mov esi, [codec.ac_vendor_ids]
188 serge 298
           call SysMsgBoardStr
168 serge 299
 
227 serge 300
           mov esi, [codec.chip_ids]
188 serge 301
           call SysMsgBoardStr
168 serge 302
     end if
303
 
227 serge 304
           call reset_controller
168 serge 305
           call setup_codec
306
 
307
           mov esi, msgPrimBuff
188 serge 308
           call SysMsgBoardStr
168 serge 309
 
227 serge 310
           call create_primary_buff
168 serge 311
 
188 serge 312
           stdcall AttachIntHandler, [ctrl.int_line], ac97_irq
168 serge 313
 
188 serge 314
           stdcall RegService, sz_sound_srv, service_proc
168 serge 315
 
316
           mov esi, msgOk
188 serge 317
           call SysMsgBoardStr
227 serge 318
           ret
168 serge 319
.fail:
320
   if DEBUG
227 serge 321
           mov esi, msgFail
188 serge 322
           call SysMsgBoardStr
168 serge 323
   end if
214 serge 324
           xor eax, eax
325
           ret
326
.stop:
327
           call stop
227 serge 328
           xor eax, eax
214 serge 329
           ret
330
endp
168 serge 331
 
332
handle     equ  IOCTL.handle
333
io_code    equ  IOCTL.io_code
334
input      equ  IOCTL.input
335
inp_size   equ  IOCTL.inp_size
336
output     equ  IOCTL.output
337
out_size   equ  IOCTL.out_size
338
 
339
align 4
340
proc service_proc stdcall, ioctl:dword
341
 
342
           mov edi, [ioctl]
343
           mov eax, [edi+io_code]
227 serge 344
           cmp eax, DEV_PLAY
345
           jne @F
168 serge 346
     if DEBUG
227 serge 347
           mov esi, msgPlay
188 serge 348
           call SysMsgBoardStr
168 serge 349
     end if
227 serge 350
           call play
351
           ret
168 serge 352
@@:
227 serge 353
           cmp eax, DEV_STOP
354
           jne @F
168 serge 355
     if DEBUG
227 serge 356
           mov esi, msgStop
188 serge 357
           call SysMsgBoardStr
168 serge 358
     end if
227 serge 359
           call stop
360
           ret
168 serge 361
@@:
227 serge 362
           cmp eax, DEV_CALLBACK
363
           jne @F
168 serge 364
           mov ebx, [edi+input]
365
           stdcall set_callback, [ebx]
227 serge 366
           ret
168 serge 367
@@:
227 serge 368
           cmp eax, DEV_SET_MASTERVOL
369
           jne @F
378 serge 370
           mov eax, [edi+input]
371
           mov eax, [eax]
372
           call set_master_vol      ;eax= vol
227 serge 373
           ret
168 serge 374
@@:
227 serge 375
           cmp eax, DEV_GET_MASTERVOL
376
           jne @F
168 serge 377
           mov ebx, [edi+output]
378 serge 378
           add ebx, new_app_base
168 serge 379
           stdcall get_master_vol, ebx
227 serge 380
           ret
168 serge 381
@@:
227 serge 382
           cmp eax, DEV_GET_INFO
383
           jne @F
168 serge 384
           mov ebx, [edi+output]
227 serge 385
           stdcall get_dev_info, ebx
386
           ret
168 serge 387
@@:
388
.fail:
378 serge 389
           or eax, -1
227 serge 390
           ret
168 serge 391
endp
392
 
393
restore   handle
394
restore   io_code
395
restore   input
396
restore   inp_size
397
restore   output
398
restore   out_size
399
 
400
align 4
401
proc ac97_irq
402
 
403
;     if DEBUG
404
;           mov esi, msgIRQ
188 serge 405
;           call SysMsgBoardStr
168 serge 406
;     end if
407
 
227 serge 408
           mov edx, PCM_OUT_CR_REG
378 serge 409
           mov al, 0x10
227 serge 410
           call [ctrl.ctrl_write8]
168 serge 411
 
227 serge 412
           mov ax, 0x1c
413
           mov edx, PCM_OUT_SR_REG
414
           call [ctrl.ctrl_write16]
168 serge 415
 
416
           mov edx, PCM_OUT_CIV_REG
227 serge 417
           call [ctrl.ctrl_read8]
168 serge 418
 
419
           and eax, 0x1F
420
           cmp eax, [civ_val]
421
           je .skip
422
 
423
           mov [civ_val], eax
227 serge 424
           dec eax
425
           and eax, 0x1F
426
           mov [ctrl.lvi_reg], eax
168 serge 427
 
227 serge 428
           mov edx, PCM_OUT_LVI_REG
429
           call [ctrl.ctrl_write8]
168 serge 430
 
227 serge 431
           mov edx, PCM_OUT_CR_REG
378 serge 432
           mov ax, 0x11
227 serge 433
           call [ctrl.ctrl_write8]
168 serge 434
 
435
           mov eax, [civ_val]
378 serge 436
           add eax, 1
227 serge 437
           and eax, 31
438
           mov ebx, dword [buff_list+eax*4]
168 serge 439
 
227 serge 440
           cmp [ctrl.user_callback], 0
441
           je @f
168 serge 442
 
227 serge 443
           stdcall [ctrl.user_callback], ebx
168 serge 444
@@:
227 serge 445
           ret
168 serge 446
 
447
.skip:
227 serge 448
           mov edx, PCM_OUT_CR_REG
378 serge 449
           mov ax, 0x11
227 serge 450
           call [ctrl.ctrl_write8]
168 serge 451
           ret
452
endp
453
 
454
align 4
455
proc create_primary_buff
456
 
188 serge 457
           stdcall KernelAlloc, 0x10000
227 serge 458
           mov [ctrl.buffer], eax
168 serge 459
 
460
           mov edi, eax
461
           mov ecx, 0x10000/4
462
           xor eax, eax
378 serge 463
           cld
168 serge 464
           rep stosd
465
 
285 serge 466
           mov eax, [ctrl.buffer]
467
           call GetPgAddr
168 serge 468
 
227 serge 469
           mov ebx, 0xC0004000
470
           mov ecx, 4
471
           mov edi, pcmout_bdl
168 serge 472
@@:
227 serge 473
           mov [edi], eax
474
           mov [edi+4], ebx
475
           mov [edi+32], eax
476
           mov [edi+4+32], ebx
477
           mov [edi+64], eax
478
           mov [edi+4+64], ebx
479
           mov [edi+96], eax
480
           mov [edi+4+96], ebx
481
           mov [edi+128], eax
482
           mov [edi+4+128], ebx
483
           mov [edi+160], eax
484
           mov [edi+4+160], ebx
485
           mov [edi+192], eax
486
           mov [edi+4+192], ebx
487
           mov [edi+224], eax
488
           mov [edi+4+224], ebx
168 serge 489
 
227 serge 490
           add eax, 0x4000
491
           add edi, 8
492
           loop @B
168 serge 493
 
227 serge 494
           mov edi, buff_list
495
           mov eax, [ctrl.buffer]
496
           mov ecx, 4
168 serge 497
@@:
227 serge 498
           mov [edi], eax
499
           mov [edi+16], eax
500
           mov [edi+32], eax
501
           mov [edi+48], eax
502
           mov [edi+64], eax
503
           mov [edi+80], eax
504
           mov [edi+96], eax
505
           mov [edi+112], eax
168 serge 506
 
227 serge 507
           add eax, 0x4000
508
           add edi, 4
509
           loop @B
168 serge 510
 
285 serge 511
           mov eax, pcmout_bdl
512
           mov ebx, eax
513
           call GetPgAddr     ;eax
514
           and ebx, 0xFFF
515
           add eax, ebx
168 serge 516
 
227 serge 517
           mov edx, PCM_OUT_BDL
518
           call [ctrl.ctrl_write32]
168 serge 519
 
227 serge 520
           mov eax, 16
521
           mov [ctrl.lvi_reg], eax
522
           mov edx, PCM_OUT_LVI_REG
523
           call [ctrl.ctrl_write8]
168 serge 524
 
525
           mov edx, GLOB_CTRL
526
           call [ctrl.ctrl_read32]
527
           and eax, not 0x000000C0
528
           mov edx, GLOB_CTRL
529
           call [ctrl.ctrl_write32]
530
 
531
 
532
	   ret
533
endp
534
 
535
align 4
536
proc detect_controller
227 serge 537
           locals
538
             last_bus dd ?
539
             bus      dd ?
540
             devfn    dd ?
541
           endl
168 serge 542
 
227 serge 543
           xor eax, eax
544
           mov [bus], eax
545
           inc eax
188 serge 546
           call PciApi
227 serge 547
           cmp eax, -1
548
           je .err
168 serge 549
 
550
           mov [last_bus], eax
551
 
552
.next_bus:
227 serge 553
           and [devfn], 0
168 serge 554
.next_dev:
188 serge 555
           stdcall PciRead32, [bus], [devfn], dword 0
227 serge 556
           test eax, eax
557
           jz .next
558
           cmp eax, -1
559
           je .next
560
           mov edi, devices
168 serge 561
@@:
227 serge 562
           mov ebx, [edi]
563
           test ebx, ebx
564
           jz .next
168 serge 565
 
227 serge 566
           cmp eax, ebx
567
           je .found
568
           add edi, 12
569
           jmp @B
168 serge 570
 
227 serge 571
.next:
572
           inc [devfn]
573
           cmp [devfn], 256
574
           jb  .next_dev
575
           mov eax, [bus]
576
           inc eax
577
           mov [bus], eax
578
           cmp eax, [last_bus]
579
           jna .next_bus
580
           xor eax, eax
581
           ret
168 serge 582
.found:
227 serge 583
           mov ebx, [bus]
584
           mov [ctrl.bus], ebx
168 serge 585
 
227 serge 586
           mov ecx, [devfn]
587
           mov [ctrl.devfn], ecx
168 serge 588
 
227 serge 589
           mov edx, eax
590
           and edx, 0xFFFF
591
           mov [ctrl.vendor], edx
592
           shr eax, 16
593
           mov [ctrl.dev_id], eax
168 serge 594
 
227 serge 595
           mov ebx, [edi+4]
596
           mov [ctrl.ctrl_ids], ebx
597
           mov [ctrl.vendor_ids], msg_SIS
168 serge 598
 
227 serge 599
           mov esi, [edi+8]
600
           mov [ctrl.ctrl_setup], esi
601
           ret
168 serge 602
.err:
227 serge 603
           xor eax, eax
604
           ret
168 serge 605
endp
606
 
607
align 4
608
proc init_controller
609
 
188 serge 610
           stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 4
227 serge 611
           mov ebx, eax
612
           and eax, 0xFFFF
613
           mov [ctrl.pci_cmd], eax
614
           shr ebx, 16
615
           mov [ctrl.pci_stat], ebx
168 serge 616
 
188 serge 617
           stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x10
227 serge 618
           and eax,0xFFFE
619
           mov [ctrl.codec_io_base], eax
168 serge 620
 
188 serge 621
           stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x14
227 serge 622
           and eax, 0xFFC0
623
           mov [ctrl.ctrl_io_base], eax
168 serge 624
 
188 serge 625
           stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x18
227 serge 626
           mov [ctrl.codec_mem_base], eax
168 serge 627
 
188 serge 628
           stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x1C
227 serge 629
           mov [ctrl.ctrl_mem_base], eax
168 serge 630
 
188 serge 631
           stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x3C
227 serge 632
           and eax, 0xFF
633
           mov [ctrl.int_line], eax
168 serge 634
 
188 serge 635
           stdcall PciRead8, [ctrl.bus], [ctrl.devfn], dword 0x41
227 serge 636
           and eax, 0xFF
637
           mov [ctrl.cfg_reg], eax
168 serge 638
 
227 serge 639
           call [ctrl.ctrl_setup]
640
           xor eax, eax
641
           inc eax
642
           ret
168 serge 643
endp
644
 
645
align 4
646
proc set_SIS
227 serge 647
           mov [ctrl.codec_read16],  codec_io_r16    ;virtual
648
           mov [ctrl.codec_write16], codec_io_w16    ;virtual
168 serge 649
 
227 serge 650
           mov [ctrl.ctrl_read8 ],  ctrl_io_r8      ;virtual
651
           mov [ctrl.ctrl_read16],  ctrl_io_r16      ;virtual
652
           mov [ctrl.ctrl_read32],  ctrl_io_r32      ;virtual
168 serge 653
 
227 serge 654
           mov [ctrl.ctrl_write8 ], ctrl_io_w8      ;virtual
655
           mov [ctrl.ctrl_write16], ctrl_io_w16      ;virtual
656
           mov [ctrl.ctrl_write32], ctrl_io_w32      ;virtual
657
           ret
168 serge 658
endp
659
 
660
align 4
661
proc reset_controller
662
 
227 serge 663
           xor eax, eax
664
           mov edx, PCM_IN_CR_REG
665
           call [ctrl.ctrl_write8]
168 serge 666
 
227 serge 667
           mov edx, PCM_OUT_CR_REG
668
           call [ctrl.ctrl_write8]
168 serge 669
 
227 serge 670
           mov edx, MC_IN_CR_REG
671
           call [ctrl.ctrl_write8]
168 serge 672
 
227 serge 673
           mov eax, RR
674
           mov edx, PCM_IN_CR_REG
675
           call [ctrl.ctrl_write8]
168 serge 676
 
227 serge 677
           mov edx, PCM_OUT_CR_REG
678
           call [ctrl.ctrl_write8]
168 serge 679
 
227 serge 680
           mov edx, MC_IN_CR_REG
681
           call [ctrl.ctrl_write8]
682
           ret
168 serge 683
endp
684
 
685
align 4
686
proc init_codec
233 serge 687
           locals
688
             counter dd ?
689
           endl
168 serge 690
 
247 serge 691
           mov esi, msgControl
692
           call SysMsgBoardStr
693
 
694
           mov edx, GLOB_CTRL
695
           call [ctrl.ctrl_read32]
696
           call dword2str
697
           call SysMsgBoardStr
698
 
699
           mov esi, msgStatus
700
           call SysMsgBoardStr
701
 
233 serge 702
           mov edx, CTRL_STAT
703
           call [ctrl.ctrl_read32]
247 serge 704
 
705
           call dword2str
706
           call SysMsgBoardStr
707
 
233 serge 708
           test eax, CTRL_ST_CREADY
709
           jnz .ready
168 serge 710
 
233 serge 711
           call reset_codec
712
           and eax, eax
713
           jz .err
168 serge 714
 
233 serge 715
           xor edx, edx     ;ac_reg_0
716
           call [ctrl.codec_write16]
168 serge 717
 
233 serge 718
           xor eax, eax
719
           mov edx, CODEC_REG_POWERDOWN
720
           call [ctrl.codec_write16]
721
 
722
           mov [counter], 200     ; total 200*5 ms = 1s
168 serge 723
.wait:
233 serge 724
           mov edx, CODEC_REG_POWERDOWN
725
           call [ctrl.codec_read16]
726
           and eax, 0x0F
727
           cmp eax, 0x0F
728
           je .ready
168 serge 729
 
233 serge 730
           mov eax, 5000          ; wait 5 ms
731
           call StallExec
732
           sub [counter] , 1
733
           jnz .wait
168 serge 734
.err:
233 serge 735
           xor eax, eax        ; timeout error
736
           ret
168 serge 737
.ready:
233 serge 738
           call detect_codec
168 serge 739
 
233 serge 740
           xor eax, eax
741
           inc eax
742
           ret
168 serge 743
endp
744
 
745
align 4
746
proc reset_codec
227 serge 747
           mov edx, GLOB_CTRL
748
           call [ctrl.ctrl_read32]
168 serge 749
 
750
           test eax, 0x02
751
           jz .cold
752
 
753
           call warm_reset
754
           jnc .ok
755
.cold:
227 serge 756
           call cold_reset
757
           jnc .ok
168 serge 758
 
759
     if DEBUG
227 serge 760
           mov esi, msgCFail
188 serge 761
           call SysMsgBoardStr
168 serge 762
     end if
227 serge 763
           xor eax, eax     ; timeout error
764
           ret
168 serge 765
.ok:
766
           xor eax, eax
227 serge 767
           inc eax
768
           ret
168 serge 769
endp
770
 
771
align 4
772
proc warm_reset
227 serge 773
           locals
774
             counter dd ?
775
           endl
168 serge 776
 
227 serge 777
           mov eax, 0x06
778
           mov edx, GLOB_CTRL
779
           call [ctrl.ctrl_write32]
168 serge 780
 
781
     if DEBUG
227 serge 782
           mov esi, msgWarm
188 serge 783
           call SysMsgBoardStr
168 serge 784
     end if
785
 
227 serge 786
           mov [counter], 10    ; total 10*100 ms = 1s
168 serge 787
.wait:
227 serge 788
           mov eax, 100000    ; wait 100 ms
789
           call StallExec
168 serge 790
 
227 serge 791
           mov edx, GLOB_CTRL
792
           call [ctrl.ctrl_read32]
793
           test eax, 4
794
           jz .ok
795
           sub [counter], 1
796
           jnz .wait
168 serge 797
 
798
     if DEBUG
227 serge 799
           mov esi, msgWRFail
188 serge 800
           call SysMsgBoardStr
168 serge 801
     end if
227 serge 802
           stc
803
           ret
168 serge 804
.ok:
227 serge 805
           mov edx, CTRL_STAT
806
           call [ctrl.ctrl_read32]
807
           and eax, CTRL_ST_CREADY
168 serge 808
           jz .fail
809
           clc
227 serge 810
           ret
168 serge 811
.fail:
812
           stc
227 serge 813
           ret
168 serge 814
endp
815
 
816
align 4
817
proc cold_reset
227 serge 818
           locals
819
             counter dd ?
820
            endl
168 serge 821
 
227 serge 822
           mov edx, GLOB_CTRL
233 serge 823
           call [ctrl.ctrl_read32]
824
           and eax, not 0x08
825
           or eax, 0x02
826
           mov edx, GLOB_CTRL
227 serge 827
           call [ctrl.ctrl_write32]
168 serge 828
 
829
     if DEBUG
227 serge 830
           mov esi, msgCold
188 serge 831
           call SysMsgBoardStr
168 serge 832
     end if
833
 
227 serge 834
           mov [counter], 10    ; total 10*100 ms = 1s
168 serge 835
.wait:
227 serge 836
           mov eax, 100000    ; wait 100 ms
837
           call StallExec
168 serge 838
 
227 serge 839
           mov edx, GLOB_CTRL
840
           call [ctrl.ctrl_read32]
841
           test eax, 4
842
           jz .ok
843
           sub [counter], 1
844
           jnz .wait
168 serge 845
 
846
     if DEBUG
227 serge 847
           mov esi, msgCRFail
188 serge 848
           call SysMsgBoardStr
168 serge 849
     end if
233 serge 850
.fail:
227 serge 851
           stc
852
           ret
168 serge 853
.ok:
227 serge 854
           mov edx, CTRL_STAT
855
           call [ctrl.ctrl_read32]
856
           and eax, CTRL_ST_CREADY
168 serge 857
           jz .fail
858
           clc
227 serge 859
           ret
168 serge 860
endp
861
 
862
align 4
863
proc play
864
           xor eax, eax
865
           mov [civ_val], eax
866
           mov edx, PCM_OUT_CIV_REG
227 serge 867
           call [ctrl.ctrl_write8]
168 serge 868
 
227 serge 869
           mov eax, 16
870
           mov [ctrl.lvi_reg], eax
871
           mov edx, PCM_OUT_LVI_REG
872
           call [ctrl.ctrl_write8]
168 serge 873
 
227 serge 874
           mov edx, PCM_OUT_CR_REG
875
           mov ax, 0x1D
876
           call [ctrl.ctrl_write8]
877
           ret
168 serge 878
endp
879
 
880
align 4
881
proc stop
227 serge 882
           mov edx, PCM_OUT_CR_REG
883
           mov ax, 0x0
884
           call [ctrl.ctrl_write8]
168 serge 885
 
227 serge 886
           mov ax, 0x1c
887
           mov edx, PCM_OUT_SR_REG
888
           call [ctrl.ctrl_write16]
889
           ret
168 serge 890
endp
891
 
892
align 4
893
proc get_dev_info stdcall, p_info:dword
894
           virtual at esi
895
             CTRL_INFO CTRL_INFO
896
           end virtual
897
 
898
           mov esi, [p_info]
899
           mov eax, [ctrl.int_line]
900
           mov ebx, [ctrl.codec_io_base]
901
           mov ecx, [ctrl.ctrl_io_base]
902
           mov edx, [ctrl.codec_mem_base]
903
           mov edi, [ctrl.ctrl_mem_base]
904
 
905
           mov [CTRL_INFO.irq], eax
906
           mov [CTRL_INFO.codec_io_base], ebx
907
           mov [CTRL_INFO.ctrl_io_base], ecx
908
           mov [CTRL_INFO.codec_mem_base], edx
909
           mov [CTRL_INFO.ctrl_mem_base], edi
910
 
911
           mov eax, [codec.chip_id]
912
           mov [CTRL_INFO.codec_id], eax
913
 
914
           mov edx, GLOB_CTRL
915
           call [ctrl.ctrl_read32]
916
           mov [CTRL_INFO.glob_cntrl], eax
917
 
918
           mov edx, CTRL_STAT
919
           call [ctrl.ctrl_read32]
920
           mov [CTRL_INFO.glob_sta], eax
921
 
922
           mov ebx, [ctrl.pci_cmd]
923
           mov [CTRL_INFO.pci_cmd], ebx
924
 
925
           ret
926
endp
927
 
928
align 4
929
proc set_callback stdcall, handler:dword
227 serge 930
           mov eax, [handler]
931
           mov [ctrl.user_callback], eax
932
           ret
168 serge 933
endp
934
 
935
align 4
936
proc codec_read stdcall, ac_reg:dword	   ; reg = edx, reval = eax
937
 
227 serge 938
           mov edx, [ac_reg]
168 serge 939
 
227 serge 940
           mov ebx, edx
941
           shr ebx, 1
942
           bt [codec.shadow_flag], ebx
943
           jc .use_shadow
168 serge 944
 
227 serge 945
           call [ctrl.codec_read16]  ;change edx !!!
946
           mov ecx, eax
168 serge 947
 
948
           mov edx, CTRL_STAT
227 serge 949
           call [ctrl.ctrl_read32]
950
           test eax, CTRL_ST_RCS
951
           jz .read_ok
168 serge 952
 
953
           mov edx, CTRL_STAT
227 serge 954
           call [ctrl.ctrl_write32]
955
           xor eax,eax
956
           not eax  ;timeout
957
           ret
168 serge 958
.read_ok:
227 serge 959
           mov edx, [ac_reg]
960
           mov [codec.regs+edx], cx
961
           bts [codec.shadow_flag], ebx
962
           mov eax, ecx
963
           ret
168 serge 964
.use_shadow:
227 serge 965
           movzx eax, word [codec.regs+edx]
966
           ret
168 serge 967
endp
968
 
969
align 4
970
proc codec_write stdcall, ac_reg:dword
227 serge 971
           push eax
972
           call check_semafore
973
           and eax, eax
974
           jz .err
975
           pop eax
168 serge 976
 
227 serge 977
           mov esi, [ac_reg]
978
           mov edx, esi
979
           call [ctrl.codec_write16]
980
           mov [codec.regs+esi], ax
981
           shr esi, 1
982
           bts [codec.shadow_flag], esi
983
           ret
168 serge 984
.err:
227 serge 985
           pop eax
986
           ret
168 serge 987
endp
988
 
989
 
990
align 4
991
proc codec_check_ready
992
 
227 serge 993
           mov edx, CTRL_ST
994
           call [ctrl.ctrl_read32]
995
           and eax, CTRL_ST_CREADY
996
           jz .not_ready
168 serge 997
 
227 serge 998
           xor eax, wax
999
           inc eax
1000
           ret
168 serge 1001
 
1002
align 4
1003
.not_ready:
227 serge 1004
           xor eax, eax
1005
           ret
168 serge 1006
endp
1007
 
1008
 
1009
align 4
1010
proc check_semafore
227 serge 1011
           local counter:DWORD
168 serge 1012
 
227 serge 1013
           mov [counter], 100
168 serge 1014
.l1:
227 serge 1015
           mov edx, CTRL_CAS
1016
           call [ctrl.ctrl_read8]
1017
           and eax, CAS_FLAG
1018
           jz .ok
168 serge 1019
 
227 serge 1020
           mov eax, 1
1021
           call StallExec
1022
           sub [counter], 1
1023
           jnz .l1
1024
           xor eax, eax
1025
           ret
168 serge 1026
align 4
1027
.ok:
227 serge 1028
           xor eax,eax
1029
           inc eax
1030
           ret
168 serge 1031
endp
1032
 
1033
align 4
1034
proc StallExec
227 serge 1035
           push ecx
1036
           push edx
1037
           push ebx
1038
           push eax
168 serge 1039
 
227 serge 1040
           mov ecx, CPU_FREQ
1041
           mul ecx
1042
           mov ebx, eax       ;low
1043
           mov ecx, edx       ;high
1044
           rdtsc
1045
           add ebx, eax
233 serge 1046
           adc ecx, edx
168 serge 1047
@@:
227 serge 1048
           rdtsc
1049
           sub eax, ebx
1050
           sbb edx, ecx
233 serge 1051
           js @B
168 serge 1052
 
227 serge 1053
           pop eax
1054
           pop ebx
1055
           pop edx
1056
           pop ecx
1057
           ret
168 serge 1058
endp
1059
 
1060
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1061
;          CONTROLLER IO functions
1062
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1063
 
1064
align 4
1065
proc codec_io_r16
227 serge 1066
           add edx, [ctrl.codec_io_base]
1067
           in  ax, dx
1068
           ret
168 serge 1069
endp
1070
 
1071
align 4
1072
proc codec_io_w16
227 serge 1073
           add edx, [ctrl.codec_io_base]
1074
           out dx, ax
1075
           ret
168 serge 1076
endp
1077
 
1078
align 4
1079
proc ctrl_io_r8
227 serge 1080
           add edx, [ctrl.ctrl_io_base]
1081
           in  al, dx
1082
           ret
168 serge 1083
endp
1084
 
1085
align 4
1086
proc ctrl_io_r16
227 serge 1087
           add edx, [ctrl.ctrl_io_base]
1088
           in  ax, dx
1089
           ret
168 serge 1090
endp
1091
 
1092
align 4
1093
proc ctrl_io_r32
227 serge 1094
           add edx, [ctrl.ctrl_io_base]
1095
           in  eax, dx
1096
           ret
168 serge 1097
endp
1098
 
1099
align 4
1100
proc ctrl_io_w8
227 serge 1101
           add edx, [ctrl.ctrl_io_base]
1102
           out dx, al
1103
           ret
168 serge 1104
endp
1105
 
1106
align 4
1107
proc ctrl_io_w16
227 serge 1108
           add edx, [ctrl.ctrl_io_base]
1109
           out dx, ax
1110
           ret
168 serge 1111
endp
1112
 
1113
align 4
1114
proc ctrl_io_w32
227 serge 1115
           add edx, [ctrl.ctrl_io_base]
1116
           out dx, eax
1117
           ret
168 serge 1118
endp
1119
 
247 serge 1120
align 4
1121
dword2str:
1122
      mov  esi, hex_buff
1123
      mov ecx, -8
1124
@@:
1125
      rol eax, 4
1126
      mov ebx, eax
1127
      and ebx, 0x0F
1128
      mov bl, [ebx+hexletters]
1129
      mov [8+esi+ecx], bl
1130
      inc ecx
1131
      jnz @B
1132
      ret
1133
 
1134
 
168 serge 1135
include "codec.inc"
1136
 
188 serge 1137
align 4
168 serge 1138
devices dd (CTRL_SIS  shl 16)+VID_SIS,msg_AC, set_SIS
247 serge 1139
        dd 0
168 serge 1140
 
378 serge 1141
version      dd 0x00040004
168 serge 1142
 
227 serge 1143
msg_AC       db '7012 AC97 controller',13,10, 0
1144
msg_SIS      db 'Silicon Integrated Systems',13,10, 0
1145
 
168 serge 1146
sz_sound_srv	    db 'SOUND',0
1147
 
1148
msgInit      db 'detect hardware...',13,10,0
1149
msgFail      db 'device not found',13,10,0
1150
msgPlay      db 'start play', 13,10,0
1151
msgStop      db 'stop play',  13,10,0
1152
msgNotify    db 'call notify',13,10,0
227 serge 1153
msgIRQ       db 'AC97 IRQ', 13,10,0
168 serge 1154
msgInitCtrl  db 'init controller',13,10,0
1155
msgInitCodec db 'init codec',13,10,0
1156
msgPrimBuff  db 'create primary buffer',13,10,0
1157
msgReg       db 'set service handler',13,10,0
1158
msgOk        db 'service installed',13,10,0
1159
msgCold      db 'cold resret',13,10,0
1160
msgWarm      db 'warm reset',13,10,0
1161
msgWRFail    db 'warm reset failed',13,10,0
1162
msgCRFail    db 'cold reset failed',13,10,0
1163
msgCFail     db 'codec not ready',13,10,0
247 serge 1164
msgStatus    db 'global status   ',0
1165
msgControl   db 'global control  ',0
188 serge 1166
 
247 serge 1167
hexletters   db '0123456789ABCDEF'
1168
hex_buff     db 8 dup(0),13,10,0
1169
 
1170
 
188 serge 1171
section '.data' data readable writable align 16
1172
 
1173
pcmout_bdl       rq 32
1174
buff_list        rd 32
1175
 
1176
codec CODEC
1177
ctrl AC_CNTRL
1178
 
1179
lpc_bus  rd 1
1180
civ_val  rd 1