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
Kirill Smelkov
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
Show 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
)
{
...
...
@@ -1084,15 +1086,10 @@ static int snd_cs46xx_playback_hw_params(snd_pcm_substream_t * substream,
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_dsp_pcm_channel_set_period
(
chip
,
cpcm
->
pcm_channel
,
period_size
*
4
))
{
up
(
&
chip
->
spos_mutex
);
...
...
@@ -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
);
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
);
/* 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
;
}
/* 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
}
};
...
...
@@ -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,8 +1200,6 @@ 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
);
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
|
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
))
||
(
inb
(
ICEMT
(
ice
,
RATE
))
&
ICE1712_SPDIF_MASTER
))
{
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 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 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 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
,
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
(
trident
->
device
==
TRIDENT_DEVICE_ID_SI7018
)
{
err
=
snd_trident_allocate_evoice
(
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
;
}
/* 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,10 +1331,14 @@ 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
;
unsigned
int
temp
;
spin_lock_irqsave
(
&
trident
->
reg_lock
,
flags
);
spin_lock
(
&
trident
->
reg_lock
);
if
(
trident
->
device
!=
TRIDENT_DEVICE_ID_SI7018
)
{
/* set delta (rate) value */
voice
->
Delta
=
snd_trident_convert_rate
(
runtime
->
rate
);
...
...
@@ -1499,7 +1383,64 @@ static int snd_trident_spdif_prepare(snd_pcm_substream_t * substream)
outb
(
trident
->
spdif_pcm_ctrl
,
TRID_REG
(
trident
,
NX_SPCTRL_SPCSO
+
3
));
outl
(
trident
->
spdif_pcm_bits
,
TRID_REG
(
trident
,
NX_SPCSTATUS
));
spin_unlock_irqrestore
(
&
trident
->
reg_lock
,
flags
);
}
else
{
/* SiS */
/* set delta (rate) value */
voice
->
Delta
=
0x800
;
voice
->
spurious_threshold
=
snd_trident_spurious_threshold
(
48000
,
runtime
->
period_size
);
/* 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
);
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
);
}
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
(
&
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
)
{
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
));
...
...
@@ -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
;
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
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
;
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,10 +2284,21 @@ 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
(
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,8 +2356,13 @@ 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
(
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
;
}
...
...
@@ -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
)
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
)));
if
((
err
=
snd_trident_sis_reset
(
trident
))
<
0
)
{
snd_trident_free
(
trident
);
return
-
EIO
;
__si7018_ok:
/* enable 64 channel mode */
outl
(
BANK_B_EN
,
TRID_REG
(
trident
,
T4D_LFO_GC_CIR
));
break
;
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
;
}
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