Subversion Repositories Kolibri OS

Rev

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

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