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
a9e4e4e0
Commit
a9e4e4e0
authored
Mar 21, 2003
by
Alan Cox
Committed by
Linus Torvalds
Mar 21, 2003
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[PATCH] update emu10k1 driver (SB Live, Audigy etc)
parent
349a40c8
Changes
21
Hide whitespace changes
Inline
Side-by-side
Showing
21 changed files
with
391 additions
and
326 deletions
+391
-326
sound/oss/emu10k1/audio.c
sound/oss/emu10k1/audio.c
+47
-47
sound/oss/emu10k1/audio.h
sound/oss/emu10k1/audio.h
+0
-2
sound/oss/emu10k1/cardwi.c
sound/oss/emu10k1/cardwi.c
+13
-12
sound/oss/emu10k1/cardwi.h
sound/oss/emu10k1/cardwi.h
+6
-5
sound/oss/emu10k1/cardwo.c
sound/oss/emu10k1/cardwo.c
+27
-105
sound/oss/emu10k1/cardwo.h
sound/oss/emu10k1/cardwo.h
+3
-11
sound/oss/emu10k1/efxmgr.c
sound/oss/emu10k1/efxmgr.c
+4
-7
sound/oss/emu10k1/efxmgr.h
sound/oss/emu10k1/efxmgr.h
+42
-43
sound/oss/emu10k1/hwaccess.c
sound/oss/emu10k1/hwaccess.c
+9
-0
sound/oss/emu10k1/hwaccess.h
sound/oss/emu10k1/hwaccess.h
+10
-9
sound/oss/emu10k1/irqmgr.c
sound/oss/emu10k1/irqmgr.c
+12
-6
sound/oss/emu10k1/main.c
sound/oss/emu10k1/main.c
+47
-27
sound/oss/emu10k1/midi.c
sound/oss/emu10k1/midi.c
+26
-2
sound/oss/emu10k1/mixer.c
sound/oss/emu10k1/mixer.c
+21
-13
sound/oss/emu10k1/passthrough.c
sound/oss/emu10k1/passthrough.c
+4
-10
sound/oss/emu10k1/recmgr.c
sound/oss/emu10k1/recmgr.c
+15
-12
sound/oss/emu10k1/recmgr.h
sound/oss/emu10k1/recmgr.h
+1
-1
sound/oss/emu10k1/timer.c
sound/oss/emu10k1/timer.c
+4
-4
sound/oss/emu10k1/timer.h
sound/oss/emu10k1/timer.h
+5
-5
sound/oss/emu10k1/voicemgr.c
sound/oss/emu10k1/voicemgr.c
+83
-3
sound/oss/emu10k1/voicemgr.h
sound/oss/emu10k1/voicemgr.h
+12
-2
No files found.
sound/oss/emu10k1/audio.c
View file @
a9e4e4e0
...
...
@@ -30,7 +30,6 @@
**********************************************************************
*/
#define __NO_VERSION__
#include <linux/module.h>
#include <linux/poll.h>
#include <linux/slab.h>
...
...
@@ -983,11 +982,11 @@ static struct page *emu10k1_mm_nopage (struct vm_area_struct * vma, unsigned lon
unsigned
long
pgoff
;
int
rd
,
wr
;
DPF
(
4
,
"emu10k1_mm_nopage()
\n
"
);
DPD
(
4
,
"addr: %#lx
\n
"
,
address
);
DPF
(
3
,
"emu10k1_mm_nopage()
\n
"
);
DPD
(
3
,
"addr: %#lx
\n
"
,
address
);
if
(
address
>
vma
->
vm_end
)
{
DPF
(
2
,
"EXIT, returning NOPAGE_SIGBUS
\n
"
);
DPF
(
1
,
"EXIT, returning NOPAGE_SIGBUS
\n
"
);
return
NOPAGE_SIGBUS
;
/* Disallow mremap */
}
...
...
@@ -1009,14 +1008,14 @@ static struct page *emu10k1_mm_nopage (struct vm_area_struct * vma, unsigned lon
pgoff
-=
woinst
->
buffer
.
pages
;
dmapage
=
virt_to_page
((
u8
*
)
wiinst
->
buffer
.
addr
+
pgoff
*
PAGE_SIZE
);
}
else
dmapage
=
virt_to_page
(
woinst
->
buffer
.
mem
[
0
]
.
addr
[
pgoff
]);
dmapage
=
virt_to_page
(
woinst
->
voice
[
0
].
mem
.
addr
[
pgoff
]);
}
else
{
dmapage
=
virt_to_page
((
u8
*
)
wiinst
->
buffer
.
addr
+
pgoff
*
PAGE_SIZE
);
}
get_page
(
dmapage
);
DPD
(
4
,
"page: %#lx
\n
"
,
dmapage
);
DPD
(
3
,
"page: %#lx
\n
"
,
(
unsigned
long
)
dmapage
);
return
dmapage
;
}
...
...
@@ -1083,8 +1082,8 @@ static int emu10k1_audio_mmap(struct file *file, struct vm_area_struct *vma)
n_pages
=
((
vma
->
vm_end
-
vma
->
vm_start
)
+
PAGE_SIZE
-
1
)
>>
PAGE_SHIFT
;
pgoffset
=
vma
->
vm_pgoff
;
DPD
(
3
,
"vma_start: %#lx, vma_end: %#lx, vma_offset: %
d
\n
"
,
vma
->
vm_start
,
vma
->
vm_end
,
pgoffset
);
DPD
(
3
,
"n_pages: %d, max_pages: %
d
\n
"
,
n_pages
,
max_pages
);
DPD
(
2
,
"vma_start: %#lx, vma_end: %#lx, vma_offset: %l
d
\n
"
,
vma
->
vm_start
,
vma
->
vm_end
,
pgoffset
);
DPD
(
2
,
"n_pages: %ld, max_pages: %l
d
\n
"
,
n_pages
,
max_pages
);
if
(
pgoffset
+
n_pages
>
max_pages
)
return
-
EINVAL
;
...
...
@@ -1092,7 +1091,6 @@ static int emu10k1_audio_mmap(struct file *file, struct vm_area_struct *vma)
vma
->
vm_flags
|=
VM_RESERVED
;
vma
->
vm_ops
=
&
emu10k1_mm_ops
;
vma
->
vm_private_data
=
wave_dev
;
return
0
;
}
...
...
@@ -1136,7 +1134,8 @@ static int emu10k1_audio_open(struct inode *inode, struct file *file)
if
((
wiinst
=
(
struct
wiinst
*
)
kmalloc
(
sizeof
(
struct
wiinst
),
GFP_KERNEL
))
==
NULL
)
{
ERROR
();
return
-
ENODEV
;
kfree
(
wave_dev
);
return
-
ENOMEM
;
}
wiinst
->
recsrc
=
card
->
wavein
.
recsrc
;
...
...
@@ -1162,6 +1161,8 @@ static int emu10k1_audio_open(struct inode *inode, struct file *file)
wiinst
->
format
.
channels
=
hweight32
(
wiinst
->
fxwc
);
break
;
default:
kfree
(
wave_dev
);
kfree
(
wiinst
);
BUG
();
break
;
}
...
...
@@ -1211,7 +1212,7 @@ static int emu10k1_audio_open(struct inode *inode, struct file *file)
woinst
->
num_voices
=
1
;
for
(
i
=
0
;
i
<
WAVEOUT_MAXVOICES
;
i
++
)
{
woinst
->
voice
[
i
].
usage
=
VOICE_USAGE_FREE
;
woinst
->
buffer
.
mem
[
i
]
.
emupageindex
=
-
1
;
woinst
->
voice
[
i
].
mem
.
emupageindex
=
-
1
;
}
init_waitqueue_head
(
&
woinst
->
wait_queue
);
...
...
@@ -1330,23 +1331,13 @@ static unsigned int emu10k1_audio_poll(struct file *file, struct poll_table_stru
if
(
file
->
f_mode
&
FMODE_READ
)
{
spin_lock_irqsave
(
&
wiinst
->
lock
,
flags
);
if
(
wiinst
->
state
==
WAVE_STATE_CLOSED
)
{
calculate_ifrag
(
wiinst
);
if
(
emu10k1_wavein_open
(
wave_dev
)
<
0
)
{
spin_unlock_irqrestore
(
&
wiinst
->
lock
,
flags
);
return
(
mask
|=
POLLERR
);
}
}
if
(
wiinst
->
state
&
WAVE_STATE_OPEN
)
{
emu10k1_wavein_update
(
wave_dev
->
card
,
wiinst
);
emu10k1_wavein_getxfersize
(
wiinst
,
&
bytestocopy
);
if
(
!
(
wiinst
->
state
&
WAVE_STATE_STARTED
))
{
wave_dev
->
enablebits
|=
PCM_ENABLE_INPUT
;
emu10k1_wavein_start
(
wave_dev
);
if
(
bytestocopy
>=
wiinst
->
buffer
.
fragment_size
)
mask
|=
POLLIN
|
POLLRDNORM
;
}
emu10k1_wavein_update
(
wave_dev
->
card
,
wiinst
);
emu10k1_wavein_getxfersize
(
wiinst
,
&
bytestocopy
);
if
(
bytestocopy
>=
wiinst
->
buffer
.
fragment_size
)
mask
|=
POLLIN
|
POLLRDNORM
;
spin_unlock_irqrestore
(
&
wiinst
->
lock
,
flags
);
}
...
...
@@ -1376,6 +1367,13 @@ static void calculate_ofrag(struct woinst *woinst)
buffer
->
fragment_size
=
1
<<
buffer
->
ossfragshift
;
while
(
buffer
->
fragment_size
*
WAVEOUT_MINFRAGS
>
WAVEOUT_MAXBUFSIZE
)
buffer
->
fragment_size
>>=
1
;
/* now we are sure that:
(2^WAVEOUT_MINFRAGSHIFT) <= (fragment_size = 2^n) <= (WAVEOUT_MAXBUFSIZE / WAVEOUT_MINFRAGS)
*/
if
(
!
buffer
->
numfrags
)
{
u32
numfrags
;
...
...
@@ -1390,19 +1388,14 @@ static void calculate_ofrag(struct woinst *woinst)
}
}
if
(
buffer
->
numfrags
<
MINFRAGS
)
buffer
->
numfrags
=
MINFRAGS
;
if
(
buffer
->
numfrags
<
WAVEOUT_
MINFRAGS
)
buffer
->
numfrags
=
WAVEOUT_
MINFRAGS
;
if
(
buffer
->
numfrags
*
buffer
->
fragment_size
>
WAVEOUT_MAXBUFSIZE
)
{
if
(
buffer
->
numfrags
*
buffer
->
fragment_size
>
WAVEOUT_MAXBUFSIZE
)
buffer
->
numfrags
=
WAVEOUT_MAXBUFSIZE
/
buffer
->
fragment_size
;
if
(
buffer
->
numfrags
<
MINFRAGS
)
{
buffer
->
numfrags
=
MINFRAGS
;
buffer
->
fragment_size
=
WAVEOUT_MAXBUFSIZE
/
MINFRAGS
;
}
}
else
if
(
buffer
->
numfrags
*
buffer
->
fragment_size
<
WAVEOUT_MINBUFSIZE
)
buffer
->
numfrags
=
WAVEOUT_MINBUFSIZE
/
buffer
->
fragment_size
;
if
(
buffer
->
numfrags
<
WAVEOUT_MINFRAGS
)
BUG
();
buffer
->
size
=
buffer
->
fragment_size
*
buffer
->
numfrags
;
buffer
->
pages
=
buffer
->
size
/
PAGE_SIZE
+
((
buffer
->
size
%
PAGE_SIZE
)
?
1
:
0
);
...
...
@@ -1436,24 +1429,29 @@ static void calculate_ifrag(struct wiinst *wiinst)
buffer
->
fragment_size
=
1
<<
buffer
->
ossfragshift
;
while
(
buffer
->
fragment_size
*
WAVEIN_MINFRAGS
>
WAVEIN_MAXBUFSIZE
)
buffer
->
fragment_size
>>=
1
;
/* now we are sure that:
(2^WAVEIN_MINFRAGSHIFT) <= (fragment_size = 2^n) <= (WAVEIN_MAXBUFSIZE / WAVEIN_MINFRAGS)
*/
if
(
!
buffer
->
numfrags
)
buffer
->
numfrags
=
(
wiinst
->
format
.
bytespersec
*
WAVEIN_DEFAULTBUFLEN
)
/
(
buffer
->
fragment_size
*
1000
)
-
1
;
if
(
buffer
->
numfrags
<
MINFRAGS
)
buffer
->
numfrags
=
MINFRAGS
;
if
(
buffer
->
numfrags
<
WAVEIN_
MINFRAGS
)
buffer
->
numfrags
=
WAVEIN_
MINFRAGS
;
if
(
buffer
->
numfrags
*
buffer
->
fragment_size
>
WAVEIN_MAXBUFSIZE
)
{
if
(
buffer
->
numfrags
*
buffer
->
fragment_size
>
WAVEIN_MAXBUFSIZE
)
buffer
->
numfrags
=
WAVEIN_MAXBUFSIZE
/
buffer
->
fragment_size
;
if
(
buffer
->
numfrags
<
MINFRAGS
)
{
buffer
->
numfrags
=
MINFRAGS
;
buffer
->
fragment_size
=
WAVEIN_MAXBUFSIZE
/
MINFRAGS
;
}
}
else
if
(
buffer
->
numfrags
*
buffer
->
fragment_size
<
WAVEIN_MINBUFSIZE
)
buffer
->
numfrags
=
WAVEIN_MINBUFSIZE
/
buffer
->
fragment_size
;
if
(
buffer
->
numfrags
<
WAVEIN_MINFRAGS
)
BUG
();
bufsize
=
buffer
->
fragment_size
*
buffer
->
numfrags
;
/* the buffer size for recording is restricted to certain values, adjust it now */
if
(
bufsize
>=
0x10000
)
{
buffer
->
size
=
0x10000
;
buffer
->
sizeregval
=
0x1f
;
...
...
@@ -1479,10 +1477,12 @@ static void calculate_ifrag(struct wiinst *wiinst)
}
}
/* adjust the fragment size so that buffer size is an integer multiple */
while
(
buffer
->
size
%
buffer
->
fragment_size
)
buffer
->
fragment_size
>>=
1
;
buffer
->
numfrags
=
buffer
->
size
/
buffer
->
fragment_size
;
buffer
->
pages
=
buffer
->
size
/
PAGE_SIZE
+
((
buffer
->
size
%
PAGE_SIZE
)
?
1
:
0
);
if
(
buffer
->
size
%
buffer
->
fragment_size
)
BUG
();
DPD
(
2
,
" calculated recording fragment_size -> %d
\n
"
,
buffer
->
fragment_size
);
DPD
(
2
,
" calculated recording numfrags -> %d
\n
"
,
buffer
->
numfrags
);
...
...
sound/oss/emu10k1/audio.h
View file @
a9e4e4e0
...
...
@@ -33,8 +33,6 @@
#ifndef _AUDIO_H
#define _AUDIO_H
#define MINFRAGS 2
/* _don't_ got bellow 2 */
struct
emu10k1_wavedevice
{
struct
emu10k1_card
*
card
;
...
...
sound/oss/emu10k1/cardwi.c
View file @
a9e4e4e0
...
...
@@ -96,6 +96,7 @@ void query_format(int recsrc, struct wave_format *wave_fmt)
wave_fmt
->
bytesperchannel
=
wave_fmt
->
bitsperchannel
>>
3
;
wave_fmt
->
bytespersample
=
wave_fmt
->
channels
*
wave_fmt
->
bytesperchannel
;
wave_fmt
->
bytespersec
=
wave_fmt
->
bytespersample
*
wave_fmt
->
samplingrate
;
wave_fmt
->
bytespervoicesample
=
wave_fmt
->
bytespersample
;
}
static
int
alloc_buffer
(
struct
emu10k1_card
*
card
,
struct
wavein_buffer
*
buffer
)
...
...
@@ -120,7 +121,7 @@ int emu10k1_wavein_open(struct emu10k1_wavedevice *wave_dev)
struct
emu10k1_card
*
card
=
wave_dev
->
card
;
struct
wiinst
*
wiinst
=
wave_dev
->
wiinst
;
struct
wiinst
**
wiinst_tmp
=
NULL
;
u
32
delay
;
u
16
delay
;
unsigned
long
flags
;
DPF
(
2
,
"emu10k1_wavein_open()
\n
"
);
...
...
@@ -169,6 +170,12 @@ int emu10k1_wavein_open(struct emu10k1_wavedevice *wave_dev)
emu10k1_set_record_src
(
card
,
wiinst
);
emu10k1_reset_record
(
card
,
&
wiinst
->
buffer
);
wiinst
->
buffer
.
hw_pos
=
0
;
wiinst
->
buffer
.
pos
=
0
;
wiinst
->
buffer
.
bytestocopy
=
0
;
delay
=
(
48000
*
wiinst
->
buffer
.
fragment_size
)
/
wiinst
->
format
.
bytespersec
;
emu10k1_timer_install
(
card
,
&
wiinst
->
timer
,
delay
/
2
);
...
...
@@ -222,10 +229,6 @@ void emu10k1_wavein_start(struct emu10k1_wavedevice *wave_dev)
emu10k1_start_record
(
card
,
&
wiinst
->
buffer
);
emu10k1_timer_enable
(
wave_dev
->
card
,
&
wiinst
->
timer
);
wiinst
->
buffer
.
hw_pos
=
0
;
wiinst
->
buffer
.
pos
=
0
;
wiinst
->
buffer
.
bytestocopy
=
0
;
wiinst
->
state
|=
WAVE_STATE_STARTED
;
}
...
...
@@ -249,7 +252,7 @@ int emu10k1_wavein_setformat(struct emu10k1_wavedevice *wave_dev, struct wave_fo
{
struct
emu10k1_card
*
card
=
wave_dev
->
card
;
struct
wiinst
*
wiinst
=
wave_dev
->
wiinst
;
u
32
delay
;
u
16
delay
;
DPF
(
2
,
"emu10k1_wavein_setformat()
\n
"
);
...
...
@@ -304,10 +307,9 @@ void emu10k1_wavein_getxfersize(struct wiinst *wiinst, u32 * size)
static
void
copy_block
(
u8
*
dst
,
u8
*
src
,
u32
str
,
u32
len
,
u8
cov
)
{
if
(
cov
==
1
)
{
if
(
__copy_to_user
(
dst
,
src
+
str
,
len
))
return
;
}
else
{
if
(
cov
==
1
)
__copy_to_user
(
dst
,
src
+
str
,
len
);
else
{
u8
byte
;
u32
i
;
...
...
@@ -315,8 +317,7 @@ static void copy_block(u8 *dst, u8 * src, u32 str, u32 len, u8 cov)
for
(
i
=
0
;
i
<
len
;
i
++
)
{
byte
=
src
[
2
*
i
]
^
0x80
;
if
(
__copy_to_user
(
dst
+
i
,
&
byte
,
1
))
return
;
__copy_to_user
(
dst
+
i
,
&
byte
,
1
);
}
}
}
...
...
sound/oss/emu10k1/cardwi.h
View file @
a9e4e4e0
...
...
@@ -69,13 +69,14 @@ struct wiinst
u16
fxwc
;
};
#define WAVEIN_MAXBUFSIZE
65536
#define WAVEIN_MINBUFSIZE
368
#define WAVEIN_MAXBUFSIZE
65536
#define WAVEIN_MINBUFSIZE 368
#define WAVEIN_DEFAULTFRAGLEN
100
#define WAVEIN_DEFAULTBUFLEN
1000
#define WAVEIN_DEFAULTFRAGLEN
100
#define WAVEIN_DEFAULTBUFLEN
1000
#define WAVEIN_MINFRAGSHIFT 8
#define WAVEIN_MINFRAGSHIFT 8
#define WAVEIN_MINFRAGS 2
int
emu10k1_wavein_open
(
struct
emu10k1_wavedevice
*
);
void
emu10k1_wavein_close
(
struct
emu10k1_wavedevice
*
);
...
...
sound/oss/emu10k1/cardwo.c
View file @
a9e4e4e0
...
...
@@ -108,95 +108,20 @@ static void query_format(struct emu10k1_wavedevice *wave_dev, struct wave_format
}
wave_fmt
->
bytesperchannel
=
wave_fmt
->
bitsperchannel
>>
3
;
wave_fmt
->
bytespersample
=
wave_fmt
->
channels
*
wave_fmt
->
bytesperchannel
;
wave_fmt
->
bytespersec
=
wave_fmt
->
bytespersample
*
wave_fmt
->
samplingrate
;
if
(
wave_fmt
->
channels
==
2
)
wave_fmt
->
bytespervoicesample
=
wave_fmt
->
channels
*
wave_fmt
->
bytesperchannel
;
else
wave_fmt
->
bytespervoicesample
=
wave_fmt
->
bytesperchannel
;
wave_fmt
->
bytespersample
=
wave_fmt
->
channels
*
wave_fmt
->
bytesperchannel
;
wave_fmt
->
bytespersec
=
wave_fmt
->
bytespersample
*
wave_fmt
->
samplingrate
;
}
/**
* alloc_buffer -
*
* allocates the memory buffer for a voice. Two page tables are kept for each buffer.
* One (dma_handle) keeps track of the host memory pages used and the other (virtualpagetable)
* is passed to the device so that it can do DMA to host memory.
*
*/
static
int
alloc_buffer
(
struct
emu10k1_card
*
card
,
struct
waveout_buffer
*
buffer
,
unsigned
int
voicenum
)
{
u32
pageindex
,
pagecount
;
unsigned
long
busaddx
;
int
i
;
DPD
(
2
,
"requested pages is: %d
\n
"
,
buffer
->
pages
);
if
((
buffer
->
mem
[
voicenum
].
emupageindex
=
emu10k1_addxmgr_alloc
(
buffer
->
pages
*
PAGE_SIZE
,
card
))
<
0
)
return
-
1
;
/* Fill in virtual memory table */
for
(
pagecount
=
0
;
pagecount
<
buffer
->
pages
;
pagecount
++
)
{
if
((
buffer
->
mem
[
voicenum
].
addr
[
pagecount
]
=
pci_alloc_consistent
(
card
->
pci_dev
,
PAGE_SIZE
,
&
buffer
->
mem
[
voicenum
].
dma_handle
[
pagecount
]))
==
NULL
)
{
buffer
->
pages
=
pagecount
;
return
-
1
;
}
DPD
(
2
,
"Virtual Addx: %p
\n
"
,
buffer
->
mem
[
voicenum
].
addr
[
pagecount
]);
for
(
i
=
0
;
i
<
PAGE_SIZE
/
EMUPAGESIZE
;
i
++
)
{
busaddx
=
buffer
->
mem
[
voicenum
].
dma_handle
[
pagecount
]
+
i
*
EMUPAGESIZE
;
DPD
(
3
,
"Bus Addx: %#lx
\n
"
,
busaddx
);
pageindex
=
buffer
->
mem
[
voicenum
].
emupageindex
+
pagecount
*
PAGE_SIZE
/
EMUPAGESIZE
+
i
;
((
u32
*
)
card
->
virtualpagetable
.
addr
)[
pageindex
]
=
cpu_to_le32
((
busaddx
*
2
)
|
pageindex
);
}
}
return
0
;
}
/**
* free_buffer -
*
* frees the memory buffer for a voice.
*/
static
void
free_buffer
(
struct
emu10k1_card
*
card
,
struct
waveout_buffer
*
buffer
,
unsigned
int
voicenum
)
{
u32
pagecount
,
pageindex
;
int
i
;
if
(
buffer
->
mem
[
voicenum
].
emupageindex
<
0
)
return
;
for
(
pagecount
=
0
;
pagecount
<
buffer
->
pages
;
pagecount
++
)
{
pci_free_consistent
(
card
->
pci_dev
,
PAGE_SIZE
,
buffer
->
mem
[
voicenum
].
addr
[
pagecount
],
buffer
->
mem
[
voicenum
].
dma_handle
[
pagecount
]);
for
(
i
=
0
;
i
<
PAGE_SIZE
/
EMUPAGESIZE
;
i
++
)
{
pageindex
=
buffer
->
mem
[
voicenum
].
emupageindex
+
pagecount
*
PAGE_SIZE
/
EMUPAGESIZE
+
i
;
((
u32
*
)
card
->
virtualpagetable
.
addr
)[
pageindex
]
=
cpu_to_le32
((
card
->
silentpage
.
dma_handle
*
2
)
|
pageindex
);
}
}
emu10k1_addxmgr_free
(
card
,
buffer
->
mem
[
voicenum
].
emupageindex
);
buffer
->
mem
[
voicenum
].
emupageindex
=
-
1
;
}
static
int
get_voice
(
struct
emu10k1_card
*
card
,
struct
woinst
*
woinst
,
unsigned
int
voicenum
)
{
struct
emu_voice
*
voice
=
&
woinst
->
voice
[
voicenum
];
/* Allocate voices here, if no voices available, return error.
* Init voice_allocdesc first.
*/
/* Allocate voices here, if no voices available, return error.
*/
voice
->
usage
=
VOICE_USAGE_PLAYBACK
;
...
...
@@ -219,7 +144,7 @@ static int get_voice(struct emu10k1_card *card, struct woinst *woinst, unsigned
DPD
(
2
,
"Initial pitch --> %#x
\n
"
,
voice
->
initial_pitch
);
voice
->
startloop
=
(
woinst
->
buffer
.
mem
[
voicenum
]
.
emupageindex
<<
12
)
/
voice
->
startloop
=
(
voice
->
mem
.
emupageindex
<<
12
)
/
woinst
->
format
.
bytespervoicesample
;
voice
->
endloop
=
voice
->
startloop
+
woinst
->
buffer
.
size
/
woinst
->
format
.
bytespervoicesample
;
voice
->
start
=
voice
->
startloop
;
...
...
@@ -297,12 +222,12 @@ int emu10k1_waveout_open(struct emu10k1_wavedevice *wave_dev)
struct
woinst
*
woinst
=
wave_dev
->
woinst
;
struct
waveout_buffer
*
buffer
=
&
woinst
->
buffer
;
unsigned
int
voicenum
;
u
32
delay
;
u
16
delay
;
DPF
(
2
,
"emu10k1_waveout_open()
\n
"
);
for
(
voicenum
=
0
;
voicenum
<
woinst
->
num_voices
;
voicenum
++
)
{
if
(
alloc_buffer
(
card
,
buffer
,
voicenum
)
<
0
)
{
if
(
emu10k1_voice_alloc_buffer
(
card
,
&
woinst
->
voice
[
voicenum
].
mem
,
woinst
->
buffer
.
pages
)
<
0
)
{
ERROR
();
emu10k1_waveout_close
(
wave_dev
);
return
-
1
;
...
...
@@ -324,7 +249,7 @@ int emu10k1_waveout_open(struct emu10k1_wavedevice *wave_dev)
delay
=
(
48000
*
woinst
->
buffer
.
fragment_size
)
/
(
woinst
->
format
.
samplingrate
*
woinst
->
format
.
bytespervoicesample
);
emu10k1_timer_install
(
card
,
&
woinst
->
timer
,
delay
/
2
);
emu10k1_timer_install
(
card
,
&
woinst
->
timer
,
delay
);
woinst
->
state
=
WAVE_STATE_OPEN
;
...
...
@@ -345,7 +270,7 @@ void emu10k1_waveout_close(struct emu10k1_wavedevice *wave_dev)
for
(
voicenum
=
0
;
voicenum
<
woinst
->
num_voices
;
voicenum
++
)
{
emu10k1_voice_free
(
&
woinst
->
voice
[
voicenum
]);
free_buffer
(
card
,
&
woinst
->
buffer
,
voicenu
m
);
emu10k1_voice_free_buffer
(
card
,
&
woinst
->
voice
[
voicenum
].
me
m
);
}
woinst
->
state
=
WAVE_STATE_CLOSED
;
...
...
@@ -371,7 +296,7 @@ int emu10k1_waveout_setformat(struct emu10k1_wavedevice *wave_dev, struct wave_f
struct
emu10k1_card
*
card
=
wave_dev
->
card
;
struct
woinst
*
woinst
=
wave_dev
->
woinst
;
unsigned
int
voicenum
;
u
32
delay
;
u
16
delay
;
DPF
(
2
,
"emu10k1_waveout_setformat()
\n
"
);
...
...
@@ -404,7 +329,7 @@ int emu10k1_waveout_setformat(struct emu10k1_wavedevice *wave_dev, struct wave_f
delay
=
(
48000
*
woinst
->
buffer
.
fragment_size
)
/
(
woinst
->
format
.
samplingrate
*
woinst
->
format
.
bytespervoicesample
);
emu10k1_timer_install
(
card
,
&
woinst
->
timer
,
delay
/
2
);
emu10k1_timer_install
(
card
,
&
woinst
->
timer
,
delay
);
}
return
0
;
...
...
@@ -449,7 +374,7 @@ void emu10k1_waveout_getxfersize(struct woinst *woinst, u32 *total_free_bytes)
pending_bytes
=
buffer
->
size
-
buffer
->
free_bytes
;
buffer
->
fill_silence
=
(
pending_bytes
<
(
signed
)
buffer
->
fragment_size
)
?
1
:
0
;
buffer
->
fill_silence
=
(
pending_bytes
<
(
signed
)
buffer
->
fragment_size
*
2
)
?
1
:
0
;
if
(
pending_bytes
>
(
signed
)
buffer
->
silence_bytes
)
{
*
total_free_bytes
=
(
buffer
->
free_bytes
+
buffer
->
silence_bytes
);
...
...
@@ -483,17 +408,14 @@ static void copy_block(void **dst, u32 str, u8 *src, u32 len)
if
(
len
>
PAGE_SIZE
-
pgoff
)
{
k
=
PAGE_SIZE
-
pgoff
;
if
(
__copy_from_user
((
u8
*
)
dst
[
pg
]
+
pgoff
,
src
,
k
))
return
;
__copy_from_user
((
u8
*
)
dst
[
pg
]
+
pgoff
,
src
,
k
);
len
-=
k
;
while
(
len
>
PAGE_SIZE
)
{
if
(
__copy_from_user
(
dst
[
++
pg
],
src
+
k
,
PAGE_SIZE
))
return
;
__copy_from_user
(
dst
[
++
pg
],
src
+
k
,
PAGE_SIZE
);
k
+=
PAGE_SIZE
;
len
-=
PAGE_SIZE
;
}
if
(
__copy_from_user
(
dst
[
++
pg
],
src
+
k
,
len
))
return
;
__copy_from_user
(
dst
[
++
pg
],
src
+
k
,
len
);
}
else
__copy_from_user
((
u8
*
)
dst
[
pg
]
+
pgoff
,
src
,
len
);
...
...
@@ -511,15 +433,14 @@ static void copy_ilv_block(struct woinst *woinst, u32 str, u8 *src, u32 len)
unsigned
int
pg
;
unsigned
int
pgoff
;
unsigned
int
voice_num
;
struct
waveout_mem
*
mem
=
woinst
->
buffer
.
mem
;
struct
emu_voice
*
voice
=
woinst
->
voice
;
pg
=
str
/
PAGE_SIZE
;
pgoff
=
str
%
PAGE_SIZE
;
while
(
len
)
{
for
(
voice_num
=
0
;
voice_num
<
woinst
->
num_voices
;
voice_num
++
)
{
if
(
__copy_from_user
((
u8
*
)(
mem
[
voice_num
].
addr
[
pg
])
+
pgoff
,
src
,
woinst
->
format
.
bytespervoicesample
))
return
;
__copy_from_user
((
u8
*
)(
voice
[
voice_num
].
mem
.
addr
[
pg
])
+
pgoff
,
src
,
woinst
->
format
.
bytespervoicesample
);
src
+=
woinst
->
format
.
bytespervoicesample
;
}
...
...
@@ -544,7 +465,7 @@ static void fill_block(struct woinst *woinst, u32 str, u8 data, u32 len)
unsigned
int
pg
;
unsigned
int
pgoff
;
unsigned
int
voice_num
;
struct
waveout_mem
*
mem
=
woinst
->
buffer
.
mem
;
struct
emu_voice
*
voice
=
woinst
->
voice
;
unsigned
int
k
;
pg
=
str
/
PAGE_SIZE
;
...
...
@@ -553,22 +474,22 @@ static void fill_block(struct woinst *woinst, u32 str, u8 data, u32 len)
if
(
len
>
PAGE_SIZE
-
pgoff
)
{
k
=
PAGE_SIZE
-
pgoff
;
for
(
voice_num
=
0
;
voice_num
<
woinst
->
num_voices
;
voice_num
++
)
memset
((
u8
*
)
mem
[
voice_num
]
.
addr
[
pg
]
+
pgoff
,
data
,
k
);
memset
((
u8
*
)
voice
[
voice_num
].
mem
.
addr
[
pg
]
+
pgoff
,
data
,
k
);
len
-=
k
;
while
(
len
>
PAGE_SIZE
)
{
pg
++
;
for
(
voice_num
=
0
;
voice_num
<
woinst
->
num_voices
;
voice_num
++
)
memset
(
mem
[
voice_num
]
.
addr
[
pg
],
data
,
PAGE_SIZE
);
memset
(
voice
[
voice_num
].
mem
.
addr
[
pg
],
data
,
PAGE_SIZE
);
len
-=
PAGE_SIZE
;
}
pg
++
;
for
(
voice_num
=
0
;
voice_num
<
woinst
->
num_voices
;
voice_num
++
)
memset
(
mem
[
voice_num
]
.
addr
[
pg
],
data
,
len
);
memset
(
voice
[
voice_num
].
mem
.
addr
[
pg
],
data
,
len
);
}
else
{
for
(
voice_num
=
0
;
voice_num
<
woinst
->
num_voices
;
voice_num
++
)
memset
((
u8
*
)
mem
[
voice_num
]
.
addr
[
pg
]
+
pgoff
,
data
,
len
);
memset
((
u8
*
)
voice
[
voice_num
].
mem
.
addr
[
pg
]
+
pgoff
,
data
,
len
);
}
}
...
...
@@ -582,6 +503,7 @@ static void fill_block(struct woinst *woinst, u32 str, u8 data, u32 len)
void
emu10k1_waveout_xferdata
(
struct
woinst
*
woinst
,
u8
*
data
,
u32
*
size
)
{
struct
waveout_buffer
*
buffer
=
&
woinst
->
buffer
;
struct
voice_mem
*
mem
=
&
woinst
->
voice
[
0
].
mem
;
u32
sizetocopy
,
sizetocopy_now
,
start
;
unsigned
long
flags
;
...
...
@@ -610,14 +532,14 @@ void emu10k1_waveout_xferdata(struct woinst *woinst, u8 *data, u32 *size)
copy_ilv_block
(
woinst
,
start
,
data
,
sizetocopy_now
);
copy_ilv_block
(
woinst
,
0
,
data
+
sizetocopy_now
*
woinst
->
num_voices
,
sizetocopy
);
}
else
{
copy_block
(
buffer
->
mem
[
0
].
addr
,
start
,
data
,
sizetocopy_now
);
copy_block
(
buffer
->
mem
[
0
].
addr
,
0
,
data
+
sizetocopy_now
,
sizetocopy
);
copy_block
(
mem
->
addr
,
start
,
data
,
sizetocopy_now
);
copy_block
(
mem
->
addr
,
0
,
data
+
sizetocopy_now
,
sizetocopy
);
}
}
else
{
if
(
woinst
->
num_voices
>
1
)
copy_ilv_block
(
woinst
,
start
,
data
,
sizetocopy
);
else
copy_block
(
buffer
->
mem
[
0
].
addr
,
start
,
data
,
sizetocopy
);
copy_block
(
mem
->
addr
,
start
,
data
,
sizetocopy
);
}
}
...
...
@@ -674,7 +596,7 @@ void emu10k1_waveout_update(struct woinst *woinst)
{
u32
hw_pos
;
u32
diff
;
/* There is no actual start yet */
if
(
!
(
woinst
->
state
&
WAVE_STATE_STARTED
))
{
hw_pos
=
woinst
->
buffer
.
hw_pos
;
...
...
sound/oss/emu10k1/cardwo.h
View file @
a9e4e4e0
...
...
@@ -39,20 +39,13 @@
/* setting this to other than a power of two may break some applications */
#define WAVEOUT_MAXBUFSIZE MAXBUFSIZE
#define WAVEOUT_MINBUFSIZE 64
#define WAVEOUT_DEFAULTFRAGLEN 20
/* Time to play a fragment in ms (latency) */
#define WAVEOUT_DEFAULTBUFLEN 500
/* Time to play the entire buffer in ms */
#define WAVEOUT_MINFRAGSHIFT 6
#define WAVEOUT_MAXVOICES 6
/* waveout_mem is cardwo internal */
struct
waveout_mem
{
int
emupageindex
;
void
*
addr
[
BUFMAXPAGES
];
dma_addr_t
dma_handle
[
BUFMAXPAGES
];
};
#define WAVEOUT_MINFRAGSHIFT 6
/* Minimum fragment size in bytes is 2^6 */
#define WAVEOUT_MINFRAGS 3
/* _don't_ go bellow 3, it would break silence filling */
#define WAVEOUT_MAXVOICES 6
struct
waveout_buffer
{
u16
ossfragshift
;
...
...
@@ -60,7 +53,6 @@ struct waveout_buffer {
u32
fragment_size
;
/* in bytes units */
u32
size
;
/* in bytes units */
u32
pages
;
/* buffer size in page units*/
struct
waveout_mem
mem
[
WAVEOUT_MAXVOICES
];
u32
silence_pos
;
/* software cursor position (including silence bytes) */
u32
hw_pos
;
/* hardware cursor position */
u32
free_bytes
;
/* free bytes available on the buffer (not including silence bytes) */
...
...
sound/oss/emu10k1/efxmgr.c
View file @
a9e4e4e0
...
...
@@ -38,7 +38,7 @@ int emu10k1_find_control_gpr(struct patch_manager *mgr, const char *patch_name,
struct
dsp_patch
*
patch
;
struct
dsp_rpatch
*
rpatch
;
char
s
[
PATCH_NAME_SIZE
+
4
];
u
32
*
gpr_used
;
u
nsigned
long
*
gpr_used
;
int
i
;
DPD
(
2
,
"emu10k1_find_control_gpr(): %s %s
\n
"
,
patch_name
,
gpr_name
);
...
...
@@ -103,7 +103,7 @@ void emu10k1_set_oss_vol(struct emu10k1_card *card, int oss_mixer,
card
->
ac97
.
mixer_state
[
oss_mixer
]
=
(
right
<<
8
)
|
left
;
if
(
!
card
->
isaps
)
if
(
!
card
->
is
_
aps
)
card
->
ac97
.
write_mixer
(
&
card
->
ac97
,
oss_mixer
,
left
,
right
);
emu10k1_set_volume_gpr
(
card
,
card
->
mgr
.
ctrl_gpr
[
oss_mixer
][
0
],
left
,
...
...
@@ -171,9 +171,8 @@ void emu10k1_set_volume_gpr(struct emu10k1_card *card, int addr, s32 vol, int sc
{
struct
patch_manager
*
mgr
=
&
card
->
mgr
;
unsigned
long
flags
;
int
muting
;
const
s32
log2lin
[
5
]
=
{
// attenuation (dB)
static
const
s32
log2lin
[
4
]
=
{
// attenuation (dB)
0x7fffffff
,
// 0.0
0x7fffffff
*
0
.
840896415253715
,
// 1.5
0x7fffffff
*
0
.
707106781186548
,
// 3.0
...
...
@@ -183,12 +182,10 @@ void emu10k1_set_volume_gpr(struct emu10k1_card *card, int addr, s32 vol, int sc
if
(
addr
<
0
)
return
;
muting
=
(
scale
==
0x10
)
?
0x7f
:
scale
;
vol
=
(
100
-
vol
)
*
scale
/
100
;
// Thanks to the comp.dsp newsgroup for this neat trick:
vol
=
(
vol
>=
muting
)
?
0
:
(
log2lin
[
vol
&
3
]
>>
(
vol
>>
2
));
vol
=
(
vol
>=
scale
)
?
0
:
(
log2lin
[
vol
&
3
]
>>
(
vol
>>
2
));
spin_lock_irqsave
(
&
mgr
->
lock
,
flags
);
emu10k1_set_control_gpr
(
card
,
addr
,
vol
,
0
);
...
...
sound/oss/emu10k1/efxmgr.h
View file @
a9e4e4e0
...
...
@@ -35,9 +35,9 @@
#define WRITE_EFX(a, b, c) sblive_writeptr((a), MICROCODEBASE + (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)); \
++pc; } while (0)
do { WRITE_EFX(card, (pc) * 2, ((x) << 10) | (y)); \
WRITE_EFX(card, (pc) * 2 + 1, ((op) << 20) | ((z) << 10) | (w)); \
++pc; } while (0)
#define NUM_INPUTS 0x20
#define NUM_OUTPUTS 0x20
...
...
@@ -47,52 +47,52 @@
struct
dsp_rpatch
{
char
name
[
PATCH_NAME_SIZE
];
u16
code_start
;
u16
code_size
;
u16
code_start
;
u16
code_size
;
u32
gpr_used
[
NUM_GPRS
/
32
];
u32
gpr_input
[
NUM_GPRS
/
32
];
u32
route
[
NUM_OUTPUTS
];
u32
route_v
[
NUM_OUTPUTS
];
unsigned
long
gpr_used
[
NUM_GPRS
/
(
sizeof
(
unsigned
long
)
*
8
)
+
1
];
unsigned
long
gpr_input
[
NUM_GPRS
/
(
sizeof
(
unsigned
long
)
*
8
)
+
1
];
unsigned
long
route
[
NUM_OUTPUTS
];
unsigned
long
route_v
[
NUM_OUTPUTS
];
};
struct
dsp_patch
{
char
name
[
PATCH_NAME_SIZE
];
u8
id
;
u32
input
;
/* bitmap of the lines used as inputs */
u
32
output
;
/* bitmap of the lines used as outputs */
u16
code_start
;
u16
code_size
;
u32
gpr_used
[
NUM_GPRS
/
32
];
/* bitmap of used gprs */
u32
gpr_input
[
NUM_GPRS
/
32
];
u8
traml_istart
;
/* starting address of the internal tram lines used */
u8
traml_isize
;
/* number of internal tram lines used */
u8
traml_estart
;
u8
traml_esize
;
u16
tramb_istart
;
/* starting address of the internal tram memory used */
u16
tramb_isize
;
/* amount of internal memory used */
u32
tramb_estart
;
u32
tramb_esize
;
char
name
[
PATCH_NAME_SIZE
];
u8
id
;
unsigned
long
input
;
/* bitmap of the lines used as inputs */
u
nsigned
long
output
;
/* bitmap of the lines used as outputs */
u16
code_start
;
u16
code_size
;
unsigned
long
gpr_used
[
NUM_GPRS
/
(
sizeof
(
unsigned
long
)
*
8
)
+
1
];
/* bitmap of used gprs */
unsigned
long
gpr_input
[
NUM_GPRS
/
(
sizeof
(
unsigned
long
)
*
8
)
+
1
];
u8
traml_istart
;
/* starting address of the internal tram lines used */
u8
traml_isize
;
/* number of internal tram lines used */
u8
traml_estart
;
u8
traml_esize
;
u16
tramb_istart
;
/* starting address of the internal tram memory used */
u16
tramb_isize
;
/* amount of internal memory used */
u32
tramb_estart
;
u32
tramb_esize
;
};
struct
dsp_gpr
{
u8
type
;
/* gpr type, STATIC, DYNAMIC, INPUT, OUTPUT, CONTROL */
char
name
[
GPR_NAME_SIZE
];
/* gpr value, only valid for control gprs */
s32
min
,
max
;
/* value range for this gpr, only valid for control gprs */
u8
line
;
/* which input/output line is the gpr attached, only valid for input/output gprs */
u8
usage
;
u8
type
;
/* gpr type, STATIC, DYNAMIC, INPUT, OUTPUT, CONTROL */
char
name
[
GPR_NAME_SIZE
];
/* gpr value, only valid for control gprs */
s32
min
,
max
;
/* value range for this gpr, only valid for control gprs */
u8
line
;
/* which input/output line is the gpr attached, only valid for input/output gprs */
u8
usage
;
};
enum
{
GPR_TYPE_NULL
=
0
,
GPR_TYPE_IO
,
GPR_TYPE_STATIC
,
GPR_TYPE_DYNAMIC
,
GPR_TYPE_CONTROL
,
GPR_TYPE_CONSTANT
GPR_TYPE_NULL
=
0
,
GPR_TYPE_IO
,
GPR_TYPE_STATIC
,
GPR_TYPE_DYNAMIC
,
GPR_TYPE_CONTROL
,
GPR_TYPE_CONSTANT
};
#define GPR_BASE 0x100
...
...
@@ -101,15 +101,14 @@ enum {
#define MAX_PATCHES_PAGES 32
struct
patch_manager
{
void
*
patch
[
MAX_PATCHES_PAGES
];
void
*
patch
[
MAX_PATCHES_PAGES
];
int
current_pages
;
struct
dsp_rpatch
rpatch
;
struct
dsp_gpr
gpr
[
NUM_GPRS
];
/* gpr usage table */
struct
dsp_rpatch
rpatch
;
struct
dsp_gpr
gpr
[
NUM_GPRS
];
/* gpr usage table */
spinlock_t
lock
;
s16
ctrl_gpr
[
SOUND_MIXER_NRDEVICES
][
2
];
};
#define PATCHES_PER_PAGE (PAGE_SIZE / sizeof(struct dsp_patch))
#define PATCH(mgr, i) ((struct dsp_patch *) (mgr)->patch[(i) / PATCHES_PER_PAGE] + (i) % PATCHES_PER_PAGE)
...
...
sound/oss/emu10k1/hwaccess.c
View file @
a9e4e4e0
...
...
@@ -187,6 +187,15 @@ u32 emu10k1_readfn0(struct emu10k1_card * card, u32 reg)
}
}
void
emu10k1_timer_set
(
struct
emu10k1_card
*
card
,
u16
data
)
{
unsigned
long
flags
;
spin_lock_irqsave
(
&
card
->
lock
,
flags
);
outw
(
data
&
TIMER_RATE_MASK
,
card
->
iobase
+
TIMER
);
spin_unlock_irqrestore
(
&
card
->
lock
,
flags
);
}
/************************************************************************
* write/read Emu10k1 pointer-offset register set, accessed through *
* the PTR and DATA registers *
...
...
sound/oss/emu10k1/hwaccess.h
View file @
a9e4e4e0
...
...
@@ -126,6 +126,7 @@ struct mixer_private_ioctl {
#define CMD_SETMCH_FX _IOW('D', 17, struct mixer_private_ioctl)
#define CMD_SETPASSTHROUGH _IOW('D', 18, struct mixer_private_ioctl)
#define CMD_PRIVATE3_VERSION _IOW('D', 19, 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
...
...
@@ -144,7 +145,7 @@ struct emu10k1_card
u16
emupagetable
[
MAXPAGES
];
struct
list_head
timers
;
u
nsigned
timer_delay
;
u
16
timer_delay
;
spinlock_t
timer_lock
;
struct
pci_dev
*
pci_dev
;
...
...
@@ -181,7 +182,7 @@ struct emu10k1_card
u8
chiprev
;
/* Chip revision */
int
is
aps
;
u8
is_
aps
;
struct
patch_manager
mgr
;
struct
pt_data
pt
;
...
...
@@ -190,8 +191,6 @@ struct emu10k1_card
int
emu10k1_addxmgr_alloc
(
u32
,
struct
emu10k1_card
*
);
void
emu10k1_addxmgr_free
(
struct
emu10k1_card
*
,
int
);
int
emu10k1_find_control_gpr
(
struct
patch_manager
*
,
const
char
*
,
const
char
*
);
void
emu10k1_set_control_gpr
(
struct
emu10k1_card
*
,
int
,
s32
,
int
);
...
...
@@ -211,12 +210,14 @@ extern struct list_head emu10k1_devs;
/* Hardware Abstraction Layer access functions */
void
emu10k1_writefn0
(
struct
emu10k1_card
*
,
u32
,
u32
);
u32
emu10k1_readfn0
(
struct
emu10k1_card
*
,
u32
);
void
emu10k1_writefn0
(
struct
emu10k1_card
*
,
u32
,
u32
);
u32
emu10k1_readfn0
(
struct
emu10k1_card
*
,
u32
);
void
emu10k1_timer_set
(
struct
emu10k1_card
*
,
u16
);
void
sblive_writeptr
(
struct
emu10k1_card
*
,
u32
,
u32
,
u32
);
void
sblive_writeptr_tag
(
struct
emu10k1_card
*
card
,
u32
channel
,
...);
#define TAGLIST_END
0
void
sblive_writeptr
(
struct
emu10k1_card
*
,
u32
,
u32
,
u32
);
void
sblive_writeptr_tag
(
struct
emu10k1_card
*
,
u32
,
...);
#define TAGLIST_END
0
u32
sblive_readptr
(
struct
emu10k1_card
*
,
u32
,
u32
);
...
...
sound/oss/emu10k1/irqmgr.c
View file @
a9e4e4e0
/*
**********************************************************************
* irqmgr.c - IRQ manager for emu10k1 driver
...
...
@@ -41,7 +40,7 @@
void
emu10k1_interrupt
(
int
irq
,
void
*
dev_id
,
struct
pt_regs
*
regs
)
{
struct
emu10k1_card
*
card
=
(
struct
emu10k1_card
*
)
dev_id
;
u32
irqstatus
;
u32
irqstatus
,
irqstatus_tmp
;
DPD
(
4
,
"emu10k1_interrupt called, irq = %u
\n
"
,
irq
);
...
...
@@ -60,8 +59,7 @@ void emu10k1_interrupt(int irq, void *dev_id, struct pt_regs *regs)
while
((
irqstatus
=
inl
(
card
->
iobase
+
IPR
)))
{
DPD
(
4
,
"irq status %#x
\n
"
,
irqstatus
);
/* acknowledge interrupt */
outl
(
irqstatus
,
card
->
iobase
+
IPR
);
irqstatus_tmp
=
irqstatus
;
if
(
irqstatus
&
IRQTYPE_TIMER
)
{
emu10k1_timer_irqhandler
(
card
);
...
...
@@ -98,7 +96,15 @@ void emu10k1_interrupt(int irq, void *dev_id, struct pt_regs *regs)
irqstatus
&=~
IPR_VOLDECR
;
}
if
(
irqstatus
)
emu10k1_irq_disable
(
card
,
irqstatus
);
if
(
irqstatus
){
printk
(
KERN_ERR
"emu10k1: Warning, unhandled interrupt: %#08x
\n
"
,
irqstatus
);
//make sure any interrupts we don't handle are disabled:
emu10k1_irq_disable
(
card
,
~
(
INTE_MIDIRXENABLE
|
INTE_MIDITXENABLE
|
INTE_INTERVALTIMERENB
|
INTE_VOLDECRENABLE
|
INTE_VOLINCRENABLE
|
INTE_MUTEENABLE
|
INTE_FXDSPENABLE
));
}
/* acknowledge interrupt */
outl
(
irqstatus_tmp
,
card
->
iobase
+
IPR
);
}
}
sound/oss/emu10k1/main.c
View file @
a9e4e4e0
/*
/*
**********************************************************************
* main.c - Creative EMU10K1 audio driver
* Copyright 1999, 2000 Creative Labs, Inc.
...
...
@@ -69,7 +69,20 @@
* 0.16 Mixer improvements, added old treble/bass support (Daniel Bertrand)
* Small code format cleanup.
* Deadlock bug fix for emu10k1_volxxx_irqhandler().
*
* 0.17 Fix for mixer SOUND_MIXER_INFO ioctl.
* Fix for HIGHMEM machines (emu10k1 can only do 31 bit bus master)
* midi poll initial implementation.
* Small mixer fixes/cleanups.
* Improved support for 5.1 cards.
* 0.18 Fix for possible leak in pci_alloc_consistent()
* Cleaned up poll() functions (audio and midi). Don't start input.
* Restrict DMA pages used to 512Mib range.
* New AC97_BOOST mixer ioctl.
* 0.19 Real fix for kernel with highmem support (cast dma_handle to u32).
* Fix recording buffering parameters calculation.
* Use unsigned long for variables in bit ops.
* 0.20 Fixed recording startup
* Fixed timer rate setting (it's a 16-bit register)
*********************************************************************/
/* These are only included once per module */
...
...
@@ -102,11 +115,10 @@
#define SNDCARD_EMU10K1 46
#endif
#define DRIVER_VERSION "0.
16
"
#define DRIVER_VERSION "0.
20
"
/* FIXME: is this right? */
/* does the card support 32 bit bus master?*/
#define EMU10K1_DMA_MASK 0xffffffff
/* DMA buffer mask for pci_alloc_consist */
/* the emu10k1 _seems_ to only supports 29 bit (512MiB) bit bus master */
#define EMU10K1_DMA_MASK 0x1fffffff
/* DMA buffer mask for pci_alloc_consist */
#ifndef PCI_VENDOR_ID_CREATIVE
#define PCI_VENDOR_ID_CREATIVE 0x1102
...
...
@@ -188,7 +200,7 @@ static int __devinit emu10k1_audio_init(struct emu10k1_card *card)
/* Assign default recording parameters */
/* FIXME */
if
(
card
->
is
aps
)
if
(
card
->
is_
aps
)
card
->
wavein
.
recsrc
=
WAVERECORD_FX
;
else
card
->
wavein
.
recsrc
=
WAVERECORD_AC97
;
...
...
@@ -211,6 +223,8 @@ static void __devinit emu10k1_audio_cleanup(struct emu10k1_card *card)
static
int
__devinit
emu10k1_mixer_init
(
struct
emu10k1_card
*
card
)
{
char
s
[
32
];
struct
ac97_codec
*
codec
=
&
card
->
ac97
;
card
->
ac97
.
dev_mixer
=
register_sound_mixer
(
&
emu10k1_mixer_fops
,
-
1
);
if
(
card
->
ac97
.
dev_mixer
<
0
)
{
printk
(
KERN_ERR
"emu10k1: cannot register mixer device
\n
"
);
...
...
@@ -219,7 +233,7 @@ static int __devinit emu10k1_mixer_init(struct emu10k1_card *card)
card
->
ac97
.
private_data
=
card
;
if
(
!
card
->
isaps
)
{
if
(
!
card
->
is
_
aps
)
{
card
->
ac97
.
id
=
0
;
card
->
ac97
.
codec_read
=
emu10k1_ac97_read
;
card
->
ac97
.
codec_write
=
emu10k1_ac97_write
;
...
...
@@ -228,11 +242,14 @@ static int __devinit emu10k1_mixer_init(struct emu10k1_card *card)
printk
(
KERN_ERR
"emu10k1: unable to probe AC97 codec
\n
"
);
goto
err_out
;
}
/* 5.1: Enable the additional AC97 Slots. If the emu10k1 version
does not support this, it shouldn't do any harm */
sblive_writeptr
(
card
,
AC97SLOT
,
0
,
AC97SLOT_CNTR
|
AC97SLOT_LFE
);
/* 5.1: Enable the additional AC97 Slots and unmute extra channels on AC97 codec */
if
(
codec
->
codec_read
(
codec
,
AC97_EXTENDED_ID
)
&
0x0080
){
printk
(
KERN_INFO
"emu10k1: SBLive! 5.1 card detected
\n
"
);
sblive_writeptr
(
card
,
AC97SLOT
,
0
,
AC97SLOT_CNTR
|
AC97SLOT_LFE
);
codec
->
codec_write
(
codec
,
AC97_SURROUND_MASTER
,
0x0
);
}
// Force 5bit
// Force 5bit
:
//card->ac97.bit_resolution=5;
if
(
!
proc_mkdir
(
"driver/emu10k1"
,
0
))
{
...
...
@@ -274,7 +291,7 @@ static void __devinit emu10k1_mixer_cleanup(struct emu10k1_card *card)
{
char
s
[
32
];
if
(
!
card
->
isaps
)
{
if
(
!
card
->
is
_
aps
)
{
sprintf
(
s
,
"driver/emu10k1/%s/ac97"
,
card
->
pci_dev
->
slot_name
);
remove_proc_entry
(
s
,
NULL
);
...
...
@@ -586,15 +603,15 @@ static int __devinit fx_init(struct emu10k1_card *card)
CONNECT
(
PCM1_IN_R
,
ANALOG_REAR_R
);
/* Digital In + PCM + AC97 In + MULTI_FRONT --> Digital out */
OP
(
6
,
0x10
b
,
0x100
,
0x102
,
0x10c
);
OP
(
6
,
0x10
b
,
0x10b
,
0x113
,
0x40
);
OP
(
6
,
0x10
a
,
0x100
,
0x102
,
0x10c
);
OP
(
6
,
0x10
a
,
0x10a
,
0x113
,
0x40
);
CONNECT
(
MULTI_FRONT_L
,
DIGITAL_OUT_L
);
CONNECT
(
PCM_IN_L
,
DIGITAL_OUT_L
);
CONNECT
(
AC97_IN_L
,
DIGITAL_OUT_L
);
CONNECT
(
SPDIF_CD_L
,
DIGITAL_OUT_L
);
OP
(
6
,
0x10
a
,
0x101
,
0x103
,
0x10e
);
OP
(
6
,
0x10
b
,
0x101
,
0x103
,
0x10e
);
OP
(
6
,
0x10b
,
0x10b
,
0x114
,
0x40
);
CONNECT
(
MULTI_FRONT_R
,
DIGITAL_OUT_R
);
...
...
@@ -768,7 +785,7 @@ static int __devinit hw_init(struct emu10k1_card *card)
VTFT
,
0xffff
,
CVCF
,
0xffff
,
PTRX
,
0
,
CPF
,
0
,
//
CPF, 0,
CCR
,
0
,
PSST
,
0
,
...
...
@@ -794,7 +811,9 @@ static int __devinit hw_init(struct emu10k1_card *card)
ENVVOL
,
0
,
ENVVAL
,
0
,
TAGLIST_END
);
sblive_writeptr
(
card
,
CPF
,
nCh
,
0
);
}
/*
** Init to 0x02109204 :
...
...
@@ -852,19 +871,19 @@ static int __devinit hw_init(struct emu10k1_card *card)
}
for
(
pagecount
=
0
;
pagecount
<
MAXPAGES
;
pagecount
++
)
((
u32
*
)
card
->
virtualpagetable
.
addr
)[
pagecount
]
=
cpu_to_le32
((
card
->
silentpage
.
dma_handle
*
2
)
|
pagecount
);
((
u32
*
)
card
->
virtualpagetable
.
addr
)[
pagecount
]
=
cpu_to_le32
((
(
u32
)
card
->
silentpage
.
dma_handle
*
2
)
|
pagecount
);
/* Init page table & tank memory base register */
sblive_writeptr_tag
(
card
,
0
,
PTB
,
card
->
virtualpagetable
.
dma_handle
,
PTB
,
(
u32
)
card
->
virtualpagetable
.
dma_handle
,
TCB
,
0
,
TCBS
,
0
,
TAGLIST_END
);
for
(
nCh
=
0
;
nCh
<
NUM_G
;
nCh
++
)
{
sblive_writeptr_tag
(
card
,
nCh
,
MAPA
,
MAP_PTI_MASK
|
(
card
->
silentpage
.
dma_handle
*
2
),
MAPB
,
MAP_PTI_MASK
|
(
card
->
silentpage
.
dma_handle
*
2
),
MAPA
,
MAP_PTI_MASK
|
(
(
u32
)
card
->
silentpage
.
dma_handle
*
2
),
MAPB
,
MAP_PTI_MASK
|
(
(
u32
)
card
->
silentpage
.
dma_handle
*
2
),
TAGLIST_END
);
}
...
...
@@ -951,8 +970,9 @@ static void __devinit emu10k1_cleanup(struct emu10k1_card *card)
VTFT
,
0
,
CVCF
,
0
,
PTRX
,
0
,
CPF
,
0
,
//
CPF, 0,
TAGLIST_END
);
sblive_writeptr
(
card
,
CPF
,
ch
,
0
);
}
/* Disable audio and lock cache */
...
...
@@ -999,7 +1019,7 @@ static int __devinit emu10k1_probe(struct pci_dev *pci_dev, const struct pci_dev
int
ret
;
if
(
pci_set_dma_mask
(
pci_dev
,
EMU10K1_DMA_MASK
))
{
printk
(
KERN_ERR
"emu10k1: architecture does not support
32
bit PCI busmaster DMA
\n
"
);
printk
(
KERN_ERR
"emu10k1: architecture does not support
29
bit PCI busmaster DMA
\n
"
);
return
-
ENODEV
;
}
...
...
@@ -1038,12 +1058,12 @@ static int __devinit emu10k1_probe(struct pci_dev *pci_dev, const struct pci_dev
pci_read_config_byte
(
pci_dev
,
PCI_REVISION_ID
,
&
card
->
chiprev
);
pci_read_config_word
(
pci_dev
,
PCI_SUBSYSTEM_ID
,
&
card
->
model
);
printk
(
KERN_INFO
"emu10k1: %s rev %d model
0x%x found, IO at 0x%04lx-0x%
04lx, IRQ %d
\n
"
,
printk
(
KERN_INFO
"emu10k1: %s rev %d model
%#04x found, IO at %#04lx-%#
04lx, IRQ %d
\n
"
,
card_names
[
pci_id
->
driver_data
],
card
->
chiprev
,
card
->
model
,
card
->
iobase
,
card
->
iobase
+
card
->
length
-
1
,
card
->
irq
);
pci_read_config_dword
(
pci_dev
,
PCI_SUBSYSTEM_VENDOR_ID
,
&
subsysvid
);
card
->
isaps
=
(
subsysvid
==
EMU_APS_SUBID
);
card
->
is
_
aps
=
(
subsysvid
==
EMU_APS_SUBID
);
spin_lock_init
(
&
card
->
lock
);
init_MUTEX
(
&
card
->
open_sem
);
...
...
@@ -1074,7 +1094,7 @@ static int __devinit emu10k1_probe(struct pci_dev *pci_dev, const struct pci_dev
goto
err_emu10k1_init
;
}
if
(
card
->
isaps
)
if
(
card
->
is
_
aps
)
emu10k1_ecard_init
(
card
);
list_add
(
&
card
->
list
,
&
emu10k1_devs
);
...
...
@@ -1119,7 +1139,7 @@ static void __devexit emu10k1_remove(struct pci_dev *pci_dev)
pci_set_drvdata
(
pci_dev
,
NULL
);
}
MODULE_AUTHOR
(
"Bertrand Lee, Cai Ying. (Email to: emu10k1-devel@
opensource.creative.com
)"
);
MODULE_AUTHOR
(
"Bertrand Lee, Cai Ying. (Email to: emu10k1-devel@
lists.sourceforge.net
)"
);
MODULE_DESCRIPTION
(
"Creative EMU10K1 PCI Audio Driver v"
DRIVER_VERSION
"
\n
Copyright (C) 1999 Creative Technology Ltd."
);
MODULE_LICENSE
(
"GPL"
);
...
...
sound/oss/emu10k1/midi.c
View file @
a9e4e4e0
...
...
@@ -29,8 +29,8 @@
**********************************************************************
*/
#define __NO_VERSION__
#include <linux/module.h>
#include <linux/poll.h>
#include <linux/slab.h>
#include <linux/version.h>
#include <linux/sched.h>
...
...
@@ -371,8 +371,32 @@ static ssize_t emu10k1_midi_write(struct file *file, const char *buffer, size_t
static
unsigned
int
emu10k1_midi_poll
(
struct
file
*
file
,
struct
poll_table_struct
*
wait
)
{
struct
emu10k1_mididevice
*
midi_dev
=
(
struct
emu10k1_mididevice
*
)
file
->
private_data
;
unsigned
long
flags
;
unsigned
int
mask
=
0
;
DPF
(
4
,
"emu10k1_midi_poll() called
\n
"
);
return
0
;
if
(
file
->
f_mode
&
FMODE_WRITE
)
poll_wait
(
file
,
&
midi_dev
->
oWait
,
wait
);
if
(
file
->
f_mode
&
FMODE_READ
)
poll_wait
(
file
,
&
midi_dev
->
iWait
,
wait
);
spin_lock_irqsave
(
&
midi_spinlock
,
flags
);
if
(
file
->
f_mode
&
FMODE_WRITE
)
mask
|=
POLLOUT
|
POLLWRNORM
;
if
(
file
->
f_mode
&
FMODE_READ
)
{
if
(
midi_dev
->
mistate
==
MIDIIN_STATE_STARTED
)
if
(
midi_dev
->
icnt
>
0
)
mask
|=
POLLIN
|
POLLRDNORM
;
}
spin_unlock_irqrestore
(
&
midi_spinlock
,
flags
);
return
mask
;
}
int
emu10k1_midi_callback
(
unsigned
long
msg
,
unsigned
long
refdata
,
unsigned
long
*
pmsg
)
...
...
sound/oss/emu10k1/mixer.c
View file @
a9e4e4e0
...
...
@@ -30,7 +30,6 @@
**********************************************************************
*/
#define __NO_VERSION__
/* Kernel version only defined once */
#include <linux/module.h>
#include <linux/version.h>
#include <asm/uaccess.h>
...
...
@@ -251,7 +250,7 @@ static int emu10k1_private_mixer(struct emu10k1_card *card, unsigned int cmd, un
case
CMD_SETRECSRC
:
switch
(
ctl
->
val
[
0
])
{
case
WAVERECORD_AC97
:
if
(
card
->
isaps
)
{
if
(
card
->
is
_
aps
)
{
ret
=
-
EINVAL
;
break
;
}
...
...
@@ -444,6 +443,7 @@ static int emu10k1_private_mixer(struct emu10k1_card *card, unsigned int cmd, un
case
CMD_SETGPR2OSS
:
id
=
ctl
->
val
[
0
];
/* 0 == left, 1 == right */
ch
=
ctl
->
val
[
1
];
addr
=
ctl
->
val
[
2
];
...
...
@@ -454,19 +454,19 @@ static int emu10k1_private_mixer(struct emu10k1_card *card, unsigned int cmd, un
card
->
mgr
.
ctrl_gpr
[
id
][
ch
]
=
addr
;
if
(
card
->
isaps
)
if
(
card
->
is
_
aps
)
break
;
if
(
addr
>=
0
)
{
unsigned
int
state
=
card
->
ac97
.
mixer_state
[
id
];
if
(
ch
)
{
if
(
ch
==
1
)
{
state
>>=
8
;
card
->
ac97
.
stereo_mixers
|=
(
1
<<
id
);
}
else
{
card
->
ac97
.
supported_mixers
|=
(
1
<<
id
);
}
card
->
ac97
.
supported_mixers
|=
(
1
<<
id
);
if
(
id
==
SOUND_MIXER_TREBLE
)
{
set_treble
(
card
,
card
->
ac97
.
mixer_state
[
id
]
&
0xff
,
(
card
->
ac97
.
mixer_state
[
id
]
>>
8
)
&
0xff
);
}
else
if
(
id
==
SOUND_MIXER_BASS
)
{
...
...
@@ -475,10 +475,10 @@ static int emu10k1_private_mixer(struct emu10k1_card *card, unsigned int cmd, un
emu10k1_set_volume_gpr
(
card
,
addr
,
state
&
0xff
,
volume_params
[
id
]);
}
else
{
if
(
ch
)
{
card
->
ac97
.
stereo_mixers
&=
~
(
1
<<
id
)
;
card
->
ac97
.
stereo_mixers
|=
card
->
ac97_stereo_mixers
;
}
else
{
card
->
ac97
.
stereo_mixers
&=
~
(
1
<<
id
);
card
->
ac97
.
stereo_mixers
|=
card
->
ac97_stereo_mixers
;
if
(
ch
==
0
)
{
card
->
ac97
.
supported_mixers
&=
~
(
1
<<
id
);
card
->
ac97
.
supported_mixers
|=
card
->
ac97_supported_mixers
;
}
...
...
@@ -499,6 +499,12 @@ static int emu10k1_private_mixer(struct emu10k1_card *card, unsigned int cmd, un
ret
=
-
EFAULT
;
break
;
case
CMD_AC97_BOOST
:
if
(
ctl
->
val
[
0
])
emu10k1_ac97_write
(
&
card
->
ac97
,
0x18
,
0x0
);
else
emu10k1_ac97_write
(
&
card
->
ac97
,
0x18
,
0x0808
);
break
;
default:
ret
=
-
EINVAL
;
break
;
...
...
@@ -551,7 +557,7 @@ static int emu10k1_private_mixer(struct emu10k1_card *card, unsigned int cmd, un
card
->
tankmem
.
size
=
size
;
sblive_writeptr_tag
(
card
,
0
,
TCB
,
card
->
tankmem
.
dma_handle
,
TCBS
,
size_reg
,
TAGLIST_END
);
sblive_writeptr_tag
(
card
,
0
,
TCB
,
(
u32
)
card
->
tankmem
.
dma_handle
,
TCBS
,
size_reg
,
TAGLIST_END
);
emu10k1_writefn0
(
card
,
HCFG_LOCKTANKCACHE
,
0
);
}
...
...
@@ -572,6 +578,8 @@ static int emu10k1_dsp_mixer(struct emu10k1_card *card, unsigned int oss_mixer,
int
val
;
int
scale
;
card
->
ac97
.
modcnt
++
;
if
(
get_user
(
val
,
(
int
*
)
arg
))
return
-
EFAULT
;
...
...
@@ -612,7 +620,7 @@ static int emu10k1_mixer_ioctl(struct inode *inode, struct file *file, unsigned
unsigned
int
oss_mixer
=
_IOC_NR
(
cmd
);
ret
=
-
EINVAL
;
if
(
!
card
->
isaps
)
{
if
(
!
card
->
is
_
aps
)
{
if
(
cmd
==
SOUND_MIXER_INFO
)
{
mixer_info
info
;
...
...
@@ -626,7 +634,7 @@ static int emu10k1_mixer_ioctl(struct inode *inode, struct file *file, unsigned
return
0
;
}
if
((
_
IOC_DIR
(
cmd
)
==
(
_IOC_WRITE
|
_
IOC_READ
))
&&
oss_mixer
<=
SOUND_MIXER_NRDEVICES
)
if
((
_
SIOC_DIR
(
cmd
)
==
(
_SIOC_WRITE
|
_S
IOC_READ
))
&&
oss_mixer
<=
SOUND_MIXER_NRDEVICES
)
ret
=
emu10k1_dsp_mixer
(
card
,
oss_mixer
,
arg
);
else
ret
=
card
->
ac97
.
mixer_ioctl
(
&
card
->
ac97
,
cmd
,
arg
);
...
...
sound/oss/emu10k1/passthrough.c
View file @
a9e4e4e0
...
...
@@ -29,7 +29,6 @@
**********************************************************************
*/
#define __NO_VERSION__
#include <linux/module.h>
#include <linux/poll.h>
#include <linux/slab.h>
...
...
@@ -165,15 +164,12 @@ ssize_t emu10k1_pt_write(struct file *file, const char *buffer, size_t count)
DPD
(
3
,
"prepend size %d, prepending %d bytes
\n
"
,
pt
->
prepend_size
,
needed
);
if
(
count
<
needed
)
{
if
(
copy_from_user
(
pt
->
buf
+
pt
->
prepend_size
,
buffer
,
count
))
return
-
EFAULT
;
copy_from_user
(
pt
->
buf
+
pt
->
prepend_size
,
buffer
,
count
);
pt
->
prepend_size
+=
count
;
DPD
(
3
,
"prepend size now %d
\n
"
,
pt
->
prepend_size
);
return
count
;
}
if
(
copy_from_user
(
pt
->
buf
+
pt
->
prepend_size
,
buffer
,
needed
))
return
-
EFAULT
;
copy_from_user
(
pt
->
buf
+
pt
->
prepend_size
,
buffer
,
needed
);
r
=
pt_putblock
(
wave_dev
,
(
u16
*
)
pt
->
buf
,
nonblock
);
if
(
r
)
return
r
;
...
...
@@ -184,8 +180,7 @@ ssize_t emu10k1_pt_write(struct file *file, const char *buffer, size_t count)
blocks_copied
=
0
;
while
(
blocks
>
0
)
{
u16
*
bufptr
=
(
u16
*
)
buffer
+
(
bytes_copied
/
2
);
if
(
copy_from_user
(
pt
->
buf
,
bufptr
,
PT_BLOCKSIZE
))
return
-
EFAULT
;
copy_from_user
(
pt
->
buf
,
bufptr
,
PT_BLOCKSIZE
);
bufptr
=
(
u16
*
)
pt
->
buf
;
r
=
pt_putblock
(
wave_dev
,
bufptr
,
nonblock
);
if
(
r
)
{
...
...
@@ -201,8 +196,7 @@ ssize_t emu10k1_pt_write(struct file *file, const char *buffer, size_t count)
i
=
count
-
bytes_copied
;
if
(
i
)
{
pt
->
prepend_size
=
i
;
if
(
copy_from_user
(
pt
->
buf
,
buffer
+
bytes_copied
,
i
))
return
-
EFAULT
;
copy_from_user
(
pt
->
buf
,
buffer
+
bytes_copied
,
i
);
bytes_copied
+=
i
;
DPD
(
3
,
"filling prepend buffer with %d bytes"
,
i
);
}
...
...
sound/oss/emu10k1/recmgr.c
View file @
a9e4e4e0
...
...
@@ -29,19 +29,28 @@
**********************************************************************
*/
#include <asm/delay.h>
#include "8010.h"
#include "recmgr.h"
void
emu10k1_reset_record
(
struct
emu10k1_card
*
card
,
struct
wavein_buffer
*
buffer
)
{
DPF
(
2
,
"emu10k1_reset_record()
\n
"
);
sblive_writeptr
(
card
,
buffer
->
sizereg
,
0
,
ADCBS_BUFSIZE_NONE
);
sblive_writeptr
(
card
,
buffer
->
sizereg
,
0
,
buffer
->
sizeregval
);
while
(
sblive_readptr
(
card
,
buffer
->
idxreg
,
0
))
udelay
(
5
);
}
void
emu10k1_start_record
(
struct
emu10k1_card
*
card
,
struct
wavein_buffer
*
buffer
)
{
DPF
(
2
,
"emu10k1_start_record()
\n
"
);
sblive_writeptr
(
card
,
buffer
->
sizereg
,
0
,
buffer
->
sizeregval
);
if
(
buffer
->
adcctl
)
sblive_writeptr
(
card
,
ADCCR
,
0
,
buffer
->
adcctl
);
return
;
}
void
emu10k1_stop_record
(
struct
emu10k1_card
*
card
,
struct
wavein_buffer
*
buffer
)
...
...
@@ -51,10 +60,6 @@ void emu10k1_stop_record(struct emu10k1_card *card, struct wavein_buffer *buffer
/* Disable record transfer */
if
(
buffer
->
adcctl
)
sblive_writeptr
(
card
,
ADCCR
,
0
,
0
);
sblive_writeptr
(
card
,
buffer
->
sizereg
,
0
,
ADCBS_BUFSIZE_NONE
);
return
;
}
void
emu10k1_set_record_src
(
struct
emu10k1_card
*
card
,
struct
wiinst
*
wiinst
)
...
...
@@ -130,9 +135,7 @@ void emu10k1_set_record_src(struct emu10k1_card *card, struct wiinst *wiinst)
break
;
}
DPD
(
2
,
"bus addx: %#x
\n
"
,
buffer
->
dma_handle
);
sblive_writeptr
(
card
,
buffer
->
addrreg
,
0
,
buffer
->
dma_handle
);
DPD
(
2
,
"bus addx: %#lx
\n
"
,
(
unsigned
long
)
buffer
->
dma_handle
);
return
;
sblive_writeptr
(
card
,
buffer
->
addrreg
,
0
,
(
u32
)
buffer
->
dma_handle
)
;
}
sound/oss/emu10k1/recmgr.h
View file @
a9e4e4e0
...
...
@@ -40,9 +40,9 @@
#define WAVERECORD_MIC 0x02
#define WAVERECORD_FX 0x03
void
emu10k1_reset_record
(
struct
emu10k1_card
*
card
,
struct
wavein_buffer
*
buffer
);
void
emu10k1_start_record
(
struct
emu10k1_card
*
,
struct
wavein_buffer
*
);
void
emu10k1_stop_record
(
struct
emu10k1_card
*
,
struct
wavein_buffer
*
);
void
emu10k1_set_record_src
(
struct
emu10k1_card
*
,
struct
wiinst
*
wiinst
);
#endif
/* _RECORDMGR_H */
sound/oss/emu10k1/timer.c
View file @
a9e4e4e0
...
...
@@ -59,7 +59,7 @@ void emu10k1_timer_irqhandler(struct emu10k1_card *card)
return
;
}
void
emu10k1_timer_install
(
struct
emu10k1_card
*
card
,
struct
emu_timer
*
timer
,
u
32
delay
)
void
emu10k1_timer_install
(
struct
emu10k1_card
*
card
,
struct
emu_timer
*
timer
,
u
16
delay
)
{
struct
emu_timer
*
t
;
struct
list_head
*
entry
;
...
...
@@ -85,7 +85,7 @@ void emu10k1_timer_install(struct emu10k1_card *card, struct emu_timer *timer, u
card
->
timer_delay
=
delay
;
delay
=
(
delay
<
1024
?
delay
:
1024
);
emu10k1_
writefn0
(
card
,
TIMER_RATE
,
delay
);
emu10k1_
timer_set
(
card
,
delay
);
list_for_each
(
entry
,
&
card
->
timers
)
{
t
=
list_entry
(
entry
,
struct
emu_timer
,
list
);
...
...
@@ -108,7 +108,7 @@ void emu10k1_timer_uninstall(struct emu10k1_card *card, struct emu_timer *timer)
{
struct
emu_timer
*
t
;
struct
list_head
*
entry
;
u
32
delay
=
TIMER_STOPPED
;
u
16
delay
=
TIMER_STOPPED
;
unsigned
long
flags
;
if
(
timer
->
state
==
TIMER_STATE_UNINSTALLED
)
...
...
@@ -133,7 +133,7 @@ void emu10k1_timer_uninstall(struct emu10k1_card *card, struct emu_timer *timer)
else
{
delay
=
(
delay
<
1024
?
delay
:
1024
);
emu10k1_
writefn0
(
card
,
TIMER_RATE
,
delay
);
emu10k1_
timer_set
(
card
,
delay
);
list_for_each
(
entry
,
&
card
->
timers
)
{
t
=
list_entry
(
entry
,
struct
emu_timer
,
list
);
...
...
sound/oss/emu10k1/timer.h
View file @
a9e4e4e0
...
...
@@ -36,17 +36,17 @@ struct emu_timer
struct
list_head
list
;
struct
tasklet_struct
tasklet
;
u8
state
;
u
32
count
;
/* current number of interrupts */
u
32
count_max
;
/* number of interrupts needed to schedule the bh */
u
32
delay
;
/* timer delay */
u
16
count
;
/* current number of interrupts */
u
16
count_max
;
/* number of interrupts needed to schedule the bh */
u
16
delay
;
/* timer delay */
};
void
emu10k1_timer_install
(
struct
emu10k1_card
*
,
struct
emu_timer
*
,
u
32
);
void
emu10k1_timer_install
(
struct
emu10k1_card
*
,
struct
emu_timer
*
,
u
16
);
void
emu10k1_timer_uninstall
(
struct
emu10k1_card
*
,
struct
emu_timer
*
);
void
emu10k1_timer_enable
(
struct
emu10k1_card
*
,
struct
emu_timer
*
);
void
emu10k1_timer_disable
(
struct
emu10k1_card
*
,
struct
emu_timer
*
);
#define TIMER_STOPPED 0xffff
ffff
#define TIMER_STOPPED 0xffff
#define TIMER_STATE_INSTALLED 0x01
#define TIMER_STATE_ACTIVE 0x02
#define TIMER_STATE_UNINSTALLED 0x04
...
...
sound/oss/emu10k1/voicemgr.c
View file @
a9e4e4e0
...
...
@@ -32,6 +32,84 @@
#include "voicemgr.h"
#include "8010.h"
/**
* emu10k1_voice_alloc_buffer -
*
* allocates the memory buffer for a voice. Two page tables are kept for each buffer.
* One (dma_handle) keeps track of the host memory pages used and the other (virtualpagetable)
* is passed to the device so that it can do DMA to host memory.
*
*/
int
emu10k1_voice_alloc_buffer
(
struct
emu10k1_card
*
card
,
struct
voice_mem
*
mem
,
u32
pages
)
{
u32
pageindex
,
pagecount
;
u32
busaddx
;
int
i
;
DPD
(
2
,
"requested pages is: %d
\n
"
,
pages
);
if
((
mem
->
emupageindex
=
emu10k1_addxmgr_alloc
(
pages
*
PAGE_SIZE
,
card
))
<
0
)
{
DPF
(
1
,
"couldn't allocate emu10k1 address space
\n
"
);
return
-
1
;
}
/* Fill in virtual memory table */
for
(
pagecount
=
0
;
pagecount
<
pages
;
pagecount
++
)
{
if
((
mem
->
addr
[
pagecount
]
=
pci_alloc_consistent
(
card
->
pci_dev
,
PAGE_SIZE
,
&
mem
->
dma_handle
[
pagecount
]))
==
NULL
)
{
mem
->
pages
=
pagecount
;
DPF
(
1
,
"couldn't allocate dma memory
\n
"
);
return
-
1
;
}
DPD
(
2
,
"Virtual Addx: %p
\n
"
,
mem
->
addr
[
pagecount
]);
for
(
i
=
0
;
i
<
PAGE_SIZE
/
EMUPAGESIZE
;
i
++
)
{
busaddx
=
(
u32
)
mem
->
dma_handle
[
pagecount
]
+
i
*
EMUPAGESIZE
;
DPD
(
3
,
"Bus Addx: %#x
\n
"
,
busaddx
);
pageindex
=
mem
->
emupageindex
+
pagecount
*
PAGE_SIZE
/
EMUPAGESIZE
+
i
;
((
u32
*
)
card
->
virtualpagetable
.
addr
)[
pageindex
]
=
cpu_to_le32
((
busaddx
*
2
)
|
pageindex
);
}
}
mem
->
pages
=
pagecount
;
return
0
;
}
/**
* emu10k1_voice_free_buffer -
*
* frees the memory buffer for a voice.
*/
void
emu10k1_voice_free_buffer
(
struct
emu10k1_card
*
card
,
struct
voice_mem
*
mem
)
{
u32
pagecount
,
pageindex
;
int
i
;
if
(
mem
->
emupageindex
<
0
)
return
;
for
(
pagecount
=
0
;
pagecount
<
mem
->
pages
;
pagecount
++
)
{
pci_free_consistent
(
card
->
pci_dev
,
PAGE_SIZE
,
mem
->
addr
[
pagecount
],
mem
->
dma_handle
[
pagecount
]);
for
(
i
=
0
;
i
<
PAGE_SIZE
/
EMUPAGESIZE
;
i
++
)
{
pageindex
=
mem
->
emupageindex
+
pagecount
*
PAGE_SIZE
/
EMUPAGESIZE
+
i
;
((
u32
*
)
card
->
virtualpagetable
.
addr
)[
pageindex
]
=
cpu_to_le32
(((
u32
)
card
->
silentpage
.
dma_handle
*
2
)
|
pageindex
);
}
}
emu10k1_addxmgr_free
(
card
,
mem
->
emupageindex
);
mem
->
emupageindex
=
-
1
;
}
int
emu10k1_voice_alloc
(
struct
emu10k1_card
*
card
,
struct
emu_voice
*
voice
)
{
u8
*
voicetable
=
card
->
voicetable
;
...
...
@@ -96,8 +174,10 @@ void emu10k1_voice_free(struct emu_voice *voice)
VTFT
,
0x0000ffff
,
PTRX_PITCHTARGET
,
0
,
CVCF
,
0x0000ffff
,
CPF
,
0
,
//
CPF, 0,
TAGLIST_END
);
sblive_writeptr
(
card
,
CPF
,
voice
->
num
+
i
,
0
);
}
voice
->
usage
=
VOICE_USAGE_FREE
;
...
...
@@ -151,8 +231,8 @@ void emu10k1_voice_playback_setup(struct emu_voice *voice)
Z1
,
0
,
Z2
,
0
,
/* Invalidate maps */
MAPA
,
MAP_PTI_MASK
|
(
card
->
silentpage
.
dma_handle
*
2
),
MAPB
,
MAP_PTI_MASK
|
(
card
->
silentpage
.
dma_handle
*
2
),
MAPA
,
MAP_PTI_MASK
|
(
(
u32
)
card
->
silentpage
.
dma_handle
*
2
),
MAPB
,
MAP_PTI_MASK
|
(
(
u32
)
card
->
silentpage
.
dma_handle
*
2
),
/* modulation envelope */
CVCF
,
0x0000ffff
,
VTFT
,
0x0000ffff
,
...
...
sound/oss/emu10k1/voicemgr.h
View file @
a9e4e4e0
...
...
@@ -64,6 +64,12 @@ struct voice_param
u32
byampl_env_decay
;
};
struct
voice_mem
{
int
emupageindex
;
void
*
addr
[
BUFMAXPAGES
];
dma_addr_t
dma_handle
[
BUFMAXPAGES
];
u32
pages
;
};
struct
emu_voice
{
...
...
@@ -72,16 +78,20 @@ struct emu_voice
u8
num
;
/* Voice ID */
u8
flags
;
/* Stereo/mono, 8/16 bit */
u32
startloop
;
u32
endloop
;
u32
startloop
;
u32
endloop
;
u32
start
;
u32
initial_pitch
;
u32
pitch_target
;
struct
voice_param
params
[
2
];
struct
voice_mem
mem
;
};
int
emu10k1_voice_alloc_buffer
(
struct
emu10k1_card
*
,
struct
voice_mem
*
,
u32
);
void
emu10k1_voice_free_buffer
(
struct
emu10k1_card
*
,
struct
voice_mem
*
);
int
emu10k1_voice_alloc
(
struct
emu10k1_card
*
,
struct
emu_voice
*
);
void
emu10k1_voice_free
(
struct
emu_voice
*
);
void
emu10k1_voice_playback_setup
(
struct
emu_voice
*
);
...
...
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