2
* Purpose: Driver for Crystal PCI audio controller.
6
* This file is part of Open Sound System.
8
* Copyright (C) 4Front Technologies 1996-2008.
10
* This this source file is released under GPL v2 license (no other versions).
11
* See the COPYING file included in the main directory of this source
12
* distribution for the license terms and conditions.
16
#include "oss_cs4281_cfg.h"
17
#include "midi_core.h"
22
#define CRYSTAL_VENDOR_ID 0x1013
23
#define CRYSTAL_CS4281_ID 0x6005
26
#define WRITEB(a,d) devc->bRegister0[a] = d
27
#define READB(a) devc->bRegister0[a]
28
#define WRITEW(a,d) devc->wRegister0[a>>1] = d
29
#define READW(a) devc->wRegister0[a>>1]
30
#define READL(a) (devc->dwRegister0[a>>2])
31
#define WRITEL(a, d) devc->dwRegister0[a>>2] = d
33
#define WRITEB(a,d) PCI_WRITEB(devc->osdev, d, devc->bRegister0[a])
34
#define READB(a) PCI_READB(devc->osdev, devc->bRegister0[a])
35
#define WRITEW(a,d) PCI_WRITEW(devc->osdev, d, devc->wRegister0[a>>1])
36
#define READW(a) PCI_READW(devc->osdev, devc->wRegister0[a>>1])
37
#define READL(a) PCI_READL(devc->osdev, devc->dwRegister0[a>>2])
38
#define WRITEL(a, d) PCI_WRITEL(devc->osdev, d, devc->dwRegister0[a>>2])
43
be_swap (unsigned int x)
45
return ((x & 0x000000ff) << 24) |
46
((x & 0x0000ff00) << 8) |
47
((x & 0x00ff0000) >> 8) | ((x & 0xff000000) >> 24);
50
#define LSWAP(x) be_swap(x)
57
typedef struct cs4281_portc
59
int speed, bits, channels;
67
typedef struct cs4281_devc
71
oss_native_word bar0addr, bar1addr;
72
unsigned int *bar0virt, *bar1virt;
73
volatile unsigned int *dwRegister0, *dwRegister1;
74
volatile unsigned short *wRegister0, *wRegister1;
75
volatile unsigned char *bRegister0, *bRegister1;
77
volatile unsigned char intr_mask;
79
oss_mutex_t low_mutex;
84
oss_midi_inputbyte_t midi_input_intr;
86
/* Mixer parameters */
90
/* Audio parameters */
91
cs4281_portc portc[MAX_PORTC];
93
int fm_attached, mpu_attached;
100
ac97_read (void *devc_, int reg)
102
cs4281_devc *devc = devc_;
104
oss_native_word status, value;
105
oss_native_word flags;
107
MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
109
* Make sure that there is not data sitting around from a previous
110
* uncompleted access. ACSDA = Status Data Register = 47Ch
112
status = READL (BA0_ACSDA);
113
/* Get the actual AC97 register from the offset */
114
WRITEL (BA0_ACCAD, reg);
115
WRITEL (BA0_ACCDA, 0);
116
WRITEL (BA0_ACCTL, ACCTL_DCV | ACCTL_CRW | ACCTL_VFRM | ACCTL_ESYN);
118
/* Wait for the read to occur. */
119
for (count = 0; count < 500; count++)
121
/* First, we want to wait for a short time. */
124
* Now, check to see if the read has completed.
125
* ACCTL = 460h, DCV should be reset by now and 460h = 17h
127
status = READL (BA0_ACCTL);
128
if (!(status & ACCTL_DCV))
134
/* Make sure the read completed. */
135
if (status & ACCTL_DCV)
137
cmn_err (CE_WARN, "AC97 Read Timedout\n");
138
MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
142
/* Wait for the valid status bit to go active. */
144
for (count = 0; count < 500; count++)
147
* Read the AC97 status register.
148
* ACSTS = Status Register = 464h
150
status = READL (BA0_ACSTS);
152
* See if we have valid status.
153
* VSTS - Valid Status
155
if (status & ACSTS_VSTS)
159
* Wait for a short while.
163
/* Make sure we got valid status. */
164
if (!(status & ACSTS_VSTS))
166
cmn_err (CE_WARN, "AC97 Read Timedout\n");
167
MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
172
* Read the data returned from the AC97 register.
173
* ACSDA = Status Data Register = 474h
175
value = READL (BA0_ACSDA);
176
MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
181
ac97_write (void *devc_, int reg, int data)
183
cs4281_devc *devc = devc_;
185
oss_native_word status, flags;
187
MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
188
WRITEL (BA0_ACCAD, reg);
189
WRITEL (BA0_ACCDA, data);
190
WRITEL (BA0_ACCTL, ACCTL_DCV | ACCTL_VFRM | ACCTL_ESYN);
191
for (count = 0; count < 500; count++)
193
/* First, we want to wait for a short time. */
195
/* Now, check to see if the write has completed. */
196
/* ACCTL = 460h, DCV should be reset by now and 460h = 07h */
197
status = READL (BA0_ACCTL);
198
if (!(status & ACCTL_DCV))
202
/* write didn't completed. */
203
if (status & ACCTL_DCV)
205
cmn_err (CE_WARN, "AC97 Write timeout\n");
206
MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
209
MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
215
cs4281intr (oss_device_t * osdev)
217
cs4281_devc *devc = (cs4281_devc *) osdev->devc;
219
oss_native_word status, uart_stat;
223
/* Read the Interrupt Status Register */
224
status = READL (BA0_HISR);
227
* This is the MIDI read interrupt service. First check to see
228
* if the MIDI interrupt flag is set in the HISR register. Next
229
* read the MIDI status register. See if Receive Buffer Empty
230
* is empty (0=FIFO Not empty, 1=FIFO is empty
232
if ((devc->midi_opened & OPEN_READ) && (status & HISR_MIDI))
235
uart_stat = READL (BA0_MIDSR);
237
* read one byte of MIDI data and hand it off the the sequencer module
238
* to decode this. Keep checking to see if the data is available. Stop
239
* when no more data is there in the FIFO.
241
while (!(uart_stat & MIDSR_RBE))
244
d = READL (BA0_MIDRP);
246
if (devc->midi_opened & OPEN_READ && devc->midi_input_intr)
247
devc->midi_input_intr (devc->midi_dev, d);
248
uart_stat = READL (BA0_MIDSR);
251
/* Audio interrupt handling */
252
if (status & (HISR_INTENA | HISR_DMAI))
253
for (i = 0; i < MAX_PORTC; i++)
255
portc = &devc->portc[i];
256
if ((status & HISR_DMA0) && (portc->trigger_bits & PCM_ENABLE_OUTPUT))
258
dmap_t *dmapout = audio_engines[portc->audiodev]->dmap_out;
259
unsigned int currdac;
263
READL (BA0_HDSR0); /* ack the DMA interrupt */
264
currdac = READL (BA0_DCA0) - dmapout->dmabuf_phys;
265
currdac /= dmapout->fragment_size;
267
while (dmap_get_qhead (dmapout) != currdac
268
&& n++ < dmapout->nfrags)
269
oss_audio_outputintr (portc->audiodev, 1);
272
if ((status & HISR_DMA1) && (portc->trigger_bits & PCM_ENABLE_INPUT))
274
dmap_t *dmapin = audio_engines[portc->audiodev]->dmap_in;
275
unsigned int curradc;
279
READL (BA0_HDSR1); /* ack the DMA interrupt */
280
curradc = READL (BA0_DCA1) - dmapin->dmabuf_phys;
281
curradc /= dmapin->fragment_size;
283
while (dmap_get_qtail (dmapin) != curradc && n++ < dmapin->nfrags)
284
oss_audio_inputintr (portc->audiodev, 0);
286
WRITEL (BA0_HICR, HICR_IEV | HICR_CHGM);
292
cs4281_audio_set_rate (int dev, int arg)
294
cs4281_portc *portc = audio_engines[dev]->portc;
306
cs4281_audio_set_channels (int dev, short arg)
308
cs4281_portc *portc = audio_engines[dev]->portc;
309
if ((arg != 1) && (arg != 2))
310
return portc->channels;
311
portc->channels = arg;
312
return portc->channels;
316
cs4281_audio_set_format (int dev, unsigned int arg)
318
cs4281_portc *portc = audio_engines[dev]->portc;
321
if (!(arg & (AFMT_U8 | AFMT_S16_LE)))
329
cs4281_audio_ioctl (int dev, unsigned int cmd, ioctl_arg arg)
334
static void cs4281_audio_trigger (int dev, int state);
336
cs4281_audio_reset (int dev)
338
cs4281_audio_trigger (dev, 0);
342
cs4281_audio_reset_input (int dev)
344
cs4281_portc *portc = audio_engines[dev]->portc;
345
cs4281_audio_trigger (dev, portc->trigger_bits & ~PCM_ENABLE_INPUT);
349
cs4281_audio_reset_output (int dev)
351
cs4281_portc *portc = audio_engines[dev]->portc;
352
cs4281_audio_trigger (dev, portc->trigger_bits & ~PCM_ENABLE_OUTPUT);
357
cs4281_audio_open (int dev, int mode, int open_flags)
359
cs4281_portc *portc = audio_engines[dev]->portc;
360
cs4281_devc *devc = audio_engines[dev]->devc;
361
oss_native_word flags;
362
MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
363
if (portc->open_mode)
365
MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
369
if (devc->open_mode & mode)
371
MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
375
devc->open_mode |= mode;
376
portc->open_mode = mode;
377
portc->audio_enabled &= ~mode;
378
MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
383
cs4281_audio_close (int dev, int mode)
385
cs4281_portc *portc = audio_engines[dev]->portc;
386
cs4281_devc *devc = audio_engines[dev]->devc;
387
cs4281_audio_reset (dev);
388
portc->open_mode = 0;
389
devc->open_mode &= ~mode;
390
portc->audio_enabled &= ~mode;
395
cs4281_audio_output_block (int dev, oss_native_word buf, int count,
396
int fragsize, int intrflag)
398
cs4281_portc *portc = audio_engines[dev]->portc;
400
portc->audio_enabled |= PCM_ENABLE_OUTPUT;
401
portc->trigger_bits &= ~PCM_ENABLE_OUTPUT;
406
cs4281_audio_start_input (int dev, oss_native_word buf, int count,
407
int fragsize, int intrflag)
409
cs4281_portc *portc = audio_engines[dev]->portc;
411
portc->audio_enabled |= PCM_ENABLE_INPUT;
412
portc->trigger_bits &= ~PCM_ENABLE_INPUT;
416
cs4281_audio_trigger (int dev, int state)
418
cs4281_devc *devc = audio_engines[dev]->devc;
419
cs4281_portc *portc = audio_engines[dev]->portc;
420
oss_native_word tmp1;
421
oss_native_word flags;
422
MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
423
if (portc->open_mode & OPEN_WRITE)
425
if (state & PCM_ENABLE_OUTPUT)
427
if ((portc->audio_enabled & PCM_ENABLE_OUTPUT) &&
428
!(portc->trigger_bits & PCM_ENABLE_OUTPUT))
430
/* Clear DMA0 channel Mask bit. Start Playing. */
431
tmp1 = READL (BA0_DCR0) & ~DCRn_MSK; /*enable DMA */
432
WRITEL (BA0_DCR0, tmp1); /* (154h) */
433
WRITEL (BA0_HICR, HICR_IEV | HICR_CHGM); /*enable intr */
434
portc->trigger_bits |= PCM_ENABLE_OUTPUT;
439
if ((portc->audio_enabled & PCM_ENABLE_OUTPUT) &&
440
(portc->trigger_bits & PCM_ENABLE_OUTPUT))
442
portc->audio_enabled &= ~PCM_ENABLE_OUTPUT;
443
portc->trigger_bits &= ~PCM_ENABLE_OUTPUT;
444
tmp1 = READL (BA0_DCR0) & ~DCRn_MSK;
445
WRITEL (BA0_DCR0, tmp1 | DCRn_MSK);
449
if (portc->open_mode & OPEN_READ)
451
if (state & PCM_ENABLE_INPUT)
453
if ((portc->audio_enabled & PCM_ENABLE_INPUT) &&
454
!(portc->trigger_bits & PCM_ENABLE_INPUT))
456
/* Clear DMA1 channel Mask bit. Start recording. */
457
tmp1 = READL (BA0_DCR1) & ~DCRn_MSK;
458
WRITEL (BA0_DCR1, tmp1); /* (15ch) */
459
WRITEL (BA0_HICR, HICR_IEV | HICR_CHGM); /*Set INTENA=1. */
460
portc->trigger_bits |= PCM_ENABLE_INPUT;
465
if ((portc->audio_enabled & PCM_ENABLE_INPUT) &&
466
(portc->trigger_bits & PCM_ENABLE_INPUT))
468
portc->audio_enabled &= ~PCM_ENABLE_INPUT;
469
portc->trigger_bits &= ~PCM_ENABLE_INPUT;
470
tmp1 = READL (BA0_DCR1) & ~DCRn_MSK;
471
WRITEL (BA0_DCR1, tmp1 | DCRn_MSK);
475
MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
479
cs4281_rate (oss_native_word rate)
504
val = 1536000 / rate;
512
cs4281_audio_prepare_for_input (int dev, int bsize, int bcount)
514
cs4281_devc *devc = audio_engines[dev]->devc;
515
cs4281_portc *portc = audio_engines[dev]->portc;
516
dmap_t *dmap = audio_engines[dev]->dmap_in;
517
int count = dmap->bytes_in_use;
518
oss_native_word recordFormat;
519
oss_native_word flags;
521
MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
522
/* set the record rate */
523
WRITEL (BA0_ADCSR, cs4281_rate (portc->speed)); /* (748h) */
524
/* Start with defaults for the record format */
525
/* reg & modify them for the current case. */
526
recordFormat = DMRn_DMA | DMRn_AUTO | DMRn_TR_WRITE;
527
if (portc->channels == 1) /* If mono, */
528
recordFormat |= DMRn_MONO; /* Turn on mono bit. */
529
if (portc->bits == 8) /* If 8-bit, */
530
recordFormat |= (DMRn_SIZE8 | DMRn_USIGN); /* turn on 8bit/unsigned. */
531
WRITEL (BA0_DMR1, recordFormat);
532
/* set input gain to 0db */
533
/* ac97_write(devc, BA0_AC97_RECORD_GAIN, 0x0808); */
534
if (portc->channels == 2) /* If stereo, */
535
count /= 2; /* halve DMA count(stereo); */
536
if (portc->bits == 16) /* If 16-bit, */
538
/* Set the physical play buffer address DMA1 Base & Current. */
539
WRITEL (BA0_DBA1, dmap->dmabuf_phys); /* (118h) */
540
/* Set the sample count(-1) in DMA Base Count register 1. */
541
WRITEL (BA0_DBC1, count - 1);
542
portc->audio_enabled &= ~PCM_ENABLE_INPUT;
543
portc->trigger_bits &= ~PCM_ENABLE_INPUT;
544
MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
550
cs4281_audio_prepare_for_output (int dev, int bsize, int bcount)
552
cs4281_devc *devc = audio_engines[dev]->devc;
553
cs4281_portc *portc = audio_engines[dev]->portc;
554
dmap_t *dmap = audio_engines[dev]->dmap_out;
555
int count = dmap->bytes_in_use;
556
oss_native_word playFormat;
557
oss_native_word flags;
559
MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
560
/* Set the sample rate converter */
561
WRITEL (BA0_DACSR, cs4281_rate (portc->speed));
562
playFormat = DMRn_DMA | DMRn_AUTO | DMRn_TR_READ | (1 << 6);
563
if (portc->channels == 1) /* If stereo, */
564
playFormat |= DMRn_MONO; /* Turn on mono bit. */
565
if (portc->bits == 8) /* If 16-bit, */
566
playFormat |= (DMRn_SIZE8 | DMRn_USIGN); /* turn on 8-bit/unsigned. */
567
WRITEL (BA0_DMR0, playFormat); /* (150h) */
568
if (portc->channels == 2) /* If stereo, */
569
count /= 2; /* halve DMA count(stereo); */
570
if (portc->bits == 16) /* If 16-bit, */
572
/* Set the physical play buffer address DMA0 Base & Current. */
573
WRITEL (BA0_DBA0, dmap->dmabuf_phys & ~0x3); /* (118h) */
574
/* Set the sample count(-1) in DMA Base Count register 0. */
575
WRITEL (BA0_DBC0, count - 1);
576
portc->audio_enabled &= ~PCM_ENABLE_OUTPUT;
577
portc->trigger_bits &= ~PCM_ENABLE_OUTPUT;
578
MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
583
cs4281_get_buffer_pointer (int dev, dmap_t * dmap, int direction)
585
cs4281_devc *devc = audio_engines[dev]->devc;
586
unsigned int ptr = 0;
587
oss_native_word flags;
589
MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
591
if (direction == PCM_ENABLE_OUTPUT)
593
ptr = READL (BA0_DCA0);
595
if (direction == PCM_ENABLE_INPUT)
597
ptr = READL (BA0_DCA1);
599
ptr -= dmap->dmabuf_phys;
600
MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
604
static audiodrv_t cs4281_audio_driver = {
607
cs4281_audio_output_block,
608
cs4281_audio_start_input,
610
cs4281_audio_prepare_for_input,
611
cs4281_audio_prepare_for_output,
615
cs4281_audio_reset_input,
616
cs4281_audio_reset_output,
617
cs4281_audio_trigger,
618
cs4281_audio_set_rate,
619
cs4281_audio_set_format,
620
cs4281_audio_set_channels,
625
NULL, /* cs4281_alloc_buffer, */
626
NULL, /* cs4281_free_buffer, */
629
cs4281_get_buffer_pointer
632
/***********************MIDI PORT ROUTINES ****************/
635
cs4281_midi_open (int dev, int mode, oss_midi_inputbyte_t inputbyte,
636
oss_midi_inputbuf_t inputbuf,
637
oss_midi_outputintr_t outputintr)
639
cs4281_devc *devc = (cs4281_devc *) midi_devs[dev]->devc;
640
if (devc->midi_opened)
645
devc->midi_input_intr = inputbyte;
646
devc->midi_opened = mode;
647
/* first reset the MIDI port */
648
WRITEL (BA0_MIDCR, 0x10);
649
WRITEL (BA0_MIDCR, 0x00);
650
/* Now check if we're in Read or Write mode */
651
if (mode & OPEN_READ)
653
/* enable MIDI Input intr and receive enable */
654
WRITEL (BA0_MIDCR, MIDCR_RXE | MIDCR_RIE);
657
if (mode & OPEN_WRITE)
659
/* enable MIDI transmit enable */
660
WRITEL (BA0_MIDCR, MIDCR_TXE);
667
cs4281_midi_close (int dev, int mode)
669
cs4281_devc *devc = (cs4281_devc *) midi_devs[dev]->devc;
670
/* Reset the device*/
671
WRITEL (BA0_MIDCR, 0x10);
672
WRITEL (BA0_MIDCR, 0x00);
673
devc->midi_opened = 0;
677
cs4281_midi_out (int dev, unsigned char midi_byte)
679
cs4281_devc *devc = (cs4281_devc *) midi_devs[dev]->devc;
680
unsigned char uart_stat = READL (BA0_MIDSR);
681
/* Check if Transmit buffer full flag is set - if so return */
682
if ((uart_stat & MIDSR_TBF))
684
/* Now put the MIDI databyte in the write port */
685
WRITEL (BA0_MIDWP, midi_byte);
691
cs4281_midi_ioctl (int dev, unsigned cmd, ioctl_arg arg)
696
static midi_driver_t cs4281_midi_driver = {
704
init_cs4281 (cs4281_devc * devc)
708
oss_native_word dwAC97SlotID, tmp1;
710
/****************BEGIN HARDWARE INIT*****************/
712
tmp1 = READL (BA0_CFLR);
715
WRITEL (BA0_CFLR, 0x01); /*set up AC97 mode */
716
tmp1 = READL (BA0_CFLR);
719
tmp1 = READL (BA0_CWPR);
721
WRITEL (BA0_CWPR, 0x4281);
722
tmp1 = READL (BA0_CWPR);
725
cmn_err (CE_WARN, "Resetting AC97 failed\n");
728
WRITEL (BA0_CFLR, 0x1);
729
tmp1 = READL (BA0_CFLR);
732
cmn_err (CE_WARN, "Resetting AC97 still fails\n");
737
/* Setup the FM and Joystick trap address for Legacy emulation */
738
WRITEL (BA0_IOTCR, 0x1);
739
WRITEL (BA0_IOTFM, 0xc0030388);
740
WRITEL (BA0_IOTGP, 0xc0070200);
741
/**************************************** */
742
/* Set up the Sound System Configuration */
743
/**************************************** */
744
/* Set the 'Configuration Write Protect' register */
745
/* to 4281h. Allows vendor-defined configuration */
746
/* space between 0e4h and 0ffh to be written. */
747
WRITEL (BA0_CWPR, 0x4281); /* (3e0h) */
748
if ((tmp1 = READL (BA0_SERC1)) != (SERC1_SO1EN | SERC1_SO1F_AC97))
750
cmn_err (CE_WARN, "SERC1: AC97 check failed\n");
753
/* setup power management to full power */
754
WRITEL (BA0_SSPM, 0x7E);
755
/* First, blast the clock control register to zero so that the */
756
/* PLL starts out in a known state, and blast the master serial */
757
/* port control register to zero so that the serial ports also */
758
/* start out in a known state. */
759
WRITEL (BA0_CLKCR1, 0); /* (400h) */
760
WRITEL (BA0_SERMC, 0); /* (420h) */
761
/* (1) Drive the ARST# pin low for a minimum of 1uS (as defined in */
762
/* the AC97 spec) and then drive it high. This is done for non */
763
/* AC97 modes since there might be logic external to the CS461x */
764
/* that uses the ARST# line for a reset. */
765
WRITEL (BA0_ACCTL, 0);
767
WRITEL (BA0_SPMC, 0); /* (3ech) */
769
WRITEL (BA0_SPMC, SPMC_RSTN);
771
WRITEL (BA0_SERMC, SERMC_PTC_AC97 | SERMC_MSPE | 0x10000);
772
/* (3) Turn on the Sound System Clocks. */
773
WRITEL (BA0_CLKCR1, CLKCR1_DLLP); /* (400h) */
774
/* Wait for the PLL to stabilize. */
776
/* Turn on clocking of the core (CLKCR1(400h) = 0x00000030) */
777
WRITEL (BA0_CLKCR1, CLKCR1_DLLP | CLKCR1_SWCE);
778
/* (5) Wait for clock stabilization. */
779
for (tmp1 = 0; tmp1 < 100; tmp1++)
781
if (READL (BA0_CLKCR1) & CLKCR1_DLLRDY)
785
if (!(READL (BA0_CLKCR1) & CLKCR1_DLLRDY))
787
cmn_err (CE_WARN, "DLLRDY Clock not ready\n");
790
/* (6) Enable ASYNC generation. */
791
WRITEL (BA0_ACCTL, ACCTL_ESYN); /* (460h) */
792
/* Now wait 'for a short while' to allow the AC97 */
793
/* part to start generating bit clock. (so we don't */
794
/* Try to start the PLL without an input clock.) */
795
/* (7) Wait for the codec ready signal from the AC97 codec. */
796
for (tmp1 = 0; tmp1 < 100; tmp1++)
798
/* Delay a mil to let things settle out and */
799
/* to prevent retrying the read too quickly. */
800
if (READL (BA0_ACSTS) & ACSTS_CRDY) /* If ready, (464h) */
801
break; /* exit the 'for' loop. */
804
if (!(READL (BA0_ACSTS) & ACSTS_CRDY)) /* If never came ready, */
806
cmn_err (CE_WARN, "AC97 not ready\n");
807
return OSS_EIO; /* exit initialization. */
809
/* (8) Assert the 'valid frame' signal so we can */
810
/* begin sending commands to the AC97 codec. */
811
WRITEL (BA0_ACCTL, ACCTL_VFRM | ACCTL_ESYN); /* (460h) */
813
/* (11) Wait until we've sampled input slots 3 & 4 as valid, meaning */
814
/* that the codec is pumping ADC data across the AC link. */
815
for (tmp1 = 0; tmp1 < 100; tmp1++)
817
/* Read the input slot valid register; See */
818
/* if input slots 3 and 4 are valid yet. */
819
if ((READL (BA0_ACISV) & (ACISV_ISV3 | ACISV_ISV4)) == /* (474h) */
820
(ACISV_ISV3 | ACISV_ISV4))
821
break; /* Exit the 'for' if slots are valid. */
824
/* If we never got valid data, exit initialization. */
825
if ((READL (BA0_ACISV) & (ACISV_ISV3 | ACISV_ISV4)) !=
826
(ACISV_ISV3 | ACISV_ISV4))
828
cmn_err (CE_WARN, "AC97 Slot not valid\n");
829
return OSS_EIO; /* If no valid data, exit initialization. */
831
/* (12) Start digital data transfer of audio data to the codec. */
832
WRITEL (BA0_ACOSV, ACOSV_SLV3 | ACOSV_SLV4); /* (468h) */
834
/* For playback, we map AC97 slot 3 and 4(Left */
835
/* & Right PCM playback) to DMA Channel 0. */
836
/* Set the fifo to be 31 bytes at offset zero. */
837
dwAC97SlotID = 0x01001F00; /* FCR0.RS[4:0]=1(=>slot4, right PCM playback). */
838
/* FCR0.LS[4:0]=0(=>slot3, left PCM playback). */
839
/* FCR0.SZ[6-0]=15; FCR0.OF[6-0]=0. */
840
WRITEL (BA0_FCR0, dwAC97SlotID); /* (180h) */
841
WRITEL (BA0_FCR0, dwAC97SlotID | FCRn_FEN); /* Turn on FIFO Enable. */
842
/* For capture, we map AC97 slot 10 and 11(Left */
843
/* and Right PCM Record) to DMA Channel 1. */
844
/* Set the fifo to be 31 bytes at offset 32. */
845
dwAC97SlotID = 0x0B0A1F20; /* FCR1.RS[4:0]=11(=>slot11, right PCM record). */
846
/* FCR1.LS[4:0]=10(=>slot10, left PCM record). */
847
/* FCR1.SZ[6-0]=15; FCR1.OF[6-0]=16. */
848
WRITEL (BA0_FCR1, dwAC97SlotID); /* (184h) */
849
WRITEL (BA0_FCR1, dwAC97SlotID | FCRn_FEN); /* Turn on FIFO Enable. */
850
/* Map the Playback SRC to the same AC97 slots(3 & 4-- */
851
/* --Playback left & right)as DMA channel 0. */
852
/* Map the record SRC to the same AC97 slots(10 & 11-- */
853
/* -- Record left & right) as DMA channel 1. */
854
dwAC97SlotID = 0x0b0a0100; /*SCRSA.PRSS[4:0]=1(=>slot4, right PCM playback). */
855
/*SCRSA.PLSS[4:0]=0(=>slot3, left PCM playback). */
856
/*SCRSA.CRSS[4:0]=11(=>slot11, right PCM record) */
857
/*SCRSA.CLSS[4:0]=10(=>slot10, left PCM record). */
858
WRITEL (BA0_SRCSA, dwAC97SlotID); /* (75ch) */
859
/* Set 'Half Terminal Count Interrupt Enable' and 'Terminal */
860
/* Count Interrupt Enable' in DMA Control Registers 0 & 1. */
861
/* Set 'MSK' flag to 1 to keep the DMA engines paused. */
862
tmp1 = (DCRn_HTCIE | DCRn_TCIE | DCRn_MSK); /* (00030001h) */
863
WRITEL (BA0_DCR0, tmp1); /* (154h) */
864
WRITEL (BA0_DCR1, tmp1); /* (15ch) */
865
/* Set 'Auto-Initialize Control' to 'enabled'; For playback, */
866
/* set 'Transfer Type Control'(TR[1:0]) to 'read transfer', */
867
/* for record, set Transfer Type Control to 'write transfer'. */
868
/* All other bits set to zero; Some will be changed @ transfer start. */
869
tmp1 = (DMRn_DMA | DMRn_AUTO | DMRn_TR_READ); /* (20000018h) */
870
WRITEL (BA0_DMR0, tmp1); /* (150h) */
871
tmp1 = (DMRn_DMA | DMRn_AUTO | DMRn_TR_WRITE); /* (20000014h) */
872
WRITEL (BA0_DMR1, tmp1); /* (158h) */
873
/* Enable DMA interrupts generally, and */
874
/* DMA0 & DMA1 interrupts specifically. */
875
tmp1 = READL (BA0_HIMR) & 0x7fbbfcff;
876
WRITEL (BA0_HIMR, tmp1);
877
/* set up some volume defaults */
878
WRITEL (BA0_PPLVC, 0x0808);
879
WRITEL (BA0_PPRVC, 0x0808);
880
WRITEL (BA0_FMLVC, 0x0);
881
WRITEL (BA0_FMRVC, 0x0);
882
/****** END OF HARDWARE INIT *****/
886
ac97_install (&devc->ac97devc, "CS4281 AC97 Mixer", ac97_read, ac97_write,
893
devc->mixer_dev = my_mixer;
895
/* ac97_write(devc, 0x26, ac97_read(devc, 0x26) | 0x8000); */
896
for (i = 0; i < MAX_PORTC; i++)
900
cs4281_portc *portc = &devc->portc[i];
902
strcpy (tmp_name, devc->chip_name);
906
caps = ADEV_AUTOMODE | ADEV_DUPLEX;
907
strcpy (tmp_name, devc->chip_name);
911
caps = ADEV_AUTOMODE | ADEV_DUPLEX | ADEV_SHADOW;
912
strcpy (tmp_name, devc->chip_name);
915
if ((adev = oss_install_audiodev (OSS_AUDIO_DRIVER_VERSION,
919
&cs4281_audio_driver,
922
AFMT_S16_LE | AFMT_U8, devc, -1)) < 0)
931
audio_engines[adev]->portc = portc;
932
audio_engines[adev]->rate_source = first_dev;
933
audio_engines[adev]->mixer_dev = my_mixer;
934
audio_engines[adev]->min_rate = 6023;
935
audio_engines[adev]->max_rate = 48000;
936
audio_engines[adev]->caps |= PCM_CAP_FREERATE;
937
portc->open_mode = 0;
938
portc->audiodev = adev;
939
portc->audio_enabled = 0;
940
#ifdef CONFIG_OSS_VMIX
942
vmix_attach_audiodev(devc->osdev, adev, -1, 0);
947
devc->midi_dev = oss_install_mididev (OSS_MIDI_DRIVER_VERSION, "CS4281", "CS4281 MIDI Port", &cs4281_midi_driver, sizeof (midi_driver_t),
948
0, devc, devc->osdev);
949
devc->midi_opened = 0;
954
oss_cs4281_attach (oss_device_t * osdev)
956
unsigned char pci_irq_line, pci_revision, pci_irq_inta;
957
unsigned short pci_command, vendor, device;
962
DDB (cmn_err (CE_WARN, "Entered CS4281 probe routine\n"));
964
pci_read_config_word (osdev, PCI_VENDOR_ID, &vendor);
965
pci_read_config_word (osdev, PCI_DEVICE_ID, &device);
967
if (vendor != CRYSTAL_VENDOR_ID || device != CRYSTAL_CS4281_ID)
970
if ((devc = PMALLOC (osdev, sizeof (*devc))) == NULL)
972
cmn_err (CE_WARN, "Out of memory\n");
979
oss_pci_byteswap (osdev, 1);
981
pci_read_config_byte (osdev, PCI_REVISION_ID, &pci_revision);
982
pci_read_config_word (osdev, PCI_COMMAND, &pci_command);
983
pci_read_config_irq (osdev, PCI_INTERRUPT_LINE, &pci_irq_line);
984
pci_read_config_byte (osdev, PCI_INTERRUPT_LINE + 1, &pci_irq_inta);
985
pci_read_config_dword (osdev, PCI_MEM_BASE_ADDRESS_0, &ioaddr);
986
devc->bar0addr = ioaddr;
987
pci_read_config_dword (osdev, PCI_MEM_BASE_ADDRESS_1, &ioaddr);
988
devc->bar1addr = ioaddr;
990
/* activate the device enable bus master/memory space */
991
pci_command |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
992
pci_write_config_word (osdev, PCI_COMMAND, pci_command);
994
if ((devc->bar0addr == 0) || (devc->bar1addr == 0))
996
cmn_err (CE_WARN, "undefined MEMORY I/O address.\n");
1000
if (pci_irq_line == 0)
1002
cmn_err (CE_WARN, "IRQ not assigned by BIOS.\n");
1007
/* Map the shared memory area */
1009
(unsigned int *) MAP_PCI_MEM (devc->osdev, 0, devc->bar0addr, 4 * 1024);
1011
(unsigned int *) MAP_PCI_MEM (devc->osdev, 1, devc->bar1addr,
1013
devc->dwRegister0 = devc->bar0virt;
1014
devc->wRegister0 = (unsigned short *) devc->bar0virt;
1015
devc->bRegister0 = (unsigned char *) devc->bar0virt;
1016
devc->dwRegister1 = devc->bar1virt;
1017
devc->wRegister1 = (unsigned short *) devc->bar1virt;
1018
devc->bRegister1 = (unsigned char *) devc->bar1virt;
1020
devc->chip_name = "CS4281";
1021
devc->irq = pci_irq_line;
1022
devc->open_mode = 0;
1024
MUTEX_INIT (devc->osdev, devc->mutex, MH_DRV);
1025
MUTEX_INIT (devc->osdev, devc->low_mutex, MH_DRV + 1);
1027
oss_register_device (osdev, devc->chip_name);
1029
if ((err = oss_register_interrupts (devc->osdev, 0, cs4281intr, NULL)) < 0)
1031
cmn_err (CE_WARN, "Can't register interrupt handler, err=%d\n", err);
1034
return init_cs4281 (devc); /*Detected */
1039
oss_cs4281_detach (oss_device_t * osdev)
1041
cs4281_devc *devc = (cs4281_devc *) osdev->devc;
1043
if (oss_disable_device (osdev) < 0)
1046
WRITEL (BA0_HICR, 0x02); /*enable intena */
1048
oss_unregister_interrupts (devc->osdev);
1050
MUTEX_CLEANUP (devc->mutex);
1051
MUTEX_CLEANUP (devc->low_mutex);
1053
UNMAP_PCI_MEM (devc->osdev, 0, devc->bar0addr, devc->bar0virt, 4 * 1024);
1054
UNMAP_PCI_MEM (devc->osdev, 1, devc->bar1addr, devc->bar1virt, 1024 * 1024);
1059
oss_unregister_device (devc->osdev);