2
* Purpose: Driver for Yamaha YMF7xx 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_ymf7xx_cfg.h"
22
#define YAMAHA_VENDOR_ID 0x1073
23
#define YAMAHA_YMF724_ID 0x0004
24
#define YAMAHA_YMF724F_ID 0x000d
25
#define YAMAHA_YMF734_ID 0x0005
26
#define YAMAHA_YMF740_ID 0x000a
27
#define YAMAHA_YMF740C_ID 0x000c
28
#define YAMAHA_YMF744_ID 0x0010
29
#define YAMAHA_YMF754_ID 0x0012
31
#define WRITEB(a,d) devc->bRegister[a] = d
32
#define READB(a) devc->bRegister[a]
33
#define WRITEW(a,d) devc->wRegister[a>>1] = d
34
#define READW(a) devc->wRegister[a>>1]
35
#define WRITEL(a,d) devc->dwRegister[a>>2] = d
36
#define READL(a) (devc->dwRegister[a>>2])
39
static __inline__ unsigned int
40
ymf_swap (unsigned int x)
42
return ((x & 0x000000ff) << 24) |
43
((x & 0x0000ff00) << 8) |
44
((x & 0x00ff0000) >> 8) | ((x & 0xff000000) >> 24);
47
#define LSWAP(x) ymf_swap(x)
54
extern int yamaha_mpu_ioaddr;
55
extern int yamaha_mpu_irq;
56
extern int yamaha_fm_ioaddr;
59
typedef struct ymf7xx_portc
61
int speed, bits, channels;
68
PLAY_BANK *bank1, *bank2, *bank3, *bank4;
69
EFFECT_CNTRL_SLOT effectslot;
70
REC_CNTRL_SLOT recslot;
75
typedef struct ymf7xx_devc
80
unsigned int base0addr;
81
unsigned int *base0virt;
82
volatile unsigned int *dwRegister;
83
volatile unsigned short *wRegister;
84
volatile unsigned char *bRegister;
87
oss_mutex_t low_mutex;
90
int mpu_base, mpu_irq;
92
int fm_attached, mpu_attached;
94
/* Mixer parameters */
95
ac97_devc ac97devc, ac97devc2;
99
/* Audio parameters */
100
int audio_initialized;
101
ymf7xx_portc portc[MAX_PORTC];
104
volatile oss_native_word slt;
105
oss_native_word slt_phys;
106
volatile unsigned int *tab;
107
oss_native_word play_table;
108
oss_native_word play_table_virt;
109
unsigned char *dmabuf1;
110
oss_dma_handle_t dmabuf1_dma_handle;
113
volatile unsigned int *effecttab;
114
oss_native_word effect_table;
115
oss_native_word effect_table_virt, eff_buf_phys;
116
unsigned char *dmabuf2, *eff_buf;
117
oss_dma_handle_t dmabuf2_dma_handle;
118
oss_dma_handle_t eff_buf_dma_handle;
120
/* Recording Table */
121
volatile unsigned int *rectab;
122
oss_native_word rec_table;
123
oss_native_word rec_table_virt;
124
unsigned char *dmabuf3;
125
oss_dma_handle_t dmabuf3_dma_handle;
130
int SetupPlaySlot (int dev, int slot);
131
int ymf7xx_spdif_control (int dev, int ctrl, unsigned int cmd, int value);
134
ac97_read (void *devc_, int addr)
136
ymf7xx_devc *devc = devc_;
138
oss_native_word flags;
140
MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
141
WRITEW (AC97_CMD_ADDRESS, addr | 0x8000);
143
for (count = 0; count < 1000; count++)
144
if ((READW (AC97_STATUS_ADDRESS) >> 15) == 0)
146
MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
147
return READW (AC97_STATUS_DATA);
149
DDB (cmn_err (CE_WARN, "AC97 mixer read timed out\n"));
150
MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
155
ac97_write (void *devc_, int addr, int data)
157
ymf7xx_devc *devc = devc_;
158
oss_native_word flags;
161
MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
162
WRITEW (AC97_CMD_ADDRESS, addr);
163
WRITEW (AC97_CMD_DATA, data);
165
for (count = 0; count < 1000; count++)
166
if ((READW (AC97_STATUS_ADDRESS) >> 15) == 0)
168
MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
171
DDB (cmn_err (CE_WARN, "AC97 mixer write timed out\n"));
172
MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
177
install_ucode (ymf7xx_devc * devc, int addr, unsigned int *src, int len)
181
for (i = 0; i < len; i++)
190
ymf7xxintr (oss_device_t * osdev)
192
ymf7xx_devc *devc = (ymf7xx_devc *) osdev->devc;
194
dmap_t *dmapin, *dmapout;
202
status = READL (STATUS);
204
if ((status & 0x80000000))
207
for (i = 0; i < MAX_PORTC; i++)
209
portc = &devc->portc[i];
211
if (portc->trigger_bits & PCM_ENABLE_OUTPUT)
213
dmapout = audio_engines[portc->audiodev]->dmap_out;
214
currdac = LSWAP (portc->bank1->PgStart);
215
currdac /= dmapout->fragment_size / portc->dacfmt;
217
if (currdac < 0 || currdac >= dmapout->nfrags)
220
while (dmap_get_qhead (dmapout) != currdac
221
&& n++ < dmapout->nfrags)
222
oss_audio_outputintr (portc->audiodev, 1);
224
if (portc->trigger_bits & PCM_ENABLE_INPUT)
226
dmapin = audio_engines[portc->audiodev]->dmap_in;
229
curradc = LSWAP (portc->recslot.bank1->PgStartAdr);
231
curradc = LSWAP (portc->recslot.bank3->PgStartAdr);
233
curradc /= dmapin->fragment_size;
235
if (curradc < 0 || curradc >= dmapin->nfrags)
238
while (dmap_get_qtail (dmapin) != curradc
239
&& n++ < dmapin->nfrags)
240
oss_audio_inputintr (portc->audiodev, 0);
242
WRITEL (STATUS, 0x80000000);
243
WRITEL (MODE, READL (MODE) | 0x00000002);
251
*****************************************************************************
255
ymf7xx_audio_set_rate (int dev, int arg)
257
ymf7xx_portc *portc = audio_engines[dev]->portc;
271
ymf7xx_audio_set_channels (int dev, short arg)
273
ymf7xx_portc *portc = audio_engines[dev]->portc;
275
if ((arg != 1) && (arg != 2))
276
return portc->channels;
277
portc->channels = arg;
279
return portc->channels;
283
ymf7xx_audio_set_format (int dev, unsigned int arg)
285
ymf7xx_portc *portc = audio_engines[dev]->portc;
290
if (!(arg & (AFMT_U8 | AFMT_S16_LE | AFMT_AC3)))
299
ymf7xx_audio_ioctl (int dev, unsigned int cmd, ioctl_arg arg)
304
static void ymf7xx_audio_trigger (int dev, int state);
307
ymf7xx_audio_reset (int dev)
309
ymf7xx_audio_trigger (dev, 0);
313
ymf7xx_audio_reset_input (int dev)
315
ymf7xx_portc *portc = audio_engines[dev]->portc;
316
ymf7xx_audio_trigger (dev, portc->trigger_bits & ~PCM_ENABLE_INPUT);
320
ymf7xx_audio_reset_output (int dev)
322
ymf7xx_portc *portc = audio_engines[dev]->portc;
323
ymf7xx_audio_trigger (dev, portc->trigger_bits & ~PCM_ENABLE_OUTPUT);
328
ymf7xx_audio_open (int dev, int mode, int open_flags)
330
ymf7xx_portc *portc = audio_engines[dev]->portc;
331
ymf7xx_devc *devc = audio_engines[dev]->devc;
332
oss_native_word flags;
334
MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
335
if (portc->open_mode)
337
MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
341
portc->open_mode = mode;
342
portc->audio_enabled = ~mode;
343
MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
349
ymf7xx_audio_close (int dev, int mode)
351
ymf7xx_portc *portc = audio_engines[dev]->portc;
353
ymf7xx_audio_reset (dev);
354
portc->open_mode = 0;
355
portc->audio_enabled &= ~mode;
360
ymf7xx_audio_output_block (int dev, oss_native_word buf, int count,
361
int fragsize, int intrflag)
363
ymf7xx_portc *portc = audio_engines[dev]->portc;
365
portc->audio_enabled |= PCM_ENABLE_OUTPUT;
366
portc->trigger_bits &= ~PCM_ENABLE_OUTPUT;
371
ymf7xx_audio_start_input (int dev, oss_native_word buf, int count,
372
int fragsize, int intrflag)
374
ymf7xx_portc *portc = audio_engines[dev]->portc;
376
portc->audio_enabled |= PCM_ENABLE_INPUT;
377
portc->trigger_bits &= ~PCM_ENABLE_INPUT;
381
ymf7xx_audio_trigger (int dev, int state)
383
ymf7xx_devc *devc = audio_engines[dev]->devc;
384
ymf7xx_portc *portc = audio_engines[dev]->portc;
385
oss_native_word flags;
387
MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
389
if (portc->open_mode & OPEN_WRITE)
391
if (state & PCM_ENABLE_OUTPUT)
393
if ((portc->audio_enabled & PCM_ENABLE_OUTPUT) &&
394
!(portc->trigger_bits & PCM_ENABLE_OUTPUT))
396
portc->devs_opened = SetupPlaySlot (dev, portc->devnum);
398
WRITEL (CONTROL_SELECT, 1);
399
WRITEL (MODE, READL (MODE) | 0x00000003);
400
portc->trigger_bits |= PCM_ENABLE_OUTPUT;
405
if ((portc->audio_enabled & PCM_ENABLE_OUTPUT) &&
406
(portc->trigger_bits & PCM_ENABLE_OUTPUT))
408
portc->audio_enabled &= ~PCM_ENABLE_OUTPUT;
409
portc->trigger_bits &= ~PCM_ENABLE_OUTPUT;
411
devc->tab[portc->devs_opened] = 0;
412
if (portc->channels > 1)
413
devc->tab[portc->devs_opened - 1] = 0;
418
if ((portc->open_mode & OPEN_READ)
419
&& !(audio_engines[dev]->flags & ADEV_NOINPUT))
421
if (state & PCM_ENABLE_INPUT)
423
if ((portc->audio_enabled & PCM_ENABLE_INPUT) &&
424
!(portc->trigger_bits & PCM_ENABLE_INPUT))
426
/* 0x01 = REC SLOT, 0x02 = ADC SLOT */
428
WRITEL (MAP_OF_REC, 0x1);
430
WRITEL (MAP_OF_REC, 0x2);
431
WRITEL (CONTROL_SELECT, 0);
432
WRITEL (MODE, READL (MODE) | 0x00000003);
433
portc->trigger_bits |= PCM_ENABLE_INPUT;
438
if ((portc->audio_enabled & PCM_ENABLE_INPUT) &&
439
(portc->trigger_bits & PCM_ENABLE_INPUT))
441
portc->audio_enabled &= ~PCM_ENABLE_INPUT;
442
portc->trigger_bits &= ~PCM_ENABLE_INPUT;
444
/* set the map of rec 0 */
445
WRITEL (MAP_OF_REC, 0x0);
449
MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
453
SetFormatField (ymf7xx_portc * portc)
458
if (portc->bits == 8)
460
if (portc->channels > 1)
466
SetPgDeltaField (ymf7xx_portc * portc)
472
x = (double) portc->speed / 48000.0;
473
val = (int) (x * (1 << 28)) & 0x7FFFFF00;
476
x = (portc->speed * (1 << 15) + 187) / 375;
477
val = (x * (1 << 6)) & 0x7FFFFF00;
483
SetLpfKField (ymf7xx_portc * portc)
485
unsigned int i, val = 0, sr = portc->speed;
486
int freq[8] = { 100, 2000, 8000, 11025, 16000, 22050, 32000, 48000 };
488
{ 0x0057, 0x06aa, 0x18B2, 0x2093, 0x2b9a, 0x35a1, 0x3eaa, 0x4000 };
496
for (i = 0; i < 8; i++)
509
SetLpfQField (ymf7xx_portc * portc)
511
unsigned int i, val = 0, sr = portc->speed;
512
int freq[8] = { 100, 2000, 8000, 11025, 16000, 22050, 32000, 48000 };
514
{ 0x3528, 0x34a7, 0x3202, 0x3177, 0x3139, 0x31c9, 0x33d0, 0x4000 };
522
for (i = 0; i < 8; i++)
535
SetupRecSlot (int dev)
537
ymf7xx_devc *devc = audio_engines[dev]->devc;
538
ymf7xx_portc *portc = audio_engines[dev]->portc;
539
dmap_t *dmap = audio_engines[dev]->dmap_in;
542
banksize = READL (REC_CNTRL_SIZE);
543
portc->recslot.base = (devc->rec_table_virt);
545
/* banks 1 and 2 are for REC Slot and 3 and 4 are for ADC Slot */
548
portc->recslot.bank1 =
549
(REC_BANK *) (portc->recslot.base + (banksize * 0));
550
portc->recslot.bank2 =
551
(REC_BANK *) (portc->recslot.base + (banksize * 4));
554
(unsigned char) ((portc->channels & 0x02) +
555
((portc->bits & 0x08) >> 3)));
556
WRITEW (REC_SAMPLING_RATE,
557
(unsigned short) (48000 * 4096 / portc->speed) - 1);
559
portc->recslot.bank1->PgBase = portc->recslot.bank2->PgBase = LSWAP (dmap->dmabuf_phys); /* use the REC slot */
561
portc->recslot.bank1->PgLoopEndAdr = portc->recslot.bank2->PgLoopEndAdr = LSWAP (dmap->bytes_in_use); /* use the REC slot */
565
portc->recslot.bank3 =
566
(REC_BANK *) (portc->recslot.base + (banksize * 8));
567
portc->recslot.bank4 =
568
(REC_BANK *) (portc->recslot.base + (banksize * 12));
571
(unsigned char) ((portc->channels & 0x02) +
572
((portc->bits & 0x08) >> 3)));
573
WRITEW (ADC_SAMPLING_RATE,
574
(unsigned short) (48000 * 4096 / portc->speed) - 1);
576
portc->recslot.bank3->PgBase = portc->recslot.bank4->PgBase = LSWAP (dmap->dmabuf_phys); /* use the ADC slot */
578
portc->recslot.bank3->PgLoopEndAdr = portc->recslot.bank4->PgLoopEndAdr = LSWAP (dmap->bytes_in_use); /* use the ADC slot */
585
ymf7xx_audio_prepare_for_input (int dev, int bsize, int bcount)
587
ymf7xx_devc *devc = audio_engines[dev]->devc;
588
ymf7xx_portc *portc = audio_engines[dev]->portc;
589
oss_native_word flags;
591
MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
594
/* set the input level to max and go! */
595
WRITEL (NATIVE_REC_INPUT, 0xffffffff);
596
WRITEL (NATIVE_ADC_INPUT, 0xffffffff);
597
portc->audio_enabled &= ~PCM_ENABLE_INPUT;
598
portc->trigger_bits &= ~PCM_ENABLE_INPUT;
599
MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
604
SetupEffectSlot (int dev)
606
ymf7xx_devc *devc = audio_engines[dev]->devc;
607
ymf7xx_portc *portc = audio_engines[dev]->portc;
611
banksize = READL (EFF_CNTRL_SIZE);
612
portc->effectslot.base = (devc->effect_table_virt);
614
/* slots 1-5 each having 2 banks */
615
portc->effectslot.bank1 =
616
(EFFECT_BANK *) (portc->effectslot.base + (banksize * 0));
617
portc->effectslot.bank2 =
618
(EFFECT_BANK *) (portc->effectslot.base + (banksize * 4));
619
portc->effectslot.bank3 =
620
(EFFECT_BANK *) (portc->effectslot.base + (banksize * 8));
621
portc->effectslot.bank4 =
622
(EFFECT_BANK *) (portc->effectslot.base + (banksize * 12));
623
portc->effectslot.bank5 =
624
(EFFECT_BANK *) (portc->effectslot.base + (banksize * 16));
625
portc->effectslot.bank6 =
626
(EFFECT_BANK *) (portc->effectslot.base + (banksize * 20));
627
portc->effectslot.bank7 =
628
(EFFECT_BANK *) (portc->effectslot.base + (banksize * 24));
629
portc->effectslot.bank8 =
630
(EFFECT_BANK *) (portc->effectslot.base + (banksize * 28));
631
portc->effectslot.bank9 =
632
(EFFECT_BANK *) (portc->effectslot.base + (banksize * 32));
633
portc->effectslot.bank10 =
634
(EFFECT_BANK *) (portc->effectslot.base + (banksize * 36));
637
/* Dry Left Channel */
638
portc->effectslot.bank1->PgBase = portc->effectslot.bank2->PgBase =
639
LSWAP (devc->eff_buf_phys + 0 * 8192);
640
portc->effectslot.bank1->PgLoopEnd = portc->effectslot.bank2->PgLoopEnd =
642
portc->effectslot.bank1->PgStart = portc->effectslot.bank2->PgStart = 0;
644
/* Dry Right Channel */
645
portc->effectslot.bank3->PgBase = portc->effectslot.bank4->PgBase =
646
LSWAP (devc->eff_buf_phys + 1 * 8192);
647
portc->effectslot.bank3->PgLoopEnd = portc->effectslot.bank4->PgLoopEnd =
649
portc->effectslot.bank3->PgStart = portc->effectslot.bank4->PgStart = 0;
652
portc->effectslot.bank5->PgBase = portc->effectslot.bank6->PgBase =
653
LSWAP (devc->eff_buf_phys + 2 * 8192);
654
portc->effectslot.bank5->PgLoopEnd = portc->effectslot.bank6->PgLoopEnd =
656
portc->effectslot.bank5->PgStart = portc->effectslot.bank6->PgStart = 0;
661
portc->effectslot.bank7->PgBase = portc->effectslot.bank8->PgBase =
662
LSWAP (devc->eff_buf_phys + 0 * 8192);
663
portc->effectslot.bank7->PgLoopEnd = portc->effectslot.bank8->PgLoopEnd =
665
portc->effectslot.bank7->PgStart = portc->effectslot.bank8->PgStart = 0;
668
portc->effectslot.bank9->PgBase = portc->effectslot.bank10->PgBase =
669
LSWAP (devc->eff_buf_phys + 1 * 8192);
670
portc->effectslot.bank9->PgLoopEnd = portc->effectslot.bank10->PgLoopEnd =
672
portc->effectslot.bank9->PgStart = portc->effectslot.bank10->PgStart = 0;
674
WRITEL (AC97_SEC_CONFIG, (READL (AC97_SEC_CONFIG) & ~0x0030) | 0x0010);
675
WRITEL (MAP_OF_EFFECTS, 0x18); /* effect 2,3 */
676
WRITEL (MODE, READL (MODE) | (1 << 30)); /* AC3 Setup */
681
SetupPlayBank (int dev, int slot, oss_native_word sbase)
683
ymf7xx_devc *devc = audio_engines[dev]->devc;
684
ymf7xx_portc *portc = audio_engines[dev]->portc;
685
dmap_t *dmap = audio_engines[dev]->dmap_out;
689
bank1 = (PLAY_BANK *) sbase;
691
(PLAY_BANK *) (sbase + READL (PLAY_CNTRL_SIZE) * sizeof (unsigned int));
693
memset ((void *) bank1, 0, sizeof (PLAY_BANK));
694
memset ((void *) bank2, 0, sizeof (PLAY_BANK));
698
portc->bank3 = bank1;
699
portc->bank4 = bank2;
703
portc->bank1 = bank1;
704
portc->bank2 = bank2;
707
/* setup format field */
708
bank1->Format = LSWAP (SetFormatField (portc));
709
bank1->EgGain = bank1->EgGainEnd = LSWAP (0x40000000);
711
if (portc->channels == 1)
714
bank1->LchGain = bank1->LchGainEnd = LSWAP (0x40000000);
715
bank1->RchGain = bank1->RchGainEnd = LSWAP (0x40000000);
716
bank1->Effect2Gain = bank1->Effect2GainEnd = LSWAP (0x40000000);
717
bank1->Effect3Gain = bank1->Effect3GainEnd = LSWAP (0x40000000);
723
bank1->Format = LSWAP (LSWAP (bank1->Format) + 1);
724
bank1->RchGain = bank1->RchGainEnd = LSWAP (0x40000000);
725
bank1->Effect2Gain = bank1->Effect2GainEnd = LSWAP (0x40000000);
729
bank1->LchGain = bank1->LchGainEnd = LSWAP (0x40000000);
730
bank1->Effect3Gain = bank1->Effect3GainEnd = LSWAP (0x40000000);
734
bank1->LoopDefault = 0;
735
bank1->NumOfFrames = 0;
736
bank1->LoopCount = 0;
741
bank1->PgBase = LSWAP (dmap->dmabuf_phys);
744
bank1->PgLoopEnd = LSWAP (dmap->bytes_in_use / portc->dacfmt);
746
/* PgDelta & PgDeltaEnd */
747
bank1->PgDelta = bank1->PgDeltaEnd = LSWAP (SetPgDeltaField (portc));
749
if (portc->channels == 4)
750
bank1->PgDelta = bank1->PgDeltaEnd *= 2;
753
bank1->LpfK = bank1->LpfKEnd = LSWAP (SetLpfKField (portc));
756
bank1->LpfQ = LSWAP (SetLpfQField (portc));
758
memcpy (bank2, bank1, sizeof (PLAY_BANK));
762
SetupPlaySlot (int dev, int slot)
765
oss_native_word sltbase;
766
oss_native_word physbase;
768
ymf7xx_devc *devc = audio_engines[dev]->devc;
769
ymf7xx_portc *portc = audio_engines[dev]->portc;
772
sltbase = (oss_native_word) devc->slt + (tmp * 0x120);
773
physbase = devc->slt_phys + (tmp * 0x120);
774
SetupPlayBank (dev, 1, sltbase);
775
devc->tab[tmp] = LSWAP (physbase);
777
if (portc->channels > 1)
781
SetupPlayBank (dev, 2, sltbase);
783
devc->tab[tmp] = LSWAP (physbase);
790
ymf7xx_audio_prepare_for_output (int dev, int bsize, int bcount)
792
ymf7xx_devc *devc = audio_engines[dev]->devc;
793
ymf7xx_portc *portc = audio_engines[dev]->portc;
794
oss_native_word flags;
796
MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
798
if (portc->bits == AFMT_AC3)
802
ymf7xx_spdif_control (devc->mixer_dev, 1, SNDCTL_MIX_WRITE, 1); /* enable SPDIF */
803
ymf7xx_spdif_control (devc->mixer_dev, 4, SNDCTL_MIX_WRITE, 1); /* enable AC3 */
806
ymf7xx_spdif_control (devc->mixer_dev, 4, SNDCTL_MIX_WRITE, 0); /* enable AC3 */
809
portc->dacfmt = portc->channels * (portc->bits / 8);
811
if (portc->dacfmt > 4)
813
/* portc->devs_opened = SetupPlaySlot (dev, portc->devnum); -> trigger */
814
/* set effects slot */
815
SetupEffectSlot (dev);
817
if (portc->bits != AFMT_AC3)
818
WRITEL (NATIVE_DAC, 0xFFFFFFFF);
820
WRITEL (NATIVE_DAC, 0x00000000);
822
portc->audio_enabled &= ~PCM_ENABLE_OUTPUT;
823
portc->trigger_bits &= ~PCM_ENABLE_OUTPUT;
824
MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
830
ymf7xx_get_buffer_pointer (int dev, dmap_t * dmap, int direction)
832
ymf7xx_portc *portc = audio_engines[dev]->portc;
834
unsigned int ptr = 0;
836
if (direction == PCM_ENABLE_OUTPUT)
838
ptr = LSWAP (portc->bank1->PgStart);
839
ptr *= portc->dacfmt;
841
if (direction == PCM_ENABLE_INPUT)
843
ptr = LSWAP (portc->recslot.bank3->PgStartAdr);
848
static audiodrv_t ymf7xx_audio_driver = {
851
ymf7xx_audio_output_block,
852
ymf7xx_audio_start_input,
854
ymf7xx_audio_prepare_for_input,
855
ymf7xx_audio_prepare_for_output,
859
ymf7xx_audio_reset_input,
860
ymf7xx_audio_reset_output,
861
ymf7xx_audio_trigger,
862
ymf7xx_audio_set_rate,
863
ymf7xx_audio_set_format,
864
ymf7xx_audio_set_channels,
869
NULL, /* ymf7xx_alloc_buffer */
870
NULL, /* ymf7xx_free_buffer */
873
ymf7xx_get_buffer_pointer
878
init_audio (ymf7xx_devc * devc)
880
devc->audio_initialized = 1;
883
uninit_audio (ymf7xx_devc * devc)
885
devc->audio_initialized = 0;
891
#ifdef OBSOLETED_STUFF
893
* This device has "ISA style" MIDI and FM subsystems. Such devices don't
894
* use PCI config space for the I/O ports and interrupts. Instead the driver
895
* needs to allocate proper resources itself. This functionality is no longer
896
* possible. For this reason the MIDI and FM parts are not accessible.
899
attach_fm (ymf7xx_devc * devc)
901
devc->fm_attached = 0;
902
if (!opl3_detect (0x388, devc->osdev))
904
cmn_err (CE_WARN, "OPL3 not detected\n");
907
opl3_init (0x388, devc->osdev);
908
devc->fm_attached = 1;
913
attach_mpu (ymf7xx_devc * devc)
915
struct address_info hw_config;
917
hw_config.io_base = devc->mpu_base;
918
hw_config.irq = devc->mpu_irq;
921
hw_config.always_detect = 0;
922
hw_config.name = "Yamaha DS-XG MPU401";
923
hw_config.driver_use_1 = 0;
924
hw_config.driver_use_2 = 0;
925
hw_config.osdev = devc->osdev;
927
CREATE_OSP (hw_config.osdev);
929
hw_config.card_subtype = 0;
931
if (!probe_uart401 (&hw_config))
933
cmn_err (CE_WARN, "MPU-401 was not detected\n");
936
DDB (cmn_err (CE_WARN, "MPU-401 detected - Good\n"));
937
devc->mpu_attached = 1;
938
attach_uart401 (&hw_config);
942
unload_mpu (ymf7xx_devc * devc)
944
struct address_info hw_config;
946
hw_config.io_base = devc->mpu_base;
947
hw_config.irq = devc->mpu_irq;
950
hw_config.always_detect = 0;
951
hw_config.name = "Yahama DS-XG MPU401";
952
hw_config.driver_use_1 = 0;
953
hw_config.driver_use_2 = 0;
954
hw_config.osdev = devc->osdev;
956
CREATE_OSP (hw_config.osdev);
958
hw_config.card_subtype = 0;
960
devc->mpu_attached = 0;
961
unload_uart401 (&hw_config);
966
ymf7xx_spdif_control (int dev, int ctrl, unsigned int cmd, int value)
968
ymf7xx_devc *devc = mixer_devs[dev]->hw_devc;
969
/* int left, right; */
971
if (cmd == SNDCTL_MIX_READ)
976
case 1: /* S/PDIF Enable/Disable */
977
value = READL (SPDIFOUT_CONTROL) & 0x1;
980
case 2: /* S/PDIF Record Enable */
981
value = devc->spdif_in;
984
case 3: /* S/PDIF Loopback */
985
value = READL (SPDIFIN_CONTROL) & (1 << 4);
988
case 4: /* AC3 Output */
989
value = READL (SPDIFOUT_CONTROL) & (1 << 1);
992
case 5: /* CopyProtection Bit */
993
value = READL (SPDIFOUT_STATUS) & (1 << 2);
995
case 6: /* SPDIF OUTVOL */
996
value = devc->mixlevels[0];
998
case 7: /* SPDIF LOOPVOL */
999
value = devc->mixlevels[1];
1001
case 8: /* SPDIF AC3VOL */
1002
value = devc->mixlevels[2];
1007
if (cmd == SNDCTL_MIX_WRITE)
1011
case 1: /* S/PDIF OUTPUT ENABLE/DISABLE */
1013
WRITEL (SPDIFOUT_CONTROL, READL (SPDIFOUT_CONTROL) | 0x1);
1015
WRITEL (SPDIFOUT_CONTROL, READL (SPDIFOUT_CONTROL) & ~0x1);
1018
case 2: /* Record S/PDIF IN ENABLE DISABLE */
1021
WRITEL (SPDIFIN_CONTROL, READL (SPDIFIN_CONTROL) | 0x1);
1026
WRITEL (SPDIFIN_CONTROL, READL (SPDIFIN_CONTROL) & ~0x1);
1031
case 3: /* S/PDIF Loopback Mode */
1033
WRITEL (SPDIFIN_CONTROL, READL (SPDIFIN_CONTROL) | (1 << 4));
1035
WRITEL (SPDIFIN_CONTROL, READL (SPDIFIN_CONTROL) & ~(1 << 4));
1038
case 4: /* AC3 Output Mode */
1040
WRITEL (SPDIFOUT_CONTROL, READL (SPDIFOUT_CONTROL) | (1 << 1));
1042
WRITEL (SPDIFOUT_CONTROL, READL (SPDIFOUT_CONTROL) & ~(1 << 1));
1046
case 5: /* Copy Protect Mode */
1050
ac3_mode = READL (SPDIFOUT_CONTROL) & (1 << 1);
1055
WRITEL (SPDIFOUT_STATUS,
1056
READL (SPDIFOUT_STATUS) | (1 << 1));
1058
WRITEL (SPDIFOUT_STATUS, READL (SPDIFOUT_STATUS) & ~0x3E);
1063
WRITEL (SPDIFOUT_STATUS,
1064
READL (SPDIFOUT_STATUS) | (3 << 1));
1067
WRITEL (SPDIFOUT_STATUS,
1068
READL (SPDIFOUT_STATUS) | (1 << 2));
1074
left = value & 0xff;
1075
right = (value >> 8) & 0xff;
1080
value = left | (right << 8);
1081
left = left * 0xFFFF / 100;
1082
right = right * 0xFFFF / 100;
1083
WRITEL (SPDIFOUTVOL, left << 16 | right);
1084
devc->mixlevels[0] = value;
1087
left = value & 0xff;
1088
right = (value >> 8) & 0xff;
1093
value = left | (right << 8);
1094
left = left * 0xFFFF / 100;
1095
right = right * 0xFFFF / 100;
1096
WRITEL (SPDIFLOOPVOL, left << 16 | right);
1097
devc->mixlevels[1] = value;
1100
left = value & 0xff;
1101
right = (value >> 8) & 0xff;
1106
value = left | (right << 8);
1107
left = left * 0xFFFF / 100;
1108
right = right * 0xFFFF / 100;
1109
WRITEL (AC3_OUTPUT, left << 16 | right);
1110
devc->mixlevels[2] = value;
1119
ymf7xx_mix_init (int dev)
1123
if ((group = mixer_ext_create_group (dev, 0, "SPDIF")) < 0)
1126
if ((err = mixer_ext_create_control (dev, group, 1, ymf7xx_spdif_control,
1127
MIXT_ONOFF, "ENABLE", 1,
1128
MIXF_READABLE | MIXF_WRITEABLE)) < 0)
1131
if ((err = mixer_ext_create_control (dev, group, 2, ymf7xx_spdif_control,
1132
MIXT_ONOFF, "RECORD", 1,
1133
MIXF_READABLE | MIXF_WRITEABLE)) < 0)
1136
if ((err = mixer_ext_create_control (dev, group, 3, ymf7xx_spdif_control,
1137
MIXT_ONOFF, "LOOP", 1,
1138
MIXF_READABLE | MIXF_WRITEABLE)) < 0)
1142
if ((err = mixer_ext_create_control (dev, group, 4, ymf7xx_spdif_control,
1143
MIXT_ONOFF, "AC3", 1,
1144
MIXF_READABLE | MIXF_WRITEABLE)) < 0)
1146
if ((err = mixer_ext_create_control (dev, group, 5, ymf7xx_spdif_control,
1147
MIXT_ONOFF, "COPYPROT", 1,
1148
MIXF_READABLE | MIXF_WRITEABLE)) < 0)
1151
if ((err = mixer_ext_create_control (dev, group, 6, ymf7xx_spdif_control,
1152
MIXT_STEREOSLIDER, "OUTVOL", 100,
1153
MIXF_MAINVOL | MIXF_READABLE | MIXF_WRITEABLE)) < 0)
1155
if ((err = mixer_ext_create_control (dev, group, 7, ymf7xx_spdif_control,
1156
MIXT_STEREOSLIDER, "LOOPVOL", 100,
1157
MIXF_READABLE | MIXF_WRITEABLE)) < 0)
1159
if ((err = mixer_ext_create_control (dev, group, 8, ymf7xx_spdif_control,
1160
MIXT_STEREOSLIDER, "AC3VOL", 100,
1161
MIXF_READABLE | MIXF_WRITEABLE)) < 0)
1169
init_ymf7xx (ymf7xx_devc * devc)
1175
WRITEL (NATIVE_DAC, 0x00000000);
1176
WRITEL (MODE, 0x00010000);
1177
WRITEL (MODE, 0x00000000);
1178
WRITEL (MAP_OF_REC, 0x00000000);
1179
WRITEL (MAP_OF_EFFECTS, 0x00000000);
1180
WRITEL (PLAY_CNTRL_BASE, 0x00000000);
1181
WRITEL (REC_CNTRL_BASE, 0x00000000);
1182
WRITEL (EFF_CNTRL_BASE, 0x00000000);
1183
WRITEL (CONTROL_SELECT, 1);
1184
WRITEL (GLOBAL_CONTROL, READL (GLOBAL_CONTROL) & ~0x0007);
1185
WRITEL (ZVOUTVOL, 0xFFFFFFFF);
1186
WRITEL (ZVLOOPVOL, 0xFFFFFFFF);
1187
WRITEL (SPDIFOUTVOL, 0xFFFFFFFF);
1188
WRITEL (SPDIFLOOPVOL, 0x3FFF3FFF);
1191
if (ac97_read (devc, 0x02) == 0xFFFF)
1193
for (i = 0; i < 100; i++)
1194
if (ac97_read (devc, 0x02) != 0xFFFF)
1200
install_ucode (devc, 0x1000, dsp, dsp_size);
1201
switch (devc->deviceid)
1203
case YAMAHA_YMF724F_ID:
1204
case YAMAHA_YMF740C_ID:
1205
case YAMAHA_YMF744_ID:
1206
case YAMAHA_YMF754_ID:
1207
install_ucode (devc, 0x4000, cntrl1E, cntrl1E_size);
1210
install_ucode (devc, 0x4000, cntrl, cntrl_size);
1214
/* add an extra reset to init the mixers */
1215
ac97_write (devc, 0x02, 0x0000);
1216
ac97_write (devc, 0x18, 0x0808);
1218
/* Now check to see if the DSP is started or not */
1226
cmn_err (CE_WARN, "CTR/DSP Init/ TimeOut\n");
1229
fEnd = READL (CONTROL_SELECT) & 0x1;
1231
while (fEnd == 0x1);
1235
ac97_install (&devc->ac97devc, "Yamaha DS-XG", ac97_read, ac97_write,
1239
devc->mixer_dev = my_mixer;
1240
mixer_ext_set_init_fn (my_mixer, ymf7xx_mix_init, 20);
1245
#ifdef OBSOLETED_STUFF
1246
if (devc->fm_base > 0)
1248
if (devc->mpu_base > 0)
1252
if (devc->play_table_virt == 0)
1254
/* Allocate the Play Table */
1255
oss_native_word phaddr;
1257
CONTIG_MALLOC (devc->osdev, 0x1000, MEMLIMIT_32BITS, &phaddr, devc->dmabuf1_dma_handle);
1258
devc->play_table_virt = (oss_native_word) devc->dmabuf1;
1259
devc->play_table = phaddr;
1261
/* Allocate Effect Table */
1263
CONTIG_MALLOC (devc->osdev, 1024, MEMLIMIT_32BITS, &phaddr, devc->dmabuf2_dma_handle);
1264
devc->effect_table_virt = (oss_native_word) devc->dmabuf2;
1265
devc->effect_table = phaddr;
1267
/* Allocate Effect Scratch Buffer */
1269
CONTIG_MALLOC (devc->osdev, 2 * 8192, MEMLIMIT_32BITS, &phaddr, devc->eff_buf_dma_handle);
1270
devc->eff_buf_phys = phaddr;
1272
/* Allocate the Record Table */
1274
CONTIG_MALLOC (devc->osdev, 1024, MEMLIMIT_32BITS, &phaddr, devc->dmabuf3_dma_handle);
1275
devc->rec_table_virt = (oss_native_word) devc->dmabuf3;
1276
devc->rec_table = phaddr;
1278
/* Setup Play Table */
1279
devc->tab = (unsigned int *) devc->play_table_virt;
1280
devc->slt = (oss_native_word) (devc->play_table_virt + 0x100);
1281
devc->slt_phys = (devc->play_table + 0x100);
1282
memset ((void *) devc->tab, 0, 0x1000);
1283
WRITEL (PLAY_CNTRL_BASE, (unsigned int) devc->play_table);
1284
devc->tab[0] = LSWAP (20); /* setup 20 slots for 8 playback devices */
1285
/* Setup Effect Table and init Effect Slots */
1286
devc->effecttab = (unsigned int *) devc->effect_table_virt;
1287
memset ((void *) devc->effecttab, 0, 1024);
1288
WRITEL (EFF_CNTRL_BASE, (unsigned int) devc->effect_table);
1290
//SetupEffectSlot (dev);
1292
/* Setup Record Table */
1293
devc->rectab = (unsigned int *) devc->rec_table_virt;
1294
memset ((void *) devc->rectab, 0, 1024);
1295
WRITEL (REC_CNTRL_BASE, (unsigned int) devc->rec_table);
1298
for (i = 0; i < MAX_PORTC; i++)
1302
ymf7xx_portc *portc = &devc->portc[i];
1303
int caps = ADEV_AUTOMODE | ADEV_NOVIRTUAL;
1307
strcpy (tmp_name, devc->chip_name);
1308
caps |= ADEV_DUPLEX;
1312
strcpy (tmp_name, devc->chip_name);
1313
caps |= ADEV_NOINPUT;
1315
caps |= ADEV_SHADOW;
1319
if ((adev = oss_install_audiodev (OSS_AUDIO_DRIVER_VERSION,
1323
&ymf7xx_audio_driver,
1324
sizeof (audiodrv_t),
1326
AFMT_U8 | AFMT_S16_LE | AFMT_AC3,
1336
audio_engines[adev]->mixer_dev = my_mixer;
1337
audio_engines[adev]->portc = portc;
1338
audio_engines[adev]->rate_source = first_dev;
1339
audio_engines[adev]->min_block = 64;
1340
audio_engines[adev]->min_rate = 5000;
1341
audio_engines[adev]->max_rate = 48000;
1342
audio_engines[adev]->vmix_flags |= VMIX_MULTIFRAG;
1343
audio_engines[adev]->caps |= PCM_CAP_FREERATE;
1344
audio_engines[adev]->min_channels = 2;
1345
audio_engines[adev]->max_channels = 4;
1346
portc->open_mode = 0;
1347
portc->audiodev = adev;
1349
#ifdef CONFIG_OSS_VMIX
1351
vmix_attach_audiodev(devc->osdev, adev, -1, 0);
1359
oss_ymf7xx_attach (oss_device_t * osdev)
1363
unsigned char pci_irq_line, pci_revision;
1364
unsigned short pci_command, vendor, device;
1365
unsigned char pci_reset;
1366
unsigned short pci_legacy;
1369
DDB (cmn_err (CE_WARN, "Entered DS-XG attach routine\n"));
1371
pci_read_config_word (osdev, PCI_VENDOR_ID, &vendor);
1372
pci_read_config_word (osdev, PCI_DEVICE_ID, &device);
1374
if (((vendor != YAMAHA_VENDOR_ID)) ||
1375
(device != YAMAHA_YMF740_ID &&
1376
device != YAMAHA_YMF744_ID &&
1377
device != YAMAHA_YMF754_ID &&
1378
device != YAMAHA_YMF740C_ID &&
1379
device != YAMAHA_YMF724_ID &&
1380
device != YAMAHA_YMF734_ID && device != YAMAHA_YMF724F_ID))
1383
oss_pci_byteswap (osdev, 1);
1385
if ((devc = PMALLOC (osdev, sizeof (*devc))) == NULL)
1387
cmn_err (CE_WARN, "Out of memory\n");
1391
devc->osdev = osdev;
1394
pci_read_config_byte (osdev, PCI_REVISION_ID, &pci_revision);
1395
pci_read_config_word (osdev, PCI_COMMAND, &pci_command);
1396
pci_read_config_irq (osdev, PCI_INTERRUPT_LINE, &pci_irq_line);
1397
pci_read_config_dword (osdev, PCI_MEM_BASE_ADDRESS_0, &devc->base0addr);
1399
if (devc->base0addr == 0)
1401
cmn_err (CE_WARN, "I/O address not assigned by BIOS.\n");
1405
if (pci_irq_line == 0)
1407
cmn_err (CE_WARN, "IRQ not assigned by BIOS (%d).\n", pci_irq_line);
1412
(CE_WARN, "rev %x I/O base %04x\n", pci_revision, devc->base0addr));
1414
devc->deviceid = device;
1417
case YAMAHA_YMF724_ID:
1418
devc->chip_name = "Yamaha YMF724";
1421
case YAMAHA_YMF724F_ID:
1422
devc->chip_name = "Yamaha YMF724F";
1425
case YAMAHA_YMF734_ID:
1426
devc->chip_name = "Yamaha YMF734";
1429
case YAMAHA_YMF740_ID:
1430
devc->chip_name = "Yamaha YMF740";
1433
case YAMAHA_YMF740C_ID:
1434
devc->chip_name = "Yamaha YMF740C";
1437
case YAMAHA_YMF744_ID:
1438
devc->chip_name = "Yamaha YMF744";
1441
case YAMAHA_YMF754_ID:
1442
devc->chip_name = "Yamaha YMF754";
1446
devc->chip_name = "Yamaha DS-XG";
1449
devc->fm_base = yamaha_fm_ioaddr;
1450
devc->mpu_base = yamaha_mpu_ioaddr;
1451
devc->mpu_irq = yamaha_mpu_irq;
1453
/* reset the device */
1454
pci_read_config_byte (osdev, 0x48, &pci_reset);
1456
if (pci_reset & 0x03)
1458
pci_write_config_byte (osdev, 0x48, pci_reset & 0xFC);
1459
pci_write_config_byte (osdev, 0x48, pci_reset | 0x03);
1460
pci_write_config_byte (osdev, 0x48, pci_reset & 0xFC);
1463
/* Legacy I/O setup - setup MPU and FM io/irq values */
1464
devc->fm_attached = 0;
1465
devc->mpu_attached = 0;
1466
/*pcipci_legacy = 0x0020|0x00C0|0x0004; // 10 bit address decode and Joystick */
1469
pci_legacy |= 0x0002; /* FM enable */
1473
pci_legacy |= 0x0008; /* MPU I/O enable */
1475
switch (devc->mpu_irq)
1478
pci_legacy |= 0x0010;
1481
pci_legacy |= 0x0810;
1484
pci_legacy |= 0x1010;
1487
pci_legacy |= 0x1810;
1490
pci_legacy |= 0x2010;
1497
pci_write_config_word (osdev, 0x40, pci_legacy);
1499
pci_legacy = 0x0000;
1501
switch (devc->fm_base)
1504
pci_legacy |= 0x0000;
1507
pci_legacy |= 0x0001;
1510
pci_legacy |= 0x0002;
1513
pci_legacy |= 0x0003;
1519
switch (devc->mpu_base)
1522
pci_legacy |= 0x0000;
1525
pci_legacy |= 0x0010;
1528
pci_legacy |= 0x0020;
1531
pci_legacy |= 0x0020;
1536
pci_write_config_word (osdev, 0x42, pci_legacy);
1538
/* activate the device */
1539
pci_command |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
1540
pci_write_config_word (osdev, PCI_COMMAND, pci_command);
1542
/* Map the shared memory area */
1544
(unsigned int *) MAP_PCI_MEM (devc->osdev, 0, devc->base0addr, 32 * 1024);
1545
devc->dwRegister = (unsigned int *) devc->base0virt;
1546
devc->wRegister = (unsigned short *) devc->base0virt;
1547
devc->bRegister = (unsigned char *) devc->base0virt;
1550
MUTEX_INIT (devc->osdev, devc->mutex, MH_DRV);
1551
MUTEX_INIT (devc->osdev, devc->low_mutex, MH_DRV + 1);
1553
oss_register_device (osdev, devc->chip_name);
1555
if (oss_register_interrupts (devc->osdev, 0, ymf7xxintr, NULL) < 0)
1557
cmn_err (CE_WARN, "Can't allocate IRQ%d\n", pci_irq_line);
1561
return init_ymf7xx (devc); /* Detected */
1566
oss_ymf7xx_detach (oss_device_t * osdev)
1568
ymf7xx_devc *devc = (ymf7xx_devc *) osdev->devc;
1570
if (oss_disable_device (osdev) < 0)
1578
CONTIG_FREE (devc->osdev, devc->dmabuf1, 0x1000, devc->dmabuf1_dma_handle);
1584
CONTIG_FREE (devc->osdev, devc->dmabuf2, 1024, devc->dmabuf2_dma_handle);
1590
CONTIG_FREE (devc->osdev, devc->eff_buf, 16 * 1024, devc->eff_buf_dma_handle);
1596
CONTIG_FREE (devc->osdev, devc->dmabuf3, 1024, devc->dmabuf3_dma_handle);
1600
devc->play_table_virt = 0;
1601
devc->effect_table_virt = 0;
1602
devc->rec_table_virt = 0;
1604
#ifdef OBSOLETED_STUFF
1605
if (devc->mpu_attached)
1608
devc->mpu_attached = 0;
1612
oss_unregister_interrupts (devc->osdev);
1614
MUTEX_CLEANUP (devc->mutex);
1615
MUTEX_CLEANUP (devc->low_mutex);
1617
if (devc->base0addr != 0)
1619
UNMAP_PCI_MEM (devc->osdev, 0, devc->base0addr, devc->base0virt,
1621
devc->base0addr = 0;
1623
oss_unregister_device (devc->osdev);