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
d0807323
Commit
d0807323
authored
Mar 24, 2009
by
Takashi Iwai
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'topic/sscape-fix' into for-linus
parents
d7b6df5d
453e37b3
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
96 additions
and
181 deletions
+96
-181
sound/isa/Kconfig
sound/isa/Kconfig
+5
-2
sound/isa/sscape.c
sound/isa/sscape.c
+38
-151
sound/isa/wss/wss_lib.c
sound/isa/wss/wss_lib.c
+53
-28
No files found.
sound/isa/Kconfig
View file @
d0807323
...
@@ -368,14 +368,17 @@ config SND_SGALAXY
...
@@ -368,14 +368,17 @@ config SND_SGALAXY
will be called snd-sgalaxy.
will be called snd-sgalaxy.
config SND_SSCAPE
config SND_SSCAPE
tristate "Ensoniq SoundScape
PnP
driver"
tristate "Ensoniq SoundScape driver"
select SND_HWDEP
select SND_HWDEP
select SND_MPU401_UART
select SND_MPU401_UART
select SND_WSS_LIB
select SND_WSS_LIB
help
help
Say Y here to include support for Ensoniq SoundScape
PnP
Say Y here to include support for Ensoniq SoundScape
soundcards.
soundcards.
The PCM audio is supported on SoundScape Classic, Elite, PnP
and VIVO cards. The MIDI support is very experimental.
To compile this driver as a module, choose M here: the module
To compile this driver as a module, choose M here: the module
will be called snd-sscape.
will be called snd-sscape.
...
...
sound/isa/sscape.c
View file @
d0807323
...
@@ -89,9 +89,6 @@ MODULE_DEVICE_TABLE(pnp_card, sscape_pnpids);
...
@@ -89,9 +89,6 @@ MODULE_DEVICE_TABLE(pnp_card, sscape_pnpids);
#endif
#endif
#define MPU401_IO(i) ((i) + 0)
#define MIDI_DATA_IO(i) ((i) + 0)
#define MIDI_CTRL_IO(i) ((i) + 1)
#define HOST_CTRL_IO(i) ((i) + 2)
#define HOST_CTRL_IO(i) ((i) + 2)
#define HOST_DATA_IO(i) ((i) + 3)
#define HOST_DATA_IO(i) ((i) + 3)
#define ODIE_ADDR_IO(i) ((i) + 4)
#define ODIE_ADDR_IO(i) ((i) + 4)
...
@@ -129,9 +126,6 @@ enum GA_REG {
...
@@ -129,9 +126,6 @@ enum GA_REG {
#define DMA_8BIT 0x80
#define DMA_8BIT 0x80
#define AD1845_FREQ_SEL_MSB 0x16
#define AD1845_FREQ_SEL_LSB 0x17
enum
card_type
{
enum
card_type
{
SSCAPE
,
SSCAPE
,
SSCAPE_PNP
,
SSCAPE_PNP
,
...
@@ -141,8 +135,6 @@ enum card_type {
...
@@ -141,8 +135,6 @@ enum card_type {
struct
soundscape
{
struct
soundscape
{
spinlock_t
lock
;
spinlock_t
lock
;
unsigned
io_base
;
unsigned
io_base
;
unsigned
wss_base
;
int
codec_type
;
int
ic_type
;
int
ic_type
;
enum
card_type
type
;
enum
card_type
type
;
struct
resource
*
io_res
;
struct
resource
*
io_res
;
...
@@ -330,7 +322,7 @@ static int host_write_ctrl_unsafe(unsigned io_base, unsigned char data,
...
@@ -330,7 +322,7 @@ static int host_write_ctrl_unsafe(unsigned io_base, unsigned char data,
*/
*/
static
inline
int
verify_mpu401
(
const
struct
snd_mpu401
*
mpu
)
static
inline
int
verify_mpu401
(
const
struct
snd_mpu401
*
mpu
)
{
{
return
((
inb
(
M
IDI_CTRL_IO
(
mpu
->
port
))
&
0xc0
)
==
0x80
);
return
((
inb
(
M
PU401C
(
mpu
))
&
0xc0
)
==
0x80
);
}
}
/*
/*
...
@@ -338,7 +330,7 @@ static inline int verify_mpu401(const struct snd_mpu401 * mpu)
...
@@ -338,7 +330,7 @@ static inline int verify_mpu401(const struct snd_mpu401 * mpu)
*/
*/
static
inline
void
initialise_mpu401
(
const
struct
snd_mpu401
*
mpu
)
static
inline
void
initialise_mpu401
(
const
struct
snd_mpu401
*
mpu
)
{
{
outb
(
0
,
M
IDI_DATA_IO
(
mpu
->
port
));
outb
(
0
,
M
PU401D
(
mpu
));
}
}
/*
/*
...
@@ -396,20 +388,20 @@ static int sscape_wait_dma_unsafe(unsigned io_base, enum GA_REG reg, unsigned ti
...
@@ -396,20 +388,20 @@ static int sscape_wait_dma_unsafe(unsigned io_base, enum GA_REG reg, unsigned ti
*/
*/
static
int
obp_startup_ack
(
struct
soundscape
*
s
,
unsigned
timeout
)
static
int
obp_startup_ack
(
struct
soundscape
*
s
,
unsigned
timeout
)
{
{
while
(
timeout
!=
0
)
{
unsigned
long
end_time
=
jiffies
+
msecs_to_jiffies
(
timeout
);
do
{
unsigned
long
flags
;
unsigned
long
flags
;
unsigned
char
x
;
unsigned
char
x
;
schedule_timeout_uninterruptible
(
1
);
spin_lock_irqsave
(
&
s
->
lock
,
flags
);
spin_lock_irqsave
(
&
s
->
lock
,
flags
);
x
=
inb
(
HOST_DATA_IO
(
s
->
io_base
));
x
=
inb
(
HOST_DATA_IO
(
s
->
io_base
));
spin_unlock_irqrestore
(
&
s
->
lock
,
flags
);
spin_unlock_irqrestore
(
&
s
->
lock
,
flags
);
if
((
x
&
0xfe
)
==
0xfe
)
if
((
x
&
0xfe
)
==
0xfe
)
return
1
;
return
1
;
--
timeout
;
msleep
(
10
)
;
}
/* while */
}
while
(
time_before
(
jiffies
,
end_time
));
return
0
;
return
0
;
}
}
...
@@ -423,20 +415,20 @@ static int obp_startup_ack(struct soundscape *s, unsigned timeout)
...
@@ -423,20 +415,20 @@ static int obp_startup_ack(struct soundscape *s, unsigned timeout)
*/
*/
static
int
host_startup_ack
(
struct
soundscape
*
s
,
unsigned
timeout
)
static
int
host_startup_ack
(
struct
soundscape
*
s
,
unsigned
timeout
)
{
{
while
(
timeout
!=
0
)
{
unsigned
long
end_time
=
jiffies
+
msecs_to_jiffies
(
timeout
);
do
{
unsigned
long
flags
;
unsigned
long
flags
;
unsigned
char
x
;
unsigned
char
x
;
schedule_timeout_uninterruptible
(
1
);
spin_lock_irqsave
(
&
s
->
lock
,
flags
);
spin_lock_irqsave
(
&
s
->
lock
,
flags
);
x
=
inb
(
HOST_DATA_IO
(
s
->
io_base
));
x
=
inb
(
HOST_DATA_IO
(
s
->
io_base
));
spin_unlock_irqrestore
(
&
s
->
lock
,
flags
);
spin_unlock_irqrestore
(
&
s
->
lock
,
flags
);
if
(
x
==
0xfe
)
if
(
x
==
0xfe
)
return
1
;
return
1
;
--
timeout
;
msleep
(
10
)
;
}
/* while */
}
while
(
time_before
(
jiffies
,
end_time
));
return
0
;
return
0
;
}
}
...
@@ -532,10 +524,10 @@ static int upload_dma_data(struct soundscape *s,
...
@@ -532,10 +524,10 @@ static int upload_dma_data(struct soundscape *s,
* give it 5 seconds (max) ...
* give it 5 seconds (max) ...
*/
*/
ret
=
0
;
ret
=
0
;
if
(
!
obp_startup_ack
(
s
,
5
))
{
if
(
!
obp_startup_ack
(
s
,
5
000
))
{
snd_printk
(
KERN_ERR
"sscape: No response from on-board processor after upload
\n
"
);
snd_printk
(
KERN_ERR
"sscape: No response from on-board processor after upload
\n
"
);
ret
=
-
EAGAIN
;
ret
=
-
EAGAIN
;
}
else
if
(
!
host_startup_ack
(
s
,
5
))
{
}
else
if
(
!
host_startup_ack
(
s
,
5
000
))
{
snd_printk
(
KERN_ERR
"sscape: SoundScape failed to initialise
\n
"
);
snd_printk
(
KERN_ERR
"sscape: SoundScape failed to initialise
\n
"
);
ret
=
-
EAGAIN
;
ret
=
-
EAGAIN
;
}
}
...
@@ -732,13 +724,7 @@ static int sscape_midi_get(struct snd_kcontrol *kctl,
...
@@ -732,13 +724,7 @@ static int sscape_midi_get(struct snd_kcontrol *kctl,
unsigned
long
flags
;
unsigned
long
flags
;
spin_lock_irqsave
(
&
s
->
lock
,
flags
);
spin_lock_irqsave
(
&
s
->
lock
,
flags
);
set_host_mode_unsafe
(
s
->
io_base
);
uctl
->
value
.
integer
.
value
[
0
]
=
s
->
midi_vol
;
if
(
host_write_ctrl_unsafe
(
s
->
io_base
,
CMD_GET_MIDI_VOL
,
100
))
{
uctl
->
value
.
integer
.
value
[
0
]
=
host_read_ctrl_unsafe
(
s
->
io_base
,
100
);
}
set_midi_mode_unsafe
(
s
->
io_base
);
spin_unlock_irqrestore
(
&
s
->
lock
,
flags
);
spin_unlock_irqrestore
(
&
s
->
lock
,
flags
);
return
0
;
return
0
;
}
}
...
@@ -773,6 +759,7 @@ static int sscape_midi_put(struct snd_kcontrol *kctl,
...
@@ -773,6 +759,7 @@ static int sscape_midi_put(struct snd_kcontrol *kctl,
change
=
(
host_write_ctrl_unsafe
(
s
->
io_base
,
CMD_SET_MIDI_VOL
,
100
)
change
=
(
host_write_ctrl_unsafe
(
s
->
io_base
,
CMD_SET_MIDI_VOL
,
100
)
&&
host_write_ctrl_unsafe
(
s
->
io_base
,
((
unsigned
char
)
uctl
->
value
.
integer
.
value
[
0
])
&
127
,
100
)
&&
host_write_ctrl_unsafe
(
s
->
io_base
,
((
unsigned
char
)
uctl
->
value
.
integer
.
value
[
0
])
&
127
,
100
)
&&
host_write_ctrl_unsafe
(
s
->
io_base
,
CMD_XXX_MIDI_VOL
,
100
));
&&
host_write_ctrl_unsafe
(
s
->
io_base
,
CMD_XXX_MIDI_VOL
,
100
));
s
->
midi_vol
=
(
unsigned
char
)
uctl
->
value
.
integer
.
value
[
0
]
&
127
;
__skip_change:
__skip_change:
/*
/*
...
@@ -815,12 +802,11 @@ static unsigned __devinit get_irq_config(int irq)
...
@@ -815,12 +802,11 @@ static unsigned __devinit get_irq_config(int irq)
* Perform certain arcane port-checks to see whether there
* Perform certain arcane port-checks to see whether there
* is a SoundScape board lurking behind the given ports.
* is a SoundScape board lurking behind the given ports.
*/
*/
static
int
__devinit
detect_sscape
(
struct
soundscape
*
s
)
static
int
__devinit
detect_sscape
(
struct
soundscape
*
s
,
long
wss_io
)
{
{
unsigned
long
flags
;
unsigned
long
flags
;
unsigned
d
;
unsigned
d
;
int
retval
=
0
;
int
retval
=
0
;
int
codec
=
s
->
wss_base
;
spin_lock_irqsave
(
&
s
->
lock
,
flags
);
spin_lock_irqsave
(
&
s
->
lock
,
flags
);
...
@@ -836,13 +822,11 @@ static int __devinit detect_sscape(struct soundscape *s)
...
@@ -836,13 +822,11 @@ static int __devinit detect_sscape(struct soundscape *s)
if
((
d
&
0x80
)
!=
0
)
if
((
d
&
0x80
)
!=
0
)
goto
_done
;
goto
_done
;
if
(
d
==
0
)
{
if
(
d
==
0
)
s
->
codec_type
=
1
;
s
->
ic_type
=
IC_ODIE
;
s
->
ic_type
=
IC_ODIE
;
}
else
if
((
d
&
0x60
)
!=
0
)
{
else
if
((
d
&
0x60
)
!=
0
)
s
->
codec_type
=
2
;
s
->
ic_type
=
IC_OPUS
;
s
->
ic_type
=
IC_OPUS
;
}
else
else
goto
_done
;
goto
_done
;
outb
(
0xfa
,
ODIE_ADDR_IO
(
s
->
io_base
));
outb
(
0xfa
,
ODIE_ADDR_IO
(
s
->
io_base
));
...
@@ -862,10 +846,10 @@ static int __devinit detect_sscape(struct soundscape *s)
...
@@ -862,10 +846,10 @@ static int __devinit detect_sscape(struct soundscape *s)
sscape_write_unsafe
(
s
->
io_base
,
GA_HMCTL_REG
,
d
|
0xc0
);
sscape_write_unsafe
(
s
->
io_base
,
GA_HMCTL_REG
,
d
|
0xc0
);
if
(
s
->
type
==
SSCAPE_VIVO
)
if
(
s
->
type
==
SSCAPE_VIVO
)
codec
+=
4
;
wss_io
+=
4
;
/* wait for WSS codec */
/* wait for WSS codec */
for
(
d
=
0
;
d
<
500
;
d
++
)
{
for
(
d
=
0
;
d
<
500
;
d
++
)
{
if
((
inb
(
codec
)
&
0x80
)
==
0
)
if
((
inb
(
wss_io
)
&
0x80
)
==
0
)
break
;
break
;
spin_unlock_irqrestore
(
&
s
->
lock
,
flags
);
spin_unlock_irqrestore
(
&
s
->
lock
,
flags
);
msleep
(
1
);
msleep
(
1
);
...
@@ -954,82 +938,6 @@ static int __devinit create_mpu401(struct snd_card *card, int devnum, unsigned l
...
@@ -954,82 +938,6 @@ static int __devinit create_mpu401(struct snd_card *card, int devnum, unsigned l
}
}
/*
* Override for the CS4231 playback format function.
* The AD1845 has much simpler format and rate selection.
*/
static
void
ad1845_playback_format
(
struct
snd_wss
*
chip
,
struct
snd_pcm_hw_params
*
params
,
unsigned
char
format
)
{
unsigned
long
flags
;
unsigned
rate
=
params_rate
(
params
);
/*
* The AD1845 can't handle sample frequencies
* outside of 4 kHZ to 50 kHZ
*/
if
(
rate
>
50000
)
rate
=
50000
;
else
if
(
rate
<
4000
)
rate
=
4000
;
spin_lock_irqsave
(
&
chip
->
reg_lock
,
flags
);
/*
* Program the AD1845 correctly for the playback stream.
* Note that we do NOT need to toggle the MCE bit because
* the PLAYBACK_ENABLE bit of the Interface Configuration
* register is set.
*
* NOTE: We seem to need to write to the MSB before the LSB
* to get the correct sample frequency.
*/
snd_wss_out
(
chip
,
CS4231_PLAYBK_FORMAT
,
(
format
&
0xf0
));
snd_wss_out
(
chip
,
AD1845_FREQ_SEL_MSB
,
(
unsigned
char
)
(
rate
>>
8
));
snd_wss_out
(
chip
,
AD1845_FREQ_SEL_LSB
,
(
unsigned
char
)
rate
);
spin_unlock_irqrestore
(
&
chip
->
reg_lock
,
flags
);
}
/*
* Override for the CS4231 capture format function.
* The AD1845 has much simpler format and rate selection.
*/
static
void
ad1845_capture_format
(
struct
snd_wss
*
chip
,
struct
snd_pcm_hw_params
*
params
,
unsigned
char
format
)
{
unsigned
long
flags
;
unsigned
rate
=
params_rate
(
params
);
/*
* The AD1845 can't handle sample frequencies
* outside of 4 kHZ to 50 kHZ
*/
if
(
rate
>
50000
)
rate
=
50000
;
else
if
(
rate
<
4000
)
rate
=
4000
;
spin_lock_irqsave
(
&
chip
->
reg_lock
,
flags
);
/*
* Program the AD1845 correctly for the playback stream.
* Note that we do NOT need to toggle the MCE bit because
* the CAPTURE_ENABLE bit of the Interface Configuration
* register is set.
*
* NOTE: We seem to need to write to the MSB before the LSB
* to get the correct sample frequency.
*/
snd_wss_out
(
chip
,
CS4231_REC_FORMAT
,
(
format
&
0xf0
));
snd_wss_out
(
chip
,
AD1845_FREQ_SEL_MSB
,
(
unsigned
char
)
(
rate
>>
8
));
snd_wss_out
(
chip
,
AD1845_FREQ_SEL_LSB
,
(
unsigned
char
)
rate
);
spin_unlock_irqrestore
(
&
chip
->
reg_lock
,
flags
);
}
/*
/*
* Create an AD1845 PCM subdevice on the SoundScape. The AD1845
* Create an AD1845 PCM subdevice on the SoundScape. The AD1845
* is very much like a CS4231, with a few extra bits. We will
* is very much like a CS4231, with a few extra bits. We will
...
@@ -1055,11 +963,6 @@ static int __devinit create_ad1845(struct snd_card *card, unsigned port,
...
@@ -1055,11 +963,6 @@ static int __devinit create_ad1845(struct snd_card *card, unsigned port,
unsigned
long
flags
;
unsigned
long
flags
;
struct
snd_pcm
*
pcm
;
struct
snd_pcm
*
pcm
;
#define AD1845_FREQ_SEL_ENABLE 0x08
#define AD1845_PWR_DOWN_CTRL 0x1b
#define AD1845_CRYS_CLOCK_SEL 0x1d
/*
/*
* It turns out that the PLAYBACK_ENABLE bit is set
* It turns out that the PLAYBACK_ENABLE bit is set
* by the lowlevel driver ...
* by the lowlevel driver ...
...
@@ -1074,7 +977,6 @@ static int __devinit create_ad1845(struct snd_card *card, unsigned port,
...
@@ -1074,7 +977,6 @@ static int __devinit create_ad1845(struct snd_card *card, unsigned port,
*/
*/
if
(
sscape
->
type
!=
SSCAPE_VIVO
)
{
if
(
sscape
->
type
!=
SSCAPE_VIVO
)
{
int
val
;
/*
/*
* The input clock frequency on the SoundScape must
* The input clock frequency on the SoundScape must
* be 14.31818 MHz, because we must set this register
* be 14.31818 MHz, because we must set this register
...
@@ -1082,22 +984,10 @@ static int __devinit create_ad1845(struct snd_card *card, unsigned port,
...
@@ -1082,22 +984,10 @@ static int __devinit create_ad1845(struct snd_card *card, unsigned port,
*/
*/
snd_wss_mce_up
(
chip
);
snd_wss_mce_up
(
chip
);
spin_lock_irqsave
(
&
chip
->
reg_lock
,
flags
);
spin_lock_irqsave
(
&
chip
->
reg_lock
,
flags
);
snd_wss_out
(
chip
,
AD1845_C
RYS_CLOCK_SEL
,
0x20
);
snd_wss_out
(
chip
,
AD1845_C
LOCK
,
0x20
);
spin_unlock_irqrestore
(
&
chip
->
reg_lock
,
flags
);
spin_unlock_irqrestore
(
&
chip
->
reg_lock
,
flags
);
snd_wss_mce_down
(
chip
);
snd_wss_mce_down
(
chip
);
/*
* More custom configuration:
* a) select "mode 2" and provide a current drive of 8mA
* b) enable frequency selection (for capture/playback)
*/
spin_lock_irqsave
(
&
chip
->
reg_lock
,
flags
);
snd_wss_out
(
chip
,
CS4231_MISC_INFO
,
CS4231_MODE2
|
0x10
);
val
=
snd_wss_in
(
chip
,
AD1845_PWR_DOWN_CTRL
);
snd_wss_out
(
chip
,
AD1845_PWR_DOWN_CTRL
,
val
|
AD1845_FREQ_SEL_ENABLE
);
spin_unlock_irqrestore
(
&
chip
->
reg_lock
,
flags
);
}
}
err
=
snd_wss_pcm
(
chip
,
0
,
&
pcm
);
err
=
snd_wss_pcm
(
chip
,
0
,
&
pcm
);
...
@@ -1113,11 +1003,13 @@ static int __devinit create_ad1845(struct snd_card *card, unsigned port,
...
@@ -1113,11 +1003,13 @@ static int __devinit create_ad1845(struct snd_card *card, unsigned port,
"for AD1845 chip
\n
"
);
"for AD1845 chip
\n
"
);
goto
_error
;
goto
_error
;
}
}
err
=
snd_wss_timer
(
chip
,
0
,
NULL
);
if
(
chip
->
hardware
!=
WSS_HW_AD1848
)
{
if
(
err
<
0
)
{
err
=
snd_wss_timer
(
chip
,
0
,
NULL
);
snd_printk
(
KERN_ERR
"sscape: No timer device "
if
(
err
<
0
)
{
"for AD1845 chip
\n
"
);
snd_printk
(
KERN_ERR
"sscape: No timer device "
goto
_error
;
"for AD1845 chip
\n
"
);
goto
_error
;
}
}
}
if
(
sscape
->
type
!=
SSCAPE_VIVO
)
{
if
(
sscape
->
type
!=
SSCAPE_VIVO
)
{
...
@@ -1128,8 +1020,6 @@ static int __devinit create_ad1845(struct snd_card *card, unsigned port,
...
@@ -1128,8 +1020,6 @@ static int __devinit create_ad1845(struct snd_card *card, unsigned port,
"MIDI mixer control
\n
"
);
"MIDI mixer control
\n
"
);
goto
_error
;
goto
_error
;
}
}
chip
->
set_playback_format
=
ad1845_playback_format
;
chip
->
set_capture_format
=
ad1845_capture_format
;
}
}
strcpy
(
card
->
driver
,
"SoundScape"
);
strcpy
(
card
->
driver
,
"SoundScape"
);
...
@@ -1157,7 +1047,6 @@ static int __devinit create_sscape(int dev, struct snd_card *card)
...
@@ -1157,7 +1047,6 @@ static int __devinit create_sscape(int dev, struct snd_card *card)
unsigned
dma_cfg
;
unsigned
dma_cfg
;
unsigned
irq_cfg
;
unsigned
irq_cfg
;
unsigned
mpu_irq_cfg
;
unsigned
mpu_irq_cfg
;
unsigned
xport
;
struct
resource
*
io_res
;
struct
resource
*
io_res
;
struct
resource
*
wss_res
;
struct
resource
*
wss_res
;
unsigned
long
flags
;
unsigned
long
flags
;
...
@@ -1177,15 +1066,15 @@ static int __devinit create_sscape(int dev, struct snd_card *card)
...
@@ -1177,15 +1066,15 @@ static int __devinit create_sscape(int dev, struct snd_card *card)
printk
(
KERN_ERR
"sscape: Invalid IRQ %d
\n
"
,
mpu_irq
[
dev
]);
printk
(
KERN_ERR
"sscape: Invalid IRQ %d
\n
"
,
mpu_irq
[
dev
]);
return
-
ENXIO
;
return
-
ENXIO
;
}
}
xport
=
port
[
dev
];
/*
/*
* Grab IO ports that we will need to probe so that we
* Grab IO ports that we will need to probe so that we
* can detect and control this hardware ...
* can detect and control this hardware ...
*/
*/
io_res
=
request_region
(
xport
,
8
,
"SoundScape"
);
io_res
=
request_region
(
port
[
dev
]
,
8
,
"SoundScape"
);
if
(
!
io_res
)
{
if
(
!
io_res
)
{
snd_printk
(
KERN_ERR
"sscape: can't grab port 0x%x
\n
"
,
xport
);
snd_printk
(
KERN_ERR
"sscape: can't grab port 0x%lx
\n
"
,
port
[
dev
]);
return
-
EBUSY
;
return
-
EBUSY
;
}
}
wss_res
=
NULL
;
wss_res
=
NULL
;
...
@@ -1212,10 +1101,9 @@ static int __devinit create_sscape(int dev, struct snd_card *card)
...
@@ -1212,10 +1101,9 @@ static int __devinit create_sscape(int dev, struct snd_card *card)
spin_lock_init
(
&
sscape
->
fwlock
);
spin_lock_init
(
&
sscape
->
fwlock
);
sscape
->
io_res
=
io_res
;
sscape
->
io_res
=
io_res
;
sscape
->
wss_res
=
wss_res
;
sscape
->
wss_res
=
wss_res
;
sscape
->
io_base
=
xport
;
sscape
->
io_base
=
port
[
dev
];
sscape
->
wss_base
=
wss_port
[
dev
];
if
(
!
detect_sscape
(
sscape
))
{
if
(
!
detect_sscape
(
sscape
,
wss_port
[
dev
]
))
{
printk
(
KERN_ERR
"sscape: hardware not detected at 0x%x
\n
"
,
sscape
->
io_base
);
printk
(
KERN_ERR
"sscape: hardware not detected at 0x%x
\n
"
,
sscape
->
io_base
);
err
=
-
ENODEV
;
err
=
-
ENODEV
;
goto
_release_dma
;
goto
_release_dma
;
...
@@ -1288,12 +1176,11 @@ static int __devinit create_sscape(int dev, struct snd_card *card)
...
@@ -1288,12 +1176,11 @@ static int __devinit create_sscape(int dev, struct snd_card *card)
}
}
#define MIDI_DEVNUM 0
#define MIDI_DEVNUM 0
if
(
sscape
->
type
!=
SSCAPE_VIVO
)
{
if
(
sscape
->
type
!=
SSCAPE_VIVO
)
{
err
=
create_mpu401
(
card
,
MIDI_DEVNUM
,
err
=
create_mpu401
(
card
,
MIDI_DEVNUM
,
port
[
dev
],
mpu_irq
[
dev
]);
MPU401_IO
(
xport
),
mpu_irq
[
dev
]);
if
(
err
<
0
)
{
if
(
err
<
0
)
{
printk
(
KERN_ERR
"sscape: Failed to create "
printk
(
KERN_ERR
"sscape: Failed to create "
"MPU-401 device at 0x%x
\n
"
,
"MPU-401 device at 0x%
l
x
\n
"
,
MPU401_IO
(
xport
)
);
port
[
dev
]
);
goto
_release_dma
;
goto
_release_dma
;
}
}
...
...
sound/isa/wss/wss_lib.c
View file @
d0807323
...
@@ -181,25 +181,6 @@ static void snd_wss_wait(struct snd_wss *chip)
...
@@ -181,25 +181,6 @@ static void snd_wss_wait(struct snd_wss *chip)
udelay
(
100
);
udelay
(
100
);
}
}
static
void
snd_wss_outm
(
struct
snd_wss
*
chip
,
unsigned
char
reg
,
unsigned
char
mask
,
unsigned
char
value
)
{
unsigned
char
tmp
=
(
chip
->
image
[
reg
]
&
mask
)
|
value
;
snd_wss_wait
(
chip
);
#ifdef CONFIG_SND_DEBUG
if
(
wss_inb
(
chip
,
CS4231P
(
REGSEL
))
&
CS4231_INIT
)
snd_printk
(
"outm: auto calibration time out - reg = 0x%x, value = 0x%x
\n
"
,
reg
,
value
);
#endif
chip
->
image
[
reg
]
=
tmp
;
if
(
!
chip
->
calibrate_mute
)
{
wss_outb
(
chip
,
CS4231P
(
REGSEL
),
chip
->
mce_bit
|
reg
);
wmb
();
wss_outb
(
chip
,
CS4231P
(
REG
),
tmp
);
mb
();
}
}
static
void
snd_wss_dout
(
struct
snd_wss
*
chip
,
unsigned
char
reg
,
static
void
snd_wss_dout
(
struct
snd_wss
*
chip
,
unsigned
char
reg
,
unsigned
char
value
)
unsigned
char
value
)
{
{
...
@@ -597,7 +578,15 @@ static void snd_wss_calibrate_mute(struct snd_wss *chip, int mute)
...
@@ -597,7 +578,15 @@ static void snd_wss_calibrate_mute(struct snd_wss *chip, int mute)
chip
->
image
[
CS4231_RIGHT_INPUT
]);
chip
->
image
[
CS4231_RIGHT_INPUT
]);
snd_wss_dout
(
chip
,
CS4231_LOOPBACK
,
snd_wss_dout
(
chip
,
CS4231_LOOPBACK
,
chip
->
image
[
CS4231_LOOPBACK
]);
chip
->
image
[
CS4231_LOOPBACK
]);
}
else
{
snd_wss_dout
(
chip
,
CS4231_LEFT_INPUT
,
0
);
snd_wss_dout
(
chip
,
CS4231_RIGHT_INPUT
,
0
);
snd_wss_dout
(
chip
,
CS4231_LOOPBACK
,
0xfd
);
}
}
snd_wss_dout
(
chip
,
CS4231_AUX1_LEFT_INPUT
,
snd_wss_dout
(
chip
,
CS4231_AUX1_LEFT_INPUT
,
mute
|
chip
->
image
[
CS4231_AUX1_LEFT_INPUT
]);
mute
|
chip
->
image
[
CS4231_AUX1_LEFT_INPUT
]);
snd_wss_dout
(
chip
,
CS4231_AUX1_RIGHT_INPUT
,
snd_wss_dout
(
chip
,
CS4231_AUX1_RIGHT_INPUT
,
...
@@ -640,7 +629,6 @@ static void snd_wss_playback_format(struct snd_wss *chip,
...
@@ -640,7 +629,6 @@ static void snd_wss_playback_format(struct snd_wss *chip,
int
full_calib
=
1
;
int
full_calib
=
1
;
mutex_lock
(
&
chip
->
mce_mutex
);
mutex_lock
(
&
chip
->
mce_mutex
);
snd_wss_calibrate_mute
(
chip
,
1
);
if
(
chip
->
hardware
==
WSS_HW_CS4231A
||
if
(
chip
->
hardware
==
WSS_HW_CS4231A
||
(
chip
->
hardware
&
WSS_HW_CS4232_MASK
))
{
(
chip
->
hardware
&
WSS_HW_CS4232_MASK
))
{
spin_lock_irqsave
(
&
chip
->
reg_lock
,
flags
);
spin_lock_irqsave
(
&
chip
->
reg_lock
,
flags
);
...
@@ -656,6 +644,24 @@ static void snd_wss_playback_format(struct snd_wss *chip,
...
@@ -656,6 +644,24 @@ static void snd_wss_playback_format(struct snd_wss *chip,
full_calib
=
0
;
full_calib
=
0
;
}
}
spin_unlock_irqrestore
(
&
chip
->
reg_lock
,
flags
);
spin_unlock_irqrestore
(
&
chip
->
reg_lock
,
flags
);
}
else
if
(
chip
->
hardware
==
WSS_HW_AD1845
)
{
unsigned
rate
=
params_rate
(
params
);
/*
* Program the AD1845 correctly for the playback stream.
* Note that we do NOT need to toggle the MCE bit because
* the PLAYBACK_ENABLE bit of the Interface Configuration
* register is set.
*
* NOTE: We seem to need to write to the MSB before the LSB
* to get the correct sample frequency.
*/
spin_lock_irqsave
(
&
chip
->
reg_lock
,
flags
);
snd_wss_out
(
chip
,
CS4231_PLAYBK_FORMAT
,
(
pdfr
&
0xf0
));
snd_wss_out
(
chip
,
AD1845_UPR_FREQ_SEL
,
(
rate
>>
8
)
&
0xff
);
snd_wss_out
(
chip
,
AD1845_LWR_FREQ_SEL
,
rate
&
0xff
);
full_calib
=
0
;
spin_unlock_irqrestore
(
&
chip
->
reg_lock
,
flags
);
}
}
if
(
full_calib
)
{
if
(
full_calib
)
{
snd_wss_mce_up
(
chip
);
snd_wss_mce_up
(
chip
);
...
@@ -673,7 +679,6 @@ static void snd_wss_playback_format(struct snd_wss *chip,
...
@@ -673,7 +679,6 @@ static void snd_wss_playback_format(struct snd_wss *chip,
udelay
(
100
);
/* this seems to help */
udelay
(
100
);
/* this seems to help */
snd_wss_mce_down
(
chip
);
snd_wss_mce_down
(
chip
);
}
}
snd_wss_calibrate_mute
(
chip
,
0
);
mutex_unlock
(
&
chip
->
mce_mutex
);
mutex_unlock
(
&
chip
->
mce_mutex
);
}
}
...
@@ -685,7 +690,6 @@ static void snd_wss_capture_format(struct snd_wss *chip,
...
@@ -685,7 +690,6 @@ static void snd_wss_capture_format(struct snd_wss *chip,
int
full_calib
=
1
;
int
full_calib
=
1
;
mutex_lock
(
&
chip
->
mce_mutex
);
mutex_lock
(
&
chip
->
mce_mutex
);
snd_wss_calibrate_mute
(
chip
,
1
);
if
(
chip
->
hardware
==
WSS_HW_CS4231A
||
if
(
chip
->
hardware
==
WSS_HW_CS4231A
||
(
chip
->
hardware
&
WSS_HW_CS4232_MASK
))
{
(
chip
->
hardware
&
WSS_HW_CS4232_MASK
))
{
spin_lock_irqsave
(
&
chip
->
reg_lock
,
flags
);
spin_lock_irqsave
(
&
chip
->
reg_lock
,
flags
);
...
@@ -700,6 +704,24 @@ static void snd_wss_capture_format(struct snd_wss *chip,
...
@@ -700,6 +704,24 @@ static void snd_wss_capture_format(struct snd_wss *chip,
full_calib
=
0
;
full_calib
=
0
;
}
}
spin_unlock_irqrestore
(
&
chip
->
reg_lock
,
flags
);
spin_unlock_irqrestore
(
&
chip
->
reg_lock
,
flags
);
}
else
if
(
chip
->
hardware
==
WSS_HW_AD1845
)
{
unsigned
rate
=
params_rate
(
params
);
/*
* Program the AD1845 correctly for the capture stream.
* Note that we do NOT need to toggle the MCE bit because
* the PLAYBACK_ENABLE bit of the Interface Configuration
* register is set.
*
* NOTE: We seem to need to write to the MSB before the LSB
* to get the correct sample frequency.
*/
spin_lock_irqsave
(
&
chip
->
reg_lock
,
flags
);
snd_wss_out
(
chip
,
CS4231_REC_FORMAT
,
(
cdfr
&
0xf0
));
snd_wss_out
(
chip
,
AD1845_UPR_FREQ_SEL
,
(
rate
>>
8
)
&
0xff
);
snd_wss_out
(
chip
,
AD1845_LWR_FREQ_SEL
,
rate
&
0xff
);
full_calib
=
0
;
spin_unlock_irqrestore
(
&
chip
->
reg_lock
,
flags
);
}
}
if
(
full_calib
)
{
if
(
full_calib
)
{
snd_wss_mce_up
(
chip
);
snd_wss_mce_up
(
chip
);
...
@@ -724,7 +746,6 @@ static void snd_wss_capture_format(struct snd_wss *chip,
...
@@ -724,7 +746,6 @@ static void snd_wss_capture_format(struct snd_wss *chip,
spin_unlock_irqrestore
(
&
chip
->
reg_lock
,
flags
);
spin_unlock_irqrestore
(
&
chip
->
reg_lock
,
flags
);
snd_wss_mce_down
(
chip
);
snd_wss_mce_down
(
chip
);
}
}
snd_wss_calibrate_mute
(
chip
,
0
);
mutex_unlock
(
&
chip
->
mce_mutex
);
mutex_unlock
(
&
chip
->
mce_mutex
);
}
}
...
@@ -781,6 +802,7 @@ static void snd_wss_init(struct snd_wss *chip)
...
@@ -781,6 +802,7 @@ static void snd_wss_init(struct snd_wss *chip)
{
{
unsigned
long
flags
;
unsigned
long
flags
;
snd_wss_calibrate_mute
(
chip
,
1
);
snd_wss_mce_down
(
chip
);
snd_wss_mce_down
(
chip
);
#ifdef SNDRV_DEBUG_MCE
#ifdef SNDRV_DEBUG_MCE
...
@@ -804,6 +826,8 @@ static void snd_wss_init(struct snd_wss *chip)
...
@@ -804,6 +826,8 @@ static void snd_wss_init(struct snd_wss *chip)
snd_wss_mce_up
(
chip
);
snd_wss_mce_up
(
chip
);
spin_lock_irqsave
(
&
chip
->
reg_lock
,
flags
);
spin_lock_irqsave
(
&
chip
->
reg_lock
,
flags
);
chip
->
image
[
CS4231_IFACE_CTRL
]
&=
~
CS4231_AUTOCALIB
;
snd_wss_out
(
chip
,
CS4231_IFACE_CTRL
,
chip
->
image
[
CS4231_IFACE_CTRL
]);
snd_wss_out
(
chip
,
snd_wss_out
(
chip
,
CS4231_ALT_FEATURE_1
,
chip
->
image
[
CS4231_ALT_FEATURE_1
]);
CS4231_ALT_FEATURE_1
,
chip
->
image
[
CS4231_ALT_FEATURE_1
]);
spin_unlock_irqrestore
(
&
chip
->
reg_lock
,
flags
);
spin_unlock_irqrestore
(
&
chip
->
reg_lock
,
flags
);
...
@@ -837,6 +861,7 @@ static void snd_wss_init(struct snd_wss *chip)
...
@@ -837,6 +861,7 @@ static void snd_wss_init(struct snd_wss *chip)
chip
->
image
[
CS4231_REC_FORMAT
]);
chip
->
image
[
CS4231_REC_FORMAT
]);
spin_unlock_irqrestore
(
&
chip
->
reg_lock
,
flags
);
spin_unlock_irqrestore
(
&
chip
->
reg_lock
,
flags
);
snd_wss_mce_down
(
chip
);
snd_wss_mce_down
(
chip
);
snd_wss_calibrate_mute
(
chip
,
0
);
#ifdef SNDRV_DEBUG_MCE
#ifdef SNDRV_DEBUG_MCE
snd_printk
(
KERN_DEBUG
"init: (5)
\n
"
);
snd_printk
(
KERN_DEBUG
"init: (5)
\n
"
);
...
@@ -895,8 +920,6 @@ static void snd_wss_close(struct snd_wss *chip, unsigned int mode)
...
@@ -895,8 +920,6 @@ static void snd_wss_close(struct snd_wss *chip, unsigned int mode)
mutex_unlock
(
&
chip
->
open_mutex
);
mutex_unlock
(
&
chip
->
open_mutex
);
return
;
return
;
}
}
snd_wss_calibrate_mute
(
chip
,
1
);
/* disable IRQ */
/* disable IRQ */
spin_lock_irqsave
(
&
chip
->
reg_lock
,
flags
);
spin_lock_irqsave
(
&
chip
->
reg_lock
,
flags
);
if
(
!
(
chip
->
hardware
&
WSS_HW_AD1848_MASK
))
if
(
!
(
chip
->
hardware
&
WSS_HW_AD1848_MASK
))
...
@@ -929,8 +952,6 @@ static void snd_wss_close(struct snd_wss *chip, unsigned int mode)
...
@@ -929,8 +952,6 @@ static void snd_wss_close(struct snd_wss *chip, unsigned int mode)
wss_outb
(
chip
,
CS4231P
(
STATUS
),
0
);
/* clear IRQ */
wss_outb
(
chip
,
CS4231P
(
STATUS
),
0
);
/* clear IRQ */
spin_unlock_irqrestore
(
&
chip
->
reg_lock
,
flags
);
spin_unlock_irqrestore
(
&
chip
->
reg_lock
,
flags
);
snd_wss_calibrate_mute
(
chip
,
0
);
chip
->
mode
=
0
;
chip
->
mode
=
0
;
mutex_unlock
(
&
chip
->
open_mutex
);
mutex_unlock
(
&
chip
->
open_mutex
);
}
}
...
@@ -1123,7 +1144,7 @@ irqreturn_t snd_wss_interrupt(int irq, void *dev_id)
...
@@ -1123,7 +1144,7 @@ irqreturn_t snd_wss_interrupt(int irq, void *dev_id)
if
(
chip
->
hardware
&
WSS_HW_AD1848_MASK
)
if
(
chip
->
hardware
&
WSS_HW_AD1848_MASK
)
wss_outb
(
chip
,
CS4231P
(
STATUS
),
0
);
wss_outb
(
chip
,
CS4231P
(
STATUS
),
0
);
else
else
snd_wss_out
m
(
chip
,
CS4231_IRQ_STATUS
,
status
,
0
);
snd_wss_out
(
chip
,
CS4231_IRQ_STATUS
,
status
);
spin_unlock
(
&
chip
->
reg_lock
);
spin_unlock
(
&
chip
->
reg_lock
);
return
IRQ_HANDLED
;
return
IRQ_HANDLED
;
}
}
...
@@ -1325,6 +1346,10 @@ static int snd_wss_probe(struct snd_wss *chip)
...
@@ -1325,6 +1346,10 @@ static int snd_wss_probe(struct snd_wss *chip)
chip
->
image
[
CS4231_ALT_FEATURE_2
]
=
chip
->
image
[
CS4231_ALT_FEATURE_2
]
=
chip
->
hardware
==
WSS_HW_INTERWAVE
?
0xc2
:
0x01
;
chip
->
hardware
==
WSS_HW_INTERWAVE
?
0xc2
:
0x01
;
}
}
/* enable fine grained frequency selection */
if
(
chip
->
hardware
==
WSS_HW_AD1845
)
chip
->
image
[
AD1845_PWR_DOWN
]
=
8
;
ptr
=
(
unsigned
char
*
)
&
chip
->
image
;
ptr
=
(
unsigned
char
*
)
&
chip
->
image
;
regnum
=
(
chip
->
hardware
&
WSS_HW_AD1848_MASK
)
?
16
:
32
;
regnum
=
(
chip
->
hardware
&
WSS_HW_AD1848_MASK
)
?
16
:
32
;
snd_wss_mce_down
(
chip
);
snd_wss_mce_down
(
chip
);
...
...
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