Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
80e38dd5
Commit
80e38dd5
authored
Jul 17, 2003
by
Alan Cox
Committed by
Linus Torvalds
Jul 17, 2003
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[PATCH] emu10k further updates/bug fixes
parent
ebf09724
Changes
18
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
1137 additions
and
537 deletions
+1137
-537
sound/oss/emu10k1/8010.h
sound/oss/emu10k1/8010.h
+120
-7
sound/oss/emu10k1/audio.c
sound/oss/emu10k1/audio.c
+41
-21
sound/oss/emu10k1/cardmi.c
sound/oss/emu10k1/cardmi.c
+4
-4
sound/oss/emu10k1/cardmo.c
sound/oss/emu10k1/cardmo.c
+4
-4
sound/oss/emu10k1/cardwo.c
sound/oss/emu10k1/cardwo.c
+84
-64
sound/oss/emu10k1/efxmgr.c
sound/oss/emu10k1/efxmgr.c
+14
-9
sound/oss/emu10k1/efxmgr.h
sound/oss/emu10k1/efxmgr.h
+20
-3
sound/oss/emu10k1/hwaccess.c
sound/oss/emu10k1/hwaccess.c
+92
-40
sound/oss/emu10k1/hwaccess.h
sound/oss/emu10k1/hwaccess.h
+16
-7
sound/oss/emu10k1/irqmgr.h
sound/oss/emu10k1/irqmgr.h
+9
-9
sound/oss/emu10k1/main.c
sound/oss/emu10k1/main.c
+570
-310
sound/oss/emu10k1/midi.h
sound/oss/emu10k1/midi.h
+23
-0
sound/oss/emu10k1/mixer.c
sound/oss/emu10k1/mixer.c
+48
-41
sound/oss/emu10k1/passthrough.c
sound/oss/emu10k1/passthrough.c
+5
-4
sound/oss/emu10k1/passthrough.h
sound/oss/emu10k1/passthrough.h
+29
-0
sound/oss/emu10k1/recmgr.c
sound/oss/emu10k1/recmgr.c
+11
-5
sound/oss/emu10k1/voicemgr.c
sound/oss/emu10k1/voicemgr.c
+41
-5
sound/oss/emu10k1/voicemgr.h
sound/oss/emu10k1/voicemgr.h
+6
-4
No files found.
sound/oss/emu10k1/8010.h
View file @
80e38dd5
This diff is collapsed.
Click to expand it.
sound/oss/emu10k1/audio.c
View file @
80e38dd5
...
...
@@ -158,8 +158,8 @@ static ssize_t emu10k1_audio_write(struct file *file, const char *buffer, size_t
spin_unlock_irqrestore
(
&
woinst
->
lock
,
flags
);
return
-
ENXIO
;
}
if
(
woinst
->
format
.
passthrough
)
{
// This is for emu10k1 revs less than 7, we need to go through tram
if
(
woinst
->
format
.
passthrough
==
1
)
{
int
r
;
woinst
->
buffer
.
ossfragshift
=
PT_BLOCKSIZE_LOG2
;
...
...
@@ -350,8 +350,9 @@ static int emu10k1_audio_ioctl(struct inode *inode, struct file *file, unsigned
case
SNDCTL_DSP_GETCAPS
:
DPF
(
2
,
"SNDCTL_DSP_GETCAPS:
\n
"
);
return
put_user
(
DSP_CAP_DUPLEX
|
DSP_CAP_REALTIME
|
DSP_CAP_TRIGGER
|
DSP_CAP_MMAP
|
DSP_CAP_COPROC
,
(
int
*
)
arg
);
return
put_user
(
DSP_CAP_DUPLEX
|
DSP_CAP_REALTIME
|
DSP_CAP_TRIGGER
|
DSP_CAP_MMAP
|
DSP_CAP_COPROC
|
DSP_CAP_MULTI
,
(
int
*
)
arg
);
case
SNDCTL_DSP_SPEED
:
DPF
(
2
,
"SNDCTL_DSP_SPEED:
\n
"
);
...
...
@@ -528,8 +529,8 @@ static int emu10k1_audio_ioctl(struct inode *inode, struct file *file, unsigned
else
if
(
file
->
f_mode
&
FMODE_WRITE
)
{
val
=
AFMT_S16_LE
|
AFMT_U8
;
if
(
emu10k1_find_control_gpr
(
&
wave_dev
->
card
->
mgr
,
wave_dev
->
card
->
pt
.
patch_name
,
wave_dev
->
card
->
pt
.
enable_gpr_name
)
>=
0
)
wave_dev
->
card
->
pt
.
patch_name
,
wave_dev
->
card
->
pt
.
enable_gpr_name
)
>=
0
)
val
|=
AFMT_AC3
;
}
return
put_user
(
val
,
(
int
*
)
arg
);
...
...
@@ -789,7 +790,7 @@ static int emu10k1_audio_ioctl(struct inode *inode, struct file *file, unsigned
cinfo
.
blocks
=
0
;
}
if
(
wiinst
->
mmapped
)
if
(
wiinst
->
mmapped
)
wiinst
->
buffer
.
bytestocopy
%=
wiinst
->
buffer
.
fragment_size
;
spin_unlock_irqrestore
(
&
wiinst
->
lock
,
flags
);
...
...
@@ -811,15 +812,17 @@ static int emu10k1_audio_ioctl(struct inode *inode, struct file *file, unsigned
spin_lock_irqsave
(
&
woinst
->
lock
,
flags
);
if
(
woinst
->
state
&
WAVE_STATE_OPEN
||
(
woinst
->
format
.
passthrough
&&
wave_dev
->
card
->
pt
.
state
))
{
(
(
woinst
->
format
.
passthrough
==
1
)
&&
wave_dev
->
card
->
pt
.
state
))
{
int
num_fragments
;
if
(
woinst
->
format
.
passthrough
)
{
if
(
woinst
->
format
.
passthrough
==
1
)
{
emu10k1_pt_waveout_update
(
wave_dev
);
cinfo
.
bytes
=
woinst
->
total_played
;
}
else
{
emu10k1_waveout_update
(
woinst
);
cinfo
.
bytes
=
woinst
->
total_played
;
}
cinfo
.
ptr
=
woinst
->
buffer
.
hw_pos
;
num_fragments
=
cinfo
.
bytes
/
woinst
->
buffer
.
fragment_size
;
cinfo
.
blocks
=
num_fragments
-
woinst
->
blocks
;
...
...
@@ -899,7 +902,7 @@ static int emu10k1_audio_ioctl(struct inode *inode, struct file *file, unsigned
if
(
file
->
f_mode
&
FMODE_WRITE
)
{
/* digital pass-through fragment count and size are fixed values */
if
(
woinst
->
state
&
WAVE_STATE_OPEN
||
woinst
->
format
.
passthrough
)
if
(
woinst
->
state
&
WAVE_STATE_OPEN
||
(
woinst
->
format
.
passthrough
==
1
)
)
return
-
EINVAL
;
/* too late to change */
woinst
->
buffer
.
ossfragshift
=
val
&
0xffff
;
...
...
@@ -936,19 +939,35 @@ static int emu10k1_audio_ioctl(struct inode *inode, struct file *file, unsigned
kfree
(
buf
);
return
-
EINVAL
;
}
if
(
buf
->
command
==
CMD_WRITE
)
{
#ifdef DBGEMU
if
(
(
buf
->
offs
<
0
)
||
(
buf
->
offs
+
buf
->
len
>
0x8
00
)
||
(
buf
->
len
>
1000
))
{
if
((
buf
->
offs
<
0
)
||
(
buf
->
offs
+
buf
->
len
>
0xe
00
)
||
(
buf
->
len
>
1000
))
{
#else
if
(
((
buf
->
offs
<
0x100
)
||
(
buf
->
offs
+
buf
->
len
>
0x800
)
||
(
buf
->
len
>
1000
))
&&
!
(
(
buf
->
offs
==
DBG
)
&&
(
buf
->
len
==
1
)
)){
#endif
kfree
(
buf
);
return
-
EINVAL
;
}
if
(((
buf
->
offs
<
0x100
)
||
(
buf
->
offs
+
buf
->
len
>
(
wave_dev
->
card
->
is_audigy
?
0xe00
:
0x800
))
||
(
buf
->
len
>
1000
)
)
&&
!
(
//any register allowed raw access to users goes here:
(
buf
->
offs
==
DBG
||
buf
->
offs
==
A_DBG
)
&&
(
buf
->
len
==
1
)))
{
#endif
kfree
(
buf
);
return
-
EINVAL
;
}
}
else
{
if
((
buf
->
offs
<
0
)
||
(
buf
->
offs
+
buf
->
len
>
0xe00
)
||
(
buf
->
len
>
1000
))
{
kfree
(
buf
);
return
-
EINVAL
;
}
}
if
(((
unsigned
)
buf
->
flags
)
>
0x3f
)
buf
->
flags
=
0
;
if
(
buf
->
command
==
CMD_READ
)
{
for
(
i
=
0
;
i
<
buf
->
len
;
i
++
)
((
u32
*
)
buf
->
data
)[
i
]
=
sblive_readptr
(
wave_dev
->
card
,
buf
->
offs
+
i
,
0
);
((
u32
*
)
buf
->
data
)[
i
]
=
sblive_readptr
(
wave_dev
->
card
,
buf
->
offs
+
i
,
buf
->
flags
);
if
(
copy_to_user
((
copr_buffer
*
)
arg
,
buf
,
sizeof
(
copr_buffer
)))
{
kfree
(
buf
);
...
...
@@ -956,7 +975,7 @@ static int emu10k1_audio_ioctl(struct inode *inode, struct file *file, unsigned
}
}
else
{
for
(
i
=
0
;
i
<
buf
->
len
;
i
++
)
sblive_writeptr
(
wave_dev
->
card
,
buf
->
offs
+
i
,
0
,
((
u32
*
)
buf
->
data
)[
i
]);
sblive_writeptr
(
wave_dev
->
card
,
buf
->
offs
+
i
,
buf
->
flags
,
((
u32
*
)
buf
->
data
)[
i
]);
}
kfree
(
buf
);
...
...
@@ -1244,8 +1263,9 @@ static int emu10k1_audio_release(struct inode *inode, struct file *file)
struct
woinst
*
woinst
=
wave_dev
->
woinst
;
spin_lock_irqsave
(
&
woinst
->
lock
,
flags
);
if
(
woinst
->
format
.
passthrough
&&
card
->
pt
.
state
!=
PT_STATE_INACTIVE
)
{
if
(
woinst
->
format
.
passthrough
==
2
)
card
->
pt
.
state
=
PT_STATE_PLAYING
;
if
(
woinst
->
format
.
passthrough
&&
card
->
pt
.
state
!=
PT_STATE_INACTIVE
){
spin_lock
(
&
card
->
pt
.
lock
);
emu10k1_pt_stop
(
card
);
spin_unlock
(
&
card
->
pt
.
lock
);
...
...
sound/oss/emu10k1/cardmi.c
View file @
80e38dd5
...
...
@@ -113,7 +113,7 @@ int emu10k1_mpuin_close(struct emu10k1_card *card)
}
/* Disable RX interrupt */
emu10k1_irq_disable
(
card
,
INTE_MIDIRXENABLE
);
emu10k1_irq_disable
(
card
,
card
->
is_audigy
?
A_INTE_MIDIRXENABLE
:
INTE_MIDIRXENABLE
);
emu10k1_mpu_release
(
card
);
...
...
@@ -189,7 +189,7 @@ int emu10k1_mpuin_start(struct emu10k1_card *card)
card_mpuin
->
qhead
=
0
;
card_mpuin
->
qtail
=
0
;
emu10k1_irq_enable
(
card
,
INTE_MIDIRXENABLE
);
emu10k1_irq_enable
(
card
,
card
->
is_audigy
?
A_INTE_MIDIRXENABLE
:
INTE_MIDIRXENABLE
);
}
return
0
;
...
...
@@ -207,7 +207,7 @@ int emu10k1_mpuin_stop(struct emu10k1_card *card)
DPF
(
2
,
"emu10k1_mpuin_stop()
\n
"
);
emu10k1_irq_disable
(
card
,
INTE_MIDIRXENABLE
);
emu10k1_irq_disable
(
card
,
card
->
is_audigy
?
A_INTE_MIDIRXENABLE
:
INTE_MIDIRXENABLE
);
card_mpuin
->
status
&=
~
FLAGS_MIDM_STARTED
;
/* clear */
...
...
@@ -246,7 +246,7 @@ int emu10k1_mpuin_reset(struct emu10k1_card *card)
DPF
(
2
,
"emu10k1_mpuin_reset()
\n
"
);
emu10k1_irq_disable
(
card
,
INTE_MIDIRXENABLE
);
emu10k1_irq_disable
(
card
,
card
->
is_audigy
?
A_INTE_MIDIRXENABLE
:
INTE_MIDIRXENABLE
);
while
(
card_mpuin
->
firstmidiq
)
{
midiq
=
card_mpuin
->
firstmidiq
;
...
...
sound/oss/emu10k1/cardmo.c
View file @
80e38dd5
...
...
@@ -72,7 +72,7 @@ int emu10k1_mpuout_close(struct emu10k1_card *card)
DPF
(
2
,
"emu10k1_mpuout_close()
\n
"
);
emu10k1_irq_disable
(
card
,
INTE_MIDITXENABLE
);
emu10k1_irq_disable
(
card
,
card
->
is_audigy
?
A_INTE_MIDITXENABLE
:
INTE_MIDITXENABLE
);
spin_lock_irqsave
(
&
card_mpuout
->
lock
,
flags
);
...
...
@@ -142,7 +142,7 @@ int emu10k1_mpuout_add_buffer(struct emu10k1_card *card, struct midi_hdr *midihd
card_mpuout
->
intr
=
0
;
emu10k1_irq_enable
(
card
,
INTE_MIDITXENABLE
);
emu10k1_irq_enable
(
card
,
card
->
is_audigy
?
A_INTE_MIDITXENABLE
:
INTE_MIDITXENABLE
);
spin_unlock_irqrestore
(
&
card_mpuout
->
lock
,
flags
);
...
...
@@ -206,7 +206,7 @@ void emu10k1_mpuout_bh(unsigned long refdata)
if
((
card_mpuout
->
firstmidiq
!=
NULL
)
||
cByteSent
)
{
card_mpuout
->
intr
=
0
;
emu10k1_irq_enable
(
card
,
INTE_MIDITXENABLE
);
emu10k1_irq_enable
(
card
,
card
->
is_audigy
?
A_INTE_MIDITXENABLE
:
INTE_MIDITXENABLE
);
}
spin_unlock_irqrestore
(
&
card_mpuout
->
lock
,
flags
);
...
...
@@ -221,7 +221,7 @@ int emu10k1_mpuout_irqhandler(struct emu10k1_card *card)
DPF
(
4
,
"emu10k1_mpuout_irqhandler
\n
"
);
card_mpuout
->
intr
=
1
;
emu10k1_irq_disable
(
card
,
INTE_MIDITXENABLE
);
emu10k1_irq_disable
(
card
,
card
->
is_audigy
?
A_INTE_MIDITXENABLE
:
INTE_MIDITXENABLE
);
tasklet_hi_schedule
(
&
card_mpuout
->
tasklet
);
...
...
sound/oss/emu10k1/cardwo.c
View file @
80e38dd5
...
...
@@ -85,25 +85,36 @@ static void query_format(struct emu10k1_wavedevice *wave_dev, struct wave_format
break
;
}
if
(
do_passthrough
)
{
i
=
emu10k1_find_control_gpr
(
&
card
->
mgr
,
card
->
pt
.
patch_name
,
card
->
pt
.
intr_gpr_name
);
j
=
emu10k1_find_control_gpr
(
&
card
->
mgr
,
card
->
pt
.
patch_name
,
card
->
pt
.
enable_gpr_name
);
/* currently only one waveout instance may use pass-through */
if
(
i
<
0
||
j
<
0
||
woinst
->
state
!=
WAVE_STATE_CLOSED
||
if
(
woinst
->
state
!=
WAVE_STATE_CLOSED
||
card
->
pt
.
state
!=
PT_STATE_INACTIVE
||
(
wave_fmt
->
samplingrate
!=
48000
&&
!
is_ac3
)
||
(
wave_fmt
->
samplingrate
!=
48000
&&
!
is_ac3
))
{
DPF
(
2
,
"unable to set pass-through mode
\n
"
);
}
else
{
wave_fmt
->
samplingrate
=
48000
;
wave_fmt
->
channels
=
2
;
wave_fmt
->
passthrough
=
1
;
card
->
pt
.
intr_gpr
=
i
;
card
->
pt
.
enable_gpr
=
j
;
card
->
pt
.
state
=
PT_STATE_INACTIVE
;
card
->
pt
.
pos_gpr
=
emu10k1_find_control_gpr
(
&
card
->
mgr
,
card
->
pt
.
patch_name
,
card
->
pt
.
pos_gpr_name
);
DPD
(
2
,
"is_ac3 is %d
\n
"
,
is_ac3
);
card
->
pt
.
ac3data
=
is_ac3
;
wave_fmt
->
bitsperchannel
=
16
;
}
else
if
(
USE_PT_METHOD1
)
{
i
=
emu10k1_find_control_gpr
(
&
card
->
mgr
,
card
->
pt
.
patch_name
,
card
->
pt
.
intr_gpr_name
);
j
=
emu10k1_find_control_gpr
(
&
card
->
mgr
,
card
->
pt
.
patch_name
,
card
->
pt
.
enable_gpr_name
);
if
(
i
<
0
||
j
<
0
)
DPF
(
2
,
"unable to set pass-through mode
\n
"
);
else
{
wave_fmt
->
samplingrate
=
48000
;
wave_fmt
->
channels
=
2
;
card
->
pt
.
pos_gpr
=
emu10k1_find_control_gpr
(
&
card
->
mgr
,
card
->
pt
.
patch_name
,
card
->
pt
.
pos_gpr_name
);
wave_fmt
->
passthrough
=
1
;
card
->
pt
.
intr_gpr
=
i
;
card
->
pt
.
enable_gpr
=
j
;
card
->
pt
.
state
=
PT_STATE_INACTIVE
;
DPD
(
2
,
"is_ac3 is %d
\n
"
,
is_ac3
);
card
->
pt
.
ac3data
=
is_ac3
;
wave_fmt
->
bitsperchannel
=
16
;
}
}
else
{
DPF
(
2
,
"Using Passthrough Method 2
\n
"
);
card
->
pt
.
enable_gpr
=
emu10k1_find_control_gpr
(
&
card
->
mgr
,
card
->
pt
.
patch_name
,
card
->
pt
.
enable_gpr_name
);
wave_fmt
->
passthrough
=
2
;
wave_fmt
->
bitsperchannel
=
16
;
}
}
...
...
@@ -149,33 +160,37 @@ static int get_voice(struct emu10k1_card *card, struct woinst *woinst, unsigned
voice
->
endloop
=
voice
->
startloop
+
woinst
->
buffer
.
size
/
woinst
->
format
.
bytespervoicesample
;
voice
->
start
=
voice
->
startloop
;
if
(
voice
->
flags
&
VOICE_FLAGS_STEREO
)
{
voice
->
params
[
0
].
send_a
=
card
->
waveout
.
send_a
[
1
];
voice
->
params
[
0
].
send_b
=
card
->
waveout
.
send_b
[
1
];
voice
->
params
[
0
].
send_c
=
card
->
waveout
.
send_c
[
1
];
voice
->
params
[
0
].
send_d
=
card
->
waveout
.
send_d
[
1
];
if
(
woinst
->
device
)
voice
->
params
[
0
].
send_routing
=
0x7654
;
else
voice
->
params
[
0
].
send_routing
=
card
->
waveout
.
send_routing
[
1
];
voice
->
params
[
0
].
volume_target
=
0xffff
;
voice
->
params
[
0
].
initial_fc
=
0xff
;
voice
->
params
[
0
].
initial_attn
=
0x00
;
voice
->
params
[
0
].
byampl_env_sustain
=
0x7f
;
voice
->
params
[
0
].
byampl_env_decay
=
0x7f
;
voice
->
params
[
1
].
send_a
=
card
->
waveout
.
send_a
[
2
];
voice
->
params
[
1
].
send_b
=
card
->
waveout
.
send_b
[
2
];
voice
->
params
[
1
].
send_c
=
card
->
waveout
.
send_c
[
2
];
voice
->
params
[
1
].
send_d
=
card
->
waveout
.
send_d
[
2
];
if
(
woinst
->
device
)
voice
->
params
[
1
].
send_routing
=
0x7654
;
else
voice
->
params
[
1
].
send_routing
=
card
->
waveout
.
send_routing
[
2
];
voice
->
params
[
0
].
volume_target
=
0xffff
;
voice
->
params
[
0
].
initial_fc
=
0xff
;
voice
->
params
[
0
].
initial_attn
=
0x00
;
voice
->
params
[
0
].
byampl_env_sustain
=
0x7f
;
voice
->
params
[
0
].
byampl_env_decay
=
0x7f
;
if
(
voice
->
flags
&
VOICE_FLAGS_STEREO
)
{
if
(
woinst
->
format
.
passthrough
==
2
)
{
voice
->
params
[
0
].
send_routing
=
voice
->
params
[
1
].
send_routing
=
card
->
waveout
.
send_routing
[
ROUTE_PT
];
voice
->
params
[
0
].
send_routing2
=
voice
->
params
[
1
].
send_routing2
=
card
->
waveout
.
send_routing2
[
ROUTE_PT
];
voice
->
params
[
0
].
send_dcba
=
0xff
;
voice
->
params
[
1
].
send_dcba
=
0xff00
;
voice
->
params
[
0
].
send_hgfe
=
voice
->
params
[
1
].
send_hgfe
=
0
;
}
else
{
voice
->
params
[
0
].
send_dcba
=
card
->
waveout
.
send_dcba
[
SEND_LEFT
];
voice
->
params
[
0
].
send_hgfe
=
card
->
waveout
.
send_hgfe
[
SEND_LEFT
];
voice
->
params
[
1
].
send_dcba
=
card
->
waveout
.
send_dcba
[
SEND_RIGHT
];
voice
->
params
[
1
].
send_hgfe
=
card
->
waveout
.
send_hgfe
[
SEND_RIGHT
];
if
(
woinst
->
device
)
{
// /dev/dps1
voice
->
params
[
0
].
send_routing
=
voice
->
params
[
1
].
send_routing
=
card
->
waveout
.
send_routing
[
ROUTE_PCM1
];
voice
->
params
[
0
].
send_routing2
=
voice
->
params
[
1
].
send_routing2
=
card
->
waveout
.
send_routing2
[
ROUTE_PCM1
];
}
else
{
voice
->
params
[
0
].
send_routing
=
voice
->
params
[
1
].
send_routing
=
card
->
waveout
.
send_routing
[
ROUTE_PCM
];
voice
->
params
[
0
].
send_routing2
=
voice
->
params
[
1
].
send_routing2
=
card
->
waveout
.
send_routing2
[
ROUTE_PCM
];
}
}
voice
->
params
[
1
].
volume_target
=
0xffff
;
voice
->
params
[
1
].
initial_fc
=
0xff
;
voice
->
params
[
1
].
initial_attn
=
0x00
;
...
...
@@ -183,30 +198,28 @@ static int get_voice(struct emu10k1_card *card, struct woinst *woinst, unsigned
voice
->
params
[
1
].
byampl_env_decay
=
0x7f
;
}
else
{
if
(
woinst
->
num_voices
>
1
)
{
voice
->
params
[
0
].
send_a
=
0xff
;
voice
->
params
[
0
].
send_b
=
0
;
voice
->
params
[
0
].
send_c
=
0
;
voice
->
params
[
0
].
send_d
=
0
;
voice
->
params
[
0
].
send_routing
=
0xfff0
+
card
->
mchannel_fx
+
voicenum
;
// Multichannel pcm
voice
->
params
[
0
].
send_dcba
=
0xff
;
voice
->
params
[
0
].
send_hgfe
=
0
;
if
(
card
->
is_audigy
)
{
voice
->
params
[
0
].
send_routing
=
0x3f3f3f00
+
card
->
mchannel_fx
+
voicenum
;
voice
->
params
[
0
].
send_routing2
=
0x3f3f3f3f
;
}
else
{
voice
->
params
[
0
].
send_routing
=
0xfff0
+
card
->
mchannel_fx
+
voicenum
;
}
}
else
{
voice
->
params
[
0
].
send_a
=
card
->
waveout
.
send_a
[
0
];
voice
->
params
[
0
].
send_b
=
card
->
waveout
.
send_b
[
0
];
voice
->
params
[
0
].
send_c
=
card
->
waveout
.
send_c
[
0
];
voice
->
params
[
0
].
send_d
=
card
->
waveout
.
send_d
[
0
];
if
(
woinst
->
device
)
voice
->
params
[
0
].
send_routing
=
0x7654
;
else
voice
->
params
[
0
].
send_routing
=
card
->
waveout
.
send_routing
[
0
];
}
voice
->
params
[
0
].
volume_target
=
0xffff
;
voice
->
params
[
0
].
initial_fc
=
0xff
;
voice
->
params
[
0
].
initial_attn
=
0x00
;
voice
->
params
[
0
].
byampl_env_sustain
=
0x7f
;
voice
->
params
[
0
].
byampl_env_decay
=
0x7f
;
voice
->
params
[
0
].
send_dcba
=
card
->
waveout
.
send_dcba
[
SEND_MONO
];
voice
->
params
[
0
].
send_hgfe
=
card
->
waveout
.
send_hgfe
[
SEND_MONO
];
if
(
woinst
->
device
)
{
voice
->
params
[
0
].
send_routing
=
card
->
waveout
.
send_routing
[
ROUTE_PCM1
];
voice
->
params
[
0
].
send_routing2
=
card
->
waveout
.
send_routing2
[
ROUTE_PCM1
];
}
else
{
voice
->
params
[
0
].
send_routing
=
card
->
waveout
.
send_routing
[
ROUTE_PCM
];
voice
->
params
[
0
].
send_routing2
=
card
->
waveout
.
send_routing2
[
ROUTE_PCM
];
}
}
}
DPD
(
2
,
"voice: startloop=%#x, endloop=%#x
\n
"
,
voice
->
startloop
,
voice
->
endloop
);
...
...
@@ -280,9 +293,16 @@ void emu10k1_waveout_start(struct emu10k1_wavedevice *wave_dev)
{
struct
emu10k1_card
*
card
=
wave_dev
->
card
;
struct
woinst
*
woinst
=
wave_dev
->
woinst
;
struct
pt_data
*
pt
=
&
card
->
pt
;
DPF
(
2
,
"emu10k1_waveout_start()
\n
"
);
if
(
woinst
->
format
.
passthrough
==
2
)
{
emu10k1_pt_setup
(
wave_dev
);
sblive_writeptr
(
card
,
(
card
->
is_audigy
?
A_GPR_BASE
:
GPR_BASE
)
+
pt
->
enable_gpr
,
0
,
1
);
pt
->
state
=
PT_STATE_PLAYING
;
}
/* Actual start */
emu10k1_voices_start
(
woinst
->
voice
,
woinst
->
num_voices
,
woinst
->
total_played
);
...
...
sound/oss/emu10k1/efxmgr.c
View file @
80e38dd5
...
...
@@ -80,15 +80,20 @@ void emu10k1_set_control_gpr(struct emu10k1_card *card, int addr, s32 val, int f
if
(
addr
<
0
||
addr
>=
NUM_GPRS
)
return
;
if
(
flag
)
val
+=
sblive_readptr
(
card
,
GPR_BASE
+
addr
,
0
);
if
(
val
>
mgr
->
gpr
[
addr
].
max
)
val
=
mgr
->
gpr
[
addr
].
max
;
else
if
(
val
<
mgr
->
gpr
[
addr
].
min
)
val
=
mgr
->
gpr
[
addr
].
min
;
sblive_writeptr
(
card
,
GPR_BASE
+
addr
,
0
,
val
);
//fixme: once patch manager is up, remember to fix this for the audigy
if
(
card
->
is_audigy
)
{
sblive_writeptr
(
card
,
A_GPR_BASE
+
addr
,
0
,
val
);
}
else
{
if
(
flag
)
val
+=
sblive_readptr
(
card
,
GPR_BASE
+
addr
,
0
);
if
(
val
>
mgr
->
gpr
[
addr
].
max
)
val
=
mgr
->
gpr
[
addr
].
max
;
else
if
(
val
<
mgr
->
gpr
[
addr
].
min
)
val
=
mgr
->
gpr
[
addr
].
min
;
sblive_writeptr
(
card
,
GPR_BASE
+
addr
,
0
,
val
);
}
}
//TODO: make this configurable:
...
...
sound/oss/emu10k1/efxmgr.h
View file @
80e38dd5
...
...
@@ -32,16 +32,30 @@
#ifndef _EFXMGR_H
#define _EFXMGR_H
#define WRITE_EFX(a, b, c) sblive_writeptr((a), MICROCODEBASE + (b), 0, (c))
struct
emu_efx_info_t
{
int
opcode_shift
;
int
high_operand_shift
;
int
instruction_start
;
int
gpr_base
;
int
output_base
;
};
#define WRITE_EFX(a, b, c) sblive_writeptr((a), emu_efx_info[card->is_audigy].instruction_start + (b), 0, (c))
#define OP(op, z, w, x, y) \
do { WRITE_EFX(card, (pc) * 2, ((x) <<
10
) | (y)); \
WRITE_EFX(card, (pc) * 2 + 1, ((op) <<
20) | ((z) << 10
) | (w)); \
do { WRITE_EFX(card, (pc) * 2, ((x) <<
emu_efx_info[card->is_audigy].high_operand_shift
) | (y)); \
WRITE_EFX(card, (pc) * 2 + 1, ((op) <<
emu_efx_info[card->is_audigy].opcode_shift ) | ((z) << emu_efx_info[card->is_audigy].high_operand_shift
) | (w)); \
++pc; } while (0)
#define NUM_INPUTS 0x20
#define NUM_OUTPUTS 0x20
#define NUM_GPRS 0x100
#define A_NUM_INPUTS 0x60
#define A_NUM_OUTPUTS 0x60 //fixme: this may or may not be true
#define A_NUM_GPRS 0x200
#define GPR_NAME_SIZE 32
#define PATCH_NAME_SIZE 32
...
...
@@ -98,6 +112,9 @@ enum {
#define GPR_BASE 0x100
#define OUTPUT_BASE 0x20
#define A_GPR_BASE 0x400
#define A_OUTPUT_BASE 0x60
#define MAX_PATCHES_PAGES 32
struct
patch_manager
{
...
...
sound/oss/emu10k1/hwaccess.c
View file @
80e38dd5
...
...
@@ -160,6 +160,24 @@ void emu10k1_writefn0(struct emu10k1_card *card, u32 reg, u32 data)
return
;
}
void
emu10k1_writefn0_2
(
struct
emu10k1_card
*
card
,
u32
reg
,
u32
data
,
int
size
)
{
unsigned
long
flags
;
spin_lock_irqsave
(
&
card
->
lock
,
flags
);
if
(
size
==
32
)
outl
(
data
,
card
->
iobase
+
(
reg
&
0x1F
));
else
if
(
size
==
16
)
outw
(
data
,
card
->
iobase
+
(
reg
&
0x1F
));
else
outb
(
data
,
card
->
iobase
+
(
reg
&
0x1F
));
spin_unlock_irqrestore
(
&
card
->
lock
,
flags
);
return
;
}
u32
emu10k1_readfn0
(
struct
emu10k1_card
*
card
,
u32
reg
)
{
u32
val
;
...
...
@@ -200,12 +218,13 @@ void emu10k1_timer_set(struct emu10k1_card * card, u16 data)
* write/read Emu10k1 pointer-offset register set, accessed through *
* the PTR and DATA registers *
*************************************************************************/
#define A_PTR_ADDRESS_MASK 0x0fff0000
void
sblive_writeptr
(
struct
emu10k1_card
*
card
,
u32
reg
,
u32
channel
,
u32
data
)
{
u32
regptr
;
unsigned
long
flags
;
regptr
=
((
reg
<<
16
)
&
PTR_ADDRESS_MASK
)
|
(
channel
&
PTR_CHANNELNUM_MASK
);
regptr
=
((
reg
<<
16
)
&
A_
PTR_ADDRESS_MASK
)
|
(
channel
&
PTR_CHANNELNUM_MASK
);
if
(
reg
&
0xff000000
)
{
u32
mask
;
...
...
@@ -242,7 +261,7 @@ void sblive_writeptr_tag(struct emu10k1_card *card, u32 channel, ...)
spin_lock_irqsave
(
&
card
->
lock
,
flags
);
while
((
reg
=
va_arg
(
args
,
u32
))
!=
TAGLIST_END
)
{
u32
data
=
va_arg
(
args
,
u32
);
u32
regptr
=
(((
reg
<<
16
)
&
PTR_ADDRESS_MASK
)
u32
regptr
=
(((
reg
<<
16
)
&
A_
PTR_ADDRESS_MASK
)
|
(
channel
&
PTR_CHANNELNUM_MASK
));
outl
(
regptr
,
card
->
iobase
+
PTR
);
if
(
reg
&
0xff000000
)
{
...
...
@@ -267,7 +286,7 @@ u32 sblive_readptr(struct emu10k1_card * card, u32 reg, u32 channel)
u32
regptr
,
val
;
unsigned
long
flags
;
regptr
=
((
reg
<<
16
)
&
PTR_ADDRESS_MASK
)
|
(
channel
&
PTR_CHANNELNUM_MASK
);
regptr
=
((
reg
<<
16
)
&
A_
PTR_ADDRESS_MASK
)
|
(
channel
&
PTR_CHANNELNUM_MASK
);
if
(
reg
&
0xff000000
)
{
u32
mask
;
...
...
@@ -389,7 +408,7 @@ void emu10k1_ac97_write(struct ac97_codec *codec, u8 reg, u16 value)
outb
(
reg
,
card
->
iobase
+
AC97ADDRESS
);
outw
(
value
,
card
->
iobase
+
AC97DATA
);
outb
(
AC97_EXTENDED_ID
,
card
->
iobase
+
AC97ADDRESS
);
spin_unlock_irqrestore
(
&
card
->
lock
,
flags
);
}
...
...
@@ -402,15 +421,23 @@ int emu10k1_mpu_write_data(struct emu10k1_card *card, u8 data)
unsigned
long
flags
;
int
ret
;
spin_lock_irqsave
(
&
card
->
lock
,
flags
);
if
(
card
->
is_audigy
)
{
if
((
sblive_readptr
(
card
,
A_MUSTAT
,
0
)
&
MUSTAT_ORDYN
)
==
0
)
{
sblive_writeptr
(
card
,
A_MUDATA
,
0
,
data
);
ret
=
0
;
}
else
ret
=
-
1
;
}
else
{
spin_lock_irqsave
(
&
card
->
lock
,
flags
);
if
((
inb
(
card
->
iobase
+
MUSTAT
)
&
MUSTAT_ORDYN
)
==
0
)
{
outb
(
data
,
card
->
iobase
+
MUDATA
);
ret
=
0
;
}
else
ret
=
-
1
;
if
((
inb
(
card
->
iobase
+
MUSTAT
)
&
MUSTAT_ORDYN
)
==
0
)
{
outb
(
data
,
card
->
iobase
+
MUDATA
);
ret
=
0
;
}
else
ret
=
-
1
;
spin_unlock_irqrestore
(
&
card
->
lock
,
flags
);
spin_unlock_irqrestore
(
&
card
->
lock
,
flags
);
}
return
ret
;
}
...
...
@@ -420,15 +447,23 @@ int emu10k1_mpu_read_data(struct emu10k1_card *card, u8 * data)
unsigned
long
flags
;
int
ret
;
spin_lock_irqsave
(
&
card
->
lock
,
flags
);
if
(
card
->
is_audigy
)
{
if
((
sblive_readptr
(
card
,
A_MUSTAT
,
0
)
&
MUSTAT_IRDYN
)
==
0
)
{
*
data
=
sblive_readptr
(
card
,
A_MUDATA
,
0
);
ret
=
0
;
}
else
ret
=
-
1
;
}
else
{
spin_lock_irqsave
(
&
card
->
lock
,
flags
);
if
((
inb
(
card
->
iobase
+
MUSTAT
)
&
MUSTAT_IRDYN
)
==
0
)
{
*
data
=
inb
(
card
->
iobase
+
MUDATA
);
ret
=
0
;
}
else
ret
=
-
1
;
if
((
inb
(
card
->
iobase
+
MUSTAT
)
&
MUSTAT_IRDYN
)
==
0
)
{
*
data
=
inb
(
card
->
iobase
+
MUDATA
);
ret
=
0
;
}
else
ret
=
-
1
;
spin_unlock_irqrestore
(
&
card
->
lock
,
flags
);
spin_unlock_irqrestore
(
&
card
->
lock
,
flags
);
}
return
ret
;
}
...
...
@@ -439,37 +474,54 @@ int emu10k1_mpu_reset(struct emu10k1_card *card)
unsigned
long
flags
;
DPF
(
2
,
"emu10k1_mpu_reset()
\n
"
);
if
(
card
->
is_audigy
)
{
if
(
card
->
mpuacqcount
==
0
)
{
sblive_writeptr
(
card
,
A_MUCMD
,
0
,
MUCMD_RESET
);
sblive_wcwait
(
card
,
8
);
sblive_writeptr
(
card
,
A_MUCMD
,
0
,
MUCMD_RESET
);
sblive_wcwait
(
card
,
8
);
sblive_writeptr
(
card
,
A_MUCMD
,
0
,
MUCMD_ENTERUARTMODE
);
sblive_wcwait
(
card
,
8
);
status
=
sblive_readptr
(
card
,
A_MUDATA
,
0
);
if
(
status
==
0xfe
)
return
0
;
else
return
-
1
;
}
if
(
card
->
mpuacqcount
==
0
)
{
spin_lock_irqsave
(
&
card
->
lock
,
flags
);
outb
(
MUCMD_RESET
,
card
->
iobase
+
MUCMD
);
spin_unlock_irqrestore
(
&
card
->
lock
,
flags
);
return
0
;
}
else
{
if
(
card
->
mpuacqcount
==
0
)
{
spin_lock_irqsave
(
&
card
->
lock
,
flags
);
outb
(
MUCMD_RESET
,
card
->
iobase
+
MUCMD
);
spin_unlock_irqrestore
(
&
card
->
lock
,
flags
);
sblive_wcwait
(
card
,
8
);
sblive_wcwait
(
card
,
8
);
spin_lock_irqsave
(
&
card
->
lock
,
flags
);
outb
(
MUCMD_RESET
,
card
->
iobase
+
MUCMD
);
spin_unlock_irqrestore
(
&
card
->
lock
,
flags
);
spin_lock_irqsave
(
&
card
->
lock
,
flags
);
outb
(
MUCMD_RESET
,
card
->
iobase
+
MUCMD
);
spin_unlock_irqrestore
(
&
card
->
lock
,
flags
);
sblive_wcwait
(
card
,
8
);
sblive_wcwait
(
card
,
8
);
spin_lock_irqsave
(
&
card
->
lock
,
flags
);
outb
(
MUCMD_ENTERUARTMODE
,
card
->
iobase
+
MUCMD
);
spin_unlock_irqrestore
(
&
card
->
lock
,
flags
);
spin_lock_irqsave
(
&
card
->
lock
,
flags
);
outb
(
MUCMD_ENTERUARTMODE
,
card
->
iobase
+
MUCMD
);
spin_unlock_irqrestore
(
&
card
->
lock
,
flags
);
sblive_wcwait
(
card
,
8
);
sblive_wcwait
(
card
,
8
);
spin_lock_irqsave
(
&
card
->
lock
,
flags
);
status
=
inb
(
card
->
iobase
+
MUDATA
);
spin_unlock_irqrestore
(
&
card
->
lock
,
flags
);
spin_lock_irqsave
(
&
card
->
lock
,
flags
);
status
=
inb
(
card
->
iobase
+
MUDATA
);
spin_unlock_irqrestore
(
&
card
->
lock
,
flags
);
if
(
status
==
0xfe
)
return
0
;
else
return
-
1
;
}
if
(
status
==
0xfe
)
return
0
;
else
return
-
1
;
}
return
0
;
return
0
;
}
}
int
emu10k1_mpu_acquire
(
struct
emu10k1_card
*
card
)
...
...
sound/oss/emu10k1/hwaccess.h
View file @
80e38dd5
...
...
@@ -79,13 +79,21 @@ struct memhandle
struct
emu10k1_waveout
{
u16
send_routing
[
3
];
u32
send_routing
[
3
];
// audigy only:
u32
send_routing2
[
3
];
u8
send_a
[
3
];
u8
send_b
[
3
];
u8
send_c
[
3
];
u8
send_d
[
3
];
u32
send_dcba
[
3
];
// audigy only:
u32
send_hgfe
[
3
];
};
#define ROUTE_PCM 0
#define ROUTE_PT 1
#define ROUTE_PCM1 2
#define SEND_MONO 0
#define SEND_LEFT 1
#define SEND_RIGHT 2
struct
emu10k1_wavein
{
...
...
@@ -129,7 +137,7 @@ struct mixer_private_ioctl {
#define CMD_AC97_BOOST _IOW('D', 20, struct mixer_private_ioctl)
//up this number when breaking compatibility
#define PRIVATE3_VERSION
1
#define PRIVATE3_VERSION
2
struct
emu10k1_card
{
...
...
@@ -181,7 +189,7 @@ struct emu10k1_card
u32
has_toslink
;
// TOSLink detection
u8
chiprev
;
/* Chip revision */
u8
is_audigy
;
u8
is_aps
;
struct
patch_manager
mgr
;
...
...
@@ -211,6 +219,7 @@ extern struct list_head emu10k1_devs;
/* Hardware Abstraction Layer access functions */
void
emu10k1_writefn0
(
struct
emu10k1_card
*
,
u32
,
u32
);
void
emu10k1_writefn0_2
(
struct
emu10k1_card
*
,
u32
,
u32
,
int
);
u32
emu10k1_readfn0
(
struct
emu10k1_card
*
,
u32
);
void
emu10k1_timer_set
(
struct
emu10k1_card
*
,
u16
);
...
...
sound/oss/emu10k1/irqmgr.h
View file @
80e38dd5
...
...
@@ -33,15 +33,15 @@
#define _IRQ_H
/* EMU Irq Types */
#define IRQTYPE_PCIBUSERROR
IPR_PCIERROR
#define IRQTYPE_MIXERBUTTON
(IPR_VOLINCR | IPR_VOLDECR | IPR_MUTE)
#define IRQTYPE_VOICE
(IPR_CHANNELLOOP | IPR_CHANNELNUMBERMASK)
#define IRQTYPE_RECORD
(IPR_ADCBUFFULL | IPR_ADCBUFHALFFULL | IPR_MICBUFFULL | IPR_MICBUFHALFFULL | IPR_EFXBUFFULL | IPR_EFXBUFHALFFULL)
#define IRQTYPE_MPUOUT
IPR_MIDITRANSBUFEMPTY
#define IRQTYPE_MPUIN
IPR_MIDIRECVBUFEMPTY
#define IRQTYPE_TIMER
IPR_INTERVALTIMER
#define IRQTYPE_SPDIF
(IPR_GPSPDIFSTATUSCHANGE | IPR_CDROMSTATUSCHANGE)
#define IRQTYPE_DSP
IPR_FXDSP
#define IRQTYPE_PCIBUSERROR
IPR_PCIERROR
#define IRQTYPE_MIXERBUTTON
(IPR_VOLINCR | IPR_VOLDECR | IPR_MUTE)
#define IRQTYPE_VOICE
(IPR_CHANNELLOOP | IPR_CHANNELNUMBERMASK)
#define IRQTYPE_RECORD
(IPR_ADCBUFFULL | IPR_ADCBUFHALFFULL | IPR_MICBUFFULL | IPR_MICBUFHALFFULL | IPR_EFXBUFFULL | IPR_EFXBUFHALFFULL)
#define IRQTYPE_MPUOUT
(IPR_MIDITRANSBUFEMPTY | A_IPR_MIDITRANSBUFEMPTY2)
#define IRQTYPE_MPUIN
(IPR_MIDIRECVBUFEMPTY | A_IPR_MIDIRECVBUFEMPTY2)
#define IRQTYPE_TIMER
IPR_INTERVALTIMER
#define IRQTYPE_SPDIF
(IPR_GPSPDIFSTATUSCHANGE | IPR_CDROMSTATUSCHANGE)
#define IRQTYPE_DSP
IPR_FXDSP
void
emu10k1_timer_irqhandler
(
struct
emu10k1_card
*
);
void
emu10k1_dsp_irqhandler
(
struct
emu10k1_card
*
);
...
...
sound/oss/emu10k1/main.c
View file @
80e38dd5
This diff is collapsed.
Click to expand it.
sound/oss/emu10k1/midi.h
View file @
80e38dd5
...
...
@@ -52,4 +52,27 @@ struct emu10k1_mididevice
struct
list_head
mid_hdrs
;
};
/* uncomment next line to use midi port on Audigy drive */
//#define USE_AUDIGY_DRIVE_MIDI
#ifdef USE_AUDIGY_DRIVE_MIDI
#define A_MUDATA A_MUDATA2
#define A_MUCMD A_MUCMD2
#define A_MUSTAT A_MUCMD2
#define A_IPR_MIDITRANSBUFEMPTY A_IPR_MIDITRANSBUFEMPTY2
#define A_IPR_MIDIRECVBUFEMPTY A_IPR_MIDIRECVBUFEMPTY2
#define A_INTE_MIDITXENABLE A_INTE_MIDITXENABLE2
#define A_INTE_MIDIRXENABLE A_INTE_MIDIRXENABLE2
#else
#define A_MUDATA A_MUDATA1
#define A_MUCMD A_MUCMD1
#define A_MUSTAT A_MUCMD1
#define A_IPR_MIDITRANSBUFEMPTY A_IPR_MIDITRANSBUFEMPTY1
#define A_IPR_MIDIRECVBUFEMPTY A_IPR_MIDIRECVBUFEMPTY1
#define A_INTE_MIDITXENABLE A_INTE_MIDITXENABLE1
#define A_INTE_MIDIRXENABLE A_INTE_MIDIRXENABLE1
#endif
#endif
/* _MIDI_H */
sound/oss/emu10k1/mixer.c
View file @
80e38dd5
...
...
@@ -136,7 +136,7 @@ static void set_bass(struct emu10k1_card *card, int l, int r)
r
=
(
r
*
40
+
50
)
/
100
;
for
(
i
=
0
;
i
<
5
;
i
++
)
sblive_writeptr
(
card
,
GPR_BASE
+
card
->
mgr
.
ctrl_gpr
[
SOUND_MIXER_BASS
][
0
]
+
i
,
0
,
bass_table
[
l
][
i
]);
sblive_writeptr
(
card
,
(
card
->
is_audigy
?
A_GPR_BASE
:
GPR_BASE
)
+
card
->
mgr
.
ctrl_gpr
[
SOUND_MIXER_BASS
][
0
]
+
i
,
0
,
bass_table
[
l
][
i
]);
}
static
void
set_treble
(
struct
emu10k1_card
*
card
,
int
l
,
int
r
)
...
...
@@ -147,7 +147,7 @@ static void set_treble(struct emu10k1_card *card, int l, int r)
r
=
(
r
*
40
+
50
)
/
100
;
for
(
i
=
0
;
i
<
5
;
i
++
)
sblive_writeptr
(
card
,
GPR_BASE
+
card
->
mgr
.
ctrl_gpr
[
SOUND_MIXER_TREBLE
][
0
]
+
i
,
0
,
treble_table
[
l
][
i
]);
sblive_writeptr
(
card
,
(
card
->
is_audigy
?
A_GPR_BASE
:
GPR_BASE
)
+
card
->
mgr
.
ctrl_gpr
[
SOUND_MIXER_TREBLE
][
0
]
+
i
,
0
,
treble_table
[
l
][
i
]);
}
const
char
volume_params
[
SOUND_MIXER_NRDEVICES
]
=
{
...
...
@@ -206,22 +206,25 @@ static int emu10k1_private_mixer(struct emu10k1_card *card, unsigned int cmd, un
switch
(
ctl
->
cmd
)
{
#ifdef DBGEMU
case
CMD_WRITEFN0
:
emu10k1_writefn0
(
card
,
ctl
->
val
[
0
],
ctl
->
val
[
1
]);
emu10k1_writefn0
_2
(
card
,
ctl
->
val
[
0
],
ctl
->
val
[
1
],
ctl
->
val
[
2
]);
break
;
#endif
case
CMD_WRITEPTR
:
if
(
ctl
->
val
[
1
]
>=
0x40
||
ctl
->
val
[
0
]
>
0xff
)
{
#ifdef DBGEMU
if
(
ctl
->
val
[
1
]
>=
0x40
||
ctl
->
val
[
0
]
>=
0x1000
)
{
#else
if
(
ctl
->
val
[
1
]
>=
0x40
||
ctl
->
val
[
0
]
>=
0x1000
||
((
ctl
->
val
[
0
]
<
0x100
)
&&
//Any register allowed raw access goes here:
(
ctl
->
val
[
0
]
!=
A_SPDIF_SAMPLERATE
)
&&
(
ctl
->
val
[
0
]
!=
A_DBG
)
)
)
{
#endif
ret
=
-
EINVAL
;
break
;
}
if
((
ctl
->
val
[
0
]
&
0x7ff
)
>
0x3f
)
ctl
->
val
[
1
]
=
0x00
;
sblive_writeptr
(
card
,
ctl
->
val
[
0
],
ctl
->
val
[
1
],
ctl
->
val
[
2
]);
break
;
#endif
case
CMD_READFN0
:
ctl
->
val
[
2
]
=
emu10k1_readfn0
(
card
,
ctl
->
val
[
0
]);
...
...
@@ -286,16 +289,13 @@ static int emu10k1_private_mixer(struct emu10k1_card *card, unsigned int cmd, un
case
CMD_GETVOICEPARAM
:
ctl
->
val
[
0
]
=
card
->
waveout
.
send_routing
[
0
];
ctl
->
val
[
1
]
=
card
->
waveout
.
send_a
[
0
]
|
card
->
waveout
.
send_b
[
0
]
<<
8
|
card
->
waveout
.
send_c
[
0
]
<<
16
|
card
->
waveout
.
send_d
[
0
]
<<
24
;
ctl
->
val
[
1
]
=
card
->
waveout
.
send_dcba
[
0
];
ctl
->
val
[
2
]
=
card
->
waveout
.
send_routing
[
1
];
ctl
->
val
[
3
]
=
card
->
waveout
.
send_a
[
1
]
|
card
->
waveout
.
send_b
[
1
]
<<
8
|
card
->
waveout
.
send_c
[
1
]
<<
16
|
card
->
waveout
.
send_d
[
1
]
<<
24
;
ctl
->
val
[
3
]
=
card
->
waveout
.
send_dcba
[
1
];
ctl
->
val
[
4
]
=
card
->
waveout
.
send_routing
[
2
];
ctl
->
val
[
5
]
=
card
->
waveout
.
send_a
[
2
]
|
card
->
waveout
.
send_b
[
2
]
<<
8
|
card
->
waveout
.
send_c
[
2
]
<<
16
|
card
->
waveout
.
send_d
[
2
]
<<
24
;
ctl
->
val
[
5
]
=
card
->
waveout
.
send_dcba
[
2
];
if
(
copy_to_user
((
void
*
)
arg
,
ctl
,
sizeof
(
struct
mixer_private_ioctl
)))
ret
=
-
EFAULT
;
...
...
@@ -303,23 +303,14 @@ static int emu10k1_private_mixer(struct emu10k1_card *card, unsigned int cmd, un
break
;
case
CMD_SETVOICEPARAM
:
card
->
waveout
.
send_routing
[
0
]
=
ctl
->
val
[
0
]
&
0xffff
;
card
->
waveout
.
send_a
[
0
]
=
ctl
->
val
[
1
]
&
0xff
;
card
->
waveout
.
send_b
[
0
]
=
(
ctl
->
val
[
1
]
>>
8
)
&
0xff
;
card
->
waveout
.
send_c
[
0
]
=
(
ctl
->
val
[
1
]
>>
16
)
&
0xff
;
card
->
waveout
.
send_d
[
0
]
=
(
ctl
->
val
[
1
]
>>
24
)
&
0xff
;
card
->
waveout
.
send_routing
[
1
]
=
ctl
->
val
[
2
]
&
0xffff
;
card
->
waveout
.
send_a
[
1
]
=
ctl
->
val
[
3
]
&
0xff
;
card
->
waveout
.
send_b
[
1
]
=
(
ctl
->
val
[
3
]
>>
8
)
&
0xff
;
card
->
waveout
.
send_c
[
1
]
=
(
ctl
->
val
[
3
]
>>
16
)
&
0xff
;
card
->
waveout
.
send_d
[
1
]
=
(
ctl
->
val
[
3
]
>>
24
)
&
0xff
;
card
->
waveout
.
send_routing
[
2
]
=
ctl
->
val
[
4
]
&
0xffff
;
card
->
waveout
.
send_a
[
2
]
=
ctl
->
val
[
5
]
&
0xff
;
card
->
waveout
.
send_b
[
2
]
=
(
ctl
->
val
[
5
]
>>
8
)
&
0xff
;
card
->
waveout
.
send_c
[
2
]
=
(
ctl
->
val
[
5
]
>>
16
)
&
0xff
;
card
->
waveout
.
send_d
[
2
]
=
(
ctl
->
val
[
5
]
>>
24
)
&
0xff
;
card
->
waveout
.
send_routing
[
0
]
=
ctl
->
val
[
0
];
card
->
waveout
.
send_dcba
[
0
]
=
ctl
->
val
[
1
];
card
->
waveout
.
send_routing
[
1
]
=
ctl
->
val
[
2
];
card
->
waveout
.
send_dcba
[
1
]
=
ctl
->
val
[
3
];
card
->
waveout
.
send_routing
[
2
]
=
ctl
->
val
[
4
];
card
->
waveout
.
send_dcba
[
2
]
=
ctl
->
val
[
5
];
break
;
...
...
@@ -416,12 +407,16 @@ static int emu10k1_private_mixer(struct emu10k1_card *card, unsigned int cmd, un
break
;
case
CMD_SETGPOUT
:
if
(
ctl
->
val
[
0
]
>
2
||
ctl
->
val
[
1
]
>
1
)
{
if
(
((
ctl
->
val
[
0
]
>
2
)
&&
(
!
card
->
is_audigy
))
||
(
ctl
->
val
[
0
]
>
15
)
||
ctl
->
val
[
1
]
>
1
)
{
ret
=
-
EINVAL
;
break
;
}
emu10k1_writefn0
(
card
,
(
1
<<
24
)
|
(((
ctl
->
val
[
0
])
+
10
)
<<
16
)
|
HCFG
,
ctl
->
val
[
1
]);
if
(
card
->
is_audigy
)
emu10k1_writefn0
(
card
,
(
1
<<
24
)
|
((
ctl
->
val
[
0
])
<<
16
)
|
A_IOCFG
,
ctl
->
val
[
1
]);
else
emu10k1_writefn0
(
card
,
(
1
<<
24
)
|
(((
ctl
->
val
[
0
])
+
10
)
<<
16
)
|
HCFG
,
ctl
->
val
[
1
]);
break
;
case
CMD_GETGPR2OSS
:
...
...
@@ -493,13 +488,20 @@ static int emu10k1_private_mixer(struct emu10k1_card *card, unsigned int cmd, un
break
;
case
CMD_PRIVATE3_VERSION
:
ctl
->
val
[
0
]
=
PRIVATE3_VERSION
;
ctl
->
val
[
0
]
=
PRIVATE3_VERSION
;
//private3 version
ctl
->
val
[
1
]
=
MAJOR_VER
;
//major driver version
ctl
->
val
[
2
]
=
MINOR_VER
;
//minor driver version
ctl
->
val
[
3
]
=
card
->
is_audigy
;
//1=card is audigy
if
(
card
->
is_audigy
)
ctl
->
val
[
4
]
=
emu10k1_readfn0
(
card
,
0x18
);
if
(
copy_to_user
((
void
*
)
arg
,
ctl
,
sizeof
(
struct
mixer_private_ioctl
)))
ret
=
-
EFAULT
;
break
;
case
CMD_AC97_BOOST
:
if
(
ctl
->
val
[
0
])
if
(
ctl
->
val
[
0
])
emu10k1_ac97_write
(
card
->
ac97
,
0x18
,
0x0
);
else
emu10k1_ac97_write
(
card
->
ac97
,
0x18
,
0x0808
);
...
...
@@ -556,7 +558,7 @@ static int emu10k1_private_mixer(struct emu10k1_card *card, unsigned int cmd, un
card
->
tankmem
.
size
=
size
;
sblive_writeptr_tag
(
card
,
0
,
TCB
,
(
u32
)
card
->
tankmem
.
dma_handle
,
TCBS
,
size_reg
,
TAGLIST_END
);
sblive_writeptr_tag
(
card
,
0
,
TCB
,
(
u32
)
card
->
tankmem
.
dma_handle
,
TCBS
,
(
u32
)
size_reg
,
TAGLIST_END
);
emu10k1_writefn0
(
card
,
HCFG_LOCKTANKCACHE
,
0
);
}
...
...
@@ -623,8 +625,13 @@ static int emu10k1_mixer_ioctl(struct inode *inode, struct file *file, unsigned
if
(
cmd
==
SOUND_MIXER_INFO
)
{
mixer_info
info
;
strncpy
(
info
.
id
,
card
->
ac97
->
name
,
sizeof
(
info
.
id
));
strncpy
(
info
.
name
,
"Creative SBLive - Emu10k1"
,
sizeof
(
info
.
name
));
strlcpy
(
info
.
id
,
card
->
ac97
->
name
,
sizeof
(
info
.
id
));
if
(
card
->
is_audigy
)
strlcpy
(
info
.
name
,
"Audigy - Emu10k1"
,
sizeof
(
info
.
name
));
else
strlcpy
(
info
.
name
,
"Creative SBLive - Emu10k1"
,
sizeof
(
info
.
name
));
info
.
modify_counter
=
card
->
ac97
->
modcnt
;
if
(
copy_to_user
((
void
*
)
arg
,
&
info
,
sizeof
(
info
)))
...
...
sound/oss/emu10k1/passthrough.c
View file @
80e38dd5
...
...
@@ -109,7 +109,7 @@ static int pt_putblock(struct emu10k1_wavedevice *wave_dev, u16 *block, int nonb
return
0
;
}
static
int
pt_setup
(
struct
emu10k1_wavedevice
*
wave_dev
)
int
emu10k1_
pt_setup
(
struct
emu10k1_wavedevice
*
wave_dev
)
{
u32
bits
;
struct
emu10k1_card
*
card
=
wave_dev
->
card
;
...
...
@@ -155,7 +155,7 @@ ssize_t emu10k1_pt_write(struct file *file, const char *buffer, size_t count)
pt
->
prepend_size
=
0
;
if
(
pt
->
buf
==
NULL
)
return
-
ENOMEM
;
pt_setup
(
wave_dev
);
emu10k1_
pt_setup
(
wave_dev
);
}
if
(
pt
->
prepend_size
)
{
int
needed
=
PT_BLOCKSIZE
-
pt
->
prepend_size
;
...
...
@@ -208,13 +208,14 @@ void emu10k1_pt_stop(struct emu10k1_card *card)
if
(
pt
->
state
!=
PT_STATE_INACTIVE
)
{
DPF
(
2
,
"digital pass-through stopped
\n
"
);
sblive_writeptr
(
card
,
GPR_BASE
+
pt
->
enable_gpr
,
0
,
0
);
sblive_writeptr
(
card
,
(
card
->
is_audigy
?
A_GPR_BASE
:
GPR_BASE
)
+
pt
->
enable_gpr
,
0
,
0
);
for
(
i
=
0
;
i
<
3
;
i
++
)
{
if
(
pt
->
spcs_to_use
&
(
1
<<
i
))
sblive_writeptr
(
card
,
SPCS0
+
i
,
0
,
pt
->
old_spcs
[
i
]);
}
pt
->
state
=
PT_STATE_INACTIVE
;
kfree
(
pt
->
buf
);
if
(
pt
->
buf
)
kfree
(
pt
->
buf
);
}
}
...
...
sound/oss/emu10k1/passthrough.h
View file @
80e38dd5
...
...
@@ -63,7 +63,36 @@ struct pt_data
spinlock_t
lock
;
};
/*
Passthrough can be done in two methods:
Method 1 : tram
In original emu10k1, we couldn't bypass the sample rate converters. Even at 48kHz
(the internal sample rate of the emu10k1) the samples would get messed up.
To over come this, samples are copied into the tram and a special dsp patch copies
the samples out and generates interrupts when a block has finnished playing.
Method 2 : Interpolator bypass
Creative fixed the sample rate convert problem in emu10k1 rev 7 and higher
(including the emu10k2 (audigy)). This allows us to use the regular, and much simpler
playback method.
In both methods, dsp code is used to mux audio and passthrough. This ensures that the spdif
doesn't receive audio and pasthrough data at the same time. The spdif flag SPCS_NOTAUDIODATA
is set to tell
*/
// emu10k1 revs greater than or equal to 7 can use method2
#define USE_PT_METHOD2 (card->is_audigy)
#define USE_PT_METHOD1 !USE_PT_METHOD2
ssize_t
emu10k1_pt_write
(
struct
file
*
file
,
const
char
*
buf
,
size_t
count
);
int
emu10k1_pt_setup
(
struct
emu10k1_wavedevice
*
wave_dev
);
void
emu10k1_pt_stop
(
struct
emu10k1_card
*
card
);
void
emu10k1_pt_waveout_update
(
struct
emu10k1_wavedevice
*
wave_dev
);
...
...
sound/oss/emu10k1/recmgr.c
View file @
80e38dd5
...
...
@@ -74,7 +74,7 @@ void emu10k1_set_record_src(struct emu10k1_card *card, struct wiinst *wiinst)
DPF
(
2
,
"recording source: AC97
\n
"
);
buffer
->
sizereg
=
ADCBS
;
buffer
->
addrreg
=
ADCBA
;
buffer
->
idxreg
=
ADCIDX_IDX
;
buffer
->
idxreg
=
card
->
is_audigy
?
A_ADCIDX_IDX
:
ADCIDX_IDX
;
switch
(
wiinst
->
format
.
samplingrate
)
{
case
0xBB80
:
...
...
@@ -95,21 +95,27 @@ void emu10k1_set_record_src(struct emu10k1_card *card, struct wiinst *wiinst)
case
0x3E80
:
buffer
->
adcctl
=
ADCCR_SAMPLERATE_16
;
break
;
// FIXME: audigy supports 12kHz recording
/*
case ????:
buffer->adcctl = A_ADCCR_SAMPLERATE_12;
break;
*/
case
0x2B11
:
buffer
->
adcctl
=
ADCCR_SAMPLERATE_11
;
buffer
->
adcctl
=
card
->
is_audigy
?
A_ADCCR_SAMPLERATE_11
:
ADCCR_SAMPLERATE_11
;
break
;
case
0x1F40
:
buffer
->
adcctl
=
ADCCR_SAMPLERATE_8
;
buffer
->
adcctl
=
card
->
is_audigy
?
A_ADCCR_SAMPLERATE_8
:
ADCCR_SAMPLERATE_8
;
break
;
default:
BUG
();
break
;
}
buffer
->
adcctl
|=
ADCCR_LCHANENABLE
;
buffer
->
adcctl
|=
card
->
is_audigy
?
A_ADCCR_LCHANENABLE
:
ADCCR_LCHANENABLE
;
if
(
wiinst
->
format
.
channels
==
2
)
buffer
->
adcctl
|=
ADCCR_RCHANENABLE
;
buffer
->
adcctl
|=
card
->
is_audigy
?
A_ADCCR_RCHANENABLE
:
ADCCR_RCHANENABLE
;
break
;
...
...
sound/oss/emu10k1/voicemgr.c
View file @
80e38dd5
...
...
@@ -32,6 +32,34 @@
#include "voicemgr.h"
#include "8010.h"
#define PITCH_48000 0x00004000
#define PITCH_96000 0x00008000
#define PITCH_85000 0x00007155
#define PITCH_80726 0x00006ba2
#define PITCH_67882 0x00005a82
#define PITCH_57081 0x00004c1c
u32
emu10k1_select_interprom
(
struct
emu10k1_card
*
card
,
struct
emu_voice
*
voice
)
{
if
(
voice
->
pitch_target
==
PITCH_48000
)
return
CCCA_INTERPROM_0
;
else
if
(
voice
->
pitch_target
<
PITCH_48000
)
return
CCCA_INTERPROM_1
;
else
if
(
voice
->
pitch_target
>=
PITCH_96000
)
return
CCCA_INTERPROM_0
;
else
if
(
voice
->
pitch_target
>=
PITCH_85000
)
return
CCCA_INTERPROM_6
;
else
if
(
voice
->
pitch_target
>=
PITCH_80726
)
return
CCCA_INTERPROM_5
;
else
if
(
voice
->
pitch_target
>=
PITCH_67882
)
return
CCCA_INTERPROM_4
;
else
if
(
voice
->
pitch_target
>=
PITCH_57081
)
return
CCCA_INTERPROM_3
;
else
return
CCCA_INTERPROM_2
;
}
/**
* emu10k1_voice_alloc_buffer -
*
...
...
@@ -216,17 +244,25 @@ void emu10k1_voice_playback_setup(struct emu_voice *voice)
voice
->
start
+=
start
;
for
(
i
=
0
;
i
<
(
voice
->
flags
&
VOICE_FLAGS_STEREO
?
2
:
1
);
i
++
)
{
sblive_writeptr
(
card
,
FXRT
,
voice
->
num
+
i
,
voice
->
params
[
i
].
send_routing
<<
16
);
if
(
card
->
is_audigy
)
{
sblive_writeptr
(
card
,
A_FXRT1
,
voice
->
num
+
i
,
voice
->
params
[
i
].
send_routing
);
sblive_writeptr
(
card
,
A_FXRT2
,
voice
->
num
+
i
,
voice
->
params
[
i
].
send_routing2
);
sblive_writeptr
(
card
,
A_SENDAMOUNTS
,
voice
->
num
+
i
,
voice
->
params
[
i
].
send_hgfe
);
}
else
{
sblive_writeptr
(
card
,
FXRT
,
voice
->
num
+
i
,
voice
->
params
[
i
].
send_routing
<<
16
);
}
/* Stop CA */
/* Assumption that PT is already 0 so no harm overwriting */
sblive_writeptr
(
card
,
PTRX
,
voice
->
num
+
i
,
(
voice
->
params
[
i
].
send_a
<<
8
)
|
voice
->
params
[
i
].
send_b
);
sblive_writeptr
(
card
,
PTRX
,
voice
->
num
+
i
,
((
voice
->
params
[
i
].
send_dcba
&
0xff
)
<<
8
)
|
((
voice
->
params
[
i
].
send_dcba
&
0xff00
)
>>
8
));
sblive_writeptr_tag
(
card
,
voice
->
num
+
i
,
/* CSL, ST, CA */
DSL
,
voice
->
endloop
|
(
voice
->
params
[
i
].
send_d
<<
24
),
PSST
,
voice
->
startloop
|
(
voice
->
params
[
i
].
send_c
<<
24
),
CCCA
,
(
voice
->
start
)
|
CCCA_INTERPROM_0
|
((
voice
->
flags
&
VOICE_FLAGS_16BIT
)
?
0
:
CCCA_8BITSELECT
),
DSL
,
voice
->
endloop
|
(
voice
->
params
[
i
].
send_dcba
&
0xff000000
),
PSST
,
voice
->
startloop
|
((
voice
->
params
[
i
].
send_dcba
&
0x00ff0000
)
<<
8
),
CCCA
,
(
voice
->
start
)
|
emu10k1_select_interprom
(
card
,
voice
)
|
((
voice
->
flags
&
VOICE_FLAGS_16BIT
)
?
0
:
CCCA_8BITSELECT
),
/* Clear filter delay memory */
Z1
,
0
,
Z2
,
0
,
...
...
sound/oss/emu10k1/voicemgr.h
View file @
80e38dd5
...
...
@@ -48,11 +48,13 @@ struct voice_param
/* FX bus amount send */
u32
send_routing
;
// audigy only:
u32
send_routing2
;
u32
send_dcba
;
// audigy only:
u32
send_hgfe
;
u32
send_a
;
u32
send_b
;
u32
send_c
;
u32
send_d
;
u32
initial_fc
;
u32
fc_target
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment