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
2f2fc324
Commit
2f2fc324
authored
Dec 04, 2002
by
Jaroslav Kysela
Browse files
Options
Browse Files
Download
Plain Diff
Merge
http://linux.bkbits.net/linux-2.5
into suse.cz:/home/perex/bk/linux-sound/linux-sound
parents
7f9f9f51
bf734625
Changes
20
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
825 additions
and
489 deletions
+825
-489
include/sound/cs46xx_dsp_spos.h
include/sound/cs46xx_dsp_spos.h
+4
-1
include/sound/trident.h
include/sound/trident.h
+14
-4
include/sound/version.h
include/sound/version.h
+1
-1
sound/drivers/opl3/opl3_seq.c
sound/drivers/opl3/opl3_seq.c
+0
-1
sound/drivers/virmidi.c
sound/drivers/virmidi.c
+3
-0
sound/isa/sb/sb16_main.c
sound/isa/sb/sb16_main.c
+6
-0
sound/pci/cs46xx/cs46xx_lib.c
sound/pci/cs46xx/cs46xx_lib.c
+142
-54
sound/pci/cs46xx/cs46xx_lib.h
sound/pci/cs46xx/cs46xx_lib.h
+2
-2
sound/pci/cs46xx/dsp_spos.c
sound/pci/cs46xx/dsp_spos.c
+35
-22
sound/pci/cs46xx/dsp_spos.h
sound/pci/cs46xx/dsp_spos.h
+21
-3
sound/pci/cs46xx/dsp_spos_scb_lib.c
sound/pci/cs46xx/dsp_spos_scb_lib.c
+15
-22
sound/pci/ens1370.c
sound/pci/ens1370.c
+3
-2
sound/pci/ice1712/delta.c
sound/pci/ice1712/delta.c
+7
-7
sound/pci/ice1712/ice1712.c
sound/pci/ice1712/ice1712.c
+180
-37
sound/pci/ice1712/ice1712.h
sound/pci/ice1712/ice1712.h
+1
-1
sound/pci/rme9652/hammerfall_mem.c
sound/pci/rme9652/hammerfall_mem.c
+1
-1
sound/pci/trident/trident.c
sound/pci/trident/trident.c
+5
-5
sound/pci/trident/trident_main.c
sound/pci/trident/trident_main.c
+371
-305
sound/usb/usbaudio.h
sound/usb/usbaudio.h
+4
-0
sound/usb/usbmidi.c
sound/usb/usbmidi.c
+10
-21
No files found.
include/sound/cs46xx_dsp_spos.h
View file @
2f2fc324
...
...
@@ -63,7 +63,6 @@
#define DSP_SPDIF_STATUS_OUTPUT_ENABLED 1
#define DSP_SPDIF_STATUS_PLAYBACK_OPEN 2
#define DSP_SPDIF_STATUS_HW_ENABLED 4
#define DSP_SPDIF_STATUS_AC3_MODE 8
struct
_dsp_module_desc_t
;
...
...
@@ -196,6 +195,10 @@ typedef struct _dsp_spos_instance_t {
int
spdif_status_in
;
u16
spdif_input_volume_right
;
u16
spdif_input_volume_left
;
/* spdif channel status,
left right and user validity bits */
int
spdif_csuv_default
;
int
spdif_csuv_stream
;
/* SPDIF input sample rate converter */
dsp_scb_descriptor_t
*
spdif_in_src
;
...
...
include/sound/trident.h
View file @
2f2fc324
...
...
@@ -101,10 +101,18 @@
/* Global registers */
enum
global_control_bits
{
CHANNEL_IDX
=
0x0000003f
,
OVERRUN_IE
=
0x00000400
,
UNDERRUN_IE
=
0x00000800
,
ENDLP_IE
=
0x00001000
,
MIDLP_IE
=
0x00002000
,
ETOG_IE
=
0x00004000
,
EDROP_IE
=
0x00008000
,
BANK_B_EN
=
0x00010000
CHANNEL_IDX
=
0x0000003f
,
OVERRUN_IE
=
0x00000400
,
/* interrupt enable: capture overrun */
UNDERRUN_IE
=
0x00000800
,
/* interrupt enable: playback underrun */
ENDLP_IE
=
0x00001000
,
/* interrupt enable: end of buffer */
MIDLP_IE
=
0x00002000
,
/* interrupt enable: middle buffer */
ETOG_IE
=
0x00004000
,
/* interrupt enable: envelope toggling */
EDROP_IE
=
0x00008000
,
/* interrupt enable: envelope drop */
BANK_B_EN
=
0x00010000
,
/* SiS: enable bank B (64 channels) */
PCMIN_B_MIX
=
0x00020000
,
/* SiS: PCM IN B mixing enable */
I2S_OUT_ASSIGN
=
0x00040000
,
/* SiS: I2S Out contains surround PCM */
SPDIF_OUT_ASSIGN
=
0x00080000
,
/* SiS: 0=S/PDIF L/R | 1=PCM Out FIFO */
MAIN_OUT_ASSIGN
=
0x00100000
,
/* SiS: 0=PCM Out FIFO | 1=MMC Out buffer */
};
enum
miscint_bits
{
...
...
@@ -423,6 +431,8 @@ struct _snd_trident {
int
ChanPCM
;
/* max number of PCM channels */
int
ChanPCMcnt
;
/* actual number of PCM channels */
int
ac97_detect
;
/* 1 = AC97 in detection phase */
struct
_snd_4dwave
synth
;
/* synth specific variables */
spinlock_t
event_lock
;
...
...
include/sound/version.h
View file @
2f2fc324
/* include/version.h. Generated automatically by configure. */
#define CONFIG_SND_VERSION "0.9.0rc5"
#define CONFIG_SND_DATE " (S
un Nov 10 19:48:18
2002 UTC)"
#define CONFIG_SND_DATE " (S
at Nov 23 10:12:47
2002 UTC)"
sound/drivers/opl3/opl3_seq.c
View file @
2f2fc324
...
...
@@ -266,7 +266,6 @@ static int snd_opl3_seq_new_device(snd_seq_device_t *dev)
snd_seq_fm_init
(
&
opl3
->
fm_ops
,
NULL
);
/* setup system timer */
memset
(
&
opl3
->
tlist
,
0
,
sizeof
(
opl3
->
tlist
));
init_timer
(
&
opl3
->
tlist
);
opl3
->
tlist
.
function
=
snd_opl3_timer_func
;
opl3
->
tlist
.
data
=
(
unsigned
long
)
opl3
;
...
...
sound/drivers/virmidi.c
View file @
2f2fc324
...
...
@@ -51,6 +51,9 @@
#define SNDRV_GET_ID
#include <sound/initval.h>
/* hack: OSS defines midi_devs, so undefine it (versioned symbols) */
#undef midi_devs
MODULE_AUTHOR
(
"Takashi Iwai <tiwai@suse.de>"
);
MODULE_DESCRIPTION
(
"Dummy soundcard for virtual rawmidi devices"
);
MODULE_LICENSE
(
"GPL"
);
...
...
sound/isa/sb/sb16_main.c
View file @
2f2fc324
...
...
@@ -10,6 +10,12 @@
* Note: 16-bit wide is assigned to first direction which made request.
* With full duplex - playback is preferred with abstract layer.
*
* Note: Some chip revisions have hardware bug. Changing capture
* channel from full-duplex 8bit DMA to 16bit DMA will block
* 16bit DMA transfers from DSP chip (capture) until 8bit transfer
* to DSP chip (playback) starts. This bug can be avoided with
* "16bit DMA Allocation" setting set to Playback or Capture.
*
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
...
...
sound/pci/cs46xx/cs46xx_lib.c
View file @
2f2fc324
...
...
@@ -950,15 +950,15 @@ static int snd_cs46xx_playback_trigger(snd_pcm_substream_t * substream,
case
SNDRV_PCM_TRIGGER_START
:
case
SNDRV_PCM_TRIGGER_RESUME
:
#ifdef CONFIG_SND_CS46XX_NEW_DSP
/* magic value to unmute PCM stream playback volume */
snd_cs46xx_poke
(
chip
,
(
cpcm
->
pcm_channel
->
pcm_reader_scb
->
address
+
SCBVolumeCtrl
)
<<
2
,
0x80007fff
);
if
(
cpcm
->
pcm_channel
->
unlinked
)
cs46xx_dsp_pcm_link
(
chip
,
cpcm
->
pcm_channel
);
if
(
substream
->
runtime
->
periods
!=
CS46XX_FRAGS
)
snd_cs46xx_playback_transfer
(
substream
,
0
);
/* raise playback volume */
cs46xx_dsp_scb_set_volume
(
chip
,
cpcm
->
pcm_channel
->
pcm_reader_scb
,
chip
->
dsp_spos_instance
->
dac_volume_right
,
chip
->
dsp_spos_instance
->
dac_volume_left
);
#else
if
(
substream
->
runtime
->
periods
!=
CS46XX_FRAGS
)
snd_cs46xx_playback_transfer
(
substream
,
0
);
...
...
@@ -972,8 +972,9 @@ static int snd_cs46xx_playback_trigger(snd_pcm_substream_t * substream,
case
SNDRV_PCM_TRIGGER_STOP
:
case
SNDRV_PCM_TRIGGER_SUSPEND
:
#ifdef CONFIG_SND_CS46XX_NEW_DSP
/* mute channel */
cs46xx_dsp_scb_set_volume
(
chip
,
cpcm
->
pcm_channel
->
pcm_reader_scb
,
0
,
0
);
/* magic mute channel */
snd_cs46xx_poke
(
chip
,
(
cpcm
->
pcm_channel
->
pcm_reader_scb
->
address
+
SCBVolumeCtrl
)
<<
2
,
0xffffffff
);
if
(
!
cpcm
->
pcm_channel
->
unlinked
)
cs46xx_dsp_pcm_unlink
(
chip
,
cpcm
->
pcm_channel
);
...
...
@@ -1067,6 +1068,7 @@ static int _cs46xx_adjust_sample_rate (cs46xx_t *chip, cs46xx_pcm_t *cpcm,
}
#endif
static
int
snd_cs46xx_playback_hw_params
(
snd_pcm_substream_t
*
substream
,
snd_pcm_hw_params_t
*
hw_params
)
{
...
...
@@ -1083,15 +1085,10 @@ static int snd_cs46xx_playback_hw_params(snd_pcm_substream_t * substream,
down
(
&
chip
->
spos_mutex
);
snd_assert
(
cpcm
->
pcm_channel
!=
NULL
);
/* if IEC958 is opened in AC3 mode dont adjust SRCTask is not
used so dont adjust sample rate */
if
(
cpcm
->
pcm_channel
->
pcm_channel_id
!=
DSP_IEC958_CHANNEL
||
!
(
chip
->
dsp_spos_instance
->
spdif_status_out
&
DSP_SPDIF_STATUS_AC3_MODE
))
{
if
(
_cs46xx_adjust_sample_rate
(
chip
,
cpcm
,
sample_rate
))
{
up
(
&
chip
->
spos_mutex
);
return
-
ENXIO
;
}
if
(
_cs46xx_adjust_sample_rate
(
chip
,
cpcm
,
sample_rate
))
{
up
(
&
chip
->
spos_mutex
);
return
-
ENXIO
;
}
if
(
cs46xx_dsp_pcm_channel_set_period
(
chip
,
cpcm
->
pcm_channel
,
period_size
*
4
))
{
...
...
@@ -2042,34 +2039,6 @@ static int snd_cs46xx_pcm_capture_get(snd_kcontrol_t *kcontrol,
return
0
;
}
static
int
snd_cs46xx_iec958_ac3_mode_get
(
snd_kcontrol_t
*
kcontrol
,
snd_ctl_elem_value_t
*
ucontrol
)
{
cs46xx_t
*
chip
=
snd_kcontrol_chip
(
kcontrol
);
dsp_spos_instance_t
*
ins
=
chip
->
dsp_spos_instance
;
if
(
!
ins
->
spdif_status_out
&
DSP_SPDIF_STATUS_AC3_MODE
)
ucontrol
->
value
.
integer
.
value
[
0
]
=
1
;
else
ucontrol
->
value
.
integer
.
value
[
0
]
=
0
;
return
0
;
}
static
int
snd_cs46xx_iec958_ac3_mode_put
(
snd_kcontrol_t
*
kcontrol
,
snd_ctl_elem_value_t
*
ucontrol
)
{
cs46xx_t
*
chip
=
snd_kcontrol_chip
(
kcontrol
);
dsp_spos_instance_t
*
ins
=
chip
->
dsp_spos_instance
;
int
old
=
ins
->
spdif_status_out
;
if
(
ucontrol
->
value
.
integer
.
value
[
0
])
ins
->
spdif_status_out
|=
DSP_SPDIF_STATUS_AC3_MODE
;
else
ins
->
spdif_status_out
&=
~
DSP_SPDIF_STATUS_AC3_MODE
;
return
(
old
!=
ins
->
spdif_status_out
);
}
static
int
snd_cs46xx_pcm_capture_put
(
snd_kcontrol_t
*
kcontrol
,
snd_ctl_elem_value_t
*
ucontrol
)
...
...
@@ -2131,6 +2100,110 @@ static int snd_herc_spdif_select_put(snd_kcontrol_t *kcontrol,
return
(
val1
!=
snd_cs46xx_peekBA0
(
chip
,
BA0_EGPIODR
));
}
static
int
snd_cs46xx_spdif_info
(
snd_kcontrol_t
*
kcontrol
,
snd_ctl_elem_info_t
*
uinfo
)
{
uinfo
->
type
=
SNDRV_CTL_ELEM_TYPE_IEC958
;
uinfo
->
count
=
1
;
return
0
;
}
static
int
snd_cs46xx_spdif_default_get
(
snd_kcontrol_t
*
kcontrol
,
snd_ctl_elem_value_t
*
ucontrol
)
{
cs46xx_t
*
chip
=
snd_kcontrol_chip
(
kcontrol
);
dsp_spos_instance_t
*
ins
=
chip
->
dsp_spos_instance
;
down
(
&
chip
->
spos_mutex
);
ucontrol
->
value
.
iec958
.
status
[
0
]
=
_wrap_all_bits
((
ins
->
spdif_csuv_default
>>
24
)
&
0xff
);
ucontrol
->
value
.
iec958
.
status
[
1
]
=
_wrap_all_bits
((
ins
->
spdif_csuv_default
>>
16
)
&
0xff
);
ucontrol
->
value
.
iec958
.
status
[
2
]
=
0
;
ucontrol
->
value
.
iec958
.
status
[
3
]
=
_wrap_all_bits
((
ins
->
spdif_csuv_default
)
&
0xff
);
up
(
&
chip
->
spos_mutex
);
return
0
;
}
static
int
snd_cs46xx_spdif_default_put
(
snd_kcontrol_t
*
kcontrol
,
snd_ctl_elem_value_t
*
ucontrol
)
{
cs46xx_t
*
chip
=
snd_kcontrol_chip
(
kcontrol
);
dsp_spos_instance_t
*
ins
=
chip
->
dsp_spos_instance
;
unsigned
int
val
;
int
change
;
down
(
&
chip
->
spos_mutex
);
val
=
_wrap_all_bits
(((
u32
)
ucontrol
->
value
.
iec958
.
status
[
0
]
<<
24
))
|
_wrap_all_bits
(((
u32
)
ucontrol
->
value
.
iec958
.
status
[
2
]
<<
16
))
|
_wrap_all_bits
(
(
u32
)
ucontrol
->
value
.
iec958
.
status
[
3
])
|
/* left and right validity bit */
(
1
<<
13
)
|
(
1
<<
12
);
change
=
ins
->
spdif_csuv_default
!=
val
;
ins
->
spdif_csuv_default
=
val
;
if
(
!
(
ins
->
spdif_status_out
&
DSP_SPDIF_STATUS_PLAYBACK_OPEN
)
)
cs46xx_poke_via_dsp
(
chip
,
SP_SPDOUT_CSUV
,
val
);
up
(
&
chip
->
spos_mutex
);
return
change
;
}
static
int
snd_cs46xx_spdif_mask_get
(
snd_kcontrol_t
*
kcontrol
,
snd_ctl_elem_value_t
*
ucontrol
)
{
ucontrol
->
value
.
iec958
.
status
[
0
]
=
0xff
;
ucontrol
->
value
.
iec958
.
status
[
1
]
=
0xff
;
ucontrol
->
value
.
iec958
.
status
[
2
]
=
0x00
;
ucontrol
->
value
.
iec958
.
status
[
3
]
=
0xff
;
return
0
;
}
static
int
snd_cs46xx_spdif_stream_get
(
snd_kcontrol_t
*
kcontrol
,
snd_ctl_elem_value_t
*
ucontrol
)
{
cs46xx_t
*
chip
=
snd_kcontrol_chip
(
kcontrol
);
dsp_spos_instance_t
*
ins
=
chip
->
dsp_spos_instance
;
down
(
&
chip
->
spos_mutex
);
ucontrol
->
value
.
iec958
.
status
[
0
]
=
_wrap_all_bits
((
ins
->
spdif_csuv_stream
>>
24
)
&
0xff
);
ucontrol
->
value
.
iec958
.
status
[
1
]
=
_wrap_all_bits
((
ins
->
spdif_csuv_stream
>>
16
)
&
0xff
);
ucontrol
->
value
.
iec958
.
status
[
2
]
=
0
;
ucontrol
->
value
.
iec958
.
status
[
3
]
=
_wrap_all_bits
((
ins
->
spdif_csuv_stream
)
&
0xff
);
up
(
&
chip
->
spos_mutex
);
return
0
;
}
static
int
snd_cs46xx_spdif_stream_put
(
snd_kcontrol_t
*
kcontrol
,
snd_ctl_elem_value_t
*
ucontrol
)
{
cs46xx_t
*
chip
=
snd_kcontrol_chip
(
kcontrol
);
dsp_spos_instance_t
*
ins
=
chip
->
dsp_spos_instance
;
unsigned
int
val
;
int
change
;
down
(
&
chip
->
spos_mutex
);
val
=
_wrap_all_bits
(((
u32
)
ucontrol
->
value
.
iec958
.
status
[
0
]
<<
24
))
|
_wrap_all_bits
(((
u32
)
ucontrol
->
value
.
iec958
.
status
[
1
]
<<
16
))
|
_wrap_all_bits
(
(
u32
)
ucontrol
->
value
.
iec958
.
status
[
3
])
|
/* left and right validity bit */
(
1
<<
13
)
|
(
1
<<
12
);
change
=
ins
->
spdif_csuv_stream
!=
val
;
ins
->
spdif_csuv_stream
=
val
;
if
(
ins
->
spdif_status_out
&
DSP_SPDIF_STATUS_PLAYBACK_OPEN
)
cs46xx_poke_via_dsp
(
chip
,
SP_SPDOUT_CSUV
,
val
);
up
(
&
chip
->
spos_mutex
);
return
change
;
}
#endif
/* CONFIG_SND_CS46XX_NEW_DSP */
#ifdef CONFIG_SND_CS46XX_DEBUG_GPIO
...
...
@@ -2242,7 +2315,7 @@ static snd_kcontrol_new_t snd_cs46xx_controls[] __devinitdata = {
},
{
.
iface
=
SNDRV_CTL_ELEM_IFACE_MIXER
,
.
name
=
"IEC
958 Output Switch"
,
.
name
=
"IEC958 Output Switch"
,
.
info
=
snd_mixer_boolean_info
,
.
get
=
snd_cs46xx_iec958_get
,
.
put
=
snd_cs46xx_iec958_put
,
...
...
@@ -2250,14 +2323,7 @@ static snd_kcontrol_new_t snd_cs46xx_controls[] __devinitdata = {
},
{
.
iface
=
SNDRV_CTL_ELEM_IFACE_MIXER
,
.
name
=
"IEC 958 AC3 Mode Switch"
,
.
info
=
snd_mixer_boolean_info
,
.
get
=
snd_cs46xx_iec958_ac3_mode_get
,
.
put
=
snd_cs46xx_iec958_ac3_mode_put
,
},
{
.
iface
=
SNDRV_CTL_ELEM_IFACE_MIXER
,
.
name
=
"IEC 958 Input Switch"
,
.
name
=
"IEC958 Input Switch"
,
.
info
=
snd_mixer_boolean_info
,
.
get
=
snd_cs46xx_iec958_get
,
.
put
=
snd_cs46xx_iec958_put
,
...
...
@@ -2265,12 +2331,34 @@ static snd_kcontrol_new_t snd_cs46xx_controls[] __devinitdata = {
},
{
.
iface
=
SNDRV_CTL_ELEM_IFACE_MIXER
,
.
name
=
"IEC
958 Input Volume"
,
.
name
=
"IEC958 Input Volume"
,
.
info
=
snd_cs46xx_vol_info
,
.
get
=
snd_cs46xx_vol_iec958_get
,
.
put
=
snd_cs46xx_vol_iec958_put
,
.
private_value
=
(
ASYNCRX_SCB_ADDR
+
0xE
)
<<
2
,
},
{
.
iface
=
SNDRV_CTL_ELEM_IFACE_PCM
,
.
name
=
SNDRV_CTL_NAME_IEC958
(
""
,
PLAYBACK
,
DEFAULT
),
.
info
=
snd_cs46xx_spdif_info
,
.
get
=
snd_cs46xx_spdif_default_get
,
.
put
=
snd_cs46xx_spdif_default_put
,
},
{
.
iface
=
SNDRV_CTL_ELEM_IFACE_PCM
,
.
name
=
SNDRV_CTL_NAME_IEC958
(
""
,
PLAYBACK
,
MASK
),
.
info
=
snd_cs46xx_spdif_info
,
.
get
=
snd_cs46xx_spdif_mask_get
,
.
access
=
SNDRV_CTL_ELEM_ACCESS_READ
},
{
.
iface
=
SNDRV_CTL_ELEM_IFACE_PCM
,
.
name
=
SNDRV_CTL_NAME_IEC958
(
""
,
PLAYBACK
,
PCM_STREAM
),
.
info
=
snd_cs46xx_spdif_info
,
.
get
=
snd_cs46xx_spdif_stream_get
,
.
put
=
snd_cs46xx_spdif_stream_put
},
#endif
#ifdef CONFIG_SND_CS46XX_DEBUG_GPIO
{
...
...
sound/pci/cs46xx/cs46xx_lib.h
View file @
2f2fc324
...
...
@@ -217,6 +217,6 @@ int cs46xx_dsp_pcm_channel_set_period (cs46xx_t * chip,
int
period_size
);
int
cs46xx_dsp_pcm_ostream_set_period
(
cs46xx_t
*
chip
,
int
period_size
);
int
cs46xx_dsp_set_dac_volume
(
cs46xx_t
*
chip
,
u16
right
,
u16
lef
t
);
int
cs46xx_dsp_set_iec958_volume
(
cs46xx_t
*
chip
,
u16
right
,
u16
lef
t
);
int
cs46xx_dsp_set_dac_volume
(
cs46xx_t
*
chip
,
u16
left
,
u16
righ
t
);
int
cs46xx_dsp_set_iec958_volume
(
cs46xx_t
*
chip
,
u16
left
,
u16
righ
t
);
#endif
/* __CS46XX_LIB_H__ */
sound/pci/cs46xx/dsp_spos.c
View file @
2f2fc324
...
...
@@ -31,6 +31,7 @@
#include <sound/core.h>
#include <sound/control.h>
#include <sound/info.h>
#include <sound/asoundef.h>
#include <sound/cs46xx.h>
#include "cs46xx_lib.h"
...
...
@@ -262,6 +263,15 @@ dsp_spos_instance_t * cs46xx_dsp_spos_create (cs46xx_t * chip)
ins
->
spdif_input_volume_right
=
0x8000
;
ins
->
spdif_input_volume_left
=
0x8000
;
/* set left and right validity bits and
default channel status */
ins
->
spdif_csuv_default
=
ins
->
spdif_csuv_stream
=
/* byte 0 */
(
_wrap_all_bits
(
(
SNDRV_PCM_DEFAULT_CON_SPDIF
&
0xff
))
<<
24
)
|
/* byte 1 */
(
_wrap_all_bits
(
((
SNDRV_PCM_DEFAULT_CON_SPDIF
>>
16
)
&
0xff
))
<<
16
)
|
/* byte 3 */
_wrap_all_bits
(
(
SNDRV_PCM_DEFAULT_CON_SPDIF
>>
24
)
&
0xff
)
|
/* left and right validity bits */
(
1
<<
13
)
|
(
1
<<
12
);
return
ins
;
}
...
...
@@ -1549,7 +1559,7 @@ int cs46xx_dsp_enable_spdif_hw (cs46xx_t *chip)
cs46xx_poke_via_dsp
(
chip
,
SP_SPDOUT_CONTROL
,
0x80000000
);
/* right and left validate bit */
cs46xx_poke_via_dsp
(
chip
,
SP_SPDOUT_CSUV
,
0x00000000
|
(
1
<<
13
)
|
(
1
<<
12
)
);
cs46xx_poke_via_dsp
(
chip
,
SP_SPDOUT_CSUV
,
ins
->
spdif_csuv_default
);
/* monitor state */
ins
->
spdif_status_out
|=
DSP_SPDIF_STATUS_HW_ENABLED
;
...
...
@@ -1587,11 +1597,6 @@ int cs46xx_dsp_enable_spdif_in (cs46xx_t *chip)
cs46xx_poke_via_dsp
(
chip
,
SP_SPDIN_FIFOPTR
,
0x0
);
cs46xx_src_link
(
chip
,
ins
->
spdif_in_src
);
/* restore SPDIF input volume */
cs46xx_dsp_scb_set_volume
(
chip
,
ins
->
spdif_in_src
,
ins
->
spdif_input_volume_right
,
ins
->
spdif_input_volume_left
);
spin_unlock_irq
(
&
chip
->
reg_lock
);
/* set SPDIF input sample rate and unmute
...
...
@@ -1725,39 +1730,47 @@ int cs46xx_poke_via_dsp (cs46xx_t *chip,u32 address,u32 data)
return
0
;
}
int
cs46xx_dsp_set_dac_volume
(
cs46xx_t
*
chip
,
u16
right
,
u16
lef
t
)
int
cs46xx_dsp_set_dac_volume
(
cs46xx_t
*
chip
,
u16
left
,
u16
righ
t
)
{
int
i
;
dsp_spos_instance_t
*
ins
=
chip
->
dsp_spos_instance
;
dsp_scb_descriptor_t
*
scb
;
down
(
&
chip
->
spos_mutex
);
/* main output */
scb
=
ins
->
master_mix_scb
->
sub_list_ptr
;
while
(
scb
!=
ins
->
the_null_scb
)
{
cs46xx_dsp_scb_set_volume
(
chip
,
scb
,
left
,
right
);
scb
=
scb
->
next_scb_ptr
;
}
ins
->
dac_volume_right
=
right
;
ins
->
dac_volume_left
=
left
;
for
(
i
=
0
;
i
<
DSP_MAX_PCM_CHANNELS
;
++
i
)
{
if
(
ins
->
pcm_channels
[
i
].
active
&&
!
ins
->
pcm_channels
[
i
].
unlinked
)
{
cs46xx_dsp_scb_set_volume
(
chip
,
ins
->
pcm_channels
[
i
].
pcm_reader_scb
,
right
,
left
);
}
/* rear output */
scb
=
ins
->
rear_mix_scb
->
sub_list_ptr
;
while
(
scb
!=
ins
->
the_null_scb
)
{
cs46xx_dsp_scb_set_volume
(
chip
,
scb
,
left
,
right
);
scb
=
scb
->
next_scb_ptr
;
}
ins
->
dac_volume_left
=
left
;
ins
->
dac_volume_right
=
right
;
up
(
&
chip
->
spos_mutex
);
return
0
;
}
int
cs46xx_dsp_set_iec958_volume
(
cs46xx_t
*
chip
,
u16
right
,
u16
lef
t
)
{
int
cs46xx_dsp_set_iec958_volume
(
cs46xx_t
*
chip
,
u16
left
,
u16
righ
t
)
{
dsp_spos_instance_t
*
ins
=
chip
->
dsp_spos_instance
;
down
(
&
chip
->
spos_mutex
);
cs46xx_dsp_scb_set_volume
(
chip
,
ins
->
spdif_in_src
,
right
,
left
);
ins
->
spdif_input_volume_right
=
right
;
if
(
ins
->
asynch_rx_scb
!=
NULL
)
cs46xx_dsp_scb_set_volume
(
chip
,
ins
->
asynch_rx_scb
,
left
,
right
);
ins
->
spdif_input_volume_left
=
left
;
ins
->
spdif_input_volume_right
=
right
;
up
(
&
chip
->
spos_mutex
);
return
0
;
...
...
sound/pci/cs46xx/dsp_spos.h
View file @
2f2fc324
...
...
@@ -185,6 +185,25 @@ typedef enum {
#define SP_SPDOUT_CONTROL 0x804D
#define SP_SPDOUT_CSUV 0x808E
static
inline
u8
_wrap_all_bits
(
u8
val
)
{
u8
wrapped
;
/* wrap all 8 bits */
wrapped
=
((
val
&
0x1
)
<<
7
)
|
((
val
&
0x2
)
<<
5
)
|
((
val
&
0x4
)
<<
3
)
|
((
val
&
0x8
)
<<
1
)
|
((
val
&
0x10
)
>>
1
)
|
((
val
&
0x20
)
>>
3
)
|
((
val
&
0x40
)
>>
5
)
|
((
val
&
0x80
)
>>
6
);
return
wrapped
;
}
static
inline
void
cs46xx_dsp_spos_update_scb
(
cs46xx_t
*
chip
,
dsp_scb_descriptor_t
*
scb
)
{
/* update nextSCB and subListPtr in SCB */
...
...
@@ -195,12 +214,11 @@ static inline void cs46xx_dsp_spos_update_scb (cs46xx_t * chip,dsp_scb_descripto
}
static
inline
void
cs46xx_dsp_scb_set_volume
(
cs46xx_t
*
chip
,
dsp_scb_descriptor_t
*
scb
,
u16
right
,
u16
lef
t
)
{
unsigned
int
val
=
((
0xffff
-
right
)
<<
16
|
(
0xffff
-
left
));
u16
left
,
u16
righ
t
)
{
unsigned
int
val
=
((
0xffff
-
left
)
<<
16
|
(
0xffff
-
right
));
snd_cs46xx_poke
(
chip
,
(
scb
->
address
+
SCBVolumeCtrl
)
<<
2
,
val
);
snd_cs46xx_poke
(
chip
,
(
scb
->
address
+
SCBVolumeCtrl
+
1
)
<<
2
,
val
);
}
#endif
/* __DSP_SPOS_H__ */
#endif
/* CONFIG_SND_CS46XX_NEW_DSP */
sound/pci/cs46xx/dsp_spos_scb_lib.c
View file @
2f2fc324
...
...
@@ -603,8 +603,8 @@ cs46xx_dsp_create_src_task_scb(cs46xx_t * chip,char * scb_name,
src_buffer_addr
<<
0x10
,
0x04000000
,
{
0x
8000
,
0x8000
,
0xffff
,
0xffff
0x
ffff
-
ins
->
dac_volume_right
,
0xffff
-
ins
->
dac_volume_left
,
0xffff
-
ins
->
dac_volume_right
,
0xffff
-
ins
->
dac_volume_left
}
};
...
...
@@ -658,7 +658,7 @@ cs46xx_dsp_create_mix_only_scb(cs46xx_t * chip,char * scb_name,
/* D */
0
,
{
/* E */
0x8000
,
0x8000
,
/* F */
0x
ffff
,
0xffff
/* F */
0x
8000
,
0x8000
}
};
...
...
@@ -830,7 +830,7 @@ cs46xx_dsp_create_asynch_fg_tx_scb(cs46xx_t * chip,char * scb_name,u32 dest,
0
,
0x2aab
,
/* Const 1/3 */
{
0
,
/* Define the unused elements */
0
,
/* Define the unused elements */
0
,
0
},
...
...
@@ -846,7 +846,7 @@ cs46xx_dsp_create_asynch_fg_tx_scb(cs46xx_t * chip,char * scb_name,u32 dest,
rate etc */
0x18000000
,
/* Phi increment for approx 32k operation */
0x8000
,
0x8000
,
/* Volume controls are unused at this time */
0x
ffff
,
0xffff
0x
8000
,
0x8000
};
scb
=
cs46xx_dsp_create_generic_scb
(
chip
,
scb_name
,(
u32
*
)
&
asynch_fg_tx_scb
,
...
...
@@ -864,7 +864,7 @@ cs46xx_dsp_create_asynch_fg_rx_scb(cs46xx_t * chip,char * scb_name,u32 dest,
dsp_scb_descriptor_t
*
parent_scb
,
int
scb_child_type
)
{
dsp_spos_instance_t
*
ins
=
chip
->
dsp_spos_instance
;
dsp_scb_descriptor_t
*
scb
;
asynch_fg_rx_scb_t
asynch_fg_rx_scb
=
{
...
...
@@ -893,9 +893,9 @@ cs46xx_dsp_create_asynch_fg_rx_scb(cs46xx_t * chip,char * scb_name,u32 dest,
rate etc */
0x18000000
,
/*
Mute stream
*/
0x
8000
,
0x8000
,
0xffff
,
0xffff
/*
Set IEC958 input volume
*/
0x
ffff
-
ins
->
spdif_input_volume_right
,
0xffff
-
ins
->
spdif_input_volume_left
,
0xffff
-
ins
->
spdif_input_volume_right
,
0xffff
-
ins
->
spdif_input_volume_left
,
};
scb
=
cs46xx_dsp_create_generic_scb
(
chip
,
scb_name
,(
u32
*
)
&
asynch_fg_rx_scb
,
...
...
@@ -1116,11 +1116,13 @@ pcm_channel_descriptor_t * cs46xx_dsp_create_pcm_channel (cs46xx_t * chip,
case
DSP_IEC958_CHANNEL
:
snd_assert
(
ins
->
asynch_tx_scb
!=
NULL
,
return
NULL
);
mixer_scb
=
ins
->
asynch_tx_scb
;
#if 0
if (ins->spdif_status_out & DSP_SPDIF_STATUS_AC3_MODE) {
snd_printdd ("IEC958 opened in AC3 mode\n");
/*src_scb = ins->asynch_tx_scb;
ins->asynch_tx_scb->ref_count ++;*/
}
#endif
break
;
default:
snd_assert
(
0
);
...
...
@@ -1198,9 +1200,7 @@ pcm_channel_descriptor_t * cs46xx_dsp_create_pcm_channel (cs46xx_t * chip,
return
NULL
;
}
if
(
pcm_channel_id
!=
DSP_IEC958_CHANNEL
||
!
(
ins
->
spdif_status_out
&
DSP_SPDIF_STATUS_AC3_MODE
))
cs46xx_dsp_set_src_sample_rate
(
chip
,
src_scb
,
sample_rate
);
cs46xx_dsp_set_src_sample_rate
(
chip
,
src_scb
,
sample_rate
);
ins
->
nsrc_scb
++
;
}
...
...
@@ -1461,17 +1461,11 @@ void cs46xx_dsp_set_src_sample_rate(cs46xx_t *chip,dsp_scb_descriptor_t * src, u
*/
spin_lock_irqsave
(
&
chip
->
reg_lock
,
flags
);
/* mute SCB */
/* cs46xx_dsp_scb_set_volume (chip,src,0,0); */
snd_cs46xx_poke
(
chip
,
(
src
->
address
+
SRCCorPerGof
)
<<
2
,
((
correctionPerSec
<<
16
)
&
0xFFFF0000
)
|
(
correctionPerGOF
&
0xFFFF
));
snd_cs46xx_poke
(
chip
,
(
src
->
address
+
SRCPhiIncr6Int26Frac
)
<<
2
,
phiIncr
);
/* raise volume */
/* cs46xx_dsp_scb_set_volume (chip,src,0x7fff,0x7fff); */
spin_unlock_irqrestore
(
&
chip
->
reg_lock
,
flags
);
}
...
...
@@ -1641,9 +1635,8 @@ int cs46xx_iec958_pre_open (cs46xx_t *chip)
SCB_ON_PARENT_NEXT_SCB
);
if
(
ins
->
spdif_status_out
&
DSP_SPDIF_STATUS_AC3_MODE
)
/* set left (13), right validity bit (12) , and non-audio(1) and profsional bit (0) */
cs46xx_poke_via_dsp
(
chip
,
SP_SPDOUT_CSUV
,
0x00000000
|
(
1
<<
13
)
|
(
1
<<
12
)
|
(
1
<<
1
)
|
1
);
/* set spdif channel status value for streaming */
cs46xx_poke_via_dsp
(
chip
,
SP_SPDOUT_CSUV
,
ins
->
spdif_csuv_stream
);
ins
->
spdif_status_out
|=
DSP_SPDIF_STATUS_PLAYBACK_OPEN
;
...
...
@@ -1659,7 +1652,7 @@ int cs46xx_iec958_post_close (cs46xx_t *chip)
ins
->
spdif_status_out
&=
~
DSP_SPDIF_STATUS_PLAYBACK_OPEN
;
/* restore settings */
cs46xx_poke_via_dsp
(
chip
,
SP_SPDOUT_CSUV
,
0x00000000
|
(
1
<<
13
)
|
(
1
<<
12
)
);
cs46xx_poke_via_dsp
(
chip
,
SP_SPDOUT_CSUV
,
ins
->
spdif_csuv_default
);
/* deallocate stuff */
cs46xx_dsp_remove_scb
(
chip
,
ins
->
asynch_tx_scb
);
...
...
sound/pci/ens1370.c
View file @
2f2fc324
...
...
@@ -1355,6 +1355,7 @@ static snd_kcontrol_new_t snd_ens1373_spdif_default __devinitdata =
static
snd_kcontrol_new_t
snd_ens1373_spdif_mask
__devinitdata
=
{
.
access
=
SNDRV_CTL_ELEM_ACCESS_READ
,
.
iface
=
SNDRV_CTL_ELEM_IFACE_PCM
,
.
name
=
SNDRV_CTL_NAME_IEC958
(
""
,
PLAYBACK
,
MASK
),
.
info
=
snd_ens1373_spdif_info
,
...
...
@@ -2181,10 +2182,10 @@ static int __devinit snd_audiopci_probe(struct pci_dev *pci,
return
err
;
}
#ifdef CHIP1370
strcpy
(
card
->
driver
,
"ES1370"
);
strcpy
(
card
->
driver
,
"E
N
S1370"
);
#endif
#ifdef CHIP1371
strcpy
(
card
->
driver
,
"ES1371"
);
strcpy
(
card
->
driver
,
"E
N
S1371"
);
#endif
strcpy
(
card
->
shortname
,
"Ensoniq AudioPCI"
);
sprintf
(
card
->
longname
,
"%s %s at 0x%lx, irq %i"
,
...
...
sound/pci/ice1712/delta.c
View file @
2f2fc324
...
...
@@ -257,17 +257,20 @@ static int delta1010lt_ak4524_start(ice1712_t *ice, unsigned char *saved, int ch
/*
* change the rate of AK4524 on Delta 44/66, AP, 1010LT
*/
static
void
delta_ak4524_set_rate_val
(
ice1712_t
*
ice
,
unsigned
char
val
)
static
void
delta_ak4524_set_rate_val
(
ice1712_t
*
ice
,
unsigned
int
rate
)
{
unsigned
char
tmp
,
tmp2
;
if
(
rate
==
0
)
/* no hint - S/PDIF input is master, simply return */
return
;
/* check before reset ak4524 to avoid unnecessary clicks */
down
(
&
ice
->
gpio_mutex
);
tmp
=
snd_ice1712_read
(
ice
,
ICE1712_IREG_GPIO_DATA
);
up
(
&
ice
->
gpio_mutex
);
tmp2
=
tmp
;
tmp2
&=
~
ICE1712_DELTA_DFS
;
if
(
val
==
15
||
val
==
11
||
val
==
7
)
if
(
rate
>
48000
)
tmp2
|=
ICE1712_DELTA_DFS
;
if
(
tmp
==
tmp2
)
return
;
...
...
@@ -275,12 +278,9 @@ static void delta_ak4524_set_rate_val(ice1712_t *ice, unsigned char val)
/* do it again */
snd_ice1712_ak4524_reset
(
ice
,
1
);
down
(
&
ice
->
gpio_mutex
);
tmp
=
snd_ice1712_read
(
ice
,
ICE1712_IREG_GPIO_DATA
);
if
(
val
==
15
||
val
==
11
||
val
==
7
)
{
tmp
=
snd_ice1712_read
(
ice
,
ICE1712_IREG_GPIO_DATA
)
&
~
ICE1712_DELTA_DFS
;
if
(
rate
>
48000
)
tmp
|=
ICE1712_DELTA_DFS
;
}
else
{
tmp
&=
~
ICE1712_DELTA_DFS
;
}
snd_ice1712_write
(
ice
,
ICE1712_IREG_GPIO_DATA
,
tmp
);
up
(
&
ice
->
gpio_mutex
);
snd_ice1712_ak4524_reset
(
ice
,
0
);
...
...
sound/pci/ice1712/ice1712.c
View file @
2f2fc324
...
...
@@ -104,10 +104,24 @@ MODULE_DEVICE_TABLE(pci, snd_ice1712_ids);
static
int
snd_ice1712_build_pro_mixer
(
ice1712_t
*
ice
);
static
int
snd_ice1712_build_controls
(
ice1712_t
*
ice
);
static
int
PRO_RATE_LOCKED
=
0
;
static
int
PRO_RATE_RESET
=
1
;
static
unsigned
int
PRO_RATE_DEFAULT
=
44100
;
/*
* Basic I/O
*/
static
inline
int
is_spdif_master
(
ice1712_t
*
ice
)
{
return
(
inb
(
ICEMT
(
ice
,
RATE
))
&
ICE1712_SPDIF_MASTER
)
?
1
:
0
;
}
static
inline
int
is_pro_rate_locked
(
ice1712_t
*
ice
)
{
return
is_spdif_master
(
ice
)
||
PRO_RATE_LOCKED
;
}
static
inline
void
snd_ice1712_ds_write
(
ice1712_t
*
ice
,
u8
channel
,
u8
addr
,
u32
data
)
{
outb
((
channel
<<
4
)
|
addr
,
ICEDS
(
ice
,
INDEX
));
...
...
@@ -980,21 +994,25 @@ static int snd_ice1712_pro_trigger(snd_pcm_substream_t *substream,
/*
*/
static
void
snd_ice1712_set_pro_rate
(
ice1712_t
*
ice
,
snd_pcm_substream_t
*
substream
)
static
void
snd_ice1712_set_pro_rate
(
ice1712_t
*
ice
,
unsigned
int
rate
,
int
do_not_lock
)
{
unsigned
long
flags
;
unsigned
int
rate
;
unsigned
char
val
;
int
old_lock_value
;
spin_lock_irqsave
(
&
ice
->
reg_lock
,
flags
);
if
((
inb
(
ICEMT
(
ice
,
PLAYBACK_CONTROL
))
&
(
ICE1712_CAPTURE_START_SHADOW
|
ICE1712_PLAYBACK_PAUSE
|
ICE1712_PLAYBACK_START
))
||
(
inb
(
ICEMT
(
ice
,
RATE
))
&
ICE1712_SPDIF_MASTER
))
{
old_lock_value
=
PRO_RATE_LOCKED
;
if
(
do_not_lock
)
PRO_RATE_LOCKED
=
0
;
if
(
inb
(
ICEMT
(
ice
,
PLAYBACK_CONTROL
))
&
(
ICE1712_CAPTURE_START_SHADOW
|
ICE1712_PLAYBACK_PAUSE
|
ICE1712_PLAYBACK_START
))
{
spin_unlock_irqrestore
(
&
ice
->
reg_lock
,
flags
);
return
;
}
rate
=
substream
->
runtime
->
rate
;
if
(
!
is_pro_rate_locked
(
ice
))
goto
__unlock
;
switch
(
rate
)
{
case
8000
:
val
=
6
;
break
;
case
9600
:
val
=
3
;
break
;
...
...
@@ -1015,10 +1033,13 @@ static void snd_ice1712_set_pro_rate(ice1712_t *ice, snd_pcm_substream_t *substr
break
;
}
outb
(
val
,
ICEMT
(
ice
,
RATE
));
PRO_RATE_LOCKED
=
old_lock_value
;
__unlock:
spin_unlock_irqrestore
(
&
ice
->
reg_lock
,
flags
);
if
(
ice
->
ak4524
.
ops
.
set_rate_val
)
ice
->
ak4524
.
ops
.
set_rate_val
(
ice
,
val
);
ice
->
ak4524
.
ops
.
set_rate_val
(
ice
,
rate
);
}
static
int
snd_ice1712_playback_pro_prepare
(
snd_pcm_substream_t
*
substream
)
...
...
@@ -1027,7 +1048,7 @@ static int snd_ice1712_playback_pro_prepare(snd_pcm_substream_t * substream)
ice1712_t
*
ice
=
snd_pcm_substream_chip
(
substream
);
ice
->
playback_pro_size
=
snd_pcm_lib_buffer_bytes
(
substream
);
snd_ice1712_set_pro_rate
(
ice
,
substream
);
snd_ice1712_set_pro_rate
(
ice
,
substream
->
runtime
->
rate
,
0
);
spin_lock_irqsave
(
&
ice
->
reg_lock
,
flags
);
outl
(
substream
->
runtime
->
dma_addr
,
ICEMT
(
ice
,
PLAYBACK_ADDR
));
outw
((
ice
->
playback_pro_size
>>
2
)
-
1
,
ICEMT
(
ice
,
PLAYBACK_SIZE
));
...
...
@@ -1046,7 +1067,7 @@ static int snd_ice1712_capture_pro_prepare(snd_pcm_substream_t * substream)
ice1712_t
*
ice
=
snd_pcm_substream_chip
(
substream
);
ice
->
capture_pro_size
=
snd_pcm_lib_buffer_bytes
(
substream
);
snd_ice1712_set_pro_rate
(
ice
,
substream
);
snd_ice1712_set_pro_rate
(
ice
,
substream
->
runtime
->
rate
,
0
);
spin_lock_irqsave
(
&
ice
->
reg_lock
,
flags
);
outl
(
substream
->
runtime
->
dma_addr
,
ICEMT
(
ice
,
CAPTURE_ADDR
));
outw
((
ice
->
capture_pro_size
>>
2
)
-
1
,
ICEMT
(
ice
,
CAPTURE_SIZE
));
...
...
@@ -1151,6 +1172,8 @@ static int snd_ice1712_playback_pro_close(snd_pcm_substream_t * substream)
{
ice1712_t
*
ice
=
snd_pcm_substream_chip
(
substream
);
if
(
PRO_RATE_RESET
)
snd_ice1712_set_pro_rate
(
ice
,
PRO_RATE_DEFAULT
,
0
);
ice
->
playback_pro_substream
=
NULL
;
if
(
ice
->
spdif
.
ops
.
close
)
ice
->
spdif
.
ops
.
close
(
ice
,
substream
);
...
...
@@ -1162,6 +1185,8 @@ static int snd_ice1712_capture_pro_close(snd_pcm_substream_t * substream)
{
ice1712_t
*
ice
=
snd_pcm_substream_chip
(
substream
);
if
(
PRO_RATE_RESET
)
snd_ice1712_set_pro_rate
(
ice
,
PRO_RATE_DEFAULT
,
0
);
ice
->
capture_pro_substream
=
NULL
;
return
0
;
}
...
...
@@ -1695,53 +1720,165 @@ int snd_ice1712_gpio_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucont
return
val
!=
nval
;
}
static
int
snd_ice1712_pro_spdif_master_info
(
snd_kcontrol_t
*
kcontrol
,
snd_ctl_elem_info_t
*
uinfo
)
/*
* rate
*/
static
int
snd_ice1712_pro_internal_clock_info
(
snd_kcontrol_t
*
kcontrol
,
snd_ctl_elem_info_t
*
uinfo
)
{
uinfo
->
type
=
SNDRV_CTL_ELEM_TYPE_BOOLEAN
;
static
char
*
texts
[]
=
{
"8000"
,
/* 0: 6 */
"9600"
,
/* 1: 3 */
"11025"
,
/* 2: 10 */
"12000"
,
/* 3: 2 */
"16000"
,
/* 4: 5 */
"22050"
,
/* 5: 9 */
"24000"
,
/* 6: 1 */
"32000"
,
/* 7: 4 */
"44100"
,
/* 8: 8 */
"48000"
,
/* 9: 0 */
"64000"
,
/* 10: 15 */
"88200"
,
/* 11: 11 */
"96000"
,
/* 12: 7 */
"IEC958 Input"
,
/* 13: -- */
};
uinfo
->
type
=
SNDRV_CTL_ELEM_TYPE_ENUMERATED
;
uinfo
->
count
=
1
;
uinfo
->
value
.
integer
.
min
=
0
;
uinfo
->
value
.
integer
.
max
=
1
;
uinfo
->
value
.
enumerated
.
items
=
14
;
if
(
uinfo
->
value
.
enumerated
.
item
>=
uinfo
->
value
.
enumerated
.
items
)
uinfo
->
value
.
enumerated
.
item
=
uinfo
->
value
.
enumerated
.
items
-
1
;
strcpy
(
uinfo
->
value
.
enumerated
.
name
,
texts
[
uinfo
->
value
.
enumerated
.
item
]);
return
0
;
}
static
int
snd_ice1712_pro_
spdif_master
_get
(
snd_kcontrol_t
*
kcontrol
,
snd_ctl_elem_value_t
*
ucontrol
)
static
int
snd_ice1712_pro_
internal_clock
_get
(
snd_kcontrol_t
*
kcontrol
,
snd_ctl_elem_value_t
*
ucontrol
)
{
ice1712_t
*
ice
=
snd_kcontrol_chip
(
kcontrol
);
unsigned
long
flags
;
static
unsigned
char
xlate
[
16
]
=
{
9
,
6
,
3
,
1
,
7
,
4
,
0
,
12
,
8
,
5
,
2
,
11
,
255
,
255
,
255
,
10
};
unsigned
char
val
;
spin_lock_irqsave
(
&
ice
->
reg_lock
,
flags
);
ucontrol
->
value
.
integer
.
value
[
0
]
=
inb
(
ICEMT
(
ice
,
RATE
))
&
ICE1712_SPDIF_MASTER
?
1
:
0
;
spin_unlock_irqrestore
(
&
ice
->
reg_lock
,
flags
);
spin_lock_irq
(
&
ice
->
reg_lock
);
if
(
is_spdif_master
(
ice
))
{
ucontrol
->
value
.
enumerated
.
item
[
0
]
=
13
;
}
else
{
val
=
xlate
[
inb
(
ICEMT
(
ice
,
RATE
))
&
15
];
if
(
val
==
255
)
{
snd_BUG
();
val
=
0
;
}
ucontrol
->
value
.
enumerated
.
item
[
0
]
=
val
;
}
spin_unlock_irq
(
&
ice
->
reg_lock
);
return
0
;
}
static
int
snd_ice1712_pro_
spdif_master
_put
(
snd_kcontrol_t
*
kcontrol
,
snd_ctl_elem_value_t
*
ucontrol
)
static
int
snd_ice1712_pro_
internal_clock
_put
(
snd_kcontrol_t
*
kcontrol
,
snd_ctl_elem_value_t
*
ucontrol
)
{
unsigned
long
flags
;
ice1712_t
*
ice
=
snd_kcontrol_chip
(
kcontrol
);
int
nval
,
change
;
static
unsigned
int
xrate
[
13
]
=
{
8000
,
9600
,
11025
,
12000
,
1600
,
22050
,
24000
,
32000
,
44100
,
48000
,
64000
,
88200
,
96000
};
unsigned
char
oval
;
int
change
=
0
;
nval
=
ucontrol
->
value
.
integer
.
value
[
0
]
?
ICE1712_SPDIF_MASTER
:
0
;
spin_lock_irqsave
(
&
ice
->
reg_lock
,
flags
);
nval
|=
inb
(
ICEMT
(
ice
,
RATE
))
&
~
ICE1712_SPDIF_MASTER
;
change
=
inb
(
ICEMT
(
ice
,
RATE
))
!=
nval
;
outb
(
nval
,
ICEMT
(
ice
,
RATE
));
spin_unlock_irqrestore
(
&
ice
->
reg_lock
,
flags
);
spin_lock_irq
(
&
ice
->
reg_lock
);
oval
=
inb
(
ICEMT
(
ice
,
RATE
));
if
(
ucontrol
->
value
.
enumerated
.
item
[
0
]
==
13
)
{
outb
(
oval
|
ICE1712_SPDIF_MASTER
,
ICEMT
(
ice
,
RATE
));
}
else
{
PRO_RATE_DEFAULT
=
xrate
[
ucontrol
->
value
.
integer
.
value
[
0
]
%
13
];
spin_unlock_irq
(
&
ice
->
reg_lock
);
snd_ice1712_set_pro_rate
(
ice
,
PRO_RATE_DEFAULT
,
1
);
spin_lock_irq
(
&
ice
->
reg_lock
);
}
change
=
inb
(
ICEMT
(
ice
,
RATE
))
!=
oval
;
spin_unlock_irq
(
&
ice
->
reg_lock
);
if
(
ice
->
cs8427
)
{
if
(
(
oval
&
ICE1712_SPDIF_MASTER
)
!=
(
inb
(
ICEMT
(
ice
,
RATE
))
&
ICE1712_SPDIF_MASTER
)
)
{
/* change CS8427 clock source too */
snd_ice1712_cs8427_set_input_clock
(
ice
,
ucontrol
->
value
.
integer
.
value
[
0
]);
if
(
ice
->
cs8427
)
{
snd_ice1712_cs8427_set_input_clock
(
ice
,
is_spdif_master
(
ice
));
}
/* notify ak4524 chip as well */
if
(
is_spdif_master
(
ice
)
&&
ice
->
ak4524
.
ops
.
set_rate_val
)
ice
->
ak4524
.
ops
.
set_rate_val
(
ice
,
0
);
}
return
change
;
}
static
snd_kcontrol_new_t
snd_ice1712_pro_spdif_master
__devinitdata
=
{
static
snd_kcontrol_new_t
snd_ice1712_pro_internal_clock
=
__devinitdata
{
.
iface
=
SNDRV_CTL_ELEM_IFACE_MIXER
,
.
name
=
"Multi Track Internal Clock"
,
.
info
=
snd_ice1712_pro_internal_clock_info
,
.
get
=
snd_ice1712_pro_internal_clock_get
,
.
put
=
snd_ice1712_pro_internal_clock_put
};
static
int
snd_ice1712_pro_rate_locking_info
(
snd_kcontrol_t
*
kcontrol
,
snd_ctl_elem_info_t
*
uinfo
)
{
uinfo
->
type
=
SNDRV_CTL_ELEM_TYPE_BOOLEAN
;
uinfo
->
count
=
1
;
uinfo
->
value
.
integer
.
min
=
0
;
uinfo
->
value
.
integer
.
max
=
1
;
return
0
;
}
static
int
snd_ice1712_pro_rate_locking_get
(
snd_kcontrol_t
*
kcontrol
,
snd_ctl_elem_value_t
*
ucontrol
)
{
ucontrol
->
value
.
integer
.
value
[
0
]
=
PRO_RATE_LOCKED
?
1
:
0
;
return
0
;
}
static
int
snd_ice1712_pro_rate_locking_put
(
snd_kcontrol_t
*
kcontrol
,
snd_ctl_elem_value_t
*
ucontrol
)
{
int
change
=
0
;
change
=
PRO_RATE_LOCKED
?
1
:
0
!=
ucontrol
->
value
.
integer
.
value
[
0
]
?
1
:
0
;
PRO_RATE_LOCKED
=
ucontrol
->
value
.
integer
.
value
[
0
]
?
1
:
0
;
return
change
;
}
static
snd_kcontrol_new_t
snd_ice1712_pro_rate_locking
__devinitdata
=
{
.
iface
=
SNDRV_CTL_ELEM_IFACE_MIXER
,
.
name
=
"Multi Track Rate Locking"
,
.
info
=
snd_ice1712_pro_rate_locking_info
,
.
get
=
snd_ice1712_pro_rate_locking_get
,
.
put
=
snd_ice1712_pro_rate_locking_put
};
static
int
snd_ice1712_pro_rate_reset_info
(
snd_kcontrol_t
*
kcontrol
,
snd_ctl_elem_info_t
*
uinfo
)
{
uinfo
->
type
=
SNDRV_CTL_ELEM_TYPE_BOOLEAN
;
uinfo
->
count
=
1
;
uinfo
->
value
.
integer
.
min
=
0
;
uinfo
->
value
.
integer
.
max
=
1
;
return
0
;
}
static
int
snd_ice1712_pro_rate_reset_get
(
snd_kcontrol_t
*
kcontrol
,
snd_ctl_elem_value_t
*
ucontrol
)
{
ucontrol
->
value
.
integer
.
value
[
0
]
=
PRO_RATE_RESET
?
1
:
0
;
return
0
;
}
static
int
snd_ice1712_pro_rate_reset_put
(
snd_kcontrol_t
*
kcontrol
,
snd_ctl_elem_value_t
*
ucontrol
)
{
int
change
=
0
;
change
=
PRO_RATE_LOCKED
?
1
:
0
!=
ucontrol
->
value
.
integer
.
value
[
0
]
?
1
:
0
;
PRO_RATE_RESET
=
ucontrol
->
value
.
integer
.
value
[
0
]
?
1
:
0
;
return
change
;
}
static
snd_kcontrol_new_t
snd_ice1712_pro_rate_reset
__devinitdata
=
{
.
iface
=
SNDRV_CTL_ELEM_IFACE_MIXER
,
.
name
=
"Multi Track
IEC958 Master
"
,
.
info
=
snd_ice1712_pro_
spdif_master
_info
,
.
get
=
snd_ice1712_pro_
spdif_master
_get
,
.
put
=
snd_ice1712_pro_
spdif_master
_put
.
name
=
"Multi Track
Rate Reset
"
,
.
info
=
snd_ice1712_pro_
rate_reset
_info
,
.
get
=
snd_ice1712_pro_
rate_reset
_get
,
.
put
=
snd_ice1712_pro_
rate_reset
_put
};
/*
...
...
@@ -2113,7 +2250,13 @@ static int __devinit snd_ice1712_build_controls(ice1712_t *ice)
err
=
snd_ctl_add
(
ice
->
card
,
snd_ctl_new1
(
&
snd_ice1712_eeprom
,
ice
));
if
(
err
<
0
)
return
err
;
err
=
snd_ctl_add
(
ice
->
card
,
snd_ctl_new1
(
&
snd_ice1712_pro_spdif_master
,
ice
));
err
=
snd_ctl_add
(
ice
->
card
,
snd_ctl_new1
(
&
snd_ice1712_pro_internal_clock
,
ice
));
if
(
err
<
0
)
return
err
;
err
=
snd_ctl_add
(
ice
->
card
,
snd_ctl_new1
(
&
snd_ice1712_pro_rate_locking
,
ice
));
if
(
err
<
0
)
return
err
;
err
=
snd_ctl_add
(
ice
->
card
,
snd_ctl_new1
(
&
snd_ice1712_pro_rate_reset
,
ice
));
if
(
err
<
0
)
return
err
;
for
(
idx
=
0
;
idx
<
ice
->
num_total_dacs
;
idx
++
)
{
...
...
@@ -2283,7 +2426,7 @@ static int __devinit snd_ice1712_create(snd_card_t * card,
/*
*
* Registraton
* Registrat
i
on
*
*/
...
...
sound/pci/ice1712/ice1712.h
View file @
2f2fc324
...
...
@@ -256,7 +256,7 @@ struct snd_ak4524 {
struct
snd_ak4524_ops
{
int
(
*
start
)(
ice1712_t
*
,
unsigned
char
*
,
int
);
void
(
*
stop
)(
ice1712_t
*
,
unsigned
char
*
);
void
(
*
set_rate_val
)(
ice1712_t
*
,
unsigned
char
);
void
(
*
set_rate_val
)(
ice1712_t
*
,
unsigned
int
);
}
ops
;
};
...
...
sound/pci/rme9652/hammerfall_mem.c
View file @
2f2fc324
...
...
@@ -178,7 +178,7 @@ void snd_hammerfall_free_buffer (struct pci_dev *pcidev, void *addr)
printk
(
"Hammerfall memory allocator: unknown buffer address or PCI device ID"
);
}
static
void
hammerfall_free_buffers
(
void
)
static
void
__exit
hammerfall_free_buffers
(
void
)
{
int
i
;
...
...
sound/pci/trident/trident.c
View file @
2f2fc324
...
...
@@ -85,7 +85,7 @@ static int __devinit snd_trident_probe(struct pci_dev *pci,
snd_card_t
*
card
;
trident_t
*
trident
;
const
char
*
str
;
int
err
;
int
err
,
pcm_dev
=
0
;
if
(
dev
>=
SNDRV_CARDS
)
return
-
ENODEV
;
...
...
@@ -106,21 +106,21 @@ static int __devinit snd_trident_probe(struct pci_dev *pci,
snd_card_free
(
card
);
return
err
;
}
if
((
err
=
snd_trident_pcm
(
trident
,
0
,
NULL
))
<
0
)
{
if
((
err
=
snd_trident_pcm
(
trident
,
pcm_dev
++
,
NULL
))
<
0
)
{
snd_card_free
(
card
);
return
err
;
}
switch
(
trident
->
device
)
{
case
TRIDENT_DEVICE_ID_DX
:
case
TRIDENT_DEVICE_ID_NX
:
if
((
err
=
snd_trident_foldback_pcm
(
trident
,
1
,
NULL
))
<
0
)
{
if
((
err
=
snd_trident_foldback_pcm
(
trident
,
pcm_dev
++
,
NULL
))
<
0
)
{
snd_card_free
(
card
);
return
err
;
}
break
;
}
if
(
trident
->
device
==
TRIDENT_DEVICE_ID_NX
)
{
if
((
err
=
snd_trident_spdif_pcm
(
trident
,
2
,
NULL
))
<
0
)
{
if
(
trident
->
device
==
TRIDENT_DEVICE_ID_NX
||
trident
->
device
==
TRIDENT_DEVICE_ID_SI7018
)
{
if
((
err
=
snd_trident_spdif_pcm
(
trident
,
pcm_dev
++
,
NULL
))
<
0
)
{
snd_card_free
(
card
);
return
err
;
}
...
...
sound/pci/trident/trident_main.c
View file @
2f2fc324
...
...
@@ -23,6 +23,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*
* SiS7018 S/PDIF support by Thomas Winischhofer <thomas@winischhofer.net>
*/
#include <sound/driver.h>
...
...
@@ -52,6 +54,7 @@ static void snd_trident_interrupt(int irq, void *dev_id, struct pt_regs *regs);
#ifdef CONFIG_PM
static
int
snd_trident_set_power_state
(
snd_card_t
*
card
,
unsigned
int
power_state
);
#endif
static
int
snd_trident_sis_reset
(
trident_t
*
trident
);
/*
* common I/O routines
...
...
@@ -149,7 +152,7 @@ static unsigned short snd_trident_codec_read(ac97_t *ac97, unsigned short reg)
}
while
(
--
count
);
}
if
(
count
==
0
)
{
if
(
count
==
0
&&
!
trident
->
ac97_detect
)
{
snd_printk
(
"ac97 codec read TIMEOUT [0x%x/0x%x]!!!
\n
"
,
reg
,
data
);
data
=
0
;
}
...
...
@@ -477,6 +480,15 @@ void snd_trident_write_voice_regs(trident_t * trident,
outl
(
regs
[
2
],
TRID_REG
(
trident
,
CH_START
+
8
));
outl
(
regs
[
3
],
TRID_REG
(
trident
,
CH_START
+
12
));
outl
(
regs
[
4
],
TRID_REG
(
trident
,
CH_START
+
16
));
#if 0
printk("written %i channel:\n", voice->number);
printk(" regs[0] = 0x%x/0x%x\n", regs[0], inl(TRID_REG(trident, CH_START + 0)));
printk(" regs[1] = 0x%x/0x%x\n", regs[1], inl(TRID_REG(trident, CH_START + 4)));
printk(" regs[2] = 0x%x/0x%x\n", regs[2], inl(TRID_REG(trident, CH_START + 8)));
printk(" regs[3] = 0x%x/0x%x\n", regs[3], inl(TRID_REG(trident, CH_START + 12)));
printk(" regs[4] = 0x%x/0x%x\n", regs[4], inl(TRID_REG(trident, CH_START + 16)));
#endif
}
/*---------------------------------------------------------------------------
...
...
@@ -727,9 +739,9 @@ static int snd_trident_ioctl(snd_pcm_substream_t * substream,
}
/*---------------------------------------------------------------------------
snd_trident_
playback_hw_params
snd_trident_
allocate_pcm_mem
Description:
Set the hardware parameters for the playback device.
Description:
Allocate PCM ring buffer for given substream
Parameters: substream - PCM substream class
hw_params - hardware parameters
...
...
@@ -738,14 +750,12 @@ static int snd_trident_ioctl(snd_pcm_substream_t * substream,
---------------------------------------------------------------------------*/
static
int
snd_trident_playback_hw_params
(
snd_pcm_substream_t
*
substream
,
snd_pcm_hw_params_t
*
hw_params
)
int
snd_trident_allocate_pcm_mem
(
snd_pcm_substream_t
*
substream
,
snd_pcm_hw_params_t
*
hw_params
)
{
trident_t
*
trident
=
snd_pcm_substream_chip
(
substream
);
snd_pcm_runtime_t
*
runtime
=
substream
->
runtime
;
snd_trident_voice_t
*
voice
=
(
snd_trident_voice_t
*
)
runtime
->
private_data
;
snd_trident_voice_t
*
evoice
=
voice
->
extra
;
unsigned
long
flags
;
int
err
;
if
((
err
=
snd_pcm_lib_malloc_pages
(
substream
,
params_buffer_bytes
(
hw_params
)))
<
0
)
...
...
@@ -753,16 +763,38 @@ static int snd_trident_playback_hw_params(snd_pcm_substream_t * substream,
if
(
err
>
0
&&
trident
->
tlb
.
entries
)
{
if
(
voice
->
memblk
)
snd_trident_free_pages
(
trident
,
voice
->
memblk
);
spin_lock_irq
save
(
&
trident
->
reg_lock
,
flags
);
spin_lock_irq
(
&
trident
->
reg_lock
);
voice
->
memblk
=
snd_trident_alloc_pages
(
trident
,
runtime
->
dma_area
,
runtime
->
dma_addr
,
runtime
->
dma_bytes
);
spin_unlock_irq
restore
(
&
trident
->
reg_lock
,
flags
);
spin_unlock_irq
(
&
trident
->
reg_lock
);
if
(
voice
->
memblk
==
NULL
)
return
-
ENOMEM
;
}
return
0
;
}
/*---------------------------------------------------------------------------
snd_trident_allocate_evoice
Description: Allocate extra voice as interrupt generator
Parameters: substream - PCM substream class
hw_params - hardware parameters
Returns: Error status
---------------------------------------------------------------------------*/
int
snd_trident_allocate_evoice
(
snd_pcm_substream_t
*
substream
,
snd_pcm_hw_params_t
*
hw_params
)
{
trident_t
*
trident
=
snd_pcm_substream_chip
(
substream
);
snd_pcm_runtime_t
*
runtime
=
substream
->
runtime
;
snd_trident_voice_t
*
voice
=
(
snd_trident_voice_t
*
)
runtime
->
private_data
;
snd_trident_voice_t
*
evoice
=
voice
->
extra
;
/* voice management */
if
(
params_buffer_size
(
hw_params
)
/
2
!=
params_
period
_size
(
hw_params
))
{
if
(
params_buffer_size
(
hw_params
)
/
2
!=
params_
buffer
_size
(
hw_params
))
{
if
(
evoice
==
NULL
)
{
evoice
=
snd_trident_alloc_voice
(
trident
,
SNDRV_TRIDENT_VOICE_TYPE_PCM
,
0
,
0
);
if
(
evoice
==
NULL
)
...
...
@@ -780,6 +812,29 @@ static int snd_trident_playback_hw_params(snd_pcm_substream_t * substream,
return
0
;
}
/*---------------------------------------------------------------------------
snd_trident_hw_params
Description: Set the hardware parameters for the playback device.
Parameters: substream - PCM substream class
hw_params - hardware parameters
Returns: Error status
---------------------------------------------------------------------------*/
static
int
snd_trident_hw_params
(
snd_pcm_substream_t
*
substream
,
snd_pcm_hw_params_t
*
hw_params
)
{
int
err
;
err
=
snd_trident_allocate_pcm_mem
(
substream
,
hw_params
);
if
(
err
>=
0
)
err
=
snd_trident_allocate_evoice
(
substream
,
hw_params
);
return
err
;
}
/*---------------------------------------------------------------------------
snd_trident_playback_hw_free
...
...
@@ -791,7 +846,7 @@ static int snd_trident_playback_hw_params(snd_pcm_substream_t * substream,
---------------------------------------------------------------------------*/
static
int
snd_trident_
playback_
hw_free
(
snd_pcm_substream_t
*
substream
)
static
int
snd_trident_hw_free
(
snd_pcm_substream_t
*
substream
)
{
trident_t
*
trident
=
snd_pcm_substream_chip
(
substream
);
snd_pcm_runtime_t
*
runtime
=
substream
->
runtime
;
...
...
@@ -828,9 +883,8 @@ static int snd_trident_playback_prepare(snd_pcm_substream_t * substream)
snd_trident_voice_t
*
voice
=
(
snd_trident_voice_t
*
)
runtime
->
private_data
;
snd_trident_voice_t
*
evoice
=
voice
->
extra
;
snd_trident_pcm_mixer_t
*
mix
=
&
trident
->
pcm_mixer
[
substream
->
number
];
unsigned
long
flags
;
spin_lock
_irqsave
(
&
trident
->
reg_lock
,
flags
);
spin_lock
(
&
trident
->
reg_lock
);
/* set delta (rate) value */
voice
->
Delta
=
snd_trident_convert_rate
(
runtime
->
rate
);
...
...
@@ -855,6 +909,12 @@ static int snd_trident_playback_prepare(snd_pcm_substream_t * substream)
voice
->
CVol
=
mix
->
cvol
;
voice
->
Pan
=
mix
->
pan
;
voice
->
Attribute
=
0
;
#if 0
voice->Attribute = (1<<(30-16))|(2<<(26-16))|
(0<<(24-16))|(0x1f<<(19-16));
#else
voice
->
Attribute
=
0
;
#endif
snd_trident_write_voice_regs
(
trident
,
voice
);
...
...
@@ -875,14 +935,14 @@ static int snd_trident_playback_prepare(snd_pcm_substream_t * substream)
evoice
->
Pan
=
0x7f
;
/* mute */
#if 0
evoice->Attribute = (1<<(30-16))|(2<<(26-16))|
(
1
<<(24-16))|(0x1f<<(19-16));
(
0
<<(24-16))|(0x1f<<(19-16));
#else
evoice
->
Attribute
=
0
;
#endif
snd_trident_write_voice_regs
(
trident
,
evoice
);
}
spin_unlock
_irqrestore
(
&
trident
->
reg_lock
,
flags
);
spin_unlock
(
&
trident
->
reg_lock
);
return
0
;
}
...
...
@@ -902,49 +962,7 @@ static int snd_trident_playback_prepare(snd_pcm_substream_t * substream)
static
int
snd_trident_capture_hw_params
(
snd_pcm_substream_t
*
substream
,
snd_pcm_hw_params_t
*
hw_params
)
{
trident_t
*
trident
=
snd_pcm_substream_chip
(
substream
);
snd_pcm_runtime_t
*
runtime
=
substream
->
runtime
;
snd_trident_voice_t
*
voice
=
(
snd_trident_voice_t
*
)
runtime
->
private_data
;
unsigned
long
flags
;
int
err
;
if
((
err
=
snd_pcm_lib_malloc_pages
(
substream
,
params_buffer_bytes
(
hw_params
)))
<
0
)
return
err
;
if
(
err
>
0
&&
trident
->
tlb
.
entries
)
{
if
(
voice
->
memblk
)
snd_trident_free_pages
(
trident
,
voice
->
memblk
);
spin_lock_irqsave
(
&
trident
->
reg_lock
,
flags
);
voice
->
memblk
=
snd_trident_alloc_pages
(
trident
,
runtime
->
dma_area
,
runtime
->
dma_addr
,
runtime
->
dma_bytes
);
spin_unlock_irqrestore
(
&
trident
->
reg_lock
,
flags
);
if
(
voice
->
memblk
==
NULL
)
return
-
ENOMEM
;
}
return
0
;
}
/*---------------------------------------------------------------------------
snd_trident_capture_hw_free
Description: Release the hardware resources for the capture device.
Parameters: substream - PCM substream class
Returns: Error status
---------------------------------------------------------------------------*/
static
int
snd_trident_capture_hw_free
(
snd_pcm_substream_t
*
substream
)
{
trident_t
*
trident
=
snd_pcm_substream_chip
(
substream
);
snd_pcm_runtime_t
*
runtime
=
substream
->
runtime
;
snd_trident_voice_t
*
voice
=
(
snd_trident_voice_t
*
)
runtime
->
private_data
;
if
(
trident
->
tlb
.
entries
&&
voice
&&
voice
->
memblk
)
{
snd_trident_free_pages
(
trident
,
voice
->
memblk
);
voice
->
memblk
=
NULL
;
}
snd_pcm_lib_free_pages
(
substream
);
return
0
;
return
snd_trident_allocate_pcm_mem
(
substream
,
hw_params
);
}
/*---------------------------------------------------------------------------
...
...
@@ -964,9 +982,8 @@ static int snd_trident_capture_prepare(snd_pcm_substream_t * substream)
snd_pcm_runtime_t
*
runtime
=
substream
->
runtime
;
snd_trident_voice_t
*
voice
=
(
snd_trident_voice_t
*
)
runtime
->
private_data
;
unsigned
int
val
,
ESO_bytes
;
unsigned
long
flags
;
spin_lock
_irqsave
(
&
trident
->
reg_lock
,
flags
);
spin_lock
(
&
trident
->
reg_lock
);
// Initilize the channel and set channel Mode
outb
(
0
,
TRID_REG
(
trident
,
LEGACY_DMAR15
));
...
...
@@ -1037,7 +1054,7 @@ static int snd_trident_capture_prepare(snd_pcm_substream_t * substream)
snd_trident_write_voice_regs
(
trident
,
voice
);
spin_unlock
_irqrestore
(
&
trident
->
reg_lock
,
flags
);
spin_unlock
(
&
trident
->
reg_lock
);
return
0
;
}
...
...
@@ -1056,33 +1073,12 @@ static int snd_trident_capture_prepare(snd_pcm_substream_t * substream)
static
int
snd_trident_si7018_capture_hw_params
(
snd_pcm_substream_t
*
substream
,
snd_pcm_hw_params_t
*
hw_params
)
{
trident_t
*
trident
=
snd_pcm_substream_chip
(
substream
);
snd_pcm_runtime_t
*
runtime
=
substream
->
runtime
;
snd_trident_voice_t
*
voice
=
(
snd_trident_voice_t
*
)
runtime
->
private_data
;
snd_trident_voice_t
*
evoice
=
voice
->
extra
;
int
err
;
if
((
err
=
snd_pcm_lib_malloc_pages
(
substream
,
params_buffer_bytes
(
hw_params
)))
<
0
)
return
err
;
/* voice management */
if
(
params_buffer_size
(
hw_params
)
/
2
!=
params_period_size
(
hw_params
))
{
if
(
evoice
==
NULL
)
{
evoice
=
snd_trident_alloc_voice
(
trident
,
SNDRV_TRIDENT_VOICE_TYPE_PCM
,
0
,
0
);
if
(
evoice
==
NULL
)
return
-
ENOMEM
;
voice
->
extra
=
evoice
;
evoice
->
substream
=
substream
;
}
}
else
{
if
(
evoice
!=
NULL
)
{
snd_trident_free_voice
(
trident
,
evoice
);
voice
->
extra
=
evoice
=
NULL
;
}
}
return
0
;
return
snd_trident_allocate_evoice
(
substream
,
hw_params
);
}
/*---------------------------------------------------------------------------
...
...
@@ -1128,9 +1124,8 @@ static int snd_trident_si7018_capture_prepare(snd_pcm_substream_t * substream)
snd_pcm_runtime_t
*
runtime
=
substream
->
runtime
;
snd_trident_voice_t
*
voice
=
(
snd_trident_voice_t
*
)
runtime
->
private_data
;
snd_trident_voice_t
*
evoice
=
voice
->
extra
;
unsigned
long
flags
;
spin_lock
_irqsave
(
&
trident
->
reg_lock
,
flags
);
spin_lock
(
&
trident
->
reg_lock
);
voice
->
LBA
=
runtime
->
dma_addr
;
voice
->
Delta
=
snd_trident_convert_adc_rate
(
runtime
->
rate
);
...
...
@@ -1176,91 +1171,7 @@ static int snd_trident_si7018_capture_prepare(snd_pcm_substream_t * substream)
snd_trident_write_voice_regs
(
trident
,
evoice
);
}
spin_unlock_irqrestore
(
&
trident
->
reg_lock
,
flags
);
return
0
;
}
/*---------------------------------------------------------------------------
snd_trident_foldback_hw_params
Description: Set the hardware parameters for the foldback device.
Parameters: substream - PCM substream class
hw_params - hardware parameters
Returns: Error status
---------------------------------------------------------------------------*/
static
int
snd_trident_foldback_hw_params
(
snd_pcm_substream_t
*
substream
,
snd_pcm_hw_params_t
*
hw_params
)
{
trident_t
*
trident
=
snd_pcm_substream_chip
(
substream
);
snd_pcm_runtime_t
*
runtime
=
substream
->
runtime
;
snd_trident_voice_t
*
voice
=
(
snd_trident_voice_t
*
)
runtime
->
private_data
;
snd_trident_voice_t
*
evoice
=
voice
->
extra
;
unsigned
long
flags
;
int
err
;
if
((
err
=
snd_pcm_lib_malloc_pages
(
substream
,
params_buffer_bytes
(
hw_params
)))
<
0
)
return
err
;
if
(
err
>
0
&&
trident
->
tlb
.
entries
)
{
if
(
voice
->
memblk
)
snd_trident_free_pages
(
trident
,
voice
->
memblk
);
spin_lock_irqsave
(
&
trident
->
reg_lock
,
flags
);
voice
->
memblk
=
snd_trident_alloc_pages
(
trident
,
runtime
->
dma_area
,
runtime
->
dma_addr
,
runtime
->
dma_bytes
);
spin_unlock_irqrestore
(
&
trident
->
reg_lock
,
flags
);
if
(
voice
->
memblk
==
NULL
)
return
-
ENOMEM
;
}
/* voice management */
if
(
params_buffer_size
(
hw_params
)
/
2
!=
params_buffer_size
(
hw_params
))
{
if
(
evoice
==
NULL
)
{
evoice
=
snd_trident_alloc_voice
(
trident
,
SNDRV_TRIDENT_VOICE_TYPE_PCM
,
0
,
0
);
if
(
evoice
==
NULL
)
return
-
ENOMEM
;
voice
->
extra
=
evoice
;
evoice
->
substream
=
substream
;
}
}
else
{
if
(
evoice
!=
NULL
)
{
snd_trident_free_voice
(
trident
,
evoice
);
voice
->
extra
=
evoice
=
NULL
;
}
}
return
0
;
}
/*---------------------------------------------------------------------------
snd_trident_foldback_hw_free
Description: Release the hardware resources for the foldback device.
Parameters: substream - PCM substream class
Returns: Error status
---------------------------------------------------------------------------*/
static
int
snd_trident_foldback_hw_free
(
snd_pcm_substream_t
*
substream
)
{
trident_t
*
trident
=
snd_pcm_substream_chip
(
substream
);
snd_pcm_runtime_t
*
runtime
=
substream
->
runtime
;
snd_trident_voice_t
*
voice
=
(
snd_trident_voice_t
*
)
runtime
->
private_data
;
snd_trident_voice_t
*
evoice
=
voice
?
voice
->
extra
:
NULL
;
if
(
trident
->
tlb
.
entries
&&
voice
&&
voice
->
memblk
)
{
snd_trident_free_pages
(
trident
,
voice
->
memblk
);
voice
->
memblk
=
NULL
;
}
snd_pcm_lib_free_pages
(
substream
);
if
(
evoice
!=
NULL
)
{
snd_trident_free_voice
(
trident
,
evoice
);
voice
->
extra
=
NULL
;
}
spin_unlock
(
&
trident
->
reg_lock
);
return
0
;
}
...
...
@@ -1281,9 +1192,8 @@ static int snd_trident_foldback_prepare(snd_pcm_substream_t * substream)
snd_pcm_runtime_t
*
runtime
=
substream
->
runtime
;
snd_trident_voice_t
*
voice
=
(
snd_trident_voice_t
*
)
runtime
->
private_data
;
snd_trident_voice_t
*
evoice
=
voice
->
extra
;
unsigned
long
flags
;
spin_lock
_irqsave
(
&
trident
->
reg_lock
,
flags
);
spin_lock
(
&
trident
->
reg_lock
);
/* Set channel buffer Address */
if
(
voice
->
memblk
)
...
...
@@ -1335,7 +1245,7 @@ static int snd_trident_foldback_prepare(snd_pcm_substream_t * substream)
snd_trident_write_voice_regs
(
trident
,
evoice
);
}
spin_unlock
_irqrestore
(
&
trident
->
reg_lock
,
flags
);
spin_unlock
(
&
trident
->
reg_lock
);
return
0
;
}
...
...
@@ -1355,26 +1265,21 @@ static int snd_trident_spdif_hw_params(snd_pcm_substream_t * substream,
snd_pcm_hw_params_t
*
hw_params
)
{
trident_t
*
trident
=
snd_pcm_substream_chip
(
substream
);
snd_pcm_runtime_t
*
runtime
=
substream
->
runtime
;
snd_trident_voice_t
*
voice
=
(
snd_trident_voice_t
*
)
runtime
->
private_data
;
unsigned
long
flags
;
unsigned
int
old_bits
=
0
,
change
=
0
;
int
err
;
if
((
err
=
snd_pcm_lib_malloc_pages
(
substream
,
params_buffer_bytes
(
hw_params
)))
<
0
)
err
=
snd_trident_allocate_pcm_mem
(
substream
,
hw_params
);
if
(
err
<
0
)
return
err
;
if
(
err
>
0
&&
trident
->
tlb
.
entries
)
{
if
(
voice
->
memblk
)
snd_trident_free_pages
(
trident
,
voice
->
memblk
);
spin_lock_irqsave
(
&
trident
->
reg_lock
,
flags
);
voice
->
memblk
=
snd_trident_alloc_pages
(
trident
,
runtime
->
dma_area
,
runtime
->
dma_addr
,
runtime
->
dma_bytes
);
spin_unlock_irqrestore
(
&
trident
->
reg_lock
,
flags
);
if
(
voice
->
memblk
==
NULL
)
return
-
ENOMEM
;
if
(
trident
->
device
==
TRIDENT_DEVICE_ID_SI7018
)
{
err
=
snd_trident_allocate_evoice
(
substream
,
hw_params
);
if
(
err
<
0
)
return
err
;
}
/* prepare SPDIF channel */
spin_lock_irq
save
(
&
trident
->
reg_lock
,
flags
);
spin_lock_irq
(
&
trident
->
reg_lock
);
old_bits
=
trident
->
spdif_pcm_bits
;
if
(
old_bits
&
IEC958_AES0_PROFESSIONAL
)
trident
->
spdif_pcm_bits
&=
~
IEC958_AES0_PRO_FS
;
...
...
@@ -1402,7 +1307,7 @@ static int snd_trident_spdif_hw_params(snd_pcm_substream_t * substream,
(
IEC958_AES3_CON_FS_32000
<<
24
);
}
change
=
old_bits
!=
trident
->
spdif_pcm_bits
;
spin_unlock_irq
restore
(
&
trident
->
reg_lock
,
flags
);
spin_unlock_irq
(
&
trident
->
reg_lock
);
if
(
change
)
snd_ctl_notify
(
trident
->
card
,
SNDRV_CTL_EVENT_MASK_VALUE
,
&
trident
->
spdif_pcm_ctl
->
id
);
...
...
@@ -1410,31 +1315,6 @@ static int snd_trident_spdif_hw_params(snd_pcm_substream_t * substream,
return
0
;
}
/*---------------------------------------------------------------------------
snd_trident_spdif_hw_free
Description: Release the hardware resources for the spdif device.
Parameters: substream - PCM substream class
Returns: Error status
---------------------------------------------------------------------------*/
static
int
snd_trident_spdif_hw_free
(
snd_pcm_substream_t
*
substream
)
{
trident_t
*
trident
=
snd_pcm_substream_chip
(
substream
);
snd_pcm_runtime_t
*
runtime
=
substream
->
runtime
;
snd_trident_voice_t
*
voice
=
(
snd_trident_voice_t
*
)
runtime
->
private_data
;
if
(
trident
->
tlb
.
entries
&&
voice
&&
voice
->
memblk
)
{
snd_trident_free_pages
(
trident
,
voice
->
memblk
);
voice
->
memblk
=
NULL
;
}
snd_pcm_lib_free_pages
(
substream
);
return
0
;
}
/*---------------------------------------------------------------------------
snd_trident_spdif_prepare
...
...
@@ -1451,55 +1331,116 @@ static int snd_trident_spdif_prepare(snd_pcm_substream_t * substream)
trident_t
*
trident
=
snd_pcm_substream_chip
(
substream
);
snd_pcm_runtime_t
*
runtime
=
substream
->
runtime
;
snd_trident_voice_t
*
voice
=
(
snd_trident_voice_t
*
)
runtime
->
private_data
;
snd_trident_voice_t
*
evoice
=
voice
->
extra
;
snd_trident_pcm_mixer_t
*
mix
=
&
trident
->
pcm_mixer
[
substream
->
number
];
unsigned
int
RESO
,
LBAO
;
unsigned
long
flags
;
spin_lock_irqsave
(
&
trident
->
reg_lock
,
flags
);
unsigned
int
temp
;
/* set delta (rate) value */
voice
->
Delta
=
snd_trident_convert_rate
(
runtime
->
rate
);
voice
->
spurious_threshold
=
snd_trident_spurious_threshold
(
runtime
->
rate
,
runtime
->
period_size
);
spin_lock
(
&
trident
->
reg_lock
);
/* set Loop Back Address */
LBAO
=
runtime
->
dma_addr
;
if
(
voice
->
memblk
)
voice
->
LBA
=
voice
->
memblk
->
offset
;
else
voice
->
LBA
=
LBAO
;
if
(
trident
->
device
!=
TRIDENT_DEVICE_ID_SI7018
)
{
/* set target ESO for channel
*/
RESO
=
runtime
->
buffer_size
-
1
;
voice
->
ESO
=
(
runtime
->
period_size
*
2
)
-
1
;
/* set delta (rate) value
*/
voice
->
Delta
=
snd_trident_convert_rate
(
runtime
->
rate
)
;
voice
->
spurious_threshold
=
snd_trident_spurious_threshold
(
runtime
->
rate
,
runtime
->
period_size
)
;
/* set ctrl mode */
voice
->
CTRL
=
snd_trident_control_mode
(
substream
);
/* set Loop Back Address */
LBAO
=
runtime
->
dma_addr
;
if
(
voice
->
memblk
)
voice
->
LBA
=
voice
->
memblk
->
offset
;
else
voice
->
LBA
=
LBAO
;
/* set target ESO for channel */
RESO
=
runtime
->
buffer_size
-
1
;
voice
->
ESO
=
(
runtime
->
period_size
*
2
)
-
1
;
/* set ctrl mode */
voice
->
CTRL
=
snd_trident_control_mode
(
substream
);
voice
->
FMC
=
3
;
voice
->
RVol
=
0x7f
;
voice
->
CVol
=
0x7f
;
voice
->
GVSel
=
1
;
voice
->
Pan
=
0x7f
;
voice
->
Vol
=
0x3ff
;
voice
->
EC
=
0
;
voice
->
CSO
=
0
;
voice
->
Alpha
=
0
;
voice
->
FMS
=
0
;
voice
->
Attribute
=
0
;
/* prepare surrogate IRQ channel */
snd_trident_write_voice_regs
(
trident
,
voice
);
outw
((
RESO
&
0xffff
),
TRID_REG
(
trident
,
NX_SPESO
));
outb
((
RESO
>>
16
),
TRID_REG
(
trident
,
NX_SPESO
+
2
));
outl
((
LBAO
&
0xfffffffc
),
TRID_REG
(
trident
,
NX_SPLBA
));
outw
((
voice
->
CSO
&
0xffff
),
TRID_REG
(
trident
,
NX_SPCTRL_SPCSO
));
outb
((
voice
->
CSO
>>
16
),
TRID_REG
(
trident
,
NX_SPCTRL_SPCSO
+
2
));
/* set SPDIF setting */
outb
(
trident
->
spdif_pcm_ctrl
,
TRID_REG
(
trident
,
NX_SPCTRL_SPCSO
+
3
));
outl
(
trident
->
spdif_pcm_bits
,
TRID_REG
(
trident
,
NX_SPCSTATUS
));
voice
->
FMC
=
3
;
voice
->
RVol
=
0x7f
;
voice
->
CVol
=
0x7f
;
voice
->
GVSel
=
1
;
voice
->
Pan
=
0x7f
;
voice
->
Vol
=
0x3ff
;
voice
->
EC
=
0
;
voice
->
CSO
=
0
;
voice
->
Alpha
=
0
;
voice
->
FMS
=
0
;
voice
->
Attribute
=
0
;
}
else
{
/* SiS */
/* set delta (rate) value */
voice
->
Delta
=
0x800
;
voice
->
spurious_threshold
=
snd_trident_spurious_threshold
(
48000
,
runtime
->
period_size
);
/* prepare surrogate IRQ channel */
snd_trident_write_voice_regs
(
trident
,
voice
);
/* set Loop Begin Address */
if
(
voice
->
memblk
)
voice
->
LBA
=
voice
->
memblk
->
offset
;
else
voice
->
LBA
=
runtime
->
dma_addr
;
voice
->
CSO
=
0
;
voice
->
ESO
=
runtime
->
buffer_size
-
1
;
/* in samples */
voice
->
CTRL
=
snd_trident_control_mode
(
substream
);
voice
->
FMC
=
3
;
voice
->
GVSel
=
1
;
voice
->
EC
=
0
;
voice
->
Alpha
=
0
;
voice
->
FMS
=
0
;
voice
->
Vol
=
mix
->
vol
;
voice
->
RVol
=
mix
->
rvol
;
voice
->
CVol
=
mix
->
cvol
;
voice
->
Pan
=
mix
->
pan
;
voice
->
Attribute
=
(
1
<<
(
30
-
16
))
|
(
7
<<
(
26
-
16
))
|
(
0
<<
(
24
-
16
))
|
(
0
<<
(
19
-
16
));
snd_trident_write_voice_regs
(
trident
,
voice
);
outw
((
RESO
&
0xffff
),
TRID_REG
(
trident
,
NX_SPESO
));
outb
((
RESO
>>
16
),
TRID_REG
(
trident
,
NX_SPESO
+
2
));
outl
((
LBAO
&
0xfffffffc
),
TRID_REG
(
trident
,
NX_SPLBA
));
outw
((
voice
->
CSO
&
0xffff
),
TRID_REG
(
trident
,
NX_SPCTRL_SPCSO
));
outb
((
voice
->
CSO
>>
16
),
TRID_REG
(
trident
,
NX_SPCTRL_SPCSO
+
2
));
if
(
evoice
!=
NULL
)
{
evoice
->
Delta
=
voice
->
Delta
;
evoice
->
spurious_threshold
=
voice
->
spurious_threshold
;
evoice
->
LBA
=
voice
->
LBA
;
evoice
->
CSO
=
0
;
evoice
->
ESO
=
(
runtime
->
period_size
*
2
)
-
1
;
/* in samples */
evoice
->
CTRL
=
voice
->
CTRL
;
evoice
->
FMC
=
3
;
evoice
->
GVSel
=
trident
->
device
==
TRIDENT_DEVICE_ID_SI7018
?
0
:
1
;
evoice
->
EC
=
0
;
evoice
->
Alpha
=
0
;
evoice
->
FMS
=
0
;
evoice
->
Vol
=
0x3ff
;
/* mute */
evoice
->
RVol
=
evoice
->
CVol
=
0x7f
;
/* mute */
evoice
->
Pan
=
0x7f
;
/* mute */
evoice
->
Attribute
=
0
;
snd_trident_write_voice_regs
(
trident
,
evoice
);
}
/* set SPDIF setting */
outb
(
trident
->
spdif_pcm_ctrl
,
TRID_REG
(
trident
,
NX_SPCTRL_SPCSO
+
3
));
outl
(
trident
->
spdif_pcm_bits
,
TRID_REG
(
trident
,
NX_SPCSTATUS
));
outl
(
trident
->
spdif_pcm_bits
,
TRID_REG
(
trident
,
SI_SPDIF_CS
));
temp
=
inl
(
TRID_REG
(
trident
,
T4D_LFO_GC_CIR
));
temp
&=
~
(
1
<<
19
);
outl
(
temp
,
TRID_REG
(
trident
,
T4D_LFO_GC_CIR
));
temp
=
inl
(
TRID_REG
(
trident
,
SI_SERIAL_INTF_CTRL
));
temp
|=
SPDIF_EN
;
outl
(
temp
,
TRID_REG
(
trident
,
SI_SERIAL_INTF_CTRL
));
}
spin_unlock
_irqrestore
(
&
trident
->
reg_lock
,
flags
);
spin_unlock
(
&
trident
->
reg_lock
);
return
0
;
}
...
...
@@ -1570,8 +1511,14 @@ static int snd_trident_trigger(snd_pcm_substream_t *substream,
s
=
s
->
link_next
;
}
while
(
s
!=
substream
);
if
(
spdif_flag
)
{
outl
(
trident
->
spdif_pcm_bits
,
TRID_REG
(
trident
,
NX_SPCSTATUS
));
outb
(
trident
->
spdif_pcm_ctrl
,
TRID_REG
(
trident
,
NX_SPCTRL_SPCSO
+
3
));
if
(
trident
->
device
!=
TRIDENT_DEVICE_ID_SI7018
)
{
outl
(
trident
->
spdif_pcm_bits
,
TRID_REG
(
trident
,
NX_SPCSTATUS
));
outb
(
trident
->
spdif_pcm_ctrl
,
TRID_REG
(
trident
,
NX_SPCTRL_SPCSO
+
3
));
}
else
{
outl
(
trident
->
spdif_pcm_bits
,
TRID_REG
(
trident
,
SI_SPDIF_CS
));
val
=
inl
(
TRID_REG
(
trident
,
SI_SERIAL_INTF_CTRL
))
|
SPDIF_EN
;
outl
(
val
,
TRID_REG
(
trident
,
SI_SERIAL_INTF_CTRL
));
}
}
if
(
!
go
)
outl
(
what
,
TRID_REG
(
trident
,
T4D_STOP_B
));
...
...
@@ -1584,7 +1531,7 @@ static int snd_trident_trigger(snd_pcm_substream_t *substream,
outl
(
val
,
TRID_REG
(
trident
,
T4D_AINTEN_B
));
if
(
go
)
{
outl
(
what
,
TRID_REG
(
trident
,
T4D_START_B
));
if
(
capture_flag
&&
trident
->
device
!=
TRIDENT_DEVICE_ID_SI7018
)
outb
(
trident
->
bDMAStart
,
TRID_REG
(
trident
,
T4D_SBCTRL_SBE2R_SBDD
));
}
else
{
...
...
@@ -1790,6 +1737,26 @@ static snd_pcm_hardware_t snd_trident_spdif =
.
fifo_size
=
0
,
};
static
snd_pcm_hardware_t
snd_trident_spdif_7018
=
{
.
info
=
(
SNDRV_PCM_INFO_MMAP
|
SNDRV_PCM_INFO_INTERLEAVED
|
SNDRV_PCM_INFO_BLOCK_TRANSFER
|
SNDRV_PCM_INFO_MMAP_VALID
|
SNDRV_PCM_INFO_SYNC_START
|
SNDRV_PCM_INFO_PAUSE
|
SNDRV_PCM_INFO_RESUME
),
.
formats
=
SNDRV_PCM_FMTBIT_S16_LE
,
.
rates
=
SNDRV_PCM_RATE_48000
,
.
rate_min
=
48000
,
.
rate_max
=
48000
,
.
channels_min
=
2
,
.
channels_max
=
2
,
.
buffer_bytes_max
=
(
128
*
1024
),
.
period_bytes_min
=
64
,
.
period_bytes_max
=
(
128
*
1024
),
.
periods_min
=
1
,
.
periods_max
=
1024
,
.
fifo_size
=
0
,
};
static
void
snd_trident_pcm_free_substream
(
snd_pcm_runtime_t
*
runtime
)
{
unsigned
long
flags
;
...
...
@@ -1876,7 +1843,11 @@ static int snd_trident_spdif_open(snd_pcm_substream_t * substream)
runtime
->
private_data
=
voice
;
runtime
->
private_free
=
snd_trident_pcm_free_substream
;
runtime
->
hw
=
snd_trident_spdif
;
if
(
trident
->
device
==
TRIDENT_DEVICE_ID_SI7018
)
{
runtime
->
hw
=
snd_trident_spdif
;
}
else
{
runtime
->
hw
=
snd_trident_spdif_7018
;
}
trident
->
spdif_pcm_ctl
->
access
&=
~
SNDRV_CTL_ELEM_ACCESS_INACTIVE
;
snd_ctl_notify
(
trident
->
card
,
SNDRV_CTL_EVENT_MASK_VALUE
|
...
...
@@ -1899,11 +1870,23 @@ static int snd_trident_spdif_open(snd_pcm_substream_t * substream)
static
int
snd_trident_spdif_close
(
snd_pcm_substream_t
*
substream
)
{
trident_t
*
trident
=
snd_pcm_substream_chip
(
substream
);
unsigned
int
temp
;
spin_lock_irq
(
&
trident
->
reg_lock
);
// restore default SPDIF setting
outb
(
trident
->
spdif_ctrl
,
TRID_REG
(
trident
,
NX_SPCTRL_SPCSO
+
3
));
outl
(
trident
->
spdif_bits
,
TRID_REG
(
trident
,
NX_SPCSTATUS
));
if
(
trident
->
device
!=
TRIDENT_DEVICE_ID_SI7018
)
{
outb
(
trident
->
spdif_ctrl
,
TRID_REG
(
trident
,
NX_SPCTRL_SPCSO
+
3
));
outl
(
trident
->
spdif_bits
,
TRID_REG
(
trident
,
NX_SPCSTATUS
));
}
else
{
outl
(
trident
->
spdif_bits
,
TRID_REG
(
trident
,
SI_SPDIF_CS
));
temp
=
inl
(
TRID_REG
(
trident
,
SI_SERIAL_INTF_CTRL
));
if
(
trident
->
spdif_ctrl
)
{
temp
|=
SPDIF_EN
;
}
else
{
temp
&=
~
SPDIF_EN
;
}
outl
(
temp
,
TRID_REG
(
trident
,
SI_SERIAL_INTF_CTRL
));
}
spin_unlock_irq
(
&
trident
->
reg_lock
);
trident
->
spdif_pcm_ctl
->
access
|=
SNDRV_CTL_ELEM_ACCESS_INACTIVE
;
snd_ctl_notify
(
trident
->
card
,
SNDRV_CTL_EVENT_MASK_VALUE
|
...
...
@@ -2031,8 +2014,8 @@ static snd_pcm_ops_t snd_trident_playback_ops = {
.
open
=
snd_trident_playback_open
,
.
close
=
snd_trident_playback_close
,
.
ioctl
=
snd_trident_ioctl
,
.
hw_params
=
snd_trident_
playback_
hw_params
,
.
hw_free
=
snd_trident_
playback_
hw_free
,
.
hw_params
=
snd_trident_hw_params
,
.
hw_free
=
snd_trident_hw_free
,
.
prepare
=
snd_trident_playback_prepare
,
.
trigger
=
snd_trident_trigger
,
.
pointer
=
snd_trident_playback_pointer
,
...
...
@@ -2043,7 +2026,7 @@ static snd_pcm_ops_t snd_trident_capture_ops = {
.
close
=
snd_trident_capture_close
,
.
ioctl
=
snd_trident_ioctl
,
.
hw_params
=
snd_trident_capture_hw_params
,
.
hw_free
=
snd_trident_
capture_
hw_free
,
.
hw_free
=
snd_trident_hw_free
,
.
prepare
=
snd_trident_capture_prepare
,
.
trigger
=
snd_trident_trigger
,
.
pointer
=
snd_trident_capture_pointer
,
...
...
@@ -2064,8 +2047,8 @@ static snd_pcm_ops_t snd_trident_foldback_ops = {
.
open
=
snd_trident_foldback_open
,
.
close
=
snd_trident_foldback_close
,
.
ioctl
=
snd_trident_ioctl
,
.
hw_params
=
snd_trident_
foldback_
hw_params
,
.
hw_free
=
snd_trident_
foldback_
hw_free
,
.
hw_params
=
snd_trident_hw_params
,
.
hw_free
=
snd_trident_hw_free
,
.
prepare
=
snd_trident_foldback_prepare
,
.
trigger
=
snd_trident_trigger
,
.
pointer
=
snd_trident_playback_pointer
,
...
...
@@ -2076,12 +2059,23 @@ static snd_pcm_ops_t snd_trident_spdif_ops = {
.
close
=
snd_trident_spdif_close
,
.
ioctl
=
snd_trident_ioctl
,
.
hw_params
=
snd_trident_spdif_hw_params
,
.
hw_free
=
snd_trident_
spdif_
hw_free
,
.
hw_free
=
snd_trident_hw_free
,
.
prepare
=
snd_trident_spdif_prepare
,
.
trigger
=
snd_trident_trigger
,
.
pointer
=
snd_trident_spdif_pointer
,
};
static
snd_pcm_ops_t
snd_trident_spdif_7018_ops
=
{
.
open
=
snd_trident_spdif_open
,
.
close
=
snd_trident_spdif_close
,
.
ioctl
=
snd_trident_ioctl
,
.
hw_params
=
snd_trident_spdif_hw_params
,
.
hw_free
=
snd_trident_hw_free
,
.
prepare
=
snd_trident_spdif_prepare
,
.
trigger
=
snd_trident_trigger
,
.
pointer
=
snd_trident_playback_pointer
,
};
/*---------------------------------------------------------------------------
snd_trident_pcm_free
...
...
@@ -2227,7 +2221,11 @@ int __devinit snd_trident_spdif_pcm(trident_t * trident, int device, snd_pcm_t *
spdif
->
private_data
=
trident
;
spdif
->
private_free
=
snd_trident_spdif_pcm_free
;
snd_pcm_set_ops
(
spdif
,
SNDRV_PCM_STREAM_PLAYBACK
,
&
snd_trident_spdif_ops
);
if
(
trident
->
device
!=
TRIDENT_DEVICE_ID_SI7018
)
{
snd_pcm_set_ops
(
spdif
,
SNDRV_PCM_STREAM_PLAYBACK
,
&
snd_trident_spdif_ops
);
}
else
{
snd_pcm_set_ops
(
spdif
,
SNDRV_PCM_STREAM_PLAYBACK
,
&
snd_trident_spdif_7018_ops
);
}
spdif
->
info_flags
=
0
;
strcpy
(
spdif
->
name
,
"Trident 4DWave IEC958"
);
trident
->
spdif
=
spdif
;
...
...
@@ -2286,9 +2284,20 @@ static int snd_trident_spdif_control_put(snd_kcontrol_t * kcontrol,
/* S/PDIF C Channel bits 0-31 : 48khz, SCMS disabled */
change
=
trident
->
spdif_ctrl
!=
val
;
trident
->
spdif_ctrl
=
val
;
if
((
inb
(
TRID_REG
(
trident
,
NX_SPCTRL_SPCSO
+
3
))
&
0x10
)
==
0
)
{
outl
(
trident
->
spdif_bits
,
TRID_REG
(
trident
,
NX_SPCSTATUS
));
outb
(
trident
->
spdif_ctrl
,
TRID_REG
(
trident
,
NX_SPCTRL_SPCSO
+
3
));
if
(
trident
->
device
!=
TRIDENT_DEVICE_ID_SI7018
)
{
if
((
inb
(
TRID_REG
(
trident
,
NX_SPCTRL_SPCSO
+
3
))
&
0x10
)
==
0
)
{
outl
(
trident
->
spdif_bits
,
TRID_REG
(
trident
,
NX_SPCSTATUS
));
outb
(
trident
->
spdif_ctrl
,
TRID_REG
(
trident
,
NX_SPCTRL_SPCSO
+
3
));
}
}
else
{
if
(
trident
->
spdif
==
NULL
)
{
unsigned
int
temp
;
outl
(
trident
->
spdif_bits
,
TRID_REG
(
trident
,
SI_SPDIF_CS
));
temp
=
inl
(
TRID_REG
(
trident
,
SI_SERIAL_INTF_CTRL
))
&
~
SPDIF_EN
;
if
(
val
)
temp
|=
SPDIF_EN
;
outl
(
temp
,
TRID_REG
(
trident
,
SI_SERIAL_INTF_CTRL
));
}
}
spin_unlock_irqrestore
(
&
trident
->
reg_lock
,
flags
);
return
change
;
...
...
@@ -2347,16 +2356,21 @@ static int snd_trident_spdif_default_put(snd_kcontrol_t * kcontrol,
spin_lock_irqsave
(
&
trident
->
reg_lock
,
flags
);
change
=
trident
->
spdif_bits
!=
val
;
trident
->
spdif_bits
=
val
;
if
((
inb
(
TRID_REG
(
trident
,
NX_SPCTRL_SPCSO
+
3
))
&
0x10
)
==
0
)
outl
(
trident
->
spdif_bits
,
TRID_REG
(
trident
,
NX_SPCSTATUS
));
if
(
trident
->
device
!=
TRIDENT_DEVICE_ID_SI7018
)
{
if
((
inb
(
TRID_REG
(
trident
,
NX_SPCTRL_SPCSO
+
3
))
&
0x10
)
==
0
)
outl
(
trident
->
spdif_bits
,
TRID_REG
(
trident
,
NX_SPCSTATUS
));
}
else
{
if
(
trident
->
spdif
==
NULL
)
outl
(
trident
->
spdif_bits
,
TRID_REG
(
trident
,
SI_SPDIF_CS
));
}
spin_unlock_irqrestore
(
&
trident
->
reg_lock
,
flags
);
return
change
;
}
static
snd_kcontrol_new_t
snd_trident_spdif_default
__devinitdata
=
{
.
iface
=
SNDRV_CTL_ELEM_IFACE_PCM
,
.
name
=
SNDRV_CTL_NAME_IEC958
(
""
,
PLAYBACK
,
DEFAULT
),
.
iface
=
SNDRV_CTL_ELEM_IFACE_PCM
,
.
name
=
SNDRV_CTL_NAME_IEC958
(
""
,
PLAYBACK
,
DEFAULT
),
.
info
=
snd_trident_spdif_default_info
,
.
get
=
snd_trident_spdif_default_get
,
.
put
=
snd_trident_spdif_default_put
...
...
@@ -2437,8 +2451,13 @@ static int snd_trident_spdif_stream_put(snd_kcontrol_t * kcontrol,
spin_lock_irqsave
(
&
trident
->
reg_lock
,
flags
);
change
=
trident
->
spdif_pcm_bits
!=
val
;
trident
->
spdif_pcm_bits
=
val
;
if
(
trident
->
spdif
!=
NULL
)
outl
(
trident
->
spdif_pcm_bits
,
TRID_REG
(
trident
,
NX_SPCSTATUS
));
if
(
trident
->
spdif
!=
NULL
)
{
if
(
trident
->
device
!=
TRIDENT_DEVICE_ID_SI7018
)
{
outl
(
trident
->
spdif_pcm_bits
,
TRID_REG
(
trident
,
NX_SPCSTATUS
));
}
else
{
outl
(
trident
->
spdif_bits
,
TRID_REG
(
trident
,
SI_SPDIF_CS
));
}
}
spin_unlock_irqrestore
(
&
trident
->
reg_lock
,
flags
);
return
change
;
}
...
...
@@ -2873,7 +2892,7 @@ static int __devinit snd_trident_mixer(trident_t * trident, int pcm_spdif_device
snd_card_t
*
card
=
trident
->
card
;
snd_kcontrol_t
*
kctl
;
snd_ctl_elem_value_t
uctl
;
int
idx
,
err
;
int
idx
,
err
,
retries
=
2
;
memset
(
&
uctl
,
0
,
sizeof
(
uctl
));
...
...
@@ -2881,8 +2900,19 @@ static int __devinit snd_trident_mixer(trident_t * trident, int pcm_spdif_device
_ac97
.
write
=
snd_trident_codec_write
;
_ac97
.
read
=
snd_trident_codec_read
;
_ac97
.
private_data
=
trident
;
if
((
err
=
snd_ac97_mixer
(
trident
->
card
,
&
_ac97
,
&
ac97
))
<
0
)
trident
->
ac97_detect
=
1
;
__again:
if
((
err
=
snd_ac97_mixer
(
trident
->
card
,
&
_ac97
,
&
ac97
))
<
0
)
{
if
(
trident
->
device
==
TRIDENT_DEVICE_ID_SI7018
)
{
if
((
err
=
snd_trident_sis_reset
(
trident
))
<
0
)
return
err
;
if
(
retries
--
>
0
)
goto
__again
;
return
-
EIO
;
}
return
err
;
}
trident
->
ac97_detect
=
0
;
if
(
trident
->
device
!=
TRIDENT_DEVICE_ID_SI7018
)
{
if
((
err
=
snd_ctl_add
(
card
,
kctl
=
snd_ctl_new1
(
&
snd_trident_vol_wave_control
,
trident
)))
<
0
)
...
...
@@ -2934,6 +2964,8 @@ static int __devinit snd_trident_mixer(trident_t * trident, int pcm_spdif_device
if
((
err
=
snd_ctl_add
(
card
,
kctl
=
snd_ctl_new1
(
&
snd_trident_ac97_rear_control
,
trident
)))
<
0
)
return
err
;
kctl
->
put
(
kctl
,
&
uctl
);
}
if
(
trident
->
device
==
TRIDENT_DEVICE_ID_NX
||
trident
->
device
==
TRIDENT_DEVICE_ID_SI7018
)
{
if
((
err
=
snd_ctl_add
(
card
,
kctl
=
snd_ctl_new1
(
&
snd_trident_spdif_control
,
trident
)))
<
0
)
return
err
;
kctl
->
put
(
kctl
,
&
uctl
);
...
...
@@ -3046,6 +3078,55 @@ void __devinit snd_trident_gameport(trident_t *chip)
}
#endif
/*
* SiS reset routine
*/
static
int
snd_trident_sis_reset
(
trident_t
*
trident
)
{
signed
long
end_time
;
unsigned
int
i
;
int
r
;
r
=
2
;
/* count of retries */
__si7018_retry:
pci_write_config_byte
(
trident
->
pci
,
0x46
,
0x04
);
/* SOFTWARE RESET */
udelay
(
100
);
pci_write_config_byte
(
trident
->
pci
,
0x46
,
0x00
);
udelay
(
100
);
/* disable AC97 GPIO interrupt */
outb
(
0x00
,
TRID_REG
(
trident
,
SI_AC97_GPIO
));
/* initialize serial interface, force cold reset */
i
=
PCMOUT
|
SURROUT
|
CENTEROUT
|
LFEOUT
|
SECONDARY_ID
|
COLD_RESET
;
outl
(
i
,
TRID_REG
(
trident
,
SI_SERIAL_INTF_CTRL
));
udelay
(
1000
);
/* remove cold reset */
i
&=
~
COLD_RESET
;
outl
(
i
,
TRID_REG
(
trident
,
SI_SERIAL_INTF_CTRL
));
udelay
(
2000
);
/* wait, until the codec is ready */
end_time
=
(
jiffies
+
(
HZ
*
3
)
/
4
)
+
1
;
do
{
if
((
inl
(
TRID_REG
(
trident
,
SI_SERIAL_INTF_CTRL
))
&
SI_AC97_PRIMARY_READY
)
!=
0
)
goto
__si7018_ok
;
set_current_state
(
TASK_UNINTERRUPTIBLE
);
schedule_timeout
(
1
);
}
while
(
time_after_eq
(
end_time
,
jiffies
));
snd_printk
(
"AC'97 codec ready error [0x%x]
\n
"
,
inl
(
TRID_REG
(
trident
,
SI_SERIAL_INTF_CTRL
)));
if
(
r
--
>
0
)
{
end_time
=
jiffies
+
HZ
;
do
{
set_current_state
(
TASK_UNINTERRUPTIBLE
);
schedule_timeout
(
1
);
}
while
(
time_after_eq
(
end_time
,
jiffies
));
goto
__si7018_retry
;
}
__si7018_ok:
/* enable 64 channel mode */
outl
(
BANK_B_EN
,
TRID_REG
(
trident
,
T4D_LFO_GC_CIR
));
return
0
;
}
/*
* /proc interface
*/
...
...
@@ -3072,8 +3153,9 @@ static void snd_trident_proc_read(snd_info_entry_t *entry,
snd_iprintf
(
buffer
,
"%s
\n\n
"
,
s
);
snd_iprintf
(
buffer
,
"Spurious IRQs : %d
\n
"
,
trident
->
spurious_irq_count
);
snd_iprintf
(
buffer
,
"Spurious IRQ dlta: %d
\n
"
,
trident
->
spurious_irq_max_delta
);
if
(
trident
->
device
==
TRIDENT_DEVICE_ID_NX
)
{
if
(
trident
->
device
==
TRIDENT_DEVICE_ID_NX
||
trident
->
device
==
TRIDENT_DEVICE_ID_SI7018
)
snd_iprintf
(
buffer
,
"IEC958 Mixer Out : %s
\n
"
,
trident
->
spdif_ctrl
==
0x28
?
"on"
:
"off"
);
if
(
trident
->
device
==
TRIDENT_DEVICE_ID_NX
)
{
snd_iprintf
(
buffer
,
"Rear Speakers : %s
\n
"
,
trident
->
ac97_ctrl
&
0x00000010
?
"on"
:
"off"
);
if
(
trident
->
tlb
.
entries
)
{
snd_iprintf
(
buffer
,
"
\n
Virtual Memory
\n
"
);
...
...
@@ -3318,35 +3400,10 @@ int __devinit snd_trident_create(snd_card_t * card,
outl
(
NX_SB_IRQ_DISABLE
,
TRID_REG
(
trident
,
T4D_MISCINT
));
break
;
case
TRIDENT_DEVICE_ID_SI7018
:
pci_write_config_byte
(
pci
,
0x46
,
0x04
);
/* SOFTWARE RESET */
udelay
(
100
);
pci_write_config_byte
(
pci
,
0x46
,
0x00
);
udelay
(
100
);
/* disable AC97 GPIO interrupt */
outb
(
0x00
,
TRID_REG
(
trident
,
SI_AC97_GPIO
));
/* initialize serial interface, force cold reset */
i
=
PCMOUT
|
SURROUT
|
CENTEROUT
|
LFEOUT
|
SECONDARY_ID
|
COLD_RESET
;
outl
(
i
,
TRID_REG
(
trident
,
SI_SERIAL_INTF_CTRL
));
udelay
(
1000
);
/* remove cold reset */
i
&=
~
COLD_RESET
;
outl
(
i
,
TRID_REG
(
trident
,
SI_SERIAL_INTF_CTRL
));
udelay
(
2000
);
/* wait, until the codec is ready */
end_time
=
(
jiffies
+
(
HZ
*
3
)
/
4
)
+
1
;
do
{
if
((
inl
(
TRID_REG
(
trident
,
SI_SERIAL_INTF_CTRL
))
&
SI_AC97_PRIMARY_READY
)
!=
0
)
goto
__si7018_ok
;
set_current_state
(
TASK_UNINTERRUPTIBLE
);
schedule_timeout
(
1
);
}
while
(
end_time
-
(
signed
long
)
jiffies
>=
0
);
snd_printk
(
"AC'97 codec ready error [0x%x]
\n
"
,
inl
(
TRID_REG
(
trident
,
SI_SERIAL_INTF_CTRL
)));
snd_trident_free
(
trident
);
return
-
EIO
;
__si7018_ok:
/* enable 64 channel mode */
outl
(
BANK_B_EN
,
TRID_REG
(
trident
,
T4D_LFO_GC_CIR
));
break
;
if
((
err
=
snd_trident_sis_reset
(
trident
))
<
0
)
{
snd_trident_free
(
trident
);
return
err
;
}
}
outl
(
0xffffffff
,
TRID_REG
(
trident
,
T4D_STOP_A
));
...
...
@@ -3374,6 +3431,12 @@ int __devinit snd_trident_create(snd_card_t * card,
outb
(
trident
->
spdif_ctrl
,
TRID_REG
(
trident
,
NX_SPCTRL_SPCSO
+
3
));
}
if
(
trident
->
device
==
TRIDENT_DEVICE_ID_SI7018
)
{
/* initialize S/PDIF */
trident
->
spdif_bits
=
trident
->
spdif_pcm_bits
=
SNDRV_PCM_DEFAULT_CON_SPDIF
;
outl
(
trident
->
spdif_bits
,
TRID_REG
(
trident
,
SI_SPDIF_CS
));
}
/* initialise synth voices */
for
(
i
=
0
;
i
<
64
;
i
++
)
{
voice
=
&
trident
->
synth
.
voices
[
i
];
...
...
@@ -3429,6 +3492,9 @@ int snd_trident_free(trident_t *trident)
// Disable S/PDIF out
if
(
trident
->
device
==
TRIDENT_DEVICE_ID_NX
)
outb
(
0x00
,
TRID_REG
(
trident
,
NX_SPCTRL_SPCSO
+
3
));
else
if
(
trident
->
device
==
TRIDENT_DEVICE_ID_SI7018
)
{
outl
(
0
,
TRID_REG
(
trident
,
SI_SERIAL_INTF_CTRL
));
}
snd_trident_proc_done
(
trident
);
if
(
trident
->
tlb
.
buffer
)
{
outl
(
0
,
TRID_REG
(
trident
,
NX_TLBC
));
...
...
sound/usb/usbaudio.h
View file @
2f2fc324
...
...
@@ -202,4 +202,8 @@ int snd_usb_create_midi_interface(snd_usb_audio_t *chip, struct usb_interface *i
#define get_cfg_desc(cfg) (&(cfg)->desc)
#endif
#ifndef usb_pipe_needs_resubmit
#define usb_pipe_needs_resubmit(pipe) 1
#endif
#endif
/* __USBAUDIO_H */
sound/usb/usbmidi.c
View file @
2f2fc324
...
...
@@ -114,7 +114,6 @@ struct snd_usb_midi_in_endpoint {
struct
urb
*
urb
;
struct
usbmidi_in_port
{
snd_rawmidi_substream_t
*
substream
;
int
active
;
}
ports
[
0x10
];
};
...
...
@@ -159,7 +158,12 @@ static void snd_usbmidi_input_packet(snd_usb_midi_in_endpoint_t* ep,
int
cable
=
packet
[
0
]
>>
4
;
usbmidi_in_port_t
*
port
=
&
ep
->
ports
[
cable
];
if
(
!
port
->
active
)
if
(
!
port
->
substream
)
{
snd_printd
(
"unexpected port %d!
\n
"
,
cable
);
return
;
}
if
(
!
port
->
substream
->
runtime
||
!
port
->
substream
->
runtime
->
trigger
)
return
;
snd_rawmidi_receive
(
port
->
substream
,
&
packet
[
1
],
snd_usbmidi_cin_length
[
packet
[
0
]
&
0x0f
]);
...
...
@@ -184,8 +188,10 @@ static void snd_usbmidi_in_urb_complete(struct urb* urb)
return
;
}
urb
->
dev
=
ep
->
umidi
->
chip
->
dev
;
snd_usbmidi_submit_urb
(
urb
,
GFP_ATOMIC
);
if
(
usb_pipe_needs_resubmit
(
urb
->
pipe
))
{
urb
->
dev
=
ep
->
umidi
->
chip
->
dev
;
snd_usbmidi_submit_urb
(
urb
,
GFP_ATOMIC
);
}
}
/*
...
...
@@ -451,20 +457,6 @@ static void snd_usbmidi_output_trigger(snd_rawmidi_substream_t* substream, int u
static
int
snd_usbmidi_input_open
(
snd_rawmidi_substream_t
*
substream
)
{
snd_usb_midi_t
*
umidi
=
snd_magic_cast
(
snd_usb_midi_t
,
substream
->
rmidi
->
private_data
,
return
-
ENXIO
);
usbmidi_in_port_t
*
port
=
NULL
;
int
i
,
j
;
for
(
i
=
0
;
i
<
MIDI_MAX_ENDPOINTS
;
++
i
)
if
(
umidi
->
endpoints
[
i
].
in
)
for
(
j
=
0
;
j
<
0x10
;
++
j
)
if
(
umidi
->
endpoints
[
i
].
in
->
ports
[
j
].
substream
==
substream
)
{
port
=
&
umidi
->
endpoints
[
i
].
in
->
ports
[
j
];
break
;
}
if
(
!
port
)
return
-
ENXIO
;
substream
->
runtime
->
private_data
=
port
;
return
0
;
}
...
...
@@ -475,9 +467,6 @@ static int snd_usbmidi_input_close(snd_rawmidi_substream_t* substream)
static
void
snd_usbmidi_input_trigger
(
snd_rawmidi_substream_t
*
substream
,
int
up
)
{
usbmidi_in_port_t
*
port
=
(
usbmidi_in_port_t
*
)
substream
->
runtime
->
private_data
;
port
->
active
=
up
;
}
static
snd_rawmidi_ops_t
snd_usbmidi_output_ops
=
{
...
...
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