Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
linux-davinci
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
linux
linux-davinci
Commits
bd05dbd3
Commit
bd05dbd3
authored
Jun 02, 2009
by
Takashi Iwai
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'topic/ctxfi-fix' into topic/ctxfi
parents
67fbf880
c76157d9
Changes
9
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
92 additions
and
108 deletions
+92
-108
sound/pci/Kconfig
sound/pci/Kconfig
+0
-1
sound/pci/ctxfi/ctatc.c
sound/pci/ctxfi/ctatc.c
+16
-19
sound/pci/ctxfi/ctatc.h
sound/pci/ctxfi/ctatc.h
+2
-3
sound/pci/ctxfi/cthw20k1.c
sound/pci/ctxfi/cthw20k1.c
+6
-10
sound/pci/ctxfi/cthw20k2.c
sound/pci/ctxfi/cthw20k2.c
+4
-13
sound/pci/ctxfi/ctmixer.c
sound/pci/ctxfi/ctmixer.c
+4
-4
sound/pci/ctxfi/ctpcm.c
sound/pci/ctxfi/ctpcm.c
+10
-15
sound/pci/ctxfi/ctvmem.c
sound/pci/ctxfi/ctvmem.c
+36
-41
sound/pci/ctxfi/ctvmem.h
sound/pci/ctxfi/ctvmem.h
+14
-2
No files found.
sound/pci/Kconfig
View file @
bd05dbd3
...
...
@@ -277,7 +277,6 @@ config SND_CS5535AUDIO
config SND_CTXFI
tristate "Creative Sound Blaster X-Fi"
depends on X86
select SND_PCM
help
If you want to use soundcards based on Creative Sound Blastr X-Fi
...
...
sound/pci/ctxfi/ctatc.c
View file @
bd05dbd3
...
...
@@ -72,15 +72,15 @@ static struct {
[
FRONT
]
=
{
.
create
=
ct_alsa_pcm_create
,
.
destroy
=
NULL
,
.
public_name
=
"Front/WaveIn"
},
[
REAR
]
=
{
.
create
=
ct_alsa_pcm_create
,
[
SURROUND
]
=
{
.
create
=
ct_alsa_pcm_create
,
.
destroy
=
NULL
,
.
public_name
=
"
Rear
"
},
.
public_name
=
"
Surround
"
},
[
CLFE
]
=
{
.
create
=
ct_alsa_pcm_create
,
.
destroy
=
NULL
,
.
public_name
=
"Center/LFE"
},
[
S
URROUND
]
=
{
.
create
=
ct_alsa_pcm_create
,
[
S
IDE
]
=
{
.
create
=
ct_alsa_pcm_create
,
.
destroy
=
NULL
,
.
public_name
=
"S
urround
"
},
.
public_name
=
"S
ide
"
},
[
IEC958
]
=
{
.
create
=
ct_alsa_pcm_create
,
.
destroy
=
NULL
,
.
public_name
=
"IEC958 Non-audio"
},
...
...
@@ -119,7 +119,6 @@ atc_pcm_release_resources(struct ct_atc *atc, struct ct_atc_pcm *apcm);
static
int
ct_map_audio_buffer
(
struct
ct_atc
*
atc
,
struct
ct_atc_pcm
*
apcm
)
{
unsigned
long
flags
;
struct
snd_pcm_runtime
*
runtime
;
struct
ct_vm
*
vm
;
...
...
@@ -129,9 +128,7 @@ static int ct_map_audio_buffer(struct ct_atc *atc, struct ct_atc_pcm *apcm)
runtime
=
apcm
->
substream
->
runtime
;
vm
=
atc
->
vm
;
spin_lock_irqsave
(
&
atc
->
vm_lock
,
flags
);
apcm
->
vm_block
=
vm
->
map
(
vm
,
runtime
->
dma_area
,
runtime
->
dma_bytes
);
spin_unlock_irqrestore
(
&
atc
->
vm_lock
,
flags
);
apcm
->
vm_block
=
vm
->
map
(
vm
,
apcm
->
substream
,
runtime
->
dma_bytes
);
if
(
NULL
==
apcm
->
vm_block
)
return
-
ENOENT
;
...
...
@@ -141,7 +138,6 @@ static int ct_map_audio_buffer(struct ct_atc *atc, struct ct_atc_pcm *apcm)
static
void
ct_unmap_audio_buffer
(
struct
ct_atc
*
atc
,
struct
ct_atc_pcm
*
apcm
)
{
unsigned
long
flags
;
struct
ct_vm
*
vm
;
if
(
NULL
==
apcm
->
vm_block
)
...
...
@@ -149,9 +145,7 @@ static void ct_unmap_audio_buffer(struct ct_atc *atc, struct ct_atc_pcm *apcm)
vm
=
atc
->
vm
;
spin_lock_irqsave
(
&
atc
->
vm_lock
,
flags
);
vm
->
unmap
(
vm
,
apcm
->
vm_block
);
spin_unlock_irqrestore
(
&
atc
->
vm_lock
,
flags
);
apcm
->
vm_block
=
NULL
;
}
...
...
@@ -161,9 +155,7 @@ static unsigned long atc_get_ptp_phys(struct ct_atc *atc, int index)
struct
ct_vm
*
vm
;
void
*
kvirt_addr
;
unsigned
long
phys_addr
;
unsigned
long
flags
;
spin_lock_irqsave
(
&
atc
->
vm_lock
,
flags
);
vm
=
atc
->
vm
;
kvirt_addr
=
vm
->
get_ptp_virt
(
vm
,
index
);
if
(
kvirt_addr
==
NULL
)
...
...
@@ -171,8 +163,6 @@ static unsigned long atc_get_ptp_phys(struct ct_atc *atc, int index)
else
phys_addr
=
virt_to_phys
(
kvirt_addr
);
spin_unlock_irqrestore
(
&
atc
->
vm_lock
,
flags
);
return
phys_addr
;
}
...
...
@@ -180,16 +170,15 @@ static unsigned int convert_format(snd_pcm_format_t snd_format)
{
switch
(
snd_format
)
{
case
SNDRV_PCM_FORMAT_U8
:
case
SNDRV_PCM_FORMAT_S8
:
return
SRC_SF_U8
;
case
SNDRV_PCM_FORMAT_S16_LE
:
case
SNDRV_PCM_FORMAT_U16_LE
:
return
SRC_SF_S16
;
case
SNDRV_PCM_FORMAT_S24_3LE
:
return
SRC_SF_S24
;
case
SNDRV_PCM_FORMAT_S24_LE
:
case
SNDRV_PCM_FORMAT_S32_LE
:
return
SRC_SF_S32
;
case
SNDRV_PCM_FORMAT_FLOAT_LE
:
return
SRC_SF_F32
;
default:
printk
(
KERN_ERR
"ctxfi: not recognized snd format is %d
\n
"
,
snd_format
);
...
...
@@ -264,6 +253,9 @@ static int atc_pcm_playback_prepare(struct ct_atc *atc, struct ct_atc_pcm *apcm)
return
0
;
}
/* first release old resources */
atc
->
pcm_release_resources
(
atc
,
apcm
);
/* Get SRC resource */
desc
.
multi
=
apcm
->
substream
->
runtime
->
channels
;
desc
.
msr
=
atc
->
msr
;
...
...
@@ -506,6 +498,9 @@ atc_pcm_capture_get_resources(struct ct_atc *atc, struct ct_atc_pcm *apcm)
int
n_srcimp
=
0
,
n_amixer
=
0
,
n_srcc
=
0
,
n_sum
=
0
;
struct
src_node_conf_t
src_node_conf
[
2
]
=
{{
0
}
};
/* first release old resources */
atc
->
pcm_release_resources
(
atc
,
apcm
);
/* The numbers of converting SRCs and SRCIMPs should be determined
* by pitch value. */
...
...
@@ -777,6 +772,9 @@ static int spdif_passthru_playback_get_resources(struct ct_atc *atc,
int
n_amixer
=
apcm
->
substream
->
runtime
->
channels
,
i
=
0
;
unsigned
int
pitch
=
0
,
rsr
=
atc
->
pll_rate
;
/* first release old resources */
atc
->
pcm_release_resources
(
atc
,
apcm
);
/* Get SRC resource */
desc
.
multi
=
apcm
->
substream
->
runtime
->
channels
;
desc
.
msr
=
1
;
...
...
@@ -1562,7 +1560,6 @@ int ct_atc_create(struct snd_card *card, struct pci_dev *pci,
atc_set_ops
(
atc
);
spin_lock_init
(
&
atc
->
atc_lock
);
spin_lock_init
(
&
atc
->
vm_lock
);
/* Find card model */
err
=
atc_identify_card
(
atc
);
...
...
sound/pci/ctxfi/ctatc.h
View file @
bd05dbd3
...
...
@@ -29,9 +29,9 @@
enum
CTALSADEVS
{
/* Types of alsa devices */
FRONT
,
REAR
,
CLFE
,
SURROUND
,
CLFE
,
SIDE
,
IEC958
,
MIXER
,
NUM_CTALSADEVS
/* This should always be the last */
...
...
@@ -101,7 +101,6 @@ struct ct_atc {
unsigned
long
(
*
get_ptp_phys
)(
struct
ct_atc
*
atc
,
int
index
);
spinlock_t
atc_lock
;
spinlock_t
vm_lock
;
int
(
*
pcm_playback_prepare
)(
struct
ct_atc
*
atc
,
struct
ct_atc_pcm
*
apcm
);
...
...
sound/pci/ctxfi/cthw20k1.c
View file @
bd05dbd3
...
...
@@ -1249,18 +1249,14 @@ static int hw_trn_init(struct hw *hw, const struct trn_conf *info)
}
trnctl
=
0x13
;
/* 32-bit, 4k-size page */
#if BITS_PER_LONG == 64
ptp_phys_low
=
info
->
vm_pgt_phys
&
((
1UL
<<
32
)
-
1
);
ptp_phys_high
=
(
info
->
vm_pgt_phys
>>
32
)
&
((
1UL
<<
32
)
-
1
);
trnctl
|=
(
1
<<
2
);
#elif BITS_PER_LONG == 32
ptp_phys_low
=
info
->
vm_pgt_phys
&
(
~
0UL
);
ptp_phys_high
=
0
;
#else
# error "Unknown BITS_PER_LONG!"
#endif
ptp_phys_low
=
(
u32
)
info
->
vm_pgt_phys
;
ptp_phys_high
=
upper_32_bits
(
info
->
vm_pgt_phys
);
if
(
sizeof
(
void
*
)
==
8
)
/* 64bit address */
trnctl
|=
(
1
<<
2
);
#if 0 /* Only 4k h/w pages for simplicitiy */
#if PAGE_SIZE == 8192
trnctl |= (1<<5);
#endif
#endif
hw_write_20kx
(
hw
,
PTPALX
,
ptp_phys_low
);
hw_write_20kx
(
hw
,
PTPAHX
,
ptp_phys_high
);
...
...
sound/pci/ctxfi/cthw20k2.c
View file @
bd05dbd3
...
...
@@ -1203,19 +1203,10 @@ static int hw_trn_init(struct hw *hw, const struct trn_conf *info)
}
vmctl
=
0x80000C0F
;
/* 32-bit, 4k-size page */
#if BITS_PER_LONG == 64
ptp_phys_low
=
info
->
vm_pgt_phys
&
((
1UL
<<
32
)
-
1
);
ptp_phys_high
=
(
info
->
vm_pgt_phys
>>
32
)
&
((
1UL
<<
32
)
-
1
);
vmctl
|=
(
3
<<
8
);
#elif BITS_PER_LONG == 32
ptp_phys_low
=
info
->
vm_pgt_phys
&
(
~
0UL
);
ptp_phys_high
=
0
;
#else
# error "Unknown BITS_PER_LONG!"
#endif
#if PAGE_SIZE == 8192
# error "Don't support 8k-page!"
#endif
ptp_phys_low
=
(
u32
)
info
->
vm_pgt_phys
;
ptp_phys_high
=
upper_32_bits
(
info
->
vm_pgt_phys
);
if
(
sizeof
(
void
*
)
==
8
)
/* 64bit address */
vmctl
|=
(
3
<<
8
);
/* Write page table physical address to all PTPAL registers */
for
(
i
=
0
;
i
<
64
;
i
++
)
{
hw_write_20kx
(
hw
,
VMEM_PTPAL
+
(
16
*
i
),
ptp_phys_low
);
...
...
sound/pci/ctxfi/ctmixer.c
View file @
bd05dbd3
...
...
@@ -168,7 +168,7 @@ ct_kcontrol_init_table[NUM_CTALSA_MIXERS] = {
},
[
MIXER_WAVES_P
]
=
{
.
ctl
=
1
,
.
name
=
"S
urround
Playback Volume"
,
.
name
=
"S
ide
Playback Volume"
,
},
[
MIXER_WAVEC_P
]
=
{
.
ctl
=
1
,
...
...
@@ -176,7 +176,7 @@ ct_kcontrol_init_table[NUM_CTALSA_MIXERS] = {
},
[
MIXER_WAVER_P
]
=
{
.
ctl
=
1
,
.
name
=
"
Rear
Playback Volume"
,
.
name
=
"
Surround
Playback Volume"
,
},
[
MIXER_PCM_C_S
]
=
{
...
...
@@ -213,7 +213,7 @@ ct_kcontrol_init_table[NUM_CTALSA_MIXERS] = {
},
[
MIXER_WAVES_P_S
]
=
{
.
ctl
=
1
,
.
name
=
"S
urround
Playback Switch"
,
.
name
=
"S
ide
Playback Switch"
,
},
[
MIXER_WAVEC_P_S
]
=
{
.
ctl
=
1
,
...
...
@@ -221,7 +221,7 @@ ct_kcontrol_init_table[NUM_CTALSA_MIXERS] = {
},
[
MIXER_WAVER_P_S
]
=
{
.
ctl
=
1
,
.
name
=
"
Rear
Playback Switch"
,
.
name
=
"
Surround
Playback Switch"
,
},
[
MIXER_DIGITAL_IO_S
]
=
{
.
ctl
=
0
,
...
...
sound/pci/ctxfi/ctpcm.c
View file @
bd05dbd3
...
...
@@ -26,12 +26,10 @@ static struct snd_pcm_hardware ct_pcm_playback_hw = {
SNDRV_PCM_INFO_MMAP_VALID
|
SNDRV_PCM_INFO_PAUSE
),
.
formats
=
(
SNDRV_PCM_FMTBIT_U8
|
SNDRV_PCM_FMTBIT_S8
|
SNDRV_PCM_FMTBIT_S16_LE
|
SNDRV_PCM_FMTBIT_U16_LE
|
SNDRV_PCM_FMTBIT_S24_3LE
|
SNDRV_PCM_FMTBIT_S
24
_LE
|
SNDRV_PCM_FMTBIT_
S32
_LE
),
SNDRV_PCM_FMTBIT_S
32
_LE
|
SNDRV_PCM_FMTBIT_
FLOAT
_LE
),
.
rates
=
(
SNDRV_PCM_RATE_CONTINUOUS
|
SNDRV_PCM_RATE_8000_192000
),
.
rate_min
=
8000
,
...
...
@@ -52,8 +50,7 @@ static struct snd_pcm_hardware ct_spdif_passthru_playback_hw = {
SNDRV_PCM_INFO_BLOCK_TRANSFER
|
SNDRV_PCM_INFO_MMAP_VALID
|
SNDRV_PCM_INFO_PAUSE
),
.
formats
=
(
SNDRV_PCM_FMTBIT_S16_LE
|
SNDRV_PCM_FMTBIT_U16_LE
),
.
formats
=
SNDRV_PCM_FMTBIT_S16_LE
,
.
rates
=
(
SNDRV_PCM_RATE_48000
|
SNDRV_PCM_RATE_44100
|
SNDRV_PCM_RATE_32000
),
...
...
@@ -77,12 +74,10 @@ static struct snd_pcm_hardware ct_pcm_capture_hw = {
SNDRV_PCM_INFO_PAUSE
|
SNDRV_PCM_INFO_MMAP_VALID
),
.
formats
=
(
SNDRV_PCM_FMTBIT_U8
|
SNDRV_PCM_FMTBIT_S8
|
SNDRV_PCM_FMTBIT_S16_LE
|
SNDRV_PCM_FMTBIT_U16_LE
|
SNDRV_PCM_FMTBIT_S24_3LE
|
SNDRV_PCM_FMTBIT_S
24
_LE
|
SNDRV_PCM_FMTBIT_
S32
_LE
),
SNDRV_PCM_FMTBIT_S
32
_LE
|
SNDRV_PCM_FMTBIT_
FLOAT
_LE
),
.
rates
=
(
SNDRV_PCM_RATE_CONTINUOUS
|
SNDRV_PCM_RATE_8000_96000
),
.
rate_min
=
8000
,
...
...
@@ -447,6 +442,7 @@ static struct snd_pcm_ops ct_pcm_playback_ops = {
.
prepare
=
ct_pcm_playback_prepare
,
.
trigger
=
ct_pcm_playback_trigger
,
.
pointer
=
ct_pcm_playback_pointer
,
.
page
=
snd_pcm_sgbuf_ops_page
,
};
/* PCM operators for capture */
...
...
@@ -459,6 +455,7 @@ static struct snd_pcm_ops ct_pcm_capture_ops = {
.
prepare
=
ct_pcm_capture_prepare
,
.
trigger
=
ct_pcm_capture_trigger
,
.
pointer
=
ct_pcm_capture_pointer
,
.
page
=
snd_pcm_sgbuf_ops_page
,
};
/* Create ALSA pcm device */
...
...
@@ -469,12 +466,10 @@ int ct_alsa_pcm_create(struct ct_atc *atc,
struct
snd_pcm
*
pcm
;
int
err
;
int
playback_count
,
capture_count
;
char
name
[
128
];
strncpy
(
name
,
device_name
,
sizeof
(
name
));
playback_count
=
(
IEC958
==
device
)
?
1
:
8
;
capture_count
=
(
FRONT
==
device
)
?
1
:
0
;
err
=
snd_pcm_new
(
atc
->
card
,
name
,
device
,
err
=
snd_pcm_new
(
atc
->
card
,
"ctxfi"
,
device
,
playback_count
,
capture_count
,
&
pcm
);
if
(
err
<
0
)
{
printk
(
KERN_ERR
"ctxfi: snd_pcm_new failed!! Err=%d
\n
"
,
err
);
...
...
@@ -484,7 +479,7 @@ int ct_alsa_pcm_create(struct ct_atc *atc,
pcm
->
private_data
=
atc
;
pcm
->
info_flags
=
0
;
pcm
->
dev_subclass
=
SNDRV_PCM_SUBCLASS_GENERIC_MIX
;
str
cpy
(
pcm
->
name
,
device_name
);
str
lcpy
(
pcm
->
name
,
device_name
,
sizeof
(
pcm
->
name
)
);
snd_pcm_set_ops
(
pcm
,
SNDRV_PCM_STREAM_PLAYBACK
,
&
ct_pcm_playback_ops
);
...
...
@@ -492,7 +487,7 @@ int ct_alsa_pcm_create(struct ct_atc *atc,
snd_pcm_set_ops
(
pcm
,
SNDRV_PCM_STREAM_CAPTURE
,
&
ct_pcm_capture_ops
);
snd_pcm_lib_preallocate_pages_for_all
(
pcm
,
SNDRV_DMA_TYPE_DEV
,
snd_pcm_lib_preallocate_pages_for_all
(
pcm
,
SNDRV_DMA_TYPE_DEV
_SG
,
snd_dma_pci_data
(
atc
->
pci
),
128
*
1024
,
128
*
1024
);
return
0
;
...
...
sound/pci/ctxfi/ctvmem.c
View file @
bd05dbd3
...
...
@@ -18,12 +18,11 @@
#include "ctvmem.h"
#include <linux/slab.h>
#include <linux/mm.h>
#include <asm/page.h>
/* for PAGE_SIZE macro definition */
#include <linux/io.h>
#include <
asm/pgtable
.h>
#include <
sound/pcm
.h>
#define CT_PTES_PER_PAGE (PAGE_SIZE / sizeof(void *))
#define CT_ADDRS_PER_PAGE (CT_PTES_PER_PAGE * PAGE_SIZE)
#define CT_PTES_PER_PAGE (
CT_
PAGE_SIZE / sizeof(void *))
#define CT_ADDRS_PER_PAGE (CT_PTES_PER_PAGE *
CT_
PAGE_SIZE)
/* *
* Find or create vm block based on requested @size.
...
...
@@ -35,25 +34,34 @@ get_vm_block(struct ct_vm *vm, unsigned int size)
struct
ct_vm_block
*
block
=
NULL
,
*
entry
=
NULL
;
struct
list_head
*
pos
=
NULL
;
size
=
CT_PAGE_ALIGN
(
size
);
if
(
size
>
vm
->
size
)
{
printk
(
KERN_ERR
"ctxfi: Fail! No sufficient device virtural "
"memory space available!
\n
"
);
return
NULL
;
}
mutex_lock
(
&
vm
->
lock
);
list_for_each
(
pos
,
&
vm
->
unused
)
{
entry
=
list_entry
(
pos
,
struct
ct_vm_block
,
list
);
if
(
entry
->
size
>=
size
)
break
;
/* found a block that is big enough */
}
if
(
pos
==
&
vm
->
unused
)
return
NULL
;
goto
out
;
if
(
entry
->
size
==
size
)
{
/* Move the vm node from unused list to used list directly */
list_del
(
&
entry
->
list
);
list_add
(
&
entry
->
list
,
&
vm
->
used
);
vm
->
size
-=
size
;
return
entry
;
block
=
entry
;
goto
out
;
}
block
=
kzalloc
(
sizeof
(
*
block
),
GFP_KERNEL
);
if
(
NULL
==
block
)
return
NULL
;
goto
out
;
block
->
addr
=
entry
->
addr
;
block
->
size
=
size
;
...
...
@@ -62,6 +70,8 @@ get_vm_block(struct ct_vm *vm, unsigned int size)
entry
->
size
-=
size
;
vm
->
size
-=
size
;
out:
mutex_unlock
(
&
vm
->
lock
);
return
block
;
}
...
...
@@ -70,6 +80,9 @@ static void put_vm_block(struct ct_vm *vm, struct ct_vm_block *block)
struct
ct_vm_block
*
entry
=
NULL
,
*
pre_ent
=
NULL
;
struct
list_head
*
pos
=
NULL
,
*
pre
=
NULL
;
block
->
size
=
CT_PAGE_ALIGN
(
block
->
size
);
mutex_lock
(
&
vm
->
lock
);
list_del
(
&
block
->
list
);
vm
->
size
+=
block
->
size
;
...
...
@@ -106,61 +119,41 @@ static void put_vm_block(struct ct_vm *vm, struct ct_vm_block *block)
pos
=
pre
;
pre
=
pos
->
prev
;
}
mutex_unlock
(
&
vm
->
lock
);
}
/* Map host addr (kmalloced/vmalloced) to device logical addr. */
static
struct
ct_vm_block
*
ct_vm_map
(
struct
ct_vm
*
vm
,
void
*
host_addr
,
int
size
)
ct_vm_map
(
struct
ct_vm
*
vm
,
struct
snd_pcm_substream
*
substream
,
int
size
)
{
struct
ct_vm_block
*
block
=
NULL
;
unsigned
long
pte_start
;
unsigned
long
i
;
unsigned
long
pages
;
unsigned
long
start_phys
;
struct
ct_vm_block
*
block
;
unsigned
int
pte_start
;
unsigned
i
,
pages
;
unsigned
long
*
ptp
;
/* do mapping */
if
((
unsigned
long
)
host_addr
>=
VMALLOC_START
)
{
printk
(
KERN_ERR
"ctxfi: "
"Fail! Not support vmalloced addr now!
\n
"
);
return
NULL
;
}
if
(
size
>
vm
->
size
)
{
printk
(
KERN_ERR
"ctxfi: Fail! No sufficient device virtural "
"memory space available!
\n
"
);
return
NULL
;
}
start_phys
=
(
virt_to_phys
(
host_addr
)
&
PAGE_MASK
);
pages
=
(
PAGE_ALIGN
(
virt_to_phys
(
host_addr
)
+
size
)
-
start_phys
)
>>
PAGE_SHIFT
;
ptp
=
vm
->
ptp
[
0
];
block
=
get_vm_block
(
vm
,
(
pages
<<
PAGE_SHIFT
));
block
=
get_vm_block
(
vm
,
size
);
if
(
block
==
NULL
)
{
printk
(
KERN_ERR
"ctxfi: No virtual memory block that is big "
"enough to allocate!
\n
"
);
return
NULL
;
}
pte_start
=
(
block
->
addr
>>
PAGE_SHIFT
);
for
(
i
=
0
;
i
<
pages
;
i
++
)
ptp
[
pte_start
+
i
]
=
start_phys
+
(
i
<<
PAGE_SHIFT
);
ptp
=
vm
->
ptp
[
0
];
pte_start
=
(
block
->
addr
>>
CT_PAGE_SHIFT
);
pages
=
block
->
size
>>
CT_PAGE_SHIFT
;
for
(
i
=
0
;
i
<
pages
;
i
++
)
{
unsigned
long
addr
;
addr
=
snd_pcm_sgbuf_get_addr
(
substream
,
i
<<
CT_PAGE_SHIFT
);
ptp
[
pte_start
+
i
]
=
addr
;
}
block
->
addr
+=
(
virt_to_phys
(
host_addr
)
&
(
~
PAGE_MASK
));
block
->
size
=
size
;
return
block
;
}
static
void
ct_vm_unmap
(
struct
ct_vm
*
vm
,
struct
ct_vm_block
*
block
)
{
/* do unmapping */
block
->
size
=
((
block
->
addr
+
block
->
size
+
PAGE_SIZE
-
1
)
&
PAGE_MASK
)
-
(
block
->
addr
&
PAGE_MASK
);
block
->
addr
&=
PAGE_MASK
;
put_vm_block
(
vm
,
block
);
}
...
...
@@ -191,6 +184,8 @@ int ct_vm_create(struct ct_vm **rvm)
if
(
NULL
==
vm
)
return
-
ENOMEM
;
mutex_init
(
&
vm
->
lock
);
/* Allocate page table pages */
for
(
i
=
0
;
i
<
CT_PTP_NUM
;
i
++
)
{
vm
->
ptp
[
i
]
=
kmalloc
(
PAGE_SIZE
,
GFP_KERNEL
);
...
...
sound/pci/ctxfi/ctvmem.h
View file @
bd05dbd3
...
...
@@ -20,24 +20,36 @@
#define CT_PTP_NUM 1
/* num of device page table pages */
#include <linux/
spinlock
.h>
#include <linux/
mutex
.h>
#include <linux/list.h>
/* The chip can handle the page table of 4k pages
* (emu20k1 can handle even 8k pages, but we don't use it right now)
*/
#define CT_PAGE_SIZE 4096
#define CT_PAGE_SHIFT 12
#define CT_PAGE_MASK (~(PAGE_SIZE - 1))
#define CT_PAGE_ALIGN(addr) ALIGN(addr, CT_PAGE_SIZE)
struct
ct_vm_block
{
unsigned
int
addr
;
/* starting logical addr of this block */
unsigned
int
size
;
/* size of this device virtual mem block */
struct
list_head
list
;
};
struct
snd_pcm_substream
;
/* Virtual memory management object for card device */
struct
ct_vm
{
void
*
ptp
[
CT_PTP_NUM
];
/* Device page table pages */
unsigned
int
size
;
/* Available addr space in bytes */
struct
list_head
unused
;
/* List of unused blocks */
struct
list_head
used
;
/* List of used blocks */
struct
mutex
lock
;
/* Map host addr (kmalloced/vmalloced) to device logical addr. */
struct
ct_vm_block
*
(
*
map
)(
struct
ct_vm
*
,
void
*
host_addr
,
int
size
);
struct
ct_vm_block
*
(
*
map
)(
struct
ct_vm
*
,
struct
snd_pcm_substream
*
,
int
size
);
/* Unmap device logical addr area. */
void
(
*
unmap
)(
struct
ct_vm
*
,
struct
ct_vm_block
*
block
);
void
*
(
*
get_ptp_virt
)(
struct
ct_vm
*
vm
,
int
index
);
...
...
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