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
86b3aa39
Commit
86b3aa39
authored
Dec 25, 2008
by
Takashi Iwai
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'topic/ca0106' into to-push
parents
e4456e71
ebef7cfc
Changes
25
Hide whitespace changes
Inline
Side-by-side
Showing
25 changed files
with
1012 additions
and
670 deletions
+1012
-670
include/sound/core.h
include/sound/core.h
+25
-3
include/sound/version.h
include/sound/version.h
+1
-1
sound/ac97_bus.c
sound/ac97_bus.c
+1
-0
sound/core/device.c
sound/core/device.c
+2
-2
sound/drivers/Kconfig
sound/drivers/Kconfig
+1
-1
sound/drivers/pcsp/pcsp.c
sound/drivers/pcsp/pcsp.c
+3
-5
sound/drivers/pcsp/pcsp.h
sound/drivers/pcsp/pcsp.h
+3
-0
sound/drivers/pcsp/pcsp_lib.c
sound/drivers/pcsp/pcsp_lib.c
+101
-67
sound/isa/sb/sb8.c
sound/isa/sb/sb8.c
+3
-1
sound/pci/ac97/ac97_codec.c
sound/pci/ac97/ac97_codec.c
+1
-1
sound/pci/ac97/ac97_patch.c
sound/pci/ac97/ac97_patch.c
+2
-0
sound/pci/ca0106/ca0106.h
sound/pci/ca0106/ca0106.h
+24
-6
sound/pci/ca0106/ca0106_main.c
sound/pci/ca0106/ca0106_main.c
+333
-217
sound/pci/ca0106/ca0106_mixer.c
sound/pci/ca0106/ca0106_mixer.c
+195
-68
sound/pci/cs46xx/cs46xx_lib.c
sound/pci/cs46xx/cs46xx_lib.c
+4
-1
sound/pci/emu10k1/emu10k1_main.c
sound/pci/emu10k1/emu10k1_main.c
+258
-236
sound/pci/ice1712/ice1724.c
sound/pci/ice1712/ice1724.c
+12
-11
sound/pci/mixart/mixart.c
sound/pci/mixart/mixart.c
+3
-1
sound/pci/pcxhr/pcxhr.c
sound/pci/pcxhr/pcxhr.c
+3
-1
sound/pci/riptide/riptide.c
sound/pci/riptide/riptide.c
+1
-1
sound/ppc/pmac.c
sound/ppc/pmac.c
+1
-1
sound/ppc/tumbler.c
sound/ppc/tumbler.c
+2
-1
sound/usb/caiaq/caiaq-control.c
sound/usb/caiaq/caiaq-control.c
+30
-43
sound/usb/caiaq/caiaq-device.c
sound/usb/caiaq/caiaq-device.c
+1
-1
sound/usb/usx2y/usb_stream.c
sound/usb/usx2y/usb_stream.c
+2
-1
No files found.
include/sound/core.h
View file @
86b3aa39
...
...
@@ -353,7 +353,7 @@ void snd_verbose_printd(const char *file, int line, const char *format, ...)
* snd_printk - printk wrapper
* @fmt: format string
*
* Works like print() but prints the file and the line of the caller
* Works like print
k
() but prints the file and the line of the caller
* when configured with CONFIG_SND_VERBOSE_PRINTK.
*/
#define snd_printk(fmt, args...) \
...
...
@@ -380,18 +380,40 @@ void snd_verbose_printd(const char *file, int line, const char *format, ...)
printk(fmt ,##args)
#endif
/**
* snd_BUG - give a BUG warning message and stack trace
*
* Calls WARN() if CONFIG_SND_DEBUG is set.
* Ignored when CONFIG_SND_DEBUG is not set.
*/
#define snd_BUG() WARN(1, "BUG?\n")
/**
* snd_BUG_ON - debugging check macro
* @cond: condition to evaluate
*
* When CONFIG_SND_DEBUG is set, this macro evaluates the given condition,
* and call WARN() and returns the value if it's non-zero.
*
* When CONFIG_SND_DEBUG is not set, this just returns zero, and the given
* condition is ignored.
*
* NOTE: the argument won't be evaluated at all when CONFIG_SND_DEBUG=n.
* Thus, don't put any statement that influences on the code behavior,
* such as pre/post increment, to the argument of this macro.
* If you want to evaluate and give a warning, use standard WARN_ON().
*/
#define snd_BUG_ON(cond) WARN((cond), "BUG? (%s)\n", __stringify(cond))
#else
/* !CONFIG_SND_DEBUG */
#define snd_printd(fmt, args...) do { } while (0)
#define snd_BUG() do { } while (0)
static
inline
int
__snd_bug_on
(
voi
d
)
static
inline
int
__snd_bug_on
(
int
con
d
)
{
return
0
;
}
#define snd_BUG_ON(cond)
__snd_bug_on(
)
/* always false */
#define snd_BUG_ON(cond)
__snd_bug_on(0 && (cond)
)
/* always false */
#endif
/* CONFIG_SND_DEBUG */
...
...
include/sound/version.h
View file @
86b3aa39
/* include/version.h */
#define CONFIG_SND_VERSION "1.0.18
rc3
"
#define CONFIG_SND_VERSION "1.0.18
a
"
#define CONFIG_SND_DATE ""
sound/ac97_bus.c
View file @
86b3aa39
...
...
@@ -15,6 +15,7 @@
#include <linux/init.h>
#include <linux/device.h>
#include <linux/string.h>
#include <sound/ac97_codec.h>
/*
* Let drivers decide whether they want to support given codec from their
...
...
sound/core/device.c
View file @
86b3aa39
...
...
@@ -98,7 +98,7 @@ int snd_device_free(struct snd_card *card, void *device_data)
kfree
(
dev
);
return
0
;
}
snd_printd
(
"device free %p (from %p), not found
\n
"
,
device_data
,
snd_printd
(
"device free %p (from %p
F
), not found
\n
"
,
device_data
,
__builtin_return_address
(
0
));
return
-
ENXIO
;
}
...
...
@@ -135,7 +135,7 @@ int snd_device_disconnect(struct snd_card *card, void *device_data)
}
return
0
;
}
snd_printd
(
"device disconnect %p (from %p), not found
\n
"
,
device_data
,
snd_printd
(
"device disconnect %p (from %p
F
), not found
\n
"
,
device_data
,
__builtin_return_address
(
0
));
return
-
ENXIO
;
}
...
...
sound/drivers/Kconfig
View file @
86b3aa39
...
...
@@ -163,7 +163,7 @@ config SND_ML403_AC97CR
config SND_AC97_POWER_SAVE
bool "AC97 Power-Saving Mode"
depends on SND_AC97_CODEC
&& EXPERIMENTAL
depends on SND_AC97_CODEC
default n
help
Say Y here to enable the aggressive power-saving support of
...
...
sound/drivers/pcsp/pcsp.c
View file @
86b3aa39
...
...
@@ -96,7 +96,7 @@ static int __devinit snd_card_pcsp_probe(int devnum, struct device *dev)
return
-
EINVAL
;
hrtimer_init
(
&
pcsp_chip
.
timer
,
CLOCK_MONOTONIC
,
HRTIMER_MODE_REL
);
pcsp_chip
.
timer
.
cb_mode
=
HRTIMER_CB_
SOFTIRQ
;
pcsp_chip
.
timer
.
cb_mode
=
HRTIMER_CB_
IRQSAFE_UNLOCKED
;
pcsp_chip
.
timer
.
function
=
pcsp_do_timer
;
card
=
snd_card_new
(
index
,
id
,
THIS_MODULE
,
0
);
...
...
@@ -188,10 +188,8 @@ static int __devexit pcsp_remove(struct platform_device *dev)
static
void
pcsp_stop_beep
(
struct
snd_pcsp
*
chip
)
{
spin_lock_irq
(
&
chip
->
substream_lock
);
if
(
!
chip
->
playback_substream
)
pcspkr_stop_sound
();
spin_unlock_irq
(
&
chip
->
substream_lock
);
pcsp_sync_stop
(
chip
);
pcspkr_stop_sound
();
}
#ifdef CONFIG_PM
...
...
sound/drivers/pcsp/pcsp.h
View file @
86b3aa39
...
...
@@ -62,6 +62,8 @@ struct snd_pcsp {
unsigned
short
port
,
irq
,
dma
;
spinlock_t
substream_lock
;
struct
snd_pcm_substream
*
playback_substream
;
unsigned
int
fmt_size
;
unsigned
int
is_signed
;
size_t
playback_ptr
;
size_t
period_ptr
;
atomic_t
timer_active
;
...
...
@@ -77,6 +79,7 @@ struct snd_pcsp {
extern
struct
snd_pcsp
pcsp_chip
;
extern
enum
hrtimer_restart
pcsp_do_timer
(
struct
hrtimer
*
handle
);
extern
void
pcsp_sync_stop
(
struct
snd_pcsp
*
chip
);
extern
int
snd_pcsp_new_pcm
(
struct
snd_pcsp
*
chip
);
extern
int
snd_pcsp_new_mixer
(
struct
snd_pcsp
*
chip
);
...
...
sound/drivers/pcsp/pcsp_lib.c
View file @
86b3aa39
...
...
@@ -8,6 +8,7 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/interrupt.h>
#include <sound/pcm.h>
#include <asm/io.h>
#include "pcsp.h"
...
...
@@ -19,61 +20,57 @@ MODULE_PARM_DESC(nforce_wa, "Apply NForce chipset workaround "
#define DMIX_WANTS_S16 1
enum
hrtimer_restart
pcsp_do_timer
(
struct
hrtimer
*
handle
)
/*
* Call snd_pcm_period_elapsed in a tasklet
* This avoids spinlock messes and long-running irq contexts
*/
static
void
pcsp_call_pcm_elapsed
(
unsigned
long
priv
)
{
if
(
atomic_read
(
&
pcsp_chip
.
timer_active
))
{
struct
snd_pcm_substream
*
substream
;
substream
=
pcsp_chip
.
playback_substream
;
if
(
substream
)
snd_pcm_period_elapsed
(
substream
);
}
}
static
DECLARE_TASKLET
(
pcsp_pcm_tasklet
,
pcsp_call_pcm_elapsed
,
0
);
/* write the port and returns the next expire time in ns;
* called at the trigger-start and in hrtimer callback
*/
static
unsigned
long
pcsp_timer_update
(
struct
hrtimer
*
handle
)
{
unsigned
char
timer_cnt
,
val
;
int
fmt_size
,
periods_elapsed
;
u64
ns
;
size_t
period_bytes
,
buffer_bytes
;
struct
snd_pcm_substream
*
substream
;
struct
snd_pcm_runtime
*
runtime
;
struct
snd_pcsp
*
chip
=
container_of
(
handle
,
struct
snd_pcsp
,
timer
);
unsigned
long
flags
;
if
(
chip
->
thalf
)
{
outb
(
chip
->
val61
,
0x61
);
chip
->
thalf
=
0
;
if
(
!
atomic_read
(
&
chip
->
timer_active
))
return
HRTIMER_NORESTART
;
hrtimer_forward
(
&
chip
->
timer
,
hrtimer_get_expires
(
&
chip
->
timer
),
ktime_set
(
0
,
chip
->
ns_rem
));
return
HRTIMER_RESTART
;
return
0
;
return
chip
->
ns_rem
;
}
spin_lock_irq
(
&
chip
->
substream_lock
);
/* Takashi Iwai says regarding this extra lock:
If the irq handler handles some data on the DMA buffer, it should
do snd_pcm_stream_lock().
That protects basically against all races among PCM callbacks, yes.
However, there are two remaining issues:
1. The substream pointer you try to lock isn't protected _before_
this lock yet.
2. snd_pcm_period_elapsed() itself acquires the lock.
The requirement of another lock is because of 1. When you get
chip->playback_substream, it's not protected.
Keeping this lock while snd_pcm_period_elapsed() assures the substream
is still protected (at least, not released). And the other status is
handled properly inside snd_pcm_stream_lock() in
snd_pcm_period_elapsed().
*/
if
(
!
chip
->
playback_substream
)
goto
exit_nr_unlock1
;
substream
=
chip
->
playback_substream
;
snd_pcm_stream_lock
(
substream
);
if
(
!
atomic_read
(
&
chip
->
timer_active
))
goto
exit_nr_unlock2
;
return
0
;
substream
=
chip
->
playback_substream
;
if
(
!
substream
)
return
0
;
runtime
=
substream
->
runtime
;
fmt_size
=
snd_pcm_format_physical_width
(
runtime
->
format
)
>>
3
;
/* assume it is mono! */
val
=
runtime
->
dma_area
[
chip
->
playback_ptr
+
fmt_size
-
1
];
if
(
snd_pcm_format_signed
(
runtime
->
format
)
)
val
=
runtime
->
dma_area
[
chip
->
playback_ptr
+
chip
->
fmt_size
-
1
];
if
(
chip
->
is_signed
)
val
^=
0x80
;
timer_cnt
=
val
*
CUR_DIV
()
/
256
;
if
(
timer_cnt
&&
chip
->
enable
)
{
spin_lock
(
&
i8253_lock
);
spin_lock
_irqsave
(
&
i8253_lock
,
flags
);
if
(
!
nforce_wa
)
{
outb_p
(
chip
->
val61
,
0x61
);
outb_p
(
timer_cnt
,
0x42
);
...
...
@@ -82,12 +79,39 @@ enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle)
outb
(
chip
->
val61
^
2
,
0x61
);
chip
->
thalf
=
1
;
}
spin_unlock
(
&
i8253_lock
);
spin_unlock
_irqrestore
(
&
i8253_lock
,
flags
);
}
chip
->
ns_rem
=
PCSP_PERIOD_NS
();
ns
=
(
chip
->
thalf
?
PCSP_CALC_NS
(
timer_cnt
)
:
chip
->
ns_rem
);
chip
->
ns_rem
-=
ns
;
return
ns
;
}
enum
hrtimer_restart
pcsp_do_timer
(
struct
hrtimer
*
handle
)
{
struct
snd_pcsp
*
chip
=
container_of
(
handle
,
struct
snd_pcsp
,
timer
);
struct
snd_pcm_substream
*
substream
;
int
periods_elapsed
,
pointer_update
;
size_t
period_bytes
,
buffer_bytes
;
unsigned
long
ns
;
unsigned
long
flags
;
pointer_update
=
!
chip
->
thalf
;
ns
=
pcsp_timer_update
(
handle
);
if
(
!
ns
)
return
HRTIMER_NORESTART
;
/* update the playback position */
substream
=
chip
->
playback_substream
;
if
(
!
substream
)
return
HRTIMER_NORESTART
;
period_bytes
=
snd_pcm_lib_period_bytes
(
substream
);
buffer_bytes
=
snd_pcm_lib_buffer_bytes
(
substream
);
chip
->
playback_ptr
+=
PCSP_INDEX_INC
()
*
fmt_size
;
spin_lock_irqsave
(
&
chip
->
substream_lock
,
flags
);
chip
->
playback_ptr
+=
PCSP_INDEX_INC
()
*
chip
->
fmt_size
;
periods_elapsed
=
chip
->
playback_ptr
-
chip
->
period_ptr
;
if
(
periods_elapsed
<
0
)
{
#if PCSP_DEBUG
...
...
@@ -102,41 +126,30 @@ enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle)
* or ALSA will BUG on us. */
chip
->
playback_ptr
%=
buffer_bytes
;
snd_pcm_stream_unlock
(
substream
);
if
(
periods_elapsed
)
{
snd_pcm_period_elapsed
(
substream
);
chip
->
period_ptr
+=
periods_elapsed
*
period_bytes
;
chip
->
period_ptr
%=
buffer_bytes
;
}
spin_unlock_irqrestore
(
&
chip
->
substream_lock
,
flags
);
spin_unlock_irq
(
&
chip
->
substream_lock
);
if
(
periods_elapsed
)
tasklet_schedule
(
&
pcsp_pcm_tasklet
);
if
(
!
atomic_read
(
&
chip
->
timer_active
))
return
HRTIMER_NORESTART
;
hrtimer_forward
(
handle
,
hrtimer_get_expires
(
handle
),
ns_to_ktime
(
ns
));
chip
->
ns_rem
=
PCSP_PERIOD_NS
();
ns
=
(
chip
->
thalf
?
PCSP_CALC_NS
(
timer_cnt
)
:
chip
->
ns_rem
);
chip
->
ns_rem
-=
ns
;
hrtimer_forward
(
&
chip
->
timer
,
hrtimer_get_expires
(
&
chip
->
timer
),
ktime_set
(
0
,
ns
));
return
HRTIMER_RESTART
;
exit_nr_unlock2:
snd_pcm_stream_unlock
(
substream
);
exit_nr_unlock1:
spin_unlock_irq
(
&
chip
->
substream_lock
);
return
HRTIMER_NORESTART
;
}
static
void
pcsp_start_playing
(
struct
snd_pcsp
*
chip
)
static
int
pcsp_start_playing
(
struct
snd_pcsp
*
chip
)
{
unsigned
long
ns
;
#if PCSP_DEBUG
printk
(
KERN_INFO
"PCSP: start_playing called
\n
"
);
#endif
if
(
atomic_read
(
&
chip
->
timer_active
))
{
printk
(
KERN_ERR
"PCSP: Timer already active
\n
"
);
return
;
return
-
EIO
;
}
spin_lock
(
&
i8253_lock
);
...
...
@@ -146,7 +159,12 @@ static void pcsp_start_playing(struct snd_pcsp *chip)
atomic_set
(
&
chip
->
timer_active
,
1
);
chip
->
thalf
=
0
;
hrtimer_start
(
&
pcsp_chip
.
timer
,
ktime_set
(
0
,
0
),
HRTIMER_MODE_REL
);
ns
=
pcsp_timer_update
(
&
pcsp_chip
.
timer
);
if
(
!
ns
)
return
-
EIO
;
hrtimer_start
(
&
pcsp_chip
.
timer
,
ktime_set
(
0
,
ns
),
HRTIMER_MODE_REL
);
return
0
;
}
static
void
pcsp_stop_playing
(
struct
snd_pcsp
*
chip
)
...
...
@@ -165,26 +183,35 @@ static void pcsp_stop_playing(struct snd_pcsp *chip)
spin_unlock
(
&
i8253_lock
);
}
/*
* Force to stop and sync the stream
*/
void
pcsp_sync_stop
(
struct
snd_pcsp
*
chip
)
{
local_irq_disable
();
pcsp_stop_playing
(
chip
);
local_irq_enable
();
hrtimer_cancel
(
&
chip
->
timer
);
tasklet_kill
(
&
pcsp_pcm_tasklet
);
}
static
int
snd_pcsp_playback_close
(
struct
snd_pcm_substream
*
substream
)
{
struct
snd_pcsp
*
chip
=
snd_pcm_substream_chip
(
substream
);
#if PCSP_DEBUG
printk
(
KERN_INFO
"PCSP: close called
\n
"
);
#endif
if
(
atomic_read
(
&
chip
->
timer_active
))
{
printk
(
KERN_ERR
"PCSP: timer still active
\n
"
);
pcsp_stop_playing
(
chip
);
}
spin_lock_irq
(
&
chip
->
substream_lock
);
pcsp_sync_stop
(
chip
);
chip
->
playback_substream
=
NULL
;
spin_unlock_irq
(
&
chip
->
substream_lock
);
return
0
;
}
static
int
snd_pcsp_playback_hw_params
(
struct
snd_pcm_substream
*
substream
,
struct
snd_pcm_hw_params
*
hw_params
)
{
struct
snd_pcsp
*
chip
=
snd_pcm_substream_chip
(
substream
);
int
err
;
pcsp_sync_stop
(
chip
);
err
=
snd_pcm_lib_malloc_pages
(
substream
,
params_buffer_bytes
(
hw_params
));
if
(
err
<
0
)
...
...
@@ -194,9 +221,11 @@ static int snd_pcsp_playback_hw_params(struct snd_pcm_substream *substream,
static
int
snd_pcsp_playback_hw_free
(
struct
snd_pcm_substream
*
substream
)
{
struct
snd_pcsp
*
chip
=
snd_pcm_substream_chip
(
substream
);
#if PCSP_DEBUG
printk
(
KERN_INFO
"PCSP: hw_free called
\n
"
);
#endif
pcsp_sync_stop
(
chip
);
return
snd_pcm_lib_free_pages
(
substream
);
}
...
...
@@ -212,8 +241,12 @@ static int snd_pcsp_playback_prepare(struct snd_pcm_substream *substream)
snd_pcm_lib_period_bytes
(
substream
),
substream
->
runtime
->
periods
);
#endif
pcsp_sync_stop
(
chip
);
chip
->
playback_ptr
=
0
;
chip
->
period_ptr
=
0
;
chip
->
fmt_size
=
snd_pcm_format_physical_width
(
substream
->
runtime
->
format
)
>>
3
;
chip
->
is_signed
=
snd_pcm_format_signed
(
substream
->
runtime
->
format
);
return
0
;
}
...
...
@@ -226,8 +259,7 @@ static int snd_pcsp_trigger(struct snd_pcm_substream *substream, int cmd)
switch
(
cmd
)
{
case
SNDRV_PCM_TRIGGER_START
:
case
SNDRV_PCM_TRIGGER_RESUME
:
pcsp_start_playing
(
chip
);
break
;
return
pcsp_start_playing
(
chip
);
case
SNDRV_PCM_TRIGGER_STOP
:
case
SNDRV_PCM_TRIGGER_SUSPEND
:
pcsp_stop_playing
(
chip
);
...
...
@@ -242,7 +274,11 @@ static snd_pcm_uframes_t snd_pcsp_playback_pointer(struct snd_pcm_substream
*
substream
)
{
struct
snd_pcsp
*
chip
=
snd_pcm_substream_chip
(
substream
);
return
bytes_to_frames
(
substream
->
runtime
,
chip
->
playback_ptr
);
unsigned
int
pos
;
spin_lock
(
&
chip
->
substream_lock
);
pos
=
chip
->
playback_ptr
;
spin_unlock
(
&
chip
->
substream_lock
);
return
bytes_to_frames
(
substream
->
runtime
,
pos
);
}
static
struct
snd_pcm_hardware
snd_pcsp_playback
=
{
...
...
@@ -279,9 +315,7 @@ static int snd_pcsp_playback_open(struct snd_pcm_substream *substream)
return
-
EBUSY
;
}
runtime
->
hw
=
snd_pcsp_playback
;
spin_lock_irq
(
&
chip
->
substream_lock
);
chip
->
playback_substream
=
substream
;
spin_unlock_irq
(
&
chip
->
substream_lock
);
return
0
;
}
...
...
sound/isa/sb/sb8.c
View file @
86b3aa39
...
...
@@ -140,8 +140,10 @@ static int __devinit snd_sb8_probe(struct device *pdev, unsigned int dev)
break
;
}
}
if
(
i
>=
ARRAY_SIZE
(
possible_ports
))
if
(
i
>=
ARRAY_SIZE
(
possible_ports
))
{
err
=
-
EINVAL
;
goto
_err
;
}
}
acard
->
chip
=
chip
;
...
...
sound/pci/ac97/ac97_codec.c
View file @
86b3aa39
...
...
@@ -175,7 +175,7 @@ static const struct ac97_codec_id snd_ac97_codec_ids[] = {
{
0x574d4C04
,
0xffffffff
,
"WM9704M,WM9704Q"
,
patch_wolfson04
,
NULL
},
{
0x574d4C05
,
0xffffffff
,
"WM9705,WM9710"
,
patch_wolfson05
,
NULL
},
{
0x574d4C09
,
0xffffffff
,
"WM9709"
,
NULL
,
NULL
},
{
0x574d4C12
,
0xffffffff
,
"WM9711,WM9712"
,
patch_wolfson11
,
NULL
},
{
0x574d4C12
,
0xffffffff
,
"WM9711,WM9712
,WM9715
"
,
patch_wolfson11
,
NULL
},
{
0x574d4c13
,
0xffffffff
,
"WM9713,WM9714"
,
patch_wolfson13
,
NULL
,
AC97_DEFAULT_POWER_OFF
},
{
0x594d4800
,
0xffffffff
,
"YMF743"
,
patch_yamaha_ymf743
,
NULL
},
{
0x594d4802
,
0xffffffff
,
"YMF752"
,
NULL
,
NULL
},
...
...
sound/pci/ac97/ac97_patch.c
View file @
86b3aa39
...
...
@@ -2832,6 +2832,8 @@ static int patch_alc655(struct snd_ac97 * ac97)
val
&=
~
(
1
<<
1
);
/* Pin 47 is EAPD (for internal speaker) */
else
val
|=
(
1
<<
1
);
/* Pin 47 is spdif input pin */
/* this seems missing on some hardwares */
ac97
->
ext_id
|=
AC97_EI_SPDIF
;
}
val
&=
~
(
1
<<
12
);
/* vref enable */
snd_ac97_write_cache
(
ac97
,
0x7a
,
val
);
...
...
sound/pci/ca0106/ca0106.h
View file @
86b3aa39
...
...
@@ -664,10 +664,14 @@ struct snd_ca0106_pcm {
struct
snd_ca0106_details
{
u32
serial
;
char
*
name
;
int
ac97
;
int
gpio_type
;
int
i2c_adc
;
int
spi_dac
;
int
ac97
;
/* ac97 = 0 -> Select MIC, Line in, TAD in, AUX in.
ac97 = 1 -> Default to AC97 in. */
int
gpio_type
;
/* gpio_type = 1 -> shared mic-in/line-in
gpio_type = 2 -> shared side-out/line-in. */
int
i2c_adc
;
/* with i2c_adc=1, the driver adds some capture volume
controls, phone, mic, line-in and aux. */
int
spi_dac
;
/* spi_dac=1 adds the mute switch for each analog
output, front, rear, etc. */
};
// definition of the chip-specific record
...
...
@@ -686,11 +690,12 @@ struct snd_ca0106 {
spinlock_t
emu_lock
;
struct
snd_ac97
*
ac97
;
struct
snd_pcm
*
pcm
;
struct
snd_pcm
*
pcm
[
4
]
;
struct
snd_ca0106_channel
playback_channels
[
4
];
struct
snd_ca0106_channel
capture_channels
[
4
];
u32
spdif_bits
[
4
];
/* s/pdif out setup */
u32
spdif_bits
[
4
];
/* s/pdif out default setup */
u32
spdif_str_bits
[
4
];
/* s/pdif out per-stream setup */
int
spdif_enable
;
int
capture_source
;
int
i2c_capture_source
;
...
...
@@ -703,6 +708,11 @@ struct snd_ca0106 {
struct
snd_ca_midi
midi2
;
u16
spi_dac_reg
[
16
];
#ifdef CONFIG_PM
#define NUM_SAVED_VOLUMES 9
unsigned
int
saved_vol
[
NUM_SAVED_VOLUMES
];
#endif
};
int
snd_ca0106_mixer
(
struct
snd_ca0106
*
emu
);
...
...
@@ -721,3 +731,11 @@ int snd_ca0106_i2c_write(struct snd_ca0106 *emu, u32 reg, u32 value);
int
snd_ca0106_spi_write
(
struct
snd_ca0106
*
emu
,
unsigned
int
data
);
#ifdef CONFIG_PM
void
snd_ca0106_mixer_suspend
(
struct
snd_ca0106
*
chip
);
void
snd_ca0106_mixer_resume
(
struct
snd_ca0106
*
chip
);
#else
#define snd_ca0106_mixer_suspend(chip) do { } while (0)
#define snd_ca0106_mixer_resume(chip) do { } while (0)
#endif
sound/pci/ca0106/ca0106_main.c
View file @
86b3aa39
...
...
@@ -254,7 +254,7 @@ static struct snd_ca0106_details ca0106_chip_details[] = {
.
name
=
"MSI K8N Diamond MB"
,
.
gpio_type
=
2
,
.
i2c_adc
=
1
,
.
spi_dac
=
2
}
,
.
spi_dac
=
1
}
,
/* Shuttle XPC SD31P which has an onboard Creative Labs
* Sound Blaster Live! 24-bit EAX
* high-definition 7.1 audio processor".
...
...
@@ -305,9 +305,15 @@ static struct snd_pcm_hardware snd_ca0106_capture_hw = {
SNDRV_PCM_INFO_BLOCK_TRANSFER
|
SNDRV_PCM_INFO_MMAP_VALID
),
.
formats
=
SNDRV_PCM_FMTBIT_S16_LE
|
SNDRV_PCM_FMTBIT_S32_LE
,
#if 0 /* FIXME: looks like 44.1kHz capture causes noisy output on 48kHz */
.rates = (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000),
.rate_min = 44100,
#else
.
rates
=
(
SNDRV_PCM_RATE_48000
|
SNDRV_PCM_RATE_96000
|
SNDRV_PCM_RATE_192000
),
.
rate_min
=
48000
,
#endif
/* FIXME */
.
rate_max
=
192000
,
.
channels_min
=
2
,
.
channels_max
=
2
,
...
...
@@ -479,6 +485,15 @@ static const int spi_dacd_bit[] = {
[
PCM_UNKNOWN_CHANNEL
]
=
SPI_DACD1_BIT
,
};
static
void
restore_spdif_bits
(
struct
snd_ca0106
*
chip
,
int
idx
)
{
if
(
chip
->
spdif_str_bits
[
idx
]
!=
chip
->
spdif_bits
[
idx
])
{
chip
->
spdif_str_bits
[
idx
]
=
chip
->
spdif_bits
[
idx
];
snd_ca0106_ptr_write
(
chip
,
SPCS0
+
idx
,
0
,
chip
->
spdif_str_bits
[
idx
]);
}
}
/* open_playback callback */
static
int
snd_ca0106_pcm_open_playback_channel
(
struct
snd_pcm_substream
*
substream
,
int
channel_id
)
...
...
@@ -524,6 +539,9 @@ static int snd_ca0106_pcm_open_playback_channel(struct snd_pcm_substream *substr
if
(
err
<
0
)
return
err
;
}
restore_spdif_bits
(
chip
,
channel_id
);
return
0
;
}
...
...
@@ -535,6 +553,8 @@ static int snd_ca0106_pcm_close_playback(struct snd_pcm_substream *substream)
struct
snd_ca0106_pcm
*
epcm
=
runtime
->
private_data
;
chip
->
playback_channels
[
epcm
->
channel_id
].
use
=
0
;
restore_spdif_bits
(
chip
,
epcm
->
channel_id
);
if
(
chip
->
details
->
spi_dac
&&
epcm
->
channel_id
!=
PCM_FRONT_CHANNEL
)
{
const
int
reg
=
spi_dacd_reg
[
epcm
->
channel_id
];
...
...
@@ -847,15 +867,18 @@ static int snd_ca0106_pcm_trigger_playback(struct snd_pcm_substream *substream,
struct
snd_pcm_substream
*
s
;
u32
basic
=
0
;
u32
extended
=
0
;
int
running
=
0
;
u32
bits
;
int
running
=
0
;
switch
(
cmd
)
{
case
SNDRV_PCM_TRIGGER_START
:
running
=
1
;
case
SNDRV_PCM_TRIGGER_RESUME
:
running
=
1
;
break
;
case
SNDRV_PCM_TRIGGER_STOP
:
case
SNDRV_PCM_TRIGGER_SUSPEND
:
default:
running
=
0
;
running
=
0
;
break
;
}
snd_pcm_group_for_each_entry
(
s
,
substream
)
{
...
...
@@ -865,22 +888,32 @@ static int snd_ca0106_pcm_trigger_playback(struct snd_pcm_substream *substream,
runtime
=
s
->
runtime
;
epcm
=
runtime
->
private_data
;
channel
=
epcm
->
channel_id
;
/
/snd_printk("channel=%d\n",channel);
/
* snd_printk("channel=%d\n",channel); */
epcm
->
running
=
running
;
basic
|=
(
0x1
<<
channel
);
extended
|=
(
0x10
<<
channel
);
basic
|=
(
0x1
<<
channel
);
extended
|=
(
0x10
<<
channel
);
snd_pcm_trigger_done
(
s
,
substream
);
}
/
/snd_printk("basic=0x%x, extended=0x%x\n",basic, extended);
/
* snd_printk("basic=0x%x, extended=0x%x\n",basic, extended); */
switch
(
cmd
)
{
case
SNDRV_PCM_TRIGGER_START
:
snd_ca0106_ptr_write
(
emu
,
EXTENDED_INT_MASK
,
0
,
snd_ca0106_ptr_read
(
emu
,
EXTENDED_INT_MASK
,
0
)
|
(
extended
));
snd_ca0106_ptr_write
(
emu
,
BASIC_INTERRUPT
,
0
,
snd_ca0106_ptr_read
(
emu
,
BASIC_INTERRUPT
,
0
)
|
(
basic
));
case
SNDRV_PCM_TRIGGER_RESUME
:
bits
=
snd_ca0106_ptr_read
(
emu
,
EXTENDED_INT_MASK
,
0
);
bits
|=
extended
;
snd_ca0106_ptr_write
(
emu
,
EXTENDED_INT_MASK
,
0
,
bits
);
bits
=
snd_ca0106_ptr_read
(
emu
,
BASIC_INTERRUPT
,
0
);
bits
|=
basic
;
snd_ca0106_ptr_write
(
emu
,
BASIC_INTERRUPT
,
0
,
bits
);
break
;
case
SNDRV_PCM_TRIGGER_STOP
:
snd_ca0106_ptr_write
(
emu
,
BASIC_INTERRUPT
,
0
,
snd_ca0106_ptr_read
(
emu
,
BASIC_INTERRUPT
,
0
)
&
~
(
basic
));
snd_ca0106_ptr_write
(
emu
,
EXTENDED_INT_MASK
,
0
,
snd_ca0106_ptr_read
(
emu
,
EXTENDED_INT_MASK
,
0
)
&
~
(
extended
));
case
SNDRV_PCM_TRIGGER_SUSPEND
:
bits
=
snd_ca0106_ptr_read
(
emu
,
BASIC_INTERRUPT
,
0
);
bits
&=
~
basic
;
snd_ca0106_ptr_write
(
emu
,
BASIC_INTERRUPT
,
0
,
bits
);
bits
=
snd_ca0106_ptr_read
(
emu
,
EXTENDED_INT_MASK
,
0
);
bits
&=
~
extended
;
snd_ca0106_ptr_write
(
emu
,
EXTENDED_INT_MASK
,
0
,
bits
);
break
;
default:
result
=
-
EINVAL
;
...
...
@@ -1103,21 +1136,13 @@ static int snd_ca0106_ac97(struct snd_ca0106 *chip)
return
snd_ac97_mixer
(
pbus
,
&
ac97
,
&
chip
->
ac97
);
}
static
void
ca0106_stop_chip
(
struct
snd_ca0106
*
chip
);
static
int
snd_ca0106_free
(
struct
snd_ca0106
*
chip
)
{
if
(
chip
->
res_port
!=
NULL
)
{
/* avoid access to already used hardware */
// disable interrupts
snd_ca0106_ptr_write
(
chip
,
BASIC_INTERRUPT
,
0
,
0
);
outl
(
0
,
chip
->
port
+
INTE
);
snd_ca0106_ptr_write
(
chip
,
EXTENDED_INT_MASK
,
0
,
0
);
udelay
(
1000
);
// disable audio
//outl(HCFG_LOCKSOUNDCACHE, chip->port + HCFG);
outl
(
0
,
chip
->
port
+
HCFG
);
/* FIXME: We need to stop and DMA transfers here.
* But as I am not sure how yet, we cannot from the dma pages.
* So we can fix: snd-malloc: Memory leak? pages not freed = 8
*/
if
(
chip
->
res_port
!=
NULL
)
{
/* avoid access to already used hardware */
ca0106_stop_chip
(
chip
);
}
if
(
chip
->
irq
>=
0
)
free_irq
(
chip
->
irq
,
chip
);
...
...
@@ -1203,15 +1228,14 @@ static irqreturn_t snd_ca0106_interrupt(int irq, void *dev_id)
return
IRQ_HANDLED
;
}
static
int
__devinit
snd_ca0106_pcm
(
struct
snd_ca0106
*
emu
,
int
device
,
struct
snd_pcm
**
rpcm
)
static
int
__devinit
snd_ca0106_pcm
(
struct
snd_ca0106
*
emu
,
int
device
)
{
struct
snd_pcm
*
pcm
;
struct
snd_pcm_substream
*
substream
;
int
err
;
if
(
rpcm
)
*
rpcm
=
NULL
;
if
((
err
=
snd_pcm_new
(
emu
->
card
,
"ca0106"
,
device
,
1
,
1
,
&
pcm
))
<
0
)
err
=
snd_pcm_new
(
emu
->
card
,
"ca0106"
,
device
,
1
,
1
,
&
pcm
);
if
(
err
<
0
)
return
err
;
pcm
->
private_data
=
emu
;
...
...
@@ -1238,7 +1262,6 @@ static int __devinit snd_ca0106_pcm(struct snd_ca0106 *emu, int device, struct s
pcm
->
info_flags
=
0
;
pcm
->
dev_subclass
=
SNDRV_PCM_SUBCLASS_GENERIC_MIX
;
strcpy
(
pcm
->
name
,
"CA0106"
);
emu
->
pcm
=
pcm
;
for
(
substream
=
pcm
->
streams
[
SNDRV_PCM_STREAM_PLAYBACK
].
substream
;
substream
;
...
...
@@ -1260,8 +1283,7 @@ static int __devinit snd_ca0106_pcm(struct snd_ca0106 *emu, int device, struct s
return
err
;
}
if
(
rpcm
)
*
rpcm
=
pcm
;
emu
->
pcm
[
device
]
=
pcm
;
return
0
;
}
...
...
@@ -1301,89 +1323,10 @@ static unsigned int i2c_adc_init[][2] = {
{
0x15
,
ADC_MUX_LINEIN
},
/* ADC Mixer control */
};
static
int
__devinit
snd_ca0106_create
(
int
dev
,
struct
snd_card
*
card
,
struct
pci_dev
*
pci
,
struct
snd_ca0106
**
rchip
)
static
void
ca0106_init_chip
(
struct
snd_ca0106
*
chip
,
int
resume
)
{
struct
snd_ca0106
*
chip
;
struct
snd_ca0106_details
*
c
;
int
err
;
int
ch
;
static
struct
snd_device_ops
ops
=
{
.
dev_free
=
snd_ca0106_dev_free
,
};
*
rchip
=
NULL
;
if
((
err
=
pci_enable_device
(
pci
))
<
0
)
return
err
;
if
(
pci_set_dma_mask
(
pci
,
DMA_32BIT_MASK
)
<
0
||
pci_set_consistent_dma_mask
(
pci
,
DMA_32BIT_MASK
)
<
0
)
{
printk
(
KERN_ERR
"error to set 32bit mask DMA
\n
"
);
pci_disable_device
(
pci
);
return
-
ENXIO
;
}
chip
=
kzalloc
(
sizeof
(
*
chip
),
GFP_KERNEL
);
if
(
chip
==
NULL
)
{
pci_disable_device
(
pci
);
return
-
ENOMEM
;
}
chip
->
card
=
card
;
chip
->
pci
=
pci
;
chip
->
irq
=
-
1
;
spin_lock_init
(
&
chip
->
emu_lock
);
chip
->
port
=
pci_resource_start
(
pci
,
0
);
if
((
chip
->
res_port
=
request_region
(
chip
->
port
,
0x20
,
"snd_ca0106"
))
==
NULL
)
{
snd_ca0106_free
(
chip
);
printk
(
KERN_ERR
"cannot allocate the port
\n
"
);
return
-
EBUSY
;
}
if
(
request_irq
(
pci
->
irq
,
snd_ca0106_interrupt
,
IRQF_SHARED
,
"snd_ca0106"
,
chip
))
{
snd_ca0106_free
(
chip
);
printk
(
KERN_ERR
"cannot grab irq
\n
"
);
return
-
EBUSY
;
}
chip
->
irq
=
pci
->
irq
;
/* This stores the periods table. */
if
(
snd_dma_alloc_pages
(
SNDRV_DMA_TYPE_DEV
,
snd_dma_pci_data
(
pci
),
1024
,
&
chip
->
buffer
)
<
0
)
{
snd_ca0106_free
(
chip
);
return
-
ENOMEM
;
}
pci_set_master
(
pci
);
/* read serial */
pci_read_config_dword
(
pci
,
PCI_SUBSYSTEM_VENDOR_ID
,
&
chip
->
serial
);
pci_read_config_word
(
pci
,
PCI_SUBSYSTEM_ID
,
&
chip
->
model
);
#if 1
printk
(
KERN_INFO
"snd-ca0106: Model %04x Rev %08x Serial %08x
\n
"
,
chip
->
model
,
pci
->
revision
,
chip
->
serial
);
#endif
strcpy
(
card
->
driver
,
"CA0106"
);
strcpy
(
card
->
shortname
,
"CA0106"
);
for
(
c
=
ca0106_chip_details
;
c
->
serial
;
c
++
)
{
if
(
subsystem
[
dev
])
{
if
(
c
->
serial
==
subsystem
[
dev
])
break
;
}
else
if
(
c
->
serial
==
chip
->
serial
)
break
;
}
chip
->
details
=
c
;
if
(
subsystem
[
dev
])
{
printk
(
KERN_INFO
"snd-ca0106: Sound card name=%s, subsystem=0x%x. Forced to subsystem=0x%x
\n
"
,
c
->
name
,
chip
->
serial
,
subsystem
[
dev
]);
}
sprintf
(
card
->
longname
,
"%s at 0x%lx irq %i"
,
c
->
name
,
chip
->
port
,
chip
->
irq
);
unsigned
int
def_bits
;
outl
(
0
,
chip
->
port
+
INTE
);
...
...
@@ -1401,31 +1344,22 @@ static int __devinit snd_ca0106_create(int dev, struct snd_card *card,
* AN = 0 (Audio data)
* P = 0 (Consumer)
*/
snd_ca0106_ptr_write
(
chip
,
SPCS0
,
0
,
chip
->
spdif_bits
[
0
]
=
SPCS_CLKACCY_1000PPM
|
SPCS_SAMPLERATE_48
|
SPCS_CHANNELNUM_LEFT
|
SPCS_SOURCENUM_UNSPEC
|
SPCS_GENERATIONSTATUS
|
0x00001200
|
0x00000000
|
SPCS_EMPHASIS_NONE
|
SPCS_COPYRIGHT
);
def_bits
=
SPCS_CLKACCY_1000PPM
|
SPCS_SAMPLERATE_48
|
SPCS_CHANNELNUM_LEFT
|
SPCS_SOURCENUM_UNSPEC
|
SPCS_GENERATIONSTATUS
|
0x00001200
|
0x00000000
|
SPCS_EMPHASIS_NONE
|
SPCS_COPYRIGHT
;
if
(
!
resume
)
{
chip
->
spdif_str_bits
[
0
]
=
chip
->
spdif_bits
[
0
]
=
def_bits
;
chip
->
spdif_str_bits
[
1
]
=
chip
->
spdif_bits
[
1
]
=
def_bits
;
chip
->
spdif_str_bits
[
2
]
=
chip
->
spdif_bits
[
2
]
=
def_bits
;
chip
->
spdif_str_bits
[
3
]
=
chip
->
spdif_bits
[
3
]
=
def_bits
;
}
/* Only SPCS1 has been tested */
snd_ca0106_ptr_write
(
chip
,
SPCS1
,
0
,
chip
->
spdif_bits
[
1
]
=
SPCS_CLKACCY_1000PPM
|
SPCS_SAMPLERATE_48
|
SPCS_CHANNELNUM_LEFT
|
SPCS_SOURCENUM_UNSPEC
|
SPCS_GENERATIONSTATUS
|
0x00001200
|
0x00000000
|
SPCS_EMPHASIS_NONE
|
SPCS_COPYRIGHT
);
snd_ca0106_ptr_write
(
chip
,
SPCS2
,
0
,
chip
->
spdif_bits
[
2
]
=
SPCS_CLKACCY_1000PPM
|
SPCS_SAMPLERATE_48
|
SPCS_CHANNELNUM_LEFT
|
SPCS_SOURCENUM_UNSPEC
|
SPCS_GENERATIONSTATUS
|
0x00001200
|
0x00000000
|
SPCS_EMPHASIS_NONE
|
SPCS_COPYRIGHT
);
snd_ca0106_ptr_write
(
chip
,
SPCS3
,
0
,
chip
->
spdif_bits
[
3
]
=
SPCS_CLKACCY_1000PPM
|
SPCS_SAMPLERATE_48
|
SPCS_CHANNELNUM_LEFT
|
SPCS_SOURCENUM_UNSPEC
|
SPCS_GENERATIONSTATUS
|
0x00001200
|
0x00000000
|
SPCS_EMPHASIS_NONE
|
SPCS_COPYRIGHT
);
snd_ca0106_ptr_write
(
chip
,
SPCS1
,
0
,
chip
->
spdif_str_bits
[
1
]);
snd_ca0106_ptr_write
(
chip
,
SPCS0
,
0
,
chip
->
spdif_str_bits
[
0
]);
snd_ca0106_ptr_write
(
chip
,
SPCS2
,
0
,
chip
->
spdif_str_bits
[
2
]);
snd_ca0106_ptr_write
(
chip
,
SPCS3
,
0
,
chip
->
spdif_str_bits
[
3
]);
snd_ca0106_ptr_write
(
chip
,
PLAYBACK_MUTE
,
0
,
0x00fc0000
);
snd_ca0106_ptr_write
(
chip
,
CAPTURE_MUTE
,
0
,
0x00fc0000
);
...
...
@@ -1433,92 +1367,124 @@ static int __devinit snd_ca0106_create(int dev, struct snd_card *card,
/* Write 0x8000 to AC97_REC_GAIN to mute it. */
outb
(
AC97_REC_GAIN
,
chip
->
port
+
AC97ADDRESS
);
outw
(
0x8000
,
chip
->
port
+
AC97DATA
);
#if 0
#if 0
/* FIXME: what are these? */
snd_ca0106_ptr_write(chip, SPCS0, 0, 0x2108006);
snd_ca0106_ptr_write(chip, 0x42, 0, 0x2108006);
snd_ca0106_ptr_write(chip, 0x43, 0, 0x2108006);
snd_ca0106_ptr_write(chip, 0x44, 0, 0x2108006);
#endif
//snd_ca0106_ptr_write(chip, SPDIF_SELECT2, 0, 0xf0f003f); /* OSS drivers set this. */
/* OSS drivers set this. */
/* snd_ca0106_ptr_write(chip, SPDIF_SELECT2, 0, 0xf0f003f); */
/* Analog or Digital output */
snd_ca0106_ptr_write
(
chip
,
SPDIF_SELECT1
,
0
,
0xf
);
snd_ca0106_ptr_write
(
chip
,
SPDIF_SELECT2
,
0
,
0x000f0000
);
/* 0x0b000000 for digital, 0x000b0000 for analog, from win2000 drivers. Use 0x000f0000 for surround71 */
/* 0x0b000000 for digital, 0x000b0000 for analog, from win2000 drivers.
* Use 0x000f0000 for surround71
*/
snd_ca0106_ptr_write
(
chip
,
SPDIF_SELECT2
,
0
,
0x000f0000
);
chip
->
spdif_enable
=
0
;
/* Set digital SPDIF output off */
//snd_ca0106_ptr_write(chip, 0x45, 0, 0); /* Analogue out */
//snd_ca0106_ptr_write(chip, 0x45, 0, 0xf00); /* Digital out */
/*snd_ca0106_ptr_write(chip, 0x45, 0, 0);*/
/* Analogue out */
/*snd_ca0106_ptr_write(chip, 0x45, 0, 0xf00);*/
/* Digital out */
/* goes to 0x40c80000 when doing SPDIF IN/OUT */
snd_ca0106_ptr_write
(
chip
,
CAPTURE_CONTROL
,
0
,
0x40c81000
);
/* (Mute) CAPTURE feedback into PLAYBACK volume.
* Only lower 16 bits matter.
*/
snd_ca0106_ptr_write
(
chip
,
CAPTURE_CONTROL
,
1
,
0xffffffff
);
/* SPDIF IN Volume */
snd_ca0106_ptr_write
(
chip
,
CAPTURE_CONTROL
,
2
,
0x30300000
);
/* SPDIF IN Volume, 0x70 = (vol & 0x3f) | 0x40 */
snd_ca0106_ptr_write
(
chip
,
CAPTURE_CONTROL
,
3
,
0x00700000
);
snd_ca0106_ptr_write
(
chip
,
CAPTURE_CONTROL
,
0
,
0x40c81000
);
/* goes to 0x40c80000 when doing SPDIF IN/OUT */
snd_ca0106_ptr_write
(
chip
,
CAPTURE_CONTROL
,
1
,
0xffffffff
);
/* (Mute) CAPTURE feedback into PLAYBACK volume. Only lower 16 bits matter. */
snd_ca0106_ptr_write
(
chip
,
CAPTURE_CONTROL
,
2
,
0x30300000
);
/* SPDIF IN Volume */
snd_ca0106_ptr_write
(
chip
,
CAPTURE_CONTROL
,
3
,
0x00700000
);
/* SPDIF IN Volume, 0x70 = (vol & 0x3f) | 0x40 */
snd_ca0106_ptr_write
(
chip
,
PLAYBACK_ROUTING1
,
0
,
0x32765410
);
snd_ca0106_ptr_write
(
chip
,
PLAYBACK_ROUTING2
,
0
,
0x76767676
);
snd_ca0106_ptr_write
(
chip
,
CAPTURE_ROUTING1
,
0
,
0x32765410
);
snd_ca0106_ptr_write
(
chip
,
CAPTURE_ROUTING2
,
0
,
0x76767676
);
for
(
ch
=
0
;
ch
<
4
;
ch
++
)
{
snd_ca0106_ptr_write
(
chip
,
CAPTURE_VOLUME1
,
ch
,
0x30303030
);
/* Only high 16 bits matter */
for
(
ch
=
0
;
ch
<
4
;
ch
++
)
{
/* Only high 16 bits matter */
snd_ca0106_ptr_write
(
chip
,
CAPTURE_VOLUME1
,
ch
,
0x30303030
);
snd_ca0106_ptr_write
(
chip
,
CAPTURE_VOLUME2
,
ch
,
0x30303030
);
//snd_ca0106_ptr_write(chip, PLAYBACK_VOLUME1, ch, 0x40404040); /* Mute */
//snd_ca0106_ptr_write(chip, PLAYBACK_VOLUME2, ch, 0x40404040); /* Mute */
snd_ca0106_ptr_write
(
chip
,
PLAYBACK_VOLUME1
,
ch
,
0xffffffff
);
/* Mute */
snd_ca0106_ptr_write
(
chip
,
PLAYBACK_VOLUME2
,
ch
,
0xffffffff
);
/* Mute */
#if 0 /* Mute */
snd_ca0106_ptr_write(chip, PLAYBACK_VOLUME1, ch, 0x40404040);
snd_ca0106_ptr_write(chip, PLAYBACK_VOLUME2, ch, 0x40404040);
snd_ca0106_ptr_write(chip, PLAYBACK_VOLUME1, ch, 0xffffffff);
snd_ca0106_ptr_write(chip, PLAYBACK_VOLUME2, ch, 0xffffffff);
#endif
}
if
(
chip
->
details
->
i2c_adc
==
1
)
{
/* Select MIC, Line in, TAD in, AUX in */
snd_ca0106_ptr_write
(
chip
,
CAPTURE_SOURCE
,
0x0
,
0x333300e4
);
/* Default to CAPTURE_SOURCE to i2s in */
chip
->
capture_source
=
3
;
if
(
!
resume
)
chip
->
capture_source
=
3
;
}
else
if
(
chip
->
details
->
ac97
==
1
)
{
/* Default to AC97 in */
snd_ca0106_ptr_write
(
chip
,
CAPTURE_SOURCE
,
0x0
,
0x444400e4
);
/* Default to CAPTURE_SOURCE to AC97 in */
chip
->
capture_source
=
4
;
if
(
!
resume
)
chip
->
capture_source
=
4
;
}
else
{
/* Select MIC, Line in, TAD in, AUX in */
snd_ca0106_ptr_write
(
chip
,
CAPTURE_SOURCE
,
0x0
,
0x333300e4
);
/* Default to Set CAPTURE_SOURCE to i2s in */
chip
->
capture_source
=
3
;
if
(
!
resume
)
chip
->
capture_source
=
3
;
}
if
(
chip
->
details
->
gpio_type
==
2
)
{
/* The SB0438 use GPIO differently. */
/* FIXME: Still need to find out what the other GPIO bits do. E.g. For digital spdif out. */
if
(
chip
->
details
->
gpio_type
==
2
)
{
/* The SB0438 use GPIO differently. */
/* FIXME: Still need to find out what the other GPIO bits do.
* E.g. For digital spdif out.
*/
outl
(
0x0
,
chip
->
port
+
GPIO
);
/
/outl(0x00f0e000, chip->port+GPIO);
/* Analog */
/
* outl(0x00f0e000, chip->port+GPIO); */
/* Analog */
outl
(
0x005f5301
,
chip
->
port
+
GPIO
);
/* Analog */
}
else
if
(
chip
->
details
->
gpio_type
==
1
)
{
/* The SB0410 and SB0413 use GPIO differently. */
/* FIXME: Still need to find out what the other GPIO bits do. E.g. For digital spdif out. */
}
else
if
(
chip
->
details
->
gpio_type
==
1
)
{
/* The SB0410 and SB0413 use GPIO differently. */
/* FIXME: Still need to find out what the other GPIO bits do.
* E.g. For digital spdif out.
*/
outl
(
0x0
,
chip
->
port
+
GPIO
);
/
/outl(0x00f0e000, chip->port+GPIO);
/* Analog */
/
* outl(0x00f0e000, chip->port+GPIO); */
/* Analog */
outl
(
0x005f5301
,
chip
->
port
+
GPIO
);
/* Analog */
}
else
{
outl
(
0x0
,
chip
->
port
+
GPIO
);
outl
(
0x005f03a3
,
chip
->
port
+
GPIO
);
/* Analog */
/
/outl(0x005f02a2, chip->port+GPIO);
/* SPDIF */
/
* outl(0x005f02a2, chip->port+GPIO); */
/* SPDIF */
}
snd_ca0106_intr_enable
(
chip
,
0x105
);
/* Win2000 uses 0x1e0 */
//outl(HCFG_LOCKSOUNDCACHE|HCFG_AUDIOENABLE, chip->port+HCFG);
//outl(0x00001409, chip->port+HCFG); /* 0x1000 causes AC3 to fails. Maybe it effects 24 bit output. */
//outl(0x00000009, chip->port+HCFG);
outl
(
HCFG_AC97
|
HCFG_AUDIOENABLE
,
chip
->
port
+
HCFG
);
/* AC97 2.0, Enable outputs. */
/* outl(HCFG_LOCKSOUNDCACHE|HCFG_AUDIOENABLE, chip->port+HCFG); */
/* 0x1000 causes AC3 to fails. Maybe it effects 24 bit output. */
/* outl(0x00001409, chip->port+HCFG); */
/* outl(0x00000009, chip->port+HCFG); */
/* AC97 2.0, Enable outputs. */
outl
(
HCFG_AC97
|
HCFG_AUDIOENABLE
,
chip
->
port
+
HCFG
);
if
(
chip
->
details
->
i2c_adc
==
1
)
{
/* The SB0410 and SB0413 use I2C to control ADC. */
if
(
chip
->
details
->
i2c_adc
==
1
)
{
/* The SB0410 and SB0413 use I2C to control ADC. */
int
size
,
n
;
size
=
ARRAY_SIZE
(
i2c_adc_init
);
//snd_printk("I2C:array size=0x%x\n", size);
for
(
n
=
0
;
n
<
size
;
n
++
)
{
snd_ca0106_i2c_write
(
chip
,
i2c_adc_init
[
n
][
0
],
i2c_adc_init
[
n
][
1
]);
}
for
(
n
=
0
;
n
<
4
;
n
++
)
{
chip
->
i2c_capture_volume
[
n
][
0
]
=
0xcf
;
chip
->
i2c_capture_volume
[
n
][
1
]
=
0xcf
;
/* snd_printk("I2C:array size=0x%x\n", size); */
for
(
n
=
0
;
n
<
size
;
n
++
)
snd_ca0106_i2c_write
(
chip
,
i2c_adc_init
[
n
][
0
],
i2c_adc_init
[
n
][
1
]);
for
(
n
=
0
;
n
<
4
;
n
++
)
{
chip
->
i2c_capture_volume
[
n
][
0
]
=
0xcf
;
chip
->
i2c_capture_volume
[
n
][
1
]
=
0xcf
;
}
chip
->
i2c_capture_source
=
2
;
/* Line in */
//snd_ca0106_i2c_write(chip, ADC_MUX, ADC_MUX_LINEIN); /* Enable Line-in capture. MIC in currently untested. */
chip
->
i2c_capture_source
=
2
;
/* Line in */
/* Enable Line-in capture. MIC in currently untested. */
/* snd_ca0106_i2c_write(chip, ADC_MUX, ADC_MUX_LINEIN); */
}
if
(
chip
->
details
->
spi_dac
==
1
)
{
/* The SB0570 use SPI to control DAC. */
if
(
chip
->
details
->
spi_dac
==
1
)
{
/* The SB0570 use SPI to control DAC. */
int
size
,
n
;
size
=
ARRAY_SIZE
(
spi_dac_init
);
...
...
@@ -1530,9 +1496,112 @@ static int __devinit snd_ca0106_create(int dev, struct snd_card *card,
chip
->
spi_dac_reg
[
reg
]
=
spi_dac_init
[
n
];
}
}
}
if
((
err
=
snd_device_new
(
card
,
SNDRV_DEV_LOWLEVEL
,
chip
,
&
ops
))
<
0
)
{
static
void
ca0106_stop_chip
(
struct
snd_ca0106
*
chip
)
{
/* disable interrupts */
snd_ca0106_ptr_write
(
chip
,
BASIC_INTERRUPT
,
0
,
0
);
outl
(
0
,
chip
->
port
+
INTE
);
snd_ca0106_ptr_write
(
chip
,
EXTENDED_INT_MASK
,
0
,
0
);
udelay
(
1000
);
/* disable audio */
/* outl(HCFG_LOCKSOUNDCACHE, chip->port + HCFG); */
outl
(
0
,
chip
->
port
+
HCFG
);
/* FIXME: We need to stop and DMA transfers here.
* But as I am not sure how yet, we cannot from the dma pages.
* So we can fix: snd-malloc: Memory leak? pages not freed = 8
*/
}
static
int
__devinit
snd_ca0106_create
(
int
dev
,
struct
snd_card
*
card
,
struct
pci_dev
*
pci
,
struct
snd_ca0106
**
rchip
)
{
struct
snd_ca0106
*
chip
;
struct
snd_ca0106_details
*
c
;
int
err
;
static
struct
snd_device_ops
ops
=
{
.
dev_free
=
snd_ca0106_dev_free
,
};
*
rchip
=
NULL
;
err
=
pci_enable_device
(
pci
);
if
(
err
<
0
)
return
err
;
if
(
pci_set_dma_mask
(
pci
,
DMA_32BIT_MASK
)
<
0
||
pci_set_consistent_dma_mask
(
pci
,
DMA_32BIT_MASK
)
<
0
)
{
printk
(
KERN_ERR
"error to set 32bit mask DMA
\n
"
);
pci_disable_device
(
pci
);
return
-
ENXIO
;
}
chip
=
kzalloc
(
sizeof
(
*
chip
),
GFP_KERNEL
);
if
(
chip
==
NULL
)
{
pci_disable_device
(
pci
);
return
-
ENOMEM
;
}
chip
->
card
=
card
;
chip
->
pci
=
pci
;
chip
->
irq
=
-
1
;
spin_lock_init
(
&
chip
->
emu_lock
);
chip
->
port
=
pci_resource_start
(
pci
,
0
);
chip
->
res_port
=
request_region
(
chip
->
port
,
0x20
,
"snd_ca0106"
);
if
(
!
chip
->
res_port
)
{
snd_ca0106_free
(
chip
);
printk
(
KERN_ERR
"cannot allocate the port
\n
"
);
return
-
EBUSY
;
}
if
(
request_irq
(
pci
->
irq
,
snd_ca0106_interrupt
,
IRQF_SHARED
,
"snd_ca0106"
,
chip
))
{
snd_ca0106_free
(
chip
);
printk
(
KERN_ERR
"cannot grab irq
\n
"
);
return
-
EBUSY
;
}
chip
->
irq
=
pci
->
irq
;
/* This stores the periods table. */
if
(
snd_dma_alloc_pages
(
SNDRV_DMA_TYPE_DEV
,
snd_dma_pci_data
(
pci
),
1024
,
&
chip
->
buffer
)
<
0
)
{
snd_ca0106_free
(
chip
);
return
-
ENOMEM
;
}
pci_set_master
(
pci
);
/* read serial */
pci_read_config_dword
(
pci
,
PCI_SUBSYSTEM_VENDOR_ID
,
&
chip
->
serial
);
pci_read_config_word
(
pci
,
PCI_SUBSYSTEM_ID
,
&
chip
->
model
);
printk
(
KERN_INFO
"snd-ca0106: Model %04x Rev %08x Serial %08x
\n
"
,
chip
->
model
,
pci
->
revision
,
chip
->
serial
);
strcpy
(
card
->
driver
,
"CA0106"
);
strcpy
(
card
->
shortname
,
"CA0106"
);
for
(
c
=
ca0106_chip_details
;
c
->
serial
;
c
++
)
{
if
(
subsystem
[
dev
])
{
if
(
c
->
serial
==
subsystem
[
dev
])
break
;
}
else
if
(
c
->
serial
==
chip
->
serial
)
break
;
}
chip
->
details
=
c
;
if
(
subsystem
[
dev
])
{
printk
(
KERN_INFO
"snd-ca0106: Sound card name=%s, "
"subsystem=0x%x. Forced to subsystem=0x%x
\n
"
,
c
->
name
,
chip
->
serial
,
subsystem
[
dev
]);
}
sprintf
(
card
->
longname
,
"%s at 0x%lx irq %i"
,
c
->
name
,
chip
->
port
,
chip
->
irq
);
ca0106_init_chip
(
chip
,
0
);
err
=
snd_device_new
(
card
,
SNDRV_DEV_LOWLEVEL
,
chip
,
&
ops
);
if
(
err
<
0
)
{
snd_ca0106_free
(
chip
);
return
err
;
}
...
...
@@ -1629,7 +1698,7 @@ static int __devinit snd_ca0106_probe(struct pci_dev *pci,
static
int
dev
;
struct
snd_card
*
card
;
struct
snd_ca0106
*
chip
;
int
err
;
int
i
,
err
;
if
(
dev
>=
SNDRV_CARDS
)
return
-
ENODEV
;
...
...
@@ -1642,44 +1711,31 @@ static int __devinit snd_ca0106_probe(struct pci_dev *pci,
if
(
card
==
NULL
)
return
-
ENOMEM
;
if
((
err
=
snd_ca0106_create
(
dev
,
card
,
pci
,
&
chip
))
<
0
)
{
snd_card_free
(
card
);
return
er
r
;
}
err
=
snd_ca0106_create
(
dev
,
card
,
pci
,
&
chip
);
if
(
err
<
0
)
goto
erro
r
;
card
->
private_data
=
chip
;
if
((
err
=
snd_ca0106_pcm
(
chip
,
0
,
NULL
))
<
0
)
{
snd_card_free
(
card
);
return
err
;
}
if
((
err
=
snd_ca0106_pcm
(
chip
,
1
,
NULL
))
<
0
)
{
snd_card_free
(
card
);
return
err
;
}
if
((
err
=
snd_ca0106_pcm
(
chip
,
2
,
NULL
))
<
0
)
{
snd_card_free
(
card
);
return
err
;
}
if
((
err
=
snd_ca0106_pcm
(
chip
,
3
,
NULL
))
<
0
)
{
snd_card_free
(
card
);
return
err
;
}
if
(
chip
->
details
->
ac97
==
1
)
{
/* The SB0410 and SB0413 do not have an AC97 chip. */
if
((
err
=
snd_ca0106_ac97
(
chip
))
<
0
)
{
snd_card_free
(
card
);
return
err
;
}
for
(
i
=
0
;
i
<
4
;
i
++
)
{
err
=
snd_ca0106_pcm
(
chip
,
i
);
if
(
err
<
0
)
goto
error
;
}
if
((
err
=
snd_ca0106_mixer
(
chip
))
<
0
)
{
snd_card_free
(
card
);
return
err
;
if
(
chip
->
details
->
ac97
==
1
)
{
/* The SB0410 and SB0413 do not have an AC97 chip. */
err
=
snd_ca0106_ac97
(
chip
);
if
(
err
<
0
)
goto
error
;
}
err
=
snd_ca0106_mixer
(
chip
);
if
(
err
<
0
)
goto
error
;
snd_printdd
(
"ca0106: probe for MIDI channel A ..."
);
if
((
err
=
snd_ca0106_midi
(
chip
,
CA0106_MIDI_CHAN_A
))
<
0
)
{
snd_card_free
(
card
);
snd_printdd
(
" failed, err=0x%x
\n
"
,
err
);
return
err
;
}
err
=
snd_ca0106_midi
(
chip
,
CA0106_MIDI_CHAN_A
);
if
(
err
<
0
)
goto
error
;
snd_printdd
(
" done.
\n
"
);
#ifdef CONFIG_PROC_FS
...
...
@@ -1688,14 +1744,17 @@ static int __devinit snd_ca0106_probe(struct pci_dev *pci,
snd_card_set_dev
(
card
,
&
pci
->
dev
);
if
((
err
=
snd_card_register
(
card
))
<
0
)
{
snd_card_free
(
card
);
return
err
;
}
err
=
snd_card_register
(
card
);
if
(
err
<
0
)
goto
error
;
pci_set_drvdata
(
pci
,
card
);
dev
++
;
return
0
;
error:
snd_card_free
(
card
);
return
err
;
}
static
void
__devexit
snd_ca0106_remove
(
struct
pci_dev
*
pci
)
...
...
@@ -1704,6 +1763,59 @@ static void __devexit snd_ca0106_remove(struct pci_dev *pci)
pci_set_drvdata
(
pci
,
NULL
);
}
#ifdef CONFIG_PM
static
int
snd_ca0106_suspend
(
struct
pci_dev
*
pci
,
pm_message_t
state
)
{
struct
snd_card
*
card
=
pci_get_drvdata
(
pci
);
struct
snd_ca0106
*
chip
=
card
->
private_data
;
int
i
;
snd_power_change_state
(
card
,
SNDRV_CTL_POWER_D3hot
);
for
(
i
=
0
;
i
<
4
;
i
++
)
snd_pcm_suspend_all
(
chip
->
pcm
[
i
]);
if
(
chip
->
details
->
ac97
)
snd_ac97_suspend
(
chip
->
ac97
);
snd_ca0106_mixer_suspend
(
chip
);
ca0106_stop_chip
(
chip
);
pci_disable_device
(
pci
);
pci_save_state
(
pci
);
pci_set_power_state
(
pci
,
pci_choose_state
(
pci
,
state
));
return
0
;
}
static
int
snd_ca0106_resume
(
struct
pci_dev
*
pci
)
{
struct
snd_card
*
card
=
pci_get_drvdata
(
pci
);
struct
snd_ca0106
*
chip
=
card
->
private_data
;
int
i
;
pci_set_power_state
(
pci
,
PCI_D0
);
pci_restore_state
(
pci
);
if
(
pci_enable_device
(
pci
)
<
0
)
{
snd_card_disconnect
(
card
);
return
-
EIO
;
}
pci_set_master
(
pci
);
ca0106_init_chip
(
chip
,
1
);
if
(
chip
->
details
->
ac97
)
snd_ac97_resume
(
chip
->
ac97
);
snd_ca0106_mixer_resume
(
chip
);
if
(
chip
->
details
->
spi_dac
)
{
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
chip
->
spi_dac_reg
);
i
++
)
snd_ca0106_spi_write
(
chip
,
chip
->
spi_dac_reg
[
i
]);
}
snd_power_change_state
(
card
,
SNDRV_CTL_POWER_D0
);
return
0
;
}
#endif
// PCI IDs
static
struct
pci_device_id
snd_ca0106_ids
[]
=
{
{
0x1102
,
0x0007
,
PCI_ANY_ID
,
PCI_ANY_ID
,
0
,
0
,
0
},
/* Audigy LS or Live 24bit */
...
...
@@ -1717,6 +1829,10 @@ static struct pci_driver driver = {
.
id_table
=
snd_ca0106_ids
,
.
probe
=
snd_ca0106_probe
,
.
remove
=
__devexit_p
(
snd_ca0106_remove
),
#ifdef CONFIG_PM
.
suspend
=
snd_ca0106_suspend
,
.
resume
=
snd_ca0106_resume
,
#endif
};
// initialization of the module
...
...
sound/pci/ca0106/ca0106_mixer.c
View file @
86b3aa39
...
...
@@ -75,6 +75,84 @@
#include "ca0106.h"
static
void
ca0106_spdif_enable
(
struct
snd_ca0106
*
emu
)
{
unsigned
int
val
;
if
(
emu
->
spdif_enable
)
{
/* Digital */
snd_ca0106_ptr_write
(
emu
,
SPDIF_SELECT1
,
0
,
0xf
);
snd_ca0106_ptr_write
(
emu
,
SPDIF_SELECT2
,
0
,
0x0b000000
);
val
=
snd_ca0106_ptr_read
(
emu
,
CAPTURE_CONTROL
,
0
)
&
~
0x1000
;
snd_ca0106_ptr_write
(
emu
,
CAPTURE_CONTROL
,
0
,
val
);
val
=
inl
(
emu
->
port
+
GPIO
)
&
~
0x101
;
outl
(
val
,
emu
->
port
+
GPIO
);
}
else
{
/* Analog */
snd_ca0106_ptr_write
(
emu
,
SPDIF_SELECT1
,
0
,
0xf
);
snd_ca0106_ptr_write
(
emu
,
SPDIF_SELECT2
,
0
,
0x000f0000
);
val
=
snd_ca0106_ptr_read
(
emu
,
CAPTURE_CONTROL
,
0
)
|
0x1000
;
snd_ca0106_ptr_write
(
emu
,
CAPTURE_CONTROL
,
0
,
val
);
val
=
inl
(
emu
->
port
+
GPIO
)
|
0x101
;
outl
(
val
,
emu
->
port
+
GPIO
);
}
}
static
void
ca0106_set_capture_source
(
struct
snd_ca0106
*
emu
)
{
unsigned
int
val
=
emu
->
capture_source
;
unsigned
int
source
,
mask
;
source
=
(
val
<<
28
)
|
(
val
<<
24
)
|
(
val
<<
20
)
|
(
val
<<
16
);
mask
=
snd_ca0106_ptr_read
(
emu
,
CAPTURE_SOURCE
,
0
)
&
0xffff
;
snd_ca0106_ptr_write
(
emu
,
CAPTURE_SOURCE
,
0
,
source
|
mask
);
}
static
void
ca0106_set_i2c_capture_source
(
struct
snd_ca0106
*
emu
,
unsigned
int
val
,
int
force
)
{
unsigned
int
ngain
,
ogain
;
u32
source
;
snd_ca0106_i2c_write
(
emu
,
ADC_MUX
,
0
);
/* Mute input */
ngain
=
emu
->
i2c_capture_volume
[
val
][
0
];
/* Left */
ogain
=
emu
->
i2c_capture_volume
[
emu
->
i2c_capture_source
][
0
];
/* Left */
if
(
force
||
ngain
!=
ogain
)
snd_ca0106_i2c_write
(
emu
,
ADC_ATTEN_ADCL
,
ngain
&
0xff
);
ngain
=
emu
->
i2c_capture_volume
[
val
][
1
];
/* Right */
ogain
=
emu
->
i2c_capture_volume
[
emu
->
i2c_capture_source
][
1
];
/* Right */
if
(
force
||
ngain
!=
ogain
)
snd_ca0106_i2c_write
(
emu
,
ADC_ATTEN_ADCR
,
ngain
&
0xff
);
source
=
1
<<
val
;
snd_ca0106_i2c_write
(
emu
,
ADC_MUX
,
source
);
/* Set source */
emu
->
i2c_capture_source
=
val
;
}
static
void
ca0106_set_capture_mic_line_in
(
struct
snd_ca0106
*
emu
)
{
u32
tmp
;
if
(
emu
->
capture_mic_line_in
)
{
/* snd_ca0106_i2c_write(emu, ADC_MUX, 0); */
/* Mute input */
tmp
=
inl
(
emu
->
port
+
GPIO
)
&
~
0x400
;
tmp
=
tmp
|
0x400
;
outl
(
tmp
,
emu
->
port
+
GPIO
);
/* snd_ca0106_i2c_write(emu, ADC_MUX, ADC_MUX_MIC); */
}
else
{
/* snd_ca0106_i2c_write(emu, ADC_MUX, 0); */
/* Mute input */
tmp
=
inl
(
emu
->
port
+
GPIO
)
&
~
0x400
;
outl
(
tmp
,
emu
->
port
+
GPIO
);
/* snd_ca0106_i2c_write(emu, ADC_MUX, ADC_MUX_LINEIN); */
}
}
static
void
ca0106_set_spdif_bits
(
struct
snd_ca0106
*
emu
,
int
idx
)
{
snd_ca0106_ptr_write
(
emu
,
SPCS0
+
idx
,
0
,
emu
->
spdif_str_bits
[
idx
]);
}
/*
*/
static
const
DECLARE_TLV_DB_SCALE
(
snd_ca0106_db_scale1
,
-
5175
,
25
,
1
);
static
const
DECLARE_TLV_DB_SCALE
(
snd_ca0106_db_scale2
,
-
10350
,
50
,
1
);
...
...
@@ -95,30 +173,12 @@ static int snd_ca0106_shared_spdif_put(struct snd_kcontrol *kcontrol,
struct
snd_ca0106
*
emu
=
snd_kcontrol_chip
(
kcontrol
);
unsigned
int
val
;
int
change
=
0
;
u32
mask
;
val
=
!!
ucontrol
->
value
.
integer
.
value
[
0
];
change
=
(
emu
->
spdif_enable
!=
val
);
if
(
change
)
{
emu
->
spdif_enable
=
val
;
if
(
val
)
{
/* Digital */
snd_ca0106_ptr_write
(
emu
,
SPDIF_SELECT1
,
0
,
0xf
);
snd_ca0106_ptr_write
(
emu
,
SPDIF_SELECT2
,
0
,
0x0b000000
);
snd_ca0106_ptr_write
(
emu
,
CAPTURE_CONTROL
,
0
,
snd_ca0106_ptr_read
(
emu
,
CAPTURE_CONTROL
,
0
)
&
~
0x1000
);
mask
=
inl
(
emu
->
port
+
GPIO
)
&
~
0x101
;
outl
(
mask
,
emu
->
port
+
GPIO
);
}
else
{
/* Analog */
snd_ca0106_ptr_write
(
emu
,
SPDIF_SELECT1
,
0
,
0xf
);
snd_ca0106_ptr_write
(
emu
,
SPDIF_SELECT2
,
0
,
0x000f0000
);
snd_ca0106_ptr_write
(
emu
,
CAPTURE_CONTROL
,
0
,
snd_ca0106_ptr_read
(
emu
,
CAPTURE_CONTROL
,
0
)
|
0x1000
);
mask
=
inl
(
emu
->
port
+
GPIO
)
|
0x101
;
outl
(
mask
,
emu
->
port
+
GPIO
);
}
ca0106_spdif_enable
(
emu
);
}
return
change
;
}
...
...
@@ -154,8 +214,6 @@ static int snd_ca0106_capture_source_put(struct snd_kcontrol *kcontrol,
struct
snd_ca0106
*
emu
=
snd_kcontrol_chip
(
kcontrol
);
unsigned
int
val
;
int
change
=
0
;
u32
mask
;
u32
source
;
val
=
ucontrol
->
value
.
enumerated
.
item
[
0
]
;
if
(
val
>=
6
)
...
...
@@ -163,9 +221,7 @@ static int snd_ca0106_capture_source_put(struct snd_kcontrol *kcontrol,
change
=
(
emu
->
capture_source
!=
val
);
if
(
change
)
{
emu
->
capture_source
=
val
;
source
=
(
val
<<
28
)
|
(
val
<<
24
)
|
(
val
<<
20
)
|
(
val
<<
16
);
mask
=
snd_ca0106_ptr_read
(
emu
,
CAPTURE_SOURCE
,
0
)
&
0xffff
;
snd_ca0106_ptr_write
(
emu
,
CAPTURE_SOURCE
,
0
,
source
|
mask
);
ca0106_set_capture_source
(
emu
);
}
return
change
;
}
...
...
@@ -200,9 +256,7 @@ static int snd_ca0106_i2c_capture_source_put(struct snd_kcontrol *kcontrol,
{
struct
snd_ca0106
*
emu
=
snd_kcontrol_chip
(
kcontrol
);
unsigned
int
source_id
;
unsigned
int
ngain
,
ogain
;
int
change
=
0
;
u32
source
;
/* If the capture source has changed,
* update the capture volume from the cached value
* for the particular source.
...
...
@@ -212,18 +266,7 @@ static int snd_ca0106_i2c_capture_source_put(struct snd_kcontrol *kcontrol,
return
-
EINVAL
;
change
=
(
emu
->
i2c_capture_source
!=
source_id
);
if
(
change
)
{
snd_ca0106_i2c_write
(
emu
,
ADC_MUX
,
0
);
/* Mute input */
ngain
=
emu
->
i2c_capture_volume
[
source_id
][
0
];
/* Left */
ogain
=
emu
->
i2c_capture_volume
[
emu
->
i2c_capture_source
][
0
];
/* Left */
if
(
ngain
!=
ogain
)
snd_ca0106_i2c_write
(
emu
,
ADC_ATTEN_ADCL
,
((
ngain
)
&
0xff
));
ngain
=
emu
->
i2c_capture_volume
[
source_id
][
1
];
/* Left */
ogain
=
emu
->
i2c_capture_volume
[
emu
->
i2c_capture_source
][
1
];
/* Left */
if
(
ngain
!=
ogain
)
snd_ca0106_i2c_write
(
emu
,
ADC_ATTEN_ADCR
,
((
ngain
)
&
0xff
));
source
=
1
<<
source_id
;
snd_ca0106_i2c_write
(
emu
,
ADC_MUX
,
source
);
/* Set source */
emu
->
i2c_capture_source
=
source_id
;
ca0106_set_i2c_capture_source
(
emu
,
source_id
,
0
);
}
return
change
;
}
...
...
@@ -271,7 +314,6 @@ static int snd_ca0106_capture_mic_line_in_put(struct snd_kcontrol *kcontrol,
struct
snd_ca0106
*
emu
=
snd_kcontrol_chip
(
kcontrol
);
unsigned
int
val
;
int
change
=
0
;
u32
tmp
;
val
=
ucontrol
->
value
.
enumerated
.
item
[
0
]
;
if
(
val
>
1
)
...
...
@@ -279,18 +321,7 @@ static int snd_ca0106_capture_mic_line_in_put(struct snd_kcontrol *kcontrol,
change
=
(
emu
->
capture_mic_line_in
!=
val
);
if
(
change
)
{
emu
->
capture_mic_line_in
=
val
;
if
(
val
)
{
//snd_ca0106_i2c_write(emu, ADC_MUX, 0); /* Mute input */
tmp
=
inl
(
emu
->
port
+
GPIO
)
&
~
0x400
;
tmp
=
tmp
|
0x400
;
outl
(
tmp
,
emu
->
port
+
GPIO
);
//snd_ca0106_i2c_write(emu, ADC_MUX, ADC_MUX_MIC);
}
else
{
//snd_ca0106_i2c_write(emu, ADC_MUX, 0); /* Mute input */
tmp
=
inl
(
emu
->
port
+
GPIO
)
&
~
0x400
;
outl
(
tmp
,
emu
->
port
+
GPIO
);
//snd_ca0106_i2c_write(emu, ADC_MUX, ADC_MUX_LINEIN);
}
ca0106_set_capture_mic_line_in
(
emu
);
}
return
change
;
}
...
...
@@ -322,16 +353,33 @@ static int snd_ca0106_spdif_info(struct snd_kcontrol *kcontrol,
return
0
;
}
static
int
snd_ca0106_spdif_get
(
struct
snd_kcontrol
*
kcontrol
,
static
void
decode_spdif_bits
(
unsigned
char
*
status
,
unsigned
int
bits
)
{
status
[
0
]
=
(
bits
>>
0
)
&
0xff
;
status
[
1
]
=
(
bits
>>
8
)
&
0xff
;
status
[
2
]
=
(
bits
>>
16
)
&
0xff
;
status
[
3
]
=
(
bits
>>
24
)
&
0xff
;
}
static
int
snd_ca0106_spdif_get_default
(
struct
snd_kcontrol
*
kcontrol
,
struct
snd_ctl_elem_value
*
ucontrol
)
{
struct
snd_ca0106
*
emu
=
snd_kcontrol_chip
(
kcontrol
);
unsigned
int
idx
=
snd_ctl_get_ioffidx
(
kcontrol
,
&
ucontrol
->
id
);
ucontrol
->
value
.
iec958
.
status
[
0
]
=
(
emu
->
spdif_bits
[
idx
]
>>
0
)
&
0xff
;
ucontrol
->
value
.
iec958
.
status
[
1
]
=
(
emu
->
spdif_bits
[
idx
]
>>
8
)
&
0xff
;
ucontrol
->
value
.
iec958
.
status
[
2
]
=
(
emu
->
spdif_bits
[
idx
]
>>
16
)
&
0xff
;
ucontrol
->
value
.
iec958
.
status
[
3
]
=
(
emu
->
spdif_bits
[
idx
]
>>
24
)
&
0xff
;
decode_spdif_bits
(
ucontrol
->
value
.
iec958
.
status
,
emu
->
spdif_bits
[
idx
]);
return
0
;
}
static
int
snd_ca0106_spdif_get_stream
(
struct
snd_kcontrol
*
kcontrol
,
struct
snd_ctl_elem_value
*
ucontrol
)
{
struct
snd_ca0106
*
emu
=
snd_kcontrol_chip
(
kcontrol
);
unsigned
int
idx
=
snd_ctl_get_ioffidx
(
kcontrol
,
&
ucontrol
->
id
);
decode_spdif_bits
(
ucontrol
->
value
.
iec958
.
status
,
emu
->
spdif_str_bits
[
idx
]);
return
0
;
}
...
...
@@ -345,24 +393,48 @@ static int snd_ca0106_spdif_get_mask(struct snd_kcontrol *kcontrol,
return
0
;
}
static
int
snd_ca0106_spdif_put
(
struct
snd_kcontrol
*
kcontrol
,
static
unsigned
int
encode_spdif_bits
(
unsigned
char
*
status
)
{
return
((
unsigned
int
)
status
[
0
]
<<
0
)
|
((
unsigned
int
)
status
[
1
]
<<
8
)
|
((
unsigned
int
)
status
[
2
]
<<
16
)
|
((
unsigned
int
)
status
[
3
]
<<
24
);
}
static
int
snd_ca0106_spdif_put_default
(
struct
snd_kcontrol
*
kcontrol
,
struct
snd_ctl_elem_value
*
ucontrol
)
{
struct
snd_ca0106
*
emu
=
snd_kcontrol_chip
(
kcontrol
);
unsigned
int
idx
=
snd_ctl_get_ioffidx
(
kcontrol
,
&
ucontrol
->
id
);
int
change
;
unsigned
int
val
;
val
=
(
ucontrol
->
value
.
iec958
.
status
[
0
]
<<
0
)
|
(
ucontrol
->
value
.
iec958
.
status
[
1
]
<<
8
)
|
(
ucontrol
->
value
.
iec958
.
status
[
2
]
<<
16
)
|
(
ucontrol
->
value
.
iec958
.
status
[
3
]
<<
24
);
change
=
val
!=
emu
->
spdif_bits
[
idx
];
if
(
change
)
{
snd_ca0106_ptr_write
(
emu
,
SPCS0
+
idx
,
0
,
val
);
val
=
encode_spdif_bits
(
ucontrol
->
value
.
iec958
.
status
);
if
(
val
!=
emu
->
spdif_bits
[
idx
])
{
emu
->
spdif_bits
[
idx
]
=
val
;
/* FIXME: this isn't safe, but needed to keep the compatibility
* with older alsa-lib config
*/
emu
->
spdif_str_bits
[
idx
]
=
val
;
ca0106_set_spdif_bits
(
emu
,
idx
);
return
1
;
}
return
change
;
return
0
;
}
static
int
snd_ca0106_spdif_put_stream
(
struct
snd_kcontrol
*
kcontrol
,
struct
snd_ctl_elem_value
*
ucontrol
)
{
struct
snd_ca0106
*
emu
=
snd_kcontrol_chip
(
kcontrol
);
unsigned
int
idx
=
snd_ctl_get_ioffidx
(
kcontrol
,
&
ucontrol
->
id
);
unsigned
int
val
;
val
=
encode_spdif_bits
(
ucontrol
->
value
.
iec958
.
status
);
if
(
val
!=
emu
->
spdif_str_bits
[
idx
])
{
emu
->
spdif_str_bits
[
idx
]
=
val
;
ca0106_set_spdif_bits
(
emu
,
idx
);
return
1
;
}
return
0
;
}
static
int
snd_ca0106_volume_info
(
struct
snd_kcontrol
*
kcontrol
,
...
...
@@ -573,8 +645,16 @@ static struct snd_kcontrol_new snd_ca0106_volume_ctls[] __devinitdata = {
.
name
=
SNDRV_CTL_NAME_IEC958
(
""
,
PLAYBACK
,
DEFAULT
),
.
count
=
4
,
.
info
=
snd_ca0106_spdif_info
,
.
get
=
snd_ca0106_spdif_get
,
.
put
=
snd_ca0106_spdif_put
.
get
=
snd_ca0106_spdif_get_default
,
.
put
=
snd_ca0106_spdif_put_default
},
{
.
iface
=
SNDRV_CTL_ELEM_IFACE_PCM
,
.
name
=
SNDRV_CTL_NAME_IEC958
(
""
,
PLAYBACK
,
PCM_STREAM
),
.
count
=
4
,
.
info
=
snd_ca0106_spdif_info
,
.
get
=
snd_ca0106_spdif_get_stream
,
.
put
=
snd_ca0106_spdif_put_stream
},
};
...
...
@@ -773,3 +853,50 @@ int __devinit snd_ca0106_mixer(struct snd_ca0106 *emu)
return
0
;
}
#ifdef CONFIG_PM
struct
ca0106_vol_tbl
{
unsigned
int
channel_id
;
unsigned
int
reg
;
};
static
struct
ca0106_vol_tbl
saved_volumes
[
NUM_SAVED_VOLUMES
]
=
{
{
CONTROL_FRONT_CHANNEL
,
PLAYBACK_VOLUME2
},
{
CONTROL_REAR_CHANNEL
,
PLAYBACK_VOLUME2
},
{
CONTROL_CENTER_LFE_CHANNEL
,
PLAYBACK_VOLUME2
},
{
CONTROL_UNKNOWN_CHANNEL
,
PLAYBACK_VOLUME2
},
{
CONTROL_FRONT_CHANNEL
,
PLAYBACK_VOLUME1
},
{
CONTROL_REAR_CHANNEL
,
PLAYBACK_VOLUME1
},
{
CONTROL_CENTER_LFE_CHANNEL
,
PLAYBACK_VOLUME1
},
{
CONTROL_UNKNOWN_CHANNEL
,
PLAYBACK_VOLUME1
},
{
1
,
CAPTURE_CONTROL
},
};
void
snd_ca0106_mixer_suspend
(
struct
snd_ca0106
*
chip
)
{
int
i
;
/* save volumes */
for
(
i
=
0
;
i
<
NUM_SAVED_VOLUMES
;
i
++
)
chip
->
saved_vol
[
i
]
=
snd_ca0106_ptr_read
(
chip
,
saved_volumes
[
i
].
reg
,
saved_volumes
[
i
].
channel_id
);
}
void
snd_ca0106_mixer_resume
(
struct
snd_ca0106
*
chip
)
{
int
i
;
for
(
i
=
0
;
i
<
NUM_SAVED_VOLUMES
;
i
++
)
snd_ca0106_ptr_write
(
chip
,
saved_volumes
[
i
].
reg
,
saved_volumes
[
i
].
channel_id
,
chip
->
saved_vol
[
i
]);
ca0106_spdif_enable
(
chip
);
ca0106_set_capture_source
(
chip
);
ca0106_set_i2c_capture_source
(
chip
,
chip
->
i2c_capture_source
,
1
);
for
(
i
=
0
;
i
<
4
;
i
++
)
ca0106_set_spdif_bits
(
chip
,
i
);
if
(
chip
->
details
->
i2c_adc
)
ca0106_set_capture_mic_line_in
(
chip
);
}
#endif
/* CONFIG_PM */
sound/pci/cs46xx/cs46xx_lib.c
View file @
86b3aa39
...
...
@@ -3640,7 +3640,10 @@ int snd_cs46xx_resume(struct pci_dev *pci)
{
struct
snd_card
*
card
=
pci_get_drvdata
(
pci
);
struct
snd_cs46xx
*
chip
=
card
->
private_data
;
int
i
,
amp_saved
;
int
amp_saved
;
#ifdef CONFIG_SND_CS46XX_NEW_DSP
int
i
;
#endif
pci_set_power_state
(
pci
,
PCI_D0
);
pci_restore_state
(
pci
);
...
...
sound/pci/emu10k1/emu10k1_main.c
View file @
86b3aa39
...
...
@@ -69,7 +69,7 @@ MODULE_FIRMWARE(EMU1010_NOTEBOOK_FILENAME);
* EMU10K1 init / done
*************************************************************************/
void
snd_emu10k1_voice_init
(
struct
snd_emu10k1
*
emu
,
int
ch
)
void
snd_emu10k1_voice_init
(
struct
snd_emu10k1
*
emu
,
int
ch
)
{
snd_emu10k1_ptr_write
(
emu
,
DCYSUSV
,
ch
,
0
);
snd_emu10k1_ptr_write
(
emu
,
IP
,
ch
,
0
);
...
...
@@ -151,9 +151,9 @@ static unsigned int i2c_adc_init[][2] = {
{
0x12
,
0x32
},
/* ALC Control 3 */
{
0x13
,
0x00
},
/* Noise gate control */
{
0x14
,
0xa6
},
/* Limiter control */
{
0x15
,
ADC_MUX_2
},
/* ADC Mixer control. Mic for A
udigy 2
ZS Notebook */
{
0x15
,
ADC_MUX_2
},
/* ADC Mixer control. Mic for A
2
ZS Notebook */
};
static
int
snd_emu10k1_init
(
struct
snd_emu10k1
*
emu
,
int
enable_ir
,
int
resume
)
{
unsigned
int
silent_page
;
...
...
@@ -161,8 +161,8 @@ static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume)
u32
tmp
;
/* disable audio and lock cache */
outl
(
HCFG_LOCKSOUNDCACHE
|
HCFG_LOCKTANKCACHE_MASK
|
HCFG_MUTEBUTTONENABLE
,
emu
->
port
+
HCFG
);
outl
(
HCFG_LOCKSOUNDCACHE
|
HCFG_LOCKTANKCACHE_MASK
|
HCFG_MUTEBUTTONENABLE
,
emu
->
port
+
HCFG
);
/* reset recording buffers */
snd_emu10k1_ptr_write
(
emu
,
MICBS
,
0
,
ADCBS_BUFSIZE_NONE
);
...
...
@@ -179,7 +179,7 @@ static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume)
snd_emu10k1_ptr_write
(
emu
,
SOLEL
,
0
,
0
);
snd_emu10k1_ptr_write
(
emu
,
SOLEH
,
0
,
0
);
if
(
emu
->
audigy
){
if
(
emu
->
audigy
)
{
/* set SPDIF bypass mode */
snd_emu10k1_ptr_write
(
emu
,
SPBYPASS
,
0
,
SPBYPASS_FORMAT
);
/* enable rear left + rear right AC97 slots */
...
...
@@ -197,12 +197,12 @@ static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume)
if
(
emu
->
card_capabilities
->
ca0151_chip
)
{
/* audigy2 */
/* Hacks for Alice3 to work independent of haP16V driver */
/
/Setup SRCMulti_I2S SamplingRate
/
* Setup SRCMulti_I2S SamplingRate */
tmp
=
snd_emu10k1_ptr_read
(
emu
,
A_SPDIF_SAMPLERATE
,
0
);
tmp
&=
0xfffff1ff
;
tmp
|=
(
0x2
<<
9
);
snd_emu10k1_ptr_write
(
emu
,
A_SPDIF_SAMPLERATE
,
0
,
tmp
);
/* Setup SRCSel (Enable Spdif,I2S SRCMulti) */
snd_emu10k1_ptr20_write
(
emu
,
SRCSel
,
0
,
0x14
);
/* Setup SRCMulti Input Audio Enable */
...
...
@@ -217,7 +217,7 @@ static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume)
if
(
emu
->
card_capabilities
->
ca0108_chip
)
{
/* audigy2 Value */
/* Hacks for Alice3 to work independent of haP16V driver */
snd_printk
(
KERN_INFO
"Audigy2 value: Special config.
\n
"
);
/
/Setup SRCMulti_I2S SamplingRate
/
* Setup SRCMulti_I2S SamplingRate */
tmp
=
snd_emu10k1_ptr_read
(
emu
,
A_SPDIF_SAMPLERATE
,
0
);
tmp
&=
0xfffff1ff
;
tmp
|=
(
0x2
<<
9
);
...
...
@@ -270,13 +270,13 @@ static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume)
size
=
ARRAY_SIZE
(
i2c_adc_init
);
for
(
n
=
0
;
n
<
size
;
n
++
)
snd_emu10k1_i2c_write
(
emu
,
i2c_adc_init
[
n
][
0
],
i2c_adc_init
[
n
][
1
]);
for
(
n
=
0
;
n
<
4
;
n
++
)
{
emu
->
i2c_capture_volume
[
n
][
0
]
=
0xcf
;
emu
->
i2c_capture_volume
[
n
][
1
]
=
0xcf
;
for
(
n
=
0
;
n
<
4
;
n
++
)
{
emu
->
i2c_capture_volume
[
n
][
0
]
=
0xcf
;
emu
->
i2c_capture_volume
[
n
][
1
]
=
0xcf
;
}
}
snd_emu10k1_ptr_write
(
emu
,
PTB
,
0
,
emu
->
ptb_pages
.
addr
);
snd_emu10k1_ptr_write
(
emu
,
TCB
,
0
,
0
);
/* taken from original driver */
snd_emu10k1_ptr_write
(
emu
,
TCBS
,
0
,
4
);
/* taken from original driver */
...
...
@@ -313,7 +313,7 @@ static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume)
(
emu
->
model
==
0x21
&&
emu
->
revision
<
6
))
outl
(
HCFG_LOCKTANKCACHE_MASK
|
HCFG_AUTOMUTE
,
emu
->
port
+
HCFG
);
else
/
/ With on-chip joystick
/
* With on-chip joystick */
outl
(
HCFG_LOCKTANKCACHE_MASK
|
HCFG_AUTOMUTE
|
HCFG_JOYENABLE
,
emu
->
port
+
HCFG
);
if
(
enable_ir
)
{
/* enable IR for SB Live */
...
...
@@ -335,9 +335,9 @@ static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume)
outl
(
reg
|
HCFG_GPOUT1
|
HCFG_GPOUT2
,
emu
->
port
+
HCFG
);
udelay
(
100
);
outl
(
reg
,
emu
->
port
+
HCFG
);
}
}
}
if
(
emu
->
card_capabilities
->
emu_model
)
{
;
/* Disable all access to A_IOCFG for the emu1010 */
}
else
if
(
emu
->
card_capabilities
->
i2c_adc
)
{
...
...
@@ -364,7 +364,7 @@ static void snd_emu10k1_audio_enable(struct snd_emu10k1 *emu)
;
/* Disable A_IOCFG for Audigy 2 ZS Notebook */
}
else
if
(
emu
->
audigy
)
{
outl
(
inl
(
emu
->
port
+
A_IOCFG
)
&
~
0x44
,
emu
->
port
+
A_IOCFG
);
if
(
emu
->
card_capabilities
->
ca0151_chip
)
{
/* audigy2 */
/* Unmute Analog now. Set GPO6 to 1 for Apollo.
* This has to be done after init ALice3 I2SOut beyond 48KHz.
...
...
@@ -378,12 +378,12 @@ static void snd_emu10k1_audio_enable(struct snd_emu10k1 *emu)
outl
(
inl
(
emu
->
port
+
A_IOCFG
)
|
0x0080
,
emu
->
port
+
A_IOCFG
);
}
}
#if 0
{
unsigned int tmp;
/* FIXME: the following routine disables LiveDrive-II !! */
/
/ TOSLink detection
/
* TOSLink detection */
emu->tos_link = 0;
tmp = inl(emu->port + HCFG);
if (tmp & (HCFG_GPINPUT0 | HCFG_GPINPUT1)) {
...
...
@@ -400,7 +400,7 @@ static void snd_emu10k1_audio_enable(struct snd_emu10k1 *emu)
snd_emu10k1_intr_enable
(
emu
,
INTE_PCIERRORENABLE
);
}
int
snd_emu10k1_done
(
struct
snd_emu10k1
*
emu
)
int
snd_emu10k1_done
(
struct
snd_emu10k1
*
emu
)
{
int
ch
;
...
...
@@ -495,7 +495,7 @@ int snd_emu10k1_done(struct snd_emu10k1 * emu)
#define EC_LAST_PROMFILE_ADDR 0x2f
#define EC_SERIALNUM_ADDR 0x30
/* First word of serial number. The
#define EC_SERIALNUM_ADDR 0x30
/* First word of serial number. The
* can be up to 30 characters in length
* and is stored as a NULL-terminated
* ASCII string. Any unused bytes must be
...
...
@@ -503,8 +503,8 @@ int snd_emu10k1_done(struct snd_emu10k1 * emu)
#define EC_CHECKSUM_ADDR 0x3f
/* Location at which checksum is stored */
/* Most of this stuff is pretty self-evident. According to the hardware
* dudes, we need to leave the ADCCAL bit low in order to avoid a DC
/* Most of this stuff is pretty self-evident. According to the hardware
* dudes, we need to leave the ADCCAL bit low in order to avoid a DC
* offset problem. Weird.
*/
#define EC_RAW_RUN_MODE (EC_DACMUTEN | EC_ADCRSTN | EC_TRIM_MUTEN | \
...
...
@@ -523,7 +523,7 @@ int snd_emu10k1_done(struct snd_emu10k1 * emu)
* register.
*/
static
void
snd_emu10k1_ecard_write
(
struct
snd_emu10k1
*
emu
,
unsigned
int
value
)
static
void
snd_emu10k1_ecard_write
(
struct
snd_emu10k1
*
emu
,
unsigned
int
value
)
{
unsigned
short
count
;
unsigned
int
data
;
...
...
@@ -561,7 +561,7 @@ static void snd_emu10k1_ecard_write(struct snd_emu10k1 * emu, unsigned int value
* channel.
*/
static
void
snd_emu10k1_ecard_setadcgain
(
struct
snd_emu10k1
*
emu
,
static
void
snd_emu10k1_ecard_setadcgain
(
struct
snd_emu10k1
*
emu
,
unsigned
short
gain
)
{
unsigned
int
bit
;
...
...
@@ -574,7 +574,7 @@ static void snd_emu10k1_ecard_setadcgain(struct snd_emu10k1 * emu,
for
(
bit
=
(
1
<<
15
);
bit
;
bit
>>=
1
)
{
unsigned
int
value
;
value
=
emu
->
ecard_ctrl
&
~
(
EC_TRIM_CSN
|
EC_TRIM_SDATA
);
if
(
gain
&
bit
)
...
...
@@ -589,7 +589,7 @@ static void snd_emu10k1_ecard_setadcgain(struct snd_emu10k1 * emu,
snd_emu10k1_ecard_write
(
emu
,
emu
->
ecard_ctrl
);
}
static
int
snd_emu10k1_ecard_init
(
struct
snd_emu10k1
*
emu
)
static
int
snd_emu10k1_ecard_init
(
struct
snd_emu10k1
*
emu
)
{
unsigned
int
hc_value
;
...
...
@@ -598,7 +598,7 @@ static int snd_emu10k1_ecard_init(struct snd_emu10k1 * emu)
EC_SPDIF0_SELECT
(
EC_DEFAULT_SPDIF0_SEL
)
|
EC_SPDIF1_SELECT
(
EC_DEFAULT_SPDIF1_SEL
);
/* Step 0: Set the codec type in the hardware control register
/* Step 0: Set the codec type in the hardware control register
* and enable audio output */
hc_value
=
inl
(
emu
->
port
+
HCFG
);
outl
(
hc_value
|
HCFG_AUDIOENABLE
|
HCFG_CODECFORMAT_I2S
,
emu
->
port
+
HCFG
);
...
...
@@ -629,7 +629,7 @@ static int snd_emu10k1_ecard_init(struct snd_emu10k1 * emu)
return
0
;
}
static
int
snd_emu10k1_cardbus_init
(
struct
snd_emu10k1
*
emu
)
static
int
snd_emu10k1_cardbus_init
(
struct
snd_emu10k1
*
emu
)
{
unsigned
long
special_port
;
unsigned
int
value
;
...
...
@@ -656,7 +656,7 @@ static int snd_emu10k1_cardbus_init(struct snd_emu10k1 * emu)
return
0
;
}
static
int
snd_emu1010_load_firmware
(
struct
snd_emu10k1
*
emu
,
const
char
*
filename
)
static
int
snd_emu1010_load_firmware
(
struct
snd_emu10k1
*
emu
,
const
char
*
filename
)
{
int
err
;
int
n
,
i
;
...
...
@@ -666,11 +666,12 @@ static int snd_emu1010_load_firmware(struct snd_emu10k1 * emu, const char * file
unsigned
long
flags
;
const
struct
firmware
*
fw_entry
;
if
((
err
=
request_firmware
(
&
fw_entry
,
filename
,
&
emu
->
pci
->
dev
))
!=
0
)
{
snd_printk
(
KERN_ERR
"firmware: %s not found. Err=%d
\n
"
,
filename
,
err
);
err
=
request_firmware
(
&
fw_entry
,
filename
,
&
emu
->
pci
->
dev
);
if
(
err
!=
0
)
{
snd_printk
(
KERN_ERR
"firmware: %s not found. Err = %d
\n
"
,
filename
,
err
);
return
err
;
}
snd_printk
(
KERN_INFO
"firmware size
=
0x%zx
\n
"
,
fw_entry
->
size
);
snd_printk
(
KERN_INFO
"firmware size
=
0x%zx
\n
"
,
fw_entry
->
size
);
/* The FPGA is a Xilinx Spartan IIE XC2S50E */
/* GPIO7 -> FPGA PGMN
...
...
@@ -685,13 +686,13 @@ static int snd_emu1010_load_firmware(struct snd_emu10k1 * emu, const char * file
outl
(
0x80
,
emu
->
port
+
A_IOCFG
);
/* Leave bit 7 set during netlist setup. */
write_post
=
inl
(
emu
->
port
+
A_IOCFG
);
udelay
(
100
);
/* Allow FPGA memory to clean */
for
(
n
=
0
;
n
<
fw_entry
->
size
;
n
++
)
{
value
=
fw_entry
->
data
[
n
];
for
(
i
=
0
;
i
<
8
;
i
++
)
{
for
(
n
=
0
;
n
<
fw_entry
->
size
;
n
++
)
{
value
=
fw_entry
->
data
[
n
];
for
(
i
=
0
;
i
<
8
;
i
++
)
{
reg
=
0x80
;
if
(
value
&
0x1
)
reg
=
reg
|
0x20
;
value
=
value
>>
1
;
value
=
value
>>
1
;
outl
(
reg
,
emu
->
port
+
A_IOCFG
);
write_post
=
inl
(
emu
->
port
+
A_IOCFG
);
outl
(
reg
|
0x40
,
emu
->
port
+
A_IOCFG
);
...
...
@@ -703,14 +704,14 @@ static int snd_emu1010_load_firmware(struct snd_emu10k1 * emu, const char * file
write_post
=
inl
(
emu
->
port
+
A_IOCFG
);
spin_unlock_irqrestore
(
&
emu
->
emu_lock
,
flags
);
release_firmware
(
fw_entry
);
release_firmware
(
fw_entry
);
return
0
;
}
static
int
emu1010_firmware_thread
(
void
*
data
)
{
struct
snd_emu10k1
*
emu
=
data
;
int
tmp
,
tmp2
;
struct
snd_emu10k1
*
emu
=
data
;
int
tmp
,
tmp2
;
int
reg
;
int
err
;
...
...
@@ -719,50 +720,50 @@ static int emu1010_firmware_thread(void *data)
msleep_interruptible
(
1000
);
if
(
kthread_should_stop
())
break
;
snd_emu1010_fpga_read
(
emu
,
EMU_HANA_IRQ_STATUS
,
&
tmp
);
/* IRQ Status */
snd_emu1010_fpga_read
(
emu
,
EMU_HANA_OPTION_CARDS
,
&
reg
);
/* OPTIONS: Which cards are attached to the EMU */
snd_emu1010_fpga_read
(
emu
,
EMU_HANA_IRQ_STATUS
,
&
tmp
);
/* IRQ Status */
snd_emu1010_fpga_read
(
emu
,
EMU_HANA_OPTION_CARDS
,
&
reg
);
/* OPTIONS: Which cards are attached to the EMU */
if
(
reg
&
EMU_HANA_OPTION_DOCK_OFFLINE
)
{
/* Audio Dock attached */
/* Return to Audio Dock programming mode */
snd_printk
(
KERN_INFO
"emu1010: Loading Audio Dock Firmware
\n
"
);
snd_emu1010_fpga_write
(
emu
,
EMU_HANA_FPGA_CONFIG
,
EMU_HANA_FPGA_CONFIG_AUDIODOCK
);
snd_emu1010_fpga_write
(
emu
,
EMU_HANA_FPGA_CONFIG
,
EMU_HANA_FPGA_CONFIG_AUDIODOCK
);
if
(
emu
->
card_capabilities
->
emu_model
==
EMU_MODEL_EMU1010
)
{
if
((
err
=
snd_emu1010_load_firmware
(
emu
,
DOCK_FILENAME
))
!=
0
)
{
err
=
snd_emu1010_load_firmware
(
emu
,
DOCK_FILENAME
);
if
(
err
!=
0
)
continue
;
}
}
else
if
(
emu
->
card_capabilities
->
emu_model
==
EMU_MODEL_EMU1010B
)
{
if
((
err
=
snd_emu1010_load_firmware
(
emu
,
MICRO_DOCK_FILENAME
))
!=
0
)
{
err
=
snd_emu1010_load_firmware
(
emu
,
MICRO_DOCK_FILENAME
);
if
(
err
!=
0
)
continue
;
}
}
else
if
(
emu
->
card_capabilities
->
emu_model
==
EMU_MODEL_EMU1616
)
{
if
((
err
=
snd_emu1010_load_firmware
(
emu
,
MICRO_DOCK_FILENAME
))
!=
0
)
{
err
=
snd_emu1010_load_firmware
(
emu
,
MICRO_DOCK_FILENAME
);
if
(
err
!=
0
)
continue
;
}
}
snd_emu1010_fpga_write
(
emu
,
EMU_HANA_FPGA_CONFIG
,
0
);
snd_emu1010_fpga_read
(
emu
,
EMU_HANA_IRQ_STATUS
,
&
reg
);
snd_printk
(
KERN_INFO
"emu1010: EMU_HANA+DOCK_IRQ_STATUS
=0x%x
\n
"
,
reg
);
snd_emu1010_fpga_write
(
emu
,
EMU_HANA_FPGA_CONFIG
,
0
);
snd_emu1010_fpga_read
(
emu
,
EMU_HANA_IRQ_STATUS
,
&
reg
);
snd_printk
(
KERN_INFO
"emu1010: EMU_HANA+DOCK_IRQ_STATUS
= 0x%x
\n
"
,
reg
);
/* ID, should read & 0x7f = 0x55 when FPGA programmed. */
snd_emu1010_fpga_read
(
emu
,
EMU_HANA_ID
,
&
reg
);
snd_printk
(
KERN_INFO
"emu1010: EMU_HANA+DOCK_ID
=0x%x
\n
"
,
reg
);
snd_emu1010_fpga_read
(
emu
,
EMU_HANA_ID
,
&
reg
);
snd_printk
(
KERN_INFO
"emu1010: EMU_HANA+DOCK_ID
= 0x%x
\n
"
,
reg
);
if
((
reg
&
0x1f
)
!=
0x15
)
{
/* FPGA failed to be programmed */
snd_printk
(
KERN_INFO
"emu1010: Loading Audio Dock Firmware file failed, reg
=
0x%x
\n
"
,
reg
);
snd_printk
(
KERN_INFO
"emu1010: Loading Audio Dock Firmware file failed, reg
=
0x%x
\n
"
,
reg
);
continue
;
}
snd_printk
(
KERN_INFO
"emu1010: Audio Dock Firmware loaded
\n
"
);
snd_emu1010_fpga_read
(
emu
,
EMU_DOCK_MAJOR_REV
,
&
tmp
);
snd_emu1010_fpga_read
(
emu
,
EMU_DOCK_MINOR_REV
,
&
tmp2
);
snd_printk
(
"Audio Dock ver:%d.%d
\n
"
,
tmp
,
tmp2
);
snd_emu1010_fpga_read
(
emu
,
EMU_DOCK_MAJOR_REV
,
&
tmp
);
snd_emu1010_fpga_read
(
emu
,
EMU_DOCK_MINOR_REV
,
&
tmp2
);
snd_printk
(
"Audio Dock ver:%d.%d
\n
"
,
tmp
,
tmp2
);
/* Sync clocking between 1010 and Dock */
/* Allow DLL to settle */
msleep
(
10
);
/* Unmute all. Default is muted after a firmware load */
snd_emu1010_fpga_write
(
emu
,
EMU_HANA_UNMUTE
,
EMU_UNMUTE
);
snd_emu1010_fpga_write
(
emu
,
EMU_HANA_UNMUTE
,
EMU_UNMUTE
);
}
}
snd_printk
(
KERN_INFO
"emu1010: firmware thread stopping
\n
"
);
...
...
@@ -800,10 +801,10 @@ static int emu1010_firmware_thread(void *data)
* 16 x 16-bit playback - snd_emu10k1_fx8010_playback_ops
* 16 x 32-bit capture - snd_emu10k1_capture_efx_ops
*/
static
int
snd_emu10k1_emu1010_init
(
struct
snd_emu10k1
*
emu
)
static
int
snd_emu10k1_emu1010_init
(
struct
snd_emu10k1
*
emu
)
{
unsigned
int
i
;
int
tmp
,
tmp2
;
int
tmp
,
tmp2
;
int
reg
;
int
err
;
const
char
*
filename
=
NULL
;
...
...
@@ -818,7 +819,7 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu)
* Lock Tank Memory Cache,
* Mute all codecs.
*/
outl
(
0x0005a004
,
emu
->
port
+
HCFG
);
outl
(
0x0005a004
,
emu
->
port
+
HCFG
);
/* AC97 2.1, Any 16Meg of 4Gig address, Auto-Mute, EMU32 Slave,
* Mute all codecs.
*/
...
...
@@ -829,25 +830,25 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu)
outl
(
0x0005a000
,
emu
->
port
+
HCFG
);
/* Disable 48Volt power to Audio Dock */
snd_emu1010_fpga_write
(
emu
,
EMU_HANA_DOCK_PWR
,
0
);
snd_emu1010_fpga_write
(
emu
,
EMU_HANA_DOCK_PWR
,
0
);
/* ID, should read & 0x7f = 0x55. (Bit 7 is the IRQ bit) */
snd_emu1010_fpga_read
(
emu
,
EMU_HANA_ID
,
&
reg
);
snd_printdd
(
"reg1
=0x%x
\n
"
,
reg
);
snd_emu1010_fpga_read
(
emu
,
EMU_HANA_ID
,
&
reg
);
snd_printdd
(
"reg1
= 0x%x
\n
"
,
reg
);
if
((
reg
&
0x3f
)
==
0x15
)
{
/* FPGA netlist already present so clear it */
/* Return to programming mode */
snd_emu1010_fpga_write
(
emu
,
EMU_HANA_FPGA_CONFIG
,
0x02
);
snd_emu1010_fpga_write
(
emu
,
EMU_HANA_FPGA_CONFIG
,
0x02
);
}
snd_emu1010_fpga_read
(
emu
,
EMU_HANA_ID
,
&
reg
);
snd_printdd
(
"reg2
=0x%x
\n
"
,
reg
);
snd_emu1010_fpga_read
(
emu
,
EMU_HANA_ID
,
&
reg
);
snd_printdd
(
"reg2
= 0x%x
\n
"
,
reg
);
if
((
reg
&
0x3f
)
==
0x15
)
{
/* FPGA failed to return to programming mode */
snd_printk
(
KERN_INFO
"emu1010: FPGA failed to return to programming mode
\n
"
);
return
-
ENODEV
;
}
snd_printk
(
KERN_INFO
"emu1010: EMU_HANA_ID
=0x%x
\n
"
,
reg
);
snd_printk
(
KERN_INFO
"emu1010: EMU_HANA_ID
= 0x%x
\n
"
,
reg
);
switch
(
emu
->
card_capabilities
->
emu_model
)
{
case
EMU_MODEL_EMU1010
:
filename
=
HANA_FILENAME
;
...
...
@@ -876,25 +877,25 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu)
}
/* ID, should read & 0x7f = 0x55 when FPGA programmed. */
snd_emu1010_fpga_read
(
emu
,
EMU_HANA_ID
,
&
reg
);
snd_emu1010_fpga_read
(
emu
,
EMU_HANA_ID
,
&
reg
);
if
((
reg
&
0x3f
)
!=
0x15
)
{
/* FPGA failed to be programmed */
snd_printk
(
KERN_INFO
"emu1010: Loading Hana Firmware file failed, reg
=
0x%x
\n
"
,
reg
);
snd_printk
(
KERN_INFO
"emu1010: Loading Hana Firmware file failed, reg
=
0x%x
\n
"
,
reg
);
return
-
ENODEV
;
}
snd_printk
(
KERN_INFO
"emu1010: Hana Firmware loaded
\n
"
);
snd_emu1010_fpga_read
(
emu
,
EMU_HANA_MAJOR_REV
,
&
tmp
);
snd_emu1010_fpga_read
(
emu
,
EMU_HANA_MINOR_REV
,
&
tmp2
);
snd_printk
(
"
Hana ver:%d.%d
\n
"
,
tmp
,
tmp2
);
snd_emu1010_fpga_read
(
emu
,
EMU_HANA_MAJOR_REV
,
&
tmp
);
snd_emu1010_fpga_read
(
emu
,
EMU_HANA_MINOR_REV
,
&
tmp2
);
snd_printk
(
"
emu1010: Hana version: %d.%d
\n
"
,
tmp
,
tmp2
);
/* Enable 48Volt power to Audio Dock */
snd_emu1010_fpga_write
(
emu
,
EMU_HANA_DOCK_PWR
,
EMU_HANA_DOCK_PWR_ON
);
snd_emu1010_fpga_write
(
emu
,
EMU_HANA_DOCK_PWR
,
EMU_HANA_DOCK_PWR_ON
);
snd_emu1010_fpga_read
(
emu
,
EMU_HANA_OPTION_CARDS
,
&
reg
);
snd_printk
(
KERN_INFO
"emu1010: Card options
=0x%x
\n
"
,
reg
);
snd_emu1010_fpga_read
(
emu
,
EMU_HANA_OPTION_CARDS
,
&
reg
);
snd_printk
(
KERN_INFO
"emu1010: Card options
=0x%x
\n
"
,
reg
);
snd_emu1010_fpga_read
(
emu
,
EMU_HANA_OPTICAL_TYPE
,
&
tmp
);
snd_emu1010_fpga_read
(
emu
,
EMU_HANA_OPTION_CARDS
,
&
reg
);
snd_printk
(
KERN_INFO
"emu1010: Card options
= 0x%x
\n
"
,
reg
);
snd_emu1010_fpga_read
(
emu
,
EMU_HANA_OPTION_CARDS
,
&
reg
);
snd_printk
(
KERN_INFO
"emu1010: Card options
= 0x%x
\n
"
,
reg
);
snd_emu1010_fpga_read
(
emu
,
EMU_HANA_OPTICAL_TYPE
,
&
tmp
);
/* Optical -> ADAT I/O */
/* 0 : SPDIF
* 1 : ADAT
...
...
@@ -904,41 +905,42 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu)
tmp
=
0
;
tmp
=
(
emu
->
emu1010
.
optical_in
?
EMU_HANA_OPTICAL_IN_ADAT
:
0
)
|
(
emu
->
emu1010
.
optical_out
?
EMU_HANA_OPTICAL_OUT_ADAT
:
0
);
snd_emu1010_fpga_write
(
emu
,
EMU_HANA_OPTICAL_TYPE
,
tmp
);
snd_emu1010_fpga_read
(
emu
,
EMU_HANA_ADC_PADS
,
&
tmp
);
snd_emu1010_fpga_write
(
emu
,
EMU_HANA_OPTICAL_TYPE
,
tmp
);
snd_emu1010_fpga_read
(
emu
,
EMU_HANA_ADC_PADS
,
&
tmp
);
/* Set no attenuation on Audio Dock pads. */
snd_emu1010_fpga_write
(
emu
,
EMU_HANA_ADC_PADS
,
0x00
);
snd_emu1010_fpga_write
(
emu
,
EMU_HANA_ADC_PADS
,
0x00
);
emu
->
emu1010
.
adc_pads
=
0x00
;
snd_emu1010_fpga_read
(
emu
,
EMU_HANA_DOCK_MISC
,
&
tmp
);
snd_emu1010_fpga_read
(
emu
,
EMU_HANA_DOCK_MISC
,
&
tmp
);
/* Unmute Audio dock DACs, Headphone source DAC-4. */
snd_emu1010_fpga_write
(
emu
,
EMU_HANA_DOCK_MISC
,
0x30
);
snd_emu1010_fpga_write
(
emu
,
EMU_HANA_DOCK_LEDS_2
,
0x12
);
snd_emu1010_fpga_read
(
emu
,
EMU_HANA_DAC_PADS
,
&
tmp
);
snd_emu1010_fpga_write
(
emu
,
EMU_HANA_DOCK_MISC
,
0x30
);
snd_emu1010_fpga_write
(
emu
,
EMU_HANA_DOCK_LEDS_2
,
0x12
);
snd_emu1010_fpga_read
(
emu
,
EMU_HANA_DAC_PADS
,
&
tmp
);
/* DAC PADs. */
snd_emu1010_fpga_write
(
emu
,
EMU_HANA_DAC_PADS
,
0x0f
);
snd_emu1010_fpga_write
(
emu
,
EMU_HANA_DAC_PADS
,
0x0f
);
emu
->
emu1010
.
dac_pads
=
0x0f
;
snd_emu1010_fpga_read
(
emu
,
EMU_HANA_DOCK_MISC
,
&
tmp
);
snd_emu1010_fpga_write
(
emu
,
EMU_HANA_DOCK_MISC
,
0x30
);
snd_emu1010_fpga_read
(
emu
,
EMU_HANA_SPDIF_MODE
,
&
tmp
);
snd_emu1010_fpga_read
(
emu
,
EMU_HANA_DOCK_MISC
,
&
tmp
);
snd_emu1010_fpga_write
(
emu
,
EMU_HANA_DOCK_MISC
,
0x30
);
snd_emu1010_fpga_read
(
emu
,
EMU_HANA_SPDIF_MODE
,
&
tmp
);
/* SPDIF Format. Set Consumer mode, 24bit, copy enable */
snd_emu1010_fpga_write
(
emu
,
EMU_HANA_SPDIF_MODE
,
0x10
);
snd_emu1010_fpga_write
(
emu
,
EMU_HANA_SPDIF_MODE
,
0x10
);
/* MIDI routing */
snd_emu1010_fpga_write
(
emu
,
EMU_HANA_MIDI_IN
,
0x19
);
snd_emu1010_fpga_write
(
emu
,
EMU_HANA_MIDI_IN
,
0x19
);
/* Unknown. */
snd_emu1010_fpga_write
(
emu
,
EMU_HANA_MIDI_OUT
,
0x0c
);
/* snd_emu1010_fpga_write(emu, 0x09, 0x0f ); // IRQ Enable: All on */
snd_emu1010_fpga_write
(
emu
,
EMU_HANA_MIDI_OUT
,
0x0c
);
/* IRQ Enable: Alll on */
/* snd_emu1010_fpga_write(emu, 0x09, 0x0f ); */
/* IRQ Enable: All off */
snd_emu1010_fpga_write
(
emu
,
EMU_HANA_IRQ_ENABLE
,
0x00
);
snd_emu1010_fpga_write
(
emu
,
EMU_HANA_IRQ_ENABLE
,
0x00
);
snd_emu1010_fpga_read
(
emu
,
EMU_HANA_OPTION_CARDS
,
&
reg
);
snd_printk
(
KERN_INFO
"emu1010: Card options3
=0x%x
\n
"
,
reg
);
snd_emu1010_fpga_read
(
emu
,
EMU_HANA_OPTION_CARDS
,
&
reg
);
snd_printk
(
KERN_INFO
"emu1010: Card options3
= 0x%x
\n
"
,
reg
);
/* Default WCLK set to 48kHz. */
snd_emu1010_fpga_write
(
emu
,
EMU_HANA_DEFCLOCK
,
0x00
);
snd_emu1010_fpga_write
(
emu
,
EMU_HANA_DEFCLOCK
,
0x00
);
/* Word Clock source, Internal 48kHz x1 */
snd_emu1010_fpga_write
(
emu
,
EMU_HANA_WCLOCK
,
EMU_HANA_WCLOCK_INT_48K
);
/
/snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK, EMU_HANA_WCLOCK_INT_48K | EMU_HANA_WCLOCK_4X );
snd_emu1010_fpga_write
(
emu
,
EMU_HANA_WCLOCK
,
EMU_HANA_WCLOCK_INT_48K
);
/
* snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK, EMU_HANA_WCLOCK_INT_48K | EMU_HANA_WCLOCK_4X); */
/* Audio Dock LEDs. */
snd_emu1010_fpga_write
(
emu
,
EMU_HANA_DOCK_LEDS_2
,
0x12
);
snd_emu1010_fpga_write
(
emu
,
EMU_HANA_DOCK_LEDS_2
,
0x12
);
#if 0
/* For 96kHz */
...
...
@@ -992,7 +994,7 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu)
* Defaults only, users will set their own values anyways, let's
* just copy/paste.
*/
snd_emu1010_fpga_link_dst_src_write
(
emu
,
EMU_DST_ALICE2_EMU32_8
,
EMU_SRC_DOCK_MIC_A1
);
snd_emu1010_fpga_link_dst_src_write
(
emu
,
...
...
@@ -1037,19 +1039,19 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu)
snd_emu1010_fpga_link_dst_src_write(emu,
EMU_DST_ALICE2_EMU32_F, EMU_SRC_HAMOA_ADC_LEFT2);
#endif
for
(
i
=
0
;
i
<
0x20
;
i
++
)
{
/* AudioDock Elink <-
Silence */
snd_emu1010_fpga_link_dst_src_write
(
emu
,
0x0100
+
i
,
EMU_SRC_SILENCE
);
for
(
i
=
0
;
i
<
0x20
;
i
++
)
{
/* AudioDock Elink <- Silence */
snd_emu1010_fpga_link_dst_src_write
(
emu
,
0x0100
+
i
,
EMU_SRC_SILENCE
);
}
for
(
i
=
0
;
i
<
4
;
i
++
)
{
for
(
i
=
0
;
i
<
4
;
i
++
)
{
/* Hana SPDIF Out <- Silence */
snd_emu1010_fpga_link_dst_src_write
(
emu
,
0x0200
+
i
,
EMU_SRC_SILENCE
);
snd_emu1010_fpga_link_dst_src_write
(
emu
,
0x0200
+
i
,
EMU_SRC_SILENCE
);
}
for
(
i
=
0
;
i
<
7
;
i
++
)
{
for
(
i
=
0
;
i
<
7
;
i
++
)
{
/* Hamoa DAC <- Silence */
snd_emu1010_fpga_link_dst_src_write
(
emu
,
0x0300
+
i
,
EMU_SRC_SILENCE
);
snd_emu1010_fpga_link_dst_src_write
(
emu
,
0x0300
+
i
,
EMU_SRC_SILENCE
);
}
for
(
i
=
0
;
i
<
7
;
i
++
)
{
for
(
i
=
0
;
i
<
7
;
i
++
)
{
/* Hana ADAT Out <- Silence */
snd_emu1010_fpga_link_dst_src_write
(
emu
,
EMU_DST_HANA_ADAT
+
i
,
EMU_SRC_SILENCE
);
}
...
...
@@ -1065,30 +1067,30 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu)
EMU_DST_ALICE_I2S2_LEFT
,
EMU_SRC_DOCK_ADC3_LEFT1
);
snd_emu1010_fpga_link_dst_src_write
(
emu
,
EMU_DST_ALICE_I2S2_RIGHT
,
EMU_SRC_DOCK_ADC3_RIGHT1
);
snd_emu1010_fpga_write
(
emu
,
EMU_HANA_UNMUTE
,
0x01
);
// Unmute all
snd_emu1010_fpga_write
(
emu
,
EMU_HANA_UNMUTE
,
0x01
);
/* Unmute all */
snd_emu1010_fpga_read
(
emu
,
EMU_HANA_OPTION_CARDS
,
&
tmp
);
snd_emu1010_fpga_read
(
emu
,
EMU_HANA_OPTION_CARDS
,
&
tmp
);
/* AC97 1.03, Any 32Meg of 2Gig address, Auto-Mute, EMU32 Slave,
* Lock Sound Memory Cache, Lock Tank Memory Cache,
* Mute all codecs.
*/
outl
(
0x0000a000
,
emu
->
port
+
HCFG
);
outl
(
0x0000a000
,
emu
->
port
+
HCFG
);
/* AC97 1.03, Any 32Meg of 2Gig address, Auto-Mute, EMU32 Slave,
* Lock Sound Memory Cache, Lock Tank Memory Cache,
* Un-Mute all codecs.
*/
outl
(
0x0000a001
,
emu
->
port
+
HCFG
);
/* Initial boot complete. Now patches */
snd_emu1010_fpga_read
(
emu
,
EMU_HANA_OPTION_CARDS
,
&
tmp
);
snd_emu1010_fpga_write
(
emu
,
EMU_HANA_MIDI_IN
,
0x19
);
/* MIDI Route */
snd_emu1010_fpga_write
(
emu
,
EMU_HANA_MIDI_OUT
,
0x0c
);
/* Unknown */
snd_emu1010_fpga_write
(
emu
,
EMU_HANA_MIDI_IN
,
0x19
);
/* MIDI Route */
snd_emu1010_fpga_write
(
emu
,
EMU_HANA_MIDI_OUT
,
0x0c
);
/* Unknown */
snd_emu1010_fpga_read
(
emu
,
EMU_HANA_SPDIF_MODE
,
&
tmp
);
snd_emu1010_fpga_write
(
emu
,
EMU_HANA_SPDIF_MODE
,
0x10
);
/* SPDIF Format spdif (or 0x11 for aes/ebu) */
snd_emu1010_fpga_read
(
emu
,
EMU_HANA_OPTION_CARDS
,
&
tmp
);
snd_emu1010_fpga_write
(
emu
,
EMU_HANA_MIDI_IN
,
0x19
);
/* MIDI Route */
snd_emu1010_fpga_write
(
emu
,
EMU_HANA_MIDI_OUT
,
0x0c
);
/* Unknown */
snd_emu1010_fpga_write
(
emu
,
EMU_HANA_MIDI_IN
,
0x19
);
/* MIDI Route */
snd_emu1010_fpga_write
(
emu
,
EMU_HANA_MIDI_OUT
,
0x0c
);
/* Unknown */
snd_emu1010_fpga_read
(
emu
,
EMU_HANA_SPDIF_MODE
,
&
tmp
);
snd_emu1010_fpga_write
(
emu
,
EMU_HANA_SPDIF_MODE
,
0x10
);
/* SPDIF Format spdif (or 0x11 for aes/ebu) */
/* Start Micro/Audio Dock firmware loader thread */
if
(
!
emu
->
emu1010
.
firmware_thread
)
{
...
...
@@ -1218,20 +1220,20 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu)
emu
->
emu1010
.
output_source
[
23
]
=
28
;
}
/* TEMP: Select SPDIF in/out */
/
/snd_emu1010_fpga_write(emu, EMU_HANA_OPTICAL_TYPE, 0x0);
/* Output spdif */
/
* snd_emu1010_fpga_write(emu, EMU_HANA_OPTICAL_TYPE, 0x0); */
/* Output spdif */
/* TEMP: Select 48kHz SPDIF out */
snd_emu1010_fpga_write
(
emu
,
EMU_HANA_UNMUTE
,
0x0
);
/* Mute all */
snd_emu1010_fpga_write
(
emu
,
EMU_HANA_DEFCLOCK
,
0x0
);
/* Default fallback clock 48kHz */
/* Word Clock source, Internal 48kHz x1 */
snd_emu1010_fpga_write
(
emu
,
EMU_HANA_WCLOCK
,
EMU_HANA_WCLOCK_INT_48K
);
/
/snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK, EMU_HANA_WCLOCK_INT_48K | EMU_HANA_WCLOCK_4X );
snd_emu1010_fpga_write
(
emu
,
EMU_HANA_WCLOCK
,
EMU_HANA_WCLOCK_INT_48K
);
/
* snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK, EMU_HANA_WCLOCK_INT_48K | EMU_HANA_WCLOCK_4X); */
emu
->
emu1010
.
internal_clock
=
1
;
/* 48000 */
snd_emu1010_fpga_write
(
emu
,
EMU_HANA_DOCK_LEDS_2
,
0x12
);
/* Set LEDs on Audio Dock */
snd_emu1010_fpga_write
(
emu
,
EMU_HANA_DOCK_LEDS_2
,
0x12
);
/* Set LEDs on Audio Dock */
snd_emu1010_fpga_write
(
emu
,
EMU_HANA_UNMUTE
,
0x1
);
/* Unmute all */
/
/snd_emu1010_fpga_write(emu, 0x7, 0x0);
/* Mute all */
/
/snd_emu1010_fpga_write(emu, 0x7, 0x1);
/* Unmute all */
/
/snd_emu1010_fpga_write(emu, 0xe, 0x12);
/* Set LEDs on Audio Dock */
/
* snd_emu1010_fpga_write(emu, 0x7, 0x0); */
/* Mute all */
/
* snd_emu1010_fpga_write(emu, 0x7, 0x1); */
/* Unmute all */
/
* snd_emu1010_fpga_write(emu, 0xe, 0x12); */
/* Set LEDs on Audio Dock */
return
0
;
}
...
...
@@ -1247,13 +1249,13 @@ static void free_pm_buffer(struct snd_emu10k1 *emu);
static
int
snd_emu10k1_free
(
struct
snd_emu10k1
*
emu
)
{
if
(
emu
->
port
)
{
/* avoid access to already used hardware */
snd_emu10k1_fx8010_tram_setup
(
emu
,
0
);
snd_emu10k1_fx8010_tram_setup
(
emu
,
0
);
snd_emu10k1_done
(
emu
);
snd_emu10k1_free_efx
(
emu
);
}
}
if
(
emu
->
card_capabilities
->
emu_model
==
EMU_MODEL_EMU1010
)
{
/* Disable 48Volt power to Audio Dock */
snd_emu1010_fpga_write
(
emu
,
EMU_HANA_DOCK_PWR
,
0
);
snd_emu1010_fpga_write
(
emu
,
EMU_HANA_DOCK_PWR
,
0
);
}
if
(
emu
->
emu1010
.
firmware_thread
)
kthread_stop
(
emu
->
emu1010
.
firmware_thread
);
...
...
@@ -1278,7 +1280,7 @@ static int snd_emu10k1_free(struct snd_emu10k1 *emu)
#endif
if
(
emu
->
port
)
pci_release_regions
(
emu
->
pci
);
if
(
emu
->
card_capabilities
->
ca0151_chip
)
/* P16V */
if
(
emu
->
card_capabilities
->
ca0151_chip
)
/* P16V */
snd_p16v_free
(
emu
);
pci_disable_device
(
emu
->
pci
);
kfree
(
emu
);
...
...
@@ -1292,21 +1294,6 @@ static int snd_emu10k1_dev_free(struct snd_device *device)
}
static
struct
snd_emu_chip_details
emu_chip_details
[]
=
{
/* Audigy 2 Value AC3 out does not work yet. Need to find out how to turn off interpolators.*/
/* Tested by James@superbug.co.uk 3rd July 2005 */
/* DSP: CA0108-IAT
* DAC: CS4382-KQ
* ADC: Philips 1361T
* AC97: STAC9750
* CA0151: None
*/
{.
vendor
=
0x1102
,
.
device
=
0x0008
,
.
subsystem
=
0x10011102
,
.
driver
=
"Audigy2"
,
.
name
=
"Audigy 2 Value [SB0400]"
,
.
id
=
"Audigy2"
,
.
emu10k2_chip
=
1
,
.
ca0108_chip
=
1
,
.
spk71
=
1
,
.
ac97_chip
=
1
}
,
/* Audigy4 (Not PRO) SB0610 */
/* Tested by James@superbug.co.uk 4th April 2006 */
/* A_IOCFG bits
...
...
@@ -1346,20 +1333,37 @@ static struct snd_emu_chip_details emu_chip_details[] = {
* CA0151: None
*/
{.
vendor
=
0x1102
,
.
device
=
0x0008
,
.
subsystem
=
0x10211102
,
.
driver
=
"Audigy2"
,
.
name
=
"
Audigy 4 [SB0610]"
,
.
driver
=
"Audigy2"
,
.
name
=
"
SB Audigy 4 [SB0610]"
,
.
id
=
"Audigy2"
,
.
emu10k2_chip
=
1
,
.
ca0108_chip
=
1
,
.
spk71
=
1
,
.
adc_1361t
=
1
,
/* 24 bit capture instead of 16bit */
.
ac97_chip
=
1
}
,
/* Audigy 2 Value AC3 out does not work yet.
* Need to find out how to turn off interpolators.
*/
/* Tested by James@superbug.co.uk 3rd July 2005 */
/* DSP: CA0108-IAT
* DAC: CS4382-KQ
* ADC: Philips 1361T
* AC97: STAC9750
* CA0151: None
*/
{.
vendor
=
0x1102
,
.
device
=
0x0008
,
.
subsystem
=
0x10011102
,
.
driver
=
"Audigy2"
,
.
name
=
"SB Audigy 2 Value [SB0400]"
,
.
id
=
"Audigy2"
,
.
emu10k2_chip
=
1
,
.
ca0108_chip
=
1
,
.
spk71
=
1
,
.
ac97_chip
=
1
}
,
/* Audigy 2 ZS Notebook Cardbus card.*/
/* Tested by James@superbug.co.uk 6th November 2006 */
/* Audio output 7.1/Headphones working.
* Digital output working. (AC3 not checked, only PCM)
* Audio Mic/Line inputs working.
* Digital input not tested.
*/
*/
/* DSP: Tina2
* DAC: Wolfson WM8768/WM8568
* ADC: Wolfson WM8775
...
...
@@ -1386,7 +1390,7 @@ static struct snd_emu_chip_details emu_chip_details[] = {
*
*/
{.
vendor
=
0x1102
,
.
device
=
0x0008
,
.
subsystem
=
0x20011102
,
.
driver
=
"Audigy2"
,
.
name
=
"
Audigy 2 ZS Notebook [SB0530]"
,
.
driver
=
"Audigy2"
,
.
name
=
"
SB Audigy 2 ZS Notebook [SB0530]"
,
.
id
=
"Audigy2"
,
.
emu10k2_chip
=
1
,
.
ca0108_chip
=
1
,
...
...
@@ -1396,7 +1400,7 @@ static struct snd_emu_chip_details emu_chip_details[] = {
.
spk71
=
1
}
,
/* Tested by James@superbug.co.uk 4th Nov 2007. */
{.
vendor
=
0x1102
,
.
device
=
0x0008
,
.
subsystem
=
0x42011102
,
.
driver
=
"Audigy2"
,
.
name
=
"E-mu 1010 Notebook [MAEM8950]"
,
.
driver
=
"Audigy2"
,
.
name
=
"E-mu 1010 Notebook [MAEM8950]"
,
.
id
=
"EMU1010"
,
.
emu10k2_chip
=
1
,
.
ca0108_chip
=
1
,
...
...
@@ -1404,47 +1408,49 @@ static struct snd_emu_chip_details emu_chip_details[] = {
.
spk71
=
1
,
.
emu_model
=
EMU_MODEL_EMU1616
},
/* Tested by James@superbug.co.uk 4th Nov 2007. */
/* This is MAEM8960, 0202 is MAEM 8980 */
{.
vendor
=
0x1102
,
.
device
=
0x0008
,
.
subsystem
=
0x40041102
,
.
driver
=
"Audigy2"
,
.
name
=
"E-mu 1010b PCI [MAEM
????]"
,
.
driver
=
"Audigy2"
,
.
name
=
"E-mu 1010b PCI [MAEM
8960]"
,
.
id
=
"EMU1010"
,
.
emu10k2_chip
=
1
,
.
ca0108_chip
=
1
,
.
spk71
=
1
,
.
emu_model
=
EMU_MODEL_EMU1010B
},
.
emu_model
=
EMU_MODEL_EMU1010B
},
/* EMU 1010 new revision */
/* Tested by James@superbug.co.uk 8th July 2005. */
/* This is MAEM8810, 0202 is MAEM8820 */
{.
vendor
=
0x1102
,
.
device
=
0x0004
,
.
subsystem
=
0x40011102
,
.
driver
=
"Audigy2"
,
.
name
=
"E-mu 1010 [
4001
]"
,
.
driver
=
"Audigy2"
,
.
name
=
"E-mu 1010 [
MAEM8810
]"
,
.
id
=
"EMU1010"
,
.
emu10k2_chip
=
1
,
.
ca0102_chip
=
1
,
.
spk71
=
1
,
.
emu_model
=
EMU_MODEL_EMU1010
},
/* E
mu 1010
*/
.
emu_model
=
EMU_MODEL_EMU1010
},
/* E
MU 1010 old revision
*/
/* EMU0404b */
{.
vendor
=
0x1102
,
.
device
=
0x0008
,
.
subsystem
=
0x40021102
,
.
driver
=
"Audigy2"
,
.
name
=
"E-mu 0404b
[400
2]"
,
.
driver
=
"Audigy2"
,
.
name
=
"E-mu 0404b
PCI [MAEM885
2]"
,
.
id
=
"EMU0404"
,
.
emu10k2_chip
=
1
,
.
ca0108_chip
=
1
,
.
spk71
=
1
,
.
emu_model
=
EMU_MODEL_EMU0404
},
/* EMU 0404 */
.
emu_model
=
EMU_MODEL_EMU0404
},
/* EMU 0404
new revision
*/
/* Tested by James@superbug.co.uk 20-3-2007. */
{.
vendor
=
0x1102
,
.
device
=
0x0004
,
.
subsystem
=
0x40021102
,
.
driver
=
"Audigy2"
,
.
name
=
"E-mu 0404 [
4002
]"
,
.
driver
=
"Audigy2"
,
.
name
=
"E-mu 0404 [
MAEM8850
]"
,
.
id
=
"EMU0404"
,
.
emu10k2_chip
=
1
,
.
ca0102_chip
=
1
,
.
spk71
=
1
,
.
emu_model
=
EMU_MODEL_EMU0404
},
/* EMU 0404 */
/*
Audigy4 (Not PRO) SB0610
*/
{.
vendor
=
0x1102
,
.
device
=
0x0008
,
.
driver
=
"Audigy2"
,
.
name
=
"
Audigy 2 Value [Unknown]"
,
/*
Note that all E-mu cards require kernel 2.6 or newer.
*/
{.
vendor
=
0x1102
,
.
device
=
0x0008
,
.
driver
=
"Audigy2"
,
.
name
=
"
SB Audigy 2 Value [Unknown]"
,
.
id
=
"Audigy2"
,
.
emu10k2_chip
=
1
,
.
ca0108_chip
=
1
,
.
ac97_chip
=
1
}
,
/* Tested by James@superbug.co.uk 3rd July 2005 */
{.
vendor
=
0x1102
,
.
device
=
0x0004
,
.
subsystem
=
0x20071102
,
.
driver
=
"Audigy2"
,
.
name
=
"
Audigy 4 PRO [SB0380]"
,
.
driver
=
"Audigy2"
,
.
name
=
"
SB Audigy 4 PRO [SB0380]"
,
.
id
=
"Audigy2"
,
.
emu10k2_chip
=
1
,
.
ca0102_chip
=
1
,
...
...
@@ -1457,7 +1463,7 @@ static struct snd_emu_chip_details emu_chip_details[] = {
* Just like 0x20021102
*/
{.
vendor
=
0x1102
,
.
device
=
0x0004
,
.
subsystem
=
0x20061102
,
.
driver
=
"Audigy2"
,
.
name
=
"
Audigy 2 [SB0350b]"
,
.
driver
=
"Audigy2"
,
.
name
=
"
SB Audigy 2 [SB0350b]"
,
.
id
=
"Audigy2"
,
.
emu10k2_chip
=
1
,
.
ca0102_chip
=
1
,
...
...
@@ -1467,7 +1473,7 @@ static struct snd_emu_chip_details emu_chip_details[] = {
.
invert_shared_spdif
=
1
,
/* digital/analog switch swapped */
.
ac97_chip
=
1
}
,
{.
vendor
=
0x1102
,
.
device
=
0x0004
,
.
subsystem
=
0x20021102
,
.
driver
=
"Audigy2"
,
.
name
=
"
Audigy 2 ZS [SB0350]"
,
.
driver
=
"Audigy2"
,
.
name
=
"
SB Audigy 2 ZS [SB0350]"
,
.
id
=
"Audigy2"
,
.
emu10k2_chip
=
1
,
.
ca0102_chip
=
1
,
...
...
@@ -1477,7 +1483,7 @@ static struct snd_emu_chip_details emu_chip_details[] = {
.
invert_shared_spdif
=
1
,
/* digital/analog switch swapped */
.
ac97_chip
=
1
}
,
{.
vendor
=
0x1102
,
.
device
=
0x0004
,
.
subsystem
=
0x20011102
,
.
driver
=
"Audigy2"
,
.
name
=
"
Audigy 2 ZS [2001]"
,
.
driver
=
"Audigy2"
,
.
name
=
"
SB Audigy 2 ZS [SB0360]"
,
.
id
=
"Audigy2"
,
.
emu10k2_chip
=
1
,
.
ca0102_chip
=
1
,
...
...
@@ -1495,7 +1501,7 @@ static struct snd_emu_chip_details emu_chip_details[] = {
* CA0151: Yes
*/
{.
vendor
=
0x1102
,
.
device
=
0x0004
,
.
subsystem
=
0x10071102
,
.
driver
=
"Audigy2"
,
.
name
=
"
Audigy 2 [SB0240]"
,
.
driver
=
"Audigy2"
,
.
name
=
"
SB Audigy 2 [SB0240]"
,
.
id
=
"Audigy2"
,
.
emu10k2_chip
=
1
,
.
ca0102_chip
=
1
,
...
...
@@ -1505,7 +1511,7 @@ static struct snd_emu_chip_details emu_chip_details[] = {
.
adc_1361t
=
1
,
/* 24 bit capture instead of 16bit */
.
ac97_chip
=
1
}
,
{.
vendor
=
0x1102
,
.
device
=
0x0004
,
.
subsystem
=
0x10051102
,
.
driver
=
"Audigy2"
,
.
name
=
"
Audigy 2 EX [1005]"
,
.
driver
=
"Audigy2"
,
.
name
=
"
SB Audigy 2 Platinum EX [SB0280]"
,
.
id
=
"Audigy2"
,
.
emu10k2_chip
=
1
,
.
ca0102_chip
=
1
,
...
...
@@ -1515,7 +1521,7 @@ static struct snd_emu_chip_details emu_chip_details[] = {
/* Dell OEM/Creative Labs Audigy 2 ZS */
/* See ALSA bug#1365 */
{.
vendor
=
0x1102
,
.
device
=
0x0004
,
.
subsystem
=
0x10031102
,
.
driver
=
"Audigy2"
,
.
name
=
"Audigy 2 ZS [SB0353]"
,
.
driver
=
"Audigy2"
,
.
name
=
"
SB
Audigy 2 ZS [SB0353]"
,
.
id
=
"Audigy2"
,
.
emu10k2_chip
=
1
,
.
ca0102_chip
=
1
,
...
...
@@ -1524,7 +1530,7 @@ static struct snd_emu_chip_details emu_chip_details[] = {
.
spdif_bug
=
1
,
.
ac97_chip
=
1
}
,
{.
vendor
=
0x1102
,
.
device
=
0x0004
,
.
subsystem
=
0x10021102
,
.
driver
=
"Audigy2"
,
.
name
=
"
Audigy 2 Platinum [SB0240P]"
,
.
driver
=
"Audigy2"
,
.
name
=
"
SB Audigy 2 Platinum [SB0240P]"
,
.
id
=
"Audigy2"
,
.
emu10k2_chip
=
1
,
.
ca0102_chip
=
1
,
...
...
@@ -1535,7 +1541,7 @@ static struct snd_emu_chip_details emu_chip_details[] = {
.
adc_1361t
=
1
,
/* 24 bit capture instead of 16bit. Fixes ALSA bug#324 */
.
ac97_chip
=
1
}
,
{.
vendor
=
0x1102
,
.
device
=
0x0004
,
.
revision
=
0x04
,
.
driver
=
"Audigy2"
,
.
name
=
"Audigy 2 [Unknown]"
,
.
driver
=
"Audigy2"
,
.
name
=
"
SB
Audigy 2 [Unknown]"
,
.
id
=
"Audigy2"
,
.
emu10k2_chip
=
1
,
.
ca0102_chip
=
1
,
...
...
@@ -1543,78 +1549,79 @@ static struct snd_emu_chip_details emu_chip_details[] = {
.
spdif_bug
=
1
,
.
ac97_chip
=
1
}
,
{.
vendor
=
0x1102
,
.
device
=
0x0004
,
.
subsystem
=
0x00531102
,
.
driver
=
"Audigy"
,
.
name
=
"
Audigy 1 [SB0090]"
,
.
driver
=
"Audigy"
,
.
name
=
"
SB Audigy 1 [SB0092]"
,
.
id
=
"Audigy"
,
.
emu10k2_chip
=
1
,
.
ca0102_chip
=
1
,
.
ac97_chip
=
1
}
,
{.
vendor
=
0x1102
,
.
device
=
0x0004
,
.
subsystem
=
0x00521102
,
.
driver
=
"Audigy"
,
.
name
=
"
Audigy 1 ES [SB0160]"
,
.
driver
=
"Audigy"
,
.
name
=
"
SB Audigy 1 ES [SB0160]"
,
.
id
=
"Audigy"
,
.
emu10k2_chip
=
1
,
.
ca0102_chip
=
1
,
.
spdif_bug
=
1
,
.
ac97_chip
=
1
}
,
{.
vendor
=
0x1102
,
.
device
=
0x0004
,
.
subsystem
=
0x00511102
,
.
driver
=
"Audigy"
,
.
name
=
"
Audigy 1 [SB0090]"
,
.
driver
=
"Audigy"
,
.
name
=
"
SB Audigy 1 [SB0090]"
,
.
id
=
"Audigy"
,
.
emu10k2_chip
=
1
,
.
ca0102_chip
=
1
,
.
ac97_chip
=
1
}
,
{.
vendor
=
0x1102
,
.
device
=
0x0004
,
.
driver
=
"Audigy"
,
.
name
=
"Audigy 1 [Unknown]"
,
.
driver
=
"Audigy"
,
.
name
=
"Audigy 1 [Unknown]"
,
.
id
=
"Audigy"
,
.
emu10k2_chip
=
1
,
.
ca0102_chip
=
1
,
.
ac97_chip
=
1
}
,
{.
vendor
=
0x1102
,
.
device
=
0x0002
,
.
subsystem
=
0x806B1102
,
.
driver
=
"EMU10K1"
,
.
name
=
"SBLive! [SB0105]"
,
{.
vendor
=
0x1102
,
.
device
=
0x0002
,
.
subsystem
=
0x100a1102
,
.
driver
=
"EMU10K1"
,
.
name
=
"SB Live! 5.1 [SB0220]"
,
.
id
=
"Live"
,
.
emu10k1_chip
=
1
,
.
ac97_chip
=
1
,
.
sblive51
=
1
}
,
{.
vendor
=
0x1102
,
.
device
=
0x0002
,
.
subsystem
=
0x806b1102
,
.
driver
=
"EMU10K1"
,
.
name
=
"SB Live! [SB0105]"
,
.
id
=
"Live"
,
.
emu10k1_chip
=
1
,
.
ac97_chip
=
1
,
.
sblive51
=
1
}
,
{.
vendor
=
0x1102
,
.
device
=
0x0002
,
.
subsystem
=
0x806
A
1102
,
.
driver
=
"EMU10K1"
,
.
name
=
"SB
Live! Value [SB0103]"
,
{.
vendor
=
0x1102
,
.
device
=
0x0002
,
.
subsystem
=
0x806
a
1102
,
.
driver
=
"EMU10K1"
,
.
name
=
"SB
Live! Value [SB0103]"
,
.
id
=
"Live"
,
.
emu10k1_chip
=
1
,
.
ac97_chip
=
1
,
.
sblive51
=
1
}
,
{.
vendor
=
0x1102
,
.
device
=
0x0002
,
.
subsystem
=
0x80691102
,
.
driver
=
"EMU10K1"
,
.
name
=
"SB
Live! Value [SB0101]"
,
.
driver
=
"EMU10K1"
,
.
name
=
"SB
Live! Value [SB0101]"
,
.
id
=
"Live"
,
.
emu10k1_chip
=
1
,
.
ac97_chip
=
1
,
.
sblive51
=
1
}
,
/* Tested by ALSA bug#1680 26th December 2005 */
/* note: It really has SB0220 written on the card. */
/* note: It really has SB0220 written on the card, */
/* but it's SB0228 according to kx.inf */
{.
vendor
=
0x1102
,
.
device
=
0x0002
,
.
subsystem
=
0x80661102
,
.
driver
=
"EMU10K1"
,
.
name
=
"SB Live
5.1 Dell OEM [SB0220]"
,
.
driver
=
"EMU10K1"
,
.
name
=
"SB Live
! 5.1 Dell OEM [SB0228]"
,
.
id
=
"Live"
,
.
emu10k1_chip
=
1
,
.
ac97_chip
=
1
,
.
sblive51
=
1
}
,
/* Tested by Thomas Zehetbauer 27th Aug 2005 */
{.
vendor
=
0x1102
,
.
device
=
0x0002
,
.
subsystem
=
0x80651102
,
.
driver
=
"EMU10K1"
,
.
name
=
"SB Live 5.1 [SB0220]"
,
.
id
=
"Live"
,
.
emu10k1_chip
=
1
,
.
ac97_chip
=
1
,
.
sblive51
=
1
}
,
{.
vendor
=
0x1102
,
.
device
=
0x0002
,
.
subsystem
=
0x100a1102
,
.
driver
=
"EMU10K1"
,
.
name
=
"SB Live 5.1 [SB0220]"
,
.
driver
=
"EMU10K1"
,
.
name
=
"SB Live! 5.1 [SB0220]"
,
.
id
=
"Live"
,
.
emu10k1_chip
=
1
,
.
ac97_chip
=
1
,
.
sblive51
=
1
}
,
{.
vendor
=
0x1102
,
.
device
=
0x0002
,
.
subsystem
=
0x80641102
,
.
driver
=
"EMU10K1"
,
.
name
=
"SB Live
5.1"
,
.
driver
=
"EMU10K1"
,
.
name
=
"SB Live
! 5.1"
,
.
id
=
"Live"
,
.
emu10k1_chip
=
1
,
.
ac97_chip
=
1
,
.
sblive51
=
1
}
,
/* Tested by alsa bugtrack user "hus" bug #1297 12th Aug 2005 */
{.
vendor
=
0x1102
,
.
device
=
0x0002
,
.
subsystem
=
0x80611102
,
.
driver
=
"EMU10K1"
,
.
name
=
"SB
Live
5.1 [SB0060]"
,
.
driver
=
"EMU10K1"
,
.
name
=
"SB
Live!
5.1 [SB0060]"
,
.
id
=
"Live"
,
.
emu10k1_chip
=
1
,
.
ac97_chip
=
2
,
/* ac97 is optional; both SBLive 5.1 and platinum
...
...
@@ -1622,78 +1629,78 @@ static struct snd_emu_chip_details emu_chip_details[] = {
*/
.
sblive51
=
1
}
,
{.
vendor
=
0x1102
,
.
device
=
0x0002
,
.
subsystem
=
0x80511102
,
.
driver
=
"EMU10K1"
,
.
name
=
"SB
Live! Value [CT4850]"
,
.
driver
=
"EMU10K1"
,
.
name
=
"SB
Live! Value [CT4850]"
,
.
id
=
"Live"
,
.
emu10k1_chip
=
1
,
.
ac97_chip
=
1
,
.
sblive51
=
1
}
,
{.
vendor
=
0x1102
,
.
device
=
0x0002
,
.
subsystem
=
0x80401102
,
.
driver
=
"EMU10K1"
,
.
name
=
"SB
Live! Platinum [CT4760P]"
,
.
driver
=
"EMU10K1"
,
.
name
=
"SB
Live! Platinum [CT4760P]"
,
.
id
=
"Live"
,
.
emu10k1_chip
=
1
,
.
ac97_chip
=
1
}
,
{.
vendor
=
0x1102
,
.
device
=
0x0002
,
.
subsystem
=
0x80321102
,
.
driver
=
"EMU10K1"
,
.
name
=
"SB
Live! Value [CT4871]"
,
.
driver
=
"EMU10K1"
,
.
name
=
"SB
Live! Value [CT4871]"
,
.
id
=
"Live"
,
.
emu10k1_chip
=
1
,
.
ac97_chip
=
1
,
.
sblive51
=
1
}
,
{.
vendor
=
0x1102
,
.
device
=
0x0002
,
.
subsystem
=
0x80311102
,
.
driver
=
"EMU10K1"
,
.
name
=
"SB
Live! Value [CT4831]"
,
.
driver
=
"EMU10K1"
,
.
name
=
"SB
Live! Value [CT4831]"
,
.
id
=
"Live"
,
.
emu10k1_chip
=
1
,
.
ac97_chip
=
1
,
.
sblive51
=
1
}
,
{.
vendor
=
0x1102
,
.
device
=
0x0002
,
.
subsystem
=
0x80281102
,
.
driver
=
"EMU10K1"
,
.
name
=
"SB
Live! Value [CT4870]"
,
.
driver
=
"EMU10K1"
,
.
name
=
"SB
Live! Value [CT4870]"
,
.
id
=
"Live"
,
.
emu10k1_chip
=
1
,
.
ac97_chip
=
1
,
.
sblive51
=
1
}
,
/* Tested by James@superbug.co.uk 3rd July 2005 */
{.
vendor
=
0x1102
,
.
device
=
0x0002
,
.
subsystem
=
0x80271102
,
.
driver
=
"EMU10K1"
,
.
name
=
"SB
Live! Value [CT4832]"
,
.
driver
=
"EMU10K1"
,
.
name
=
"SB
Live! Value [CT4832]"
,
.
id
=
"Live"
,
.
emu10k1_chip
=
1
,
.
ac97_chip
=
1
,
.
sblive51
=
1
}
,
{.
vendor
=
0x1102
,
.
device
=
0x0002
,
.
subsystem
=
0x80261102
,
.
driver
=
"EMU10K1"
,
.
name
=
"SB
Live! Value [CT4830]"
,
.
driver
=
"EMU10K1"
,
.
name
=
"SB
Live! Value [CT4830]"
,
.
id
=
"Live"
,
.
emu10k1_chip
=
1
,
.
ac97_chip
=
1
,
.
sblive51
=
1
}
,
{.
vendor
=
0x1102
,
.
device
=
0x0002
,
.
subsystem
=
0x80231102
,
.
driver
=
"EMU10K1"
,
.
name
=
"SB PCI512 [CT4790]"
,
.
driver
=
"EMU10K1"
,
.
name
=
"SB PCI512 [CT4790]"
,
.
id
=
"Live"
,
.
emu10k1_chip
=
1
,
.
ac97_chip
=
1
,
.
sblive51
=
1
}
,
{.
vendor
=
0x1102
,
.
device
=
0x0002
,
.
subsystem
=
0x80221102
,
.
driver
=
"EMU10K1"
,
.
name
=
"SB
Live! Value [CT4780]"
,
.
driver
=
"EMU10K1"
,
.
name
=
"SB
Live! Value [CT4780]"
,
.
id
=
"Live"
,
.
emu10k1_chip
=
1
,
.
ac97_chip
=
1
,
.
sblive51
=
1
}
,
{.
vendor
=
0x1102
,
.
device
=
0x0002
,
.
subsystem
=
0x40011102
,
.
driver
=
"EMU10K1"
,
.
name
=
"E-mu APS [
4001]"
,
.
driver
=
"EMU10K1"
,
.
name
=
"E-mu APS [
PC545]"
,
.
id
=
"APS"
,
.
emu10k1_chip
=
1
,
.
ecard
=
1
}
,
{.
vendor
=
0x1102
,
.
device
=
0x0002
,
.
subsystem
=
0x00211102
,
.
driver
=
"EMU10K1"
,
.
name
=
"SB
Live! [CT4620]"
,
.
driver
=
"EMU10K1"
,
.
name
=
"SB
Live! [CT4620]"
,
.
id
=
"Live"
,
.
emu10k1_chip
=
1
,
.
ac97_chip
=
1
,
.
sblive51
=
1
}
,
{.
vendor
=
0x1102
,
.
device
=
0x0002
,
.
subsystem
=
0x00201102
,
.
driver
=
"EMU10K1"
,
.
name
=
"SB
Live! Value [CT4670]"
,
.
driver
=
"EMU10K1"
,
.
name
=
"SB
Live! Value [CT4670]"
,
.
id
=
"Live"
,
.
emu10k1_chip
=
1
,
.
ac97_chip
=
1
,
.
sblive51
=
1
}
,
{.
vendor
=
0x1102
,
.
device
=
0x0002
,
.
driver
=
"EMU10K1"
,
.
name
=
"SB Live
[Unknown]"
,
.
driver
=
"EMU10K1"
,
.
name
=
"SB Live
! [Unknown]"
,
.
id
=
"Live"
,
.
emu10k1_chip
=
1
,
.
ac97_chip
=
1
,
...
...
@@ -1702,13 +1709,13 @@ static struct snd_emu_chip_details emu_chip_details[] = {
};
int
__devinit
snd_emu10k1_create
(
struct
snd_card
*
card
,
struct
pci_dev
*
pci
,
struct
pci_dev
*
pci
,
unsigned
short
extin_mask
,
unsigned
short
extout_mask
,
long
max_cache_bytes
,
int
enable_ir
,
uint
subsystem
,
struct
snd_emu10k1
**
remu
)
struct
snd_emu10k1
**
remu
)
{
struct
snd_emu10k1
*
emu
;
int
idx
,
err
;
...
...
@@ -1718,11 +1725,12 @@ int __devinit snd_emu10k1_create(struct snd_card *card,
static
struct
snd_device_ops
ops
=
{
.
dev_free
=
snd_emu10k1_dev_free
,
};
*
remu
=
NULL
;
/* enable PCI device */
if
((
err
=
pci_enable_device
(
pci
))
<
0
)
err
=
pci_enable_device
(
pci
);
if
(
err
<
0
)
return
err
;
emu
=
kzalloc
(
sizeof
(
*
emu
),
GFP_KERNEL
);
...
...
@@ -1749,16 +1757,17 @@ int __devinit snd_emu10k1_create(struct snd_card *card,
emu
->
revision
=
pci
->
revision
;
pci_read_config_dword
(
pci
,
PCI_SUBSYSTEM_VENDOR_ID
,
&
emu
->
serial
);
pci_read_config_word
(
pci
,
PCI_SUBSYSTEM_ID
,
&
emu
->
model
);
snd_printdd
(
"vendor
=0x%x, device=0x%x, subsystem_vendor_id=0x%x, subsystem_id=0x%x
\n
"
,
pci
->
vendor
,
pci
->
device
,
emu
->
serial
,
emu
->
model
);
snd_printdd
(
"vendor
= 0x%x, device = 0x%x, subsystem_vendor_id = 0x%x, subsystem_id = 0x%x
\n
"
,
pci
->
vendor
,
pci
->
device
,
emu
->
serial
,
emu
->
model
);
for
(
c
=
emu_chip_details
;
c
->
vendor
;
c
++
)
{
if
(
c
->
vendor
==
pci
->
vendor
&&
c
->
device
==
pci
->
device
)
{
if
(
subsystem
)
{
if
(
c
->
subsystem
&&
(
c
->
subsystem
==
subsystem
)
)
{
if
(
c
->
subsystem
&&
(
c
->
subsystem
==
subsystem
)
)
break
;
}
else
continue
;
else
continue
;
}
else
{
if
(
c
->
subsystem
&&
(
c
->
subsystem
!=
emu
->
serial
)
)
if
(
c
->
subsystem
&&
(
c
->
subsystem
!=
emu
->
serial
))
continue
;
if
(
c
->
revision
&&
c
->
revision
!=
emu
->
revision
)
continue
;
...
...
@@ -1774,14 +1783,18 @@ int __devinit snd_emu10k1_create(struct snd_card *card,
}
emu
->
card_capabilities
=
c
;
if
(
c
->
subsystem
&&
!
subsystem
)
snd_printdd
(
"Sound card name=%s
\n
"
,
c
->
name
);
else
if
(
subsystem
)
snd_printdd
(
"Sound card name=%s, vendor=0x%x, device=0x%x, subsystem=0x%x. Forced to subsytem=0x%x
\n
"
,
c
->
name
,
pci
->
vendor
,
pci
->
device
,
emu
->
serial
,
c
->
subsystem
);
else
snd_printdd
(
"Sound card name=%s, vendor=0x%x, device=0x%x, subsystem=0x%x.
\n
"
,
c
->
name
,
pci
->
vendor
,
pci
->
device
,
emu
->
serial
);
snd_printdd
(
"Sound card name = %s
\n
"
,
c
->
name
);
else
if
(
subsystem
)
snd_printdd
(
"Sound card name = %s, "
"vendor = 0x%x, device = 0x%x, subsystem = 0x%x. "
"Forced to subsytem = 0x%x
\n
"
,
c
->
name
,
pci
->
vendor
,
pci
->
device
,
emu
->
serial
,
c
->
subsystem
);
else
snd_printdd
(
"Sound card name = %s, "
"vendor = 0x%x, device = 0x%x, subsystem = 0x%x.
\n
"
,
c
->
name
,
pci
->
vendor
,
pci
->
device
,
emu
->
serial
);
if
(
!*
card
->
id
&&
c
->
id
)
{
int
i
,
n
=
0
;
strlcpy
(
card
->
id
,
c
->
id
,
sizeof
(
card
->
id
));
...
...
@@ -1815,7 +1828,8 @@ int __devinit snd_emu10k1_create(struct snd_card *card,
else
emu
->
gpr_base
=
FXGPREGBASE
;
if
((
err
=
pci_request_regions
(
pci
,
"EMU10K1"
))
<
0
)
{
err
=
pci_request_regions
(
pci
,
"EMU10K1"
);
if
(
err
<
0
)
{
kfree
(
emu
);
pci_disable_device
(
pci
);
return
err
;
...
...
@@ -1862,21 +1876,25 @@ int __devinit snd_emu10k1_create(struct snd_card *card,
emu
->
enable_ir
=
enable_ir
;
if
(
emu
->
card_capabilities
->
ca_cardbus_chip
)
{
if
((
err
=
snd_emu10k1_cardbus_init
(
emu
))
<
0
)
err
=
snd_emu10k1_cardbus_init
(
emu
);
if
(
err
<
0
)
goto
error
;
}
if
(
emu
->
card_capabilities
->
ecard
)
{
if
((
err
=
snd_emu10k1_ecard_init
(
emu
))
<
0
)
err
=
snd_emu10k1_ecard_init
(
emu
);
if
(
err
<
0
)
goto
error
;
}
else
if
(
emu
->
card_capabilities
->
emu_model
)
{
if
((
err
=
snd_emu10k1_emu1010_init
(
emu
))
<
0
)
{
snd_emu10k1_free
(
emu
);
return
err
;
}
err
=
snd_emu10k1_emu1010_init
(
emu
);
if
(
err
<
0
)
{
snd_emu10k1_free
(
emu
);
return
err
;
}
}
else
{
/* 5.1: Enable the additional AC97 Slots. If the emu10k1 version
does not support this, it shouldn't do any harm */
snd_emu10k1_ptr_write
(
emu
,
AC97SLOT
,
0
,
AC97SLOT_CNTR
|
AC97SLOT_LFE
);
snd_emu10k1_ptr_write
(
emu
,
AC97SLOT
,
0
,
AC97SLOT_CNTR
|
AC97SLOT_LFE
);
}
/* initialize TRAM setup */
...
...
@@ -1916,7 +1934,7 @@ int __devinit snd_emu10k1_create(struct snd_card *card,
snd_emu10k1_synth_alloc
(
emu
,
4096
);
if
(
emu
->
reserved_page
)
emu
->
reserved_page
->
map_locked
=
1
;
/* Clear silent pages and set up pointers */
memset
(
emu
->
silent_page
.
area
,
0
,
PAGE_SIZE
);
silent_page
=
emu
->
silent_page
.
addr
<<
1
;
...
...
@@ -1929,19 +1947,23 @@ int __devinit snd_emu10k1_create(struct snd_card *card,
emu
->
voices
[
idx
].
number
=
idx
;
}
if
((
err
=
snd_emu10k1_init
(
emu
,
enable_ir
,
0
))
<
0
)
err
=
snd_emu10k1_init
(
emu
,
enable_ir
,
0
);
if
(
err
<
0
)
goto
error
;
#ifdef CONFIG_PM
if
((
err
=
alloc_pm_buffer
(
emu
))
<
0
)
err
=
alloc_pm_buffer
(
emu
);
if
(
err
<
0
)
goto
error
;
#endif
/* Initialize the effect engine */
if
((
err
=
snd_emu10k1_init_efx
(
emu
))
<
0
)
err
=
snd_emu10k1_init_efx
(
emu
);
if
(
err
<
0
)
goto
error
;
snd_emu10k1_audio_enable
(
emu
);
if
((
err
=
snd_device_new
(
card
,
SNDRV_DEV_LOWLEVEL
,
emu
,
&
ops
))
<
0
)
err
=
snd_device_new
(
card
,
SNDRV_DEV_LOWLEVEL
,
emu
,
&
ops
);
if
(
err
<
0
)
goto
error
;
#ifdef CONFIG_PROC_FS
...
...
@@ -1981,7 +2003,7 @@ static int __devinit alloc_pm_buffer(struct snd_emu10k1 *emu)
if
(
emu
->
audigy
)
size
+=
ARRAY_SIZE
(
saved_regs_audigy
);
emu
->
saved_ptr
=
vmalloc
(
4
*
NUM_G
*
size
);
if
(
!
emu
->
saved_ptr
)
if
(
!
emu
->
saved_ptr
)
return
-
ENOMEM
;
if
(
snd_emu10k1_efx_alloc_pm_buffer
(
emu
)
<
0
)
return
-
ENOMEM
;
...
...
@@ -2026,7 +2048,7 @@ void snd_emu10k1_resume_init(struct snd_emu10k1 *emu)
if
(
emu
->
card_capabilities
->
ecard
)
snd_emu10k1_ecard_init
(
emu
);
else
if
(
emu
->
card_capabilities
->
emu_model
)
snd_emu10k1_emu1010_init
(
emu
);
snd_emu10k1_emu1010_init
(
emu
);
else
snd_emu10k1_ptr_write
(
emu
,
AC97SLOT
,
0
,
AC97SLOT_CNTR
|
AC97SLOT_LFE
);
snd_emu10k1_init
(
emu
,
emu
->
enable_ir
,
1
);
...
...
sound/pci/ice1712/ice1724.c
View file @
86b3aa39
...
...
@@ -382,23 +382,25 @@ static irqreturn_t snd_vt1724_interrupt(int irq, void *dev_id)
unsigned
char
status_mask
=
VT1724_IRQ_MPU_RX
|
VT1724_IRQ_MPU_TX
|
VT1724_IRQ_MTPCM
;
int
handled
=
0
;
#ifdef CONFIG_SND_DEBUG
int
timeout
=
0
;
#endif
while
(
1
)
{
status
=
inb
(
ICEREG1724
(
ice
,
IRQSTAT
));
status
&=
status_mask
;
if
(
status
==
0
)
break
;
#ifdef CONFIG_SND_DEBUG
if
(
++
timeout
>
10
)
{
printk
(
KERN_ERR
"ice1724: Too long irq loop, status = 0x%x
\n
"
,
status
);
status
=
inb
(
ICEREG1724
(
ice
,
IRQSTAT
));
printk
(
KERN_ERR
"ice1724: Too long irq loop, "
"status = 0x%x
\n
"
,
status
);
if
(
status
&
VT1724_IRQ_MPU_TX
)
{
printk
(
KERN_ERR
"ice1724: Disabling MPU_TX
\n
"
);
outb
(
inb
(
ICEREG1724
(
ice
,
IRQMASK
))
|
VT1724_IRQ_MPU_TX
,
ICEREG1724
(
ice
,
IRQMASK
));
}
break
;
}
#endif
handled
=
1
;
if
(
status
&
VT1724_IRQ_MPU_TX
)
{
spin_lock
(
&
ice
->
reg_lock
);
...
...
@@ -2351,7 +2353,6 @@ static int __devinit snd_vt1724_create(struct snd_card *card,
{
struct
snd_ice1712
*
ice
;
int
err
;
unsigned
char
mask
;
static
struct
snd_device_ops
ops
=
{
.
dev_free
=
snd_vt1724_dev_free
,
};
...
...
@@ -2412,9 +2413,9 @@ static int __devinit snd_vt1724_create(struct snd_card *card,
return
-
EIO
;
}
/*
unmask used interrupts
*/
mask
=
VT1724_IRQ_MPU_RX
|
VT1724_IRQ_MPU_TX
;
outb
(
mask
,
ICEREG1724
(
ice
,
IRQMASK
));
/*
MPU_RX and TX irq masks are cleared later dynamically
*/
outb
(
VT1724_IRQ_MPU_RX
|
VT1724_IRQ_MPU_TX
,
ICEREG1724
(
ice
,
IRQMASK
))
;
/* don't handle FIFO overrun/underruns (just yet),
* since they cause machine lockups
*/
...
...
sound/pci/mixart/mixart.c
View file @
86b3aa39
...
...
@@ -1010,7 +1010,7 @@ static int __devinit snd_mixart_create(struct mixart_mgr *mgr, struct snd_card *
.
dev_free
=
snd_mixart_chip_dev_free
,
};
mgr
->
chip
[
idx
]
=
chip
=
kzalloc
(
sizeof
(
*
chip
),
GFP_KERNEL
);
chip
=
kzalloc
(
sizeof
(
*
chip
),
GFP_KERNEL
);
if
(
!
chip
)
{
snd_printk
(
KERN_ERR
"cannot allocate chip
\n
"
);
return
-
ENOMEM
;
...
...
@@ -1025,6 +1025,7 @@ static int __devinit snd_mixart_create(struct mixart_mgr *mgr, struct snd_card *
return
err
;
}
mgr
->
chip
[
idx
]
=
chip
;
snd_card_set_dev
(
card
,
&
mgr
->
pci
->
dev
);
return
0
;
...
...
@@ -1377,6 +1378,7 @@ static int __devinit snd_mixart_probe(struct pci_dev *pci,
sprintf
(
card
->
longname
,
"%s [PCM #%d]"
,
mgr
->
longname
,
i
);
if
((
err
=
snd_mixart_create
(
mgr
,
card
,
i
))
<
0
)
{
snd_card_free
(
card
);
snd_mixart_free
(
mgr
);
return
err
;
}
...
...
sound/pci/pcxhr/pcxhr.c
View file @
86b3aa39
...
...
@@ -1024,7 +1024,7 @@ static int __devinit pcxhr_create(struct pcxhr_mgr *mgr, struct snd_card *card,
.
dev_free
=
pcxhr_chip_dev_free
,
};
mgr
->
chip
[
idx
]
=
chip
=
kzalloc
(
sizeof
(
*
chip
),
GFP_KERNEL
);
chip
=
kzalloc
(
sizeof
(
*
chip
),
GFP_KERNEL
);
if
(
!
chip
)
{
snd_printk
(
KERN_ERR
"cannot allocate chip
\n
"
);
return
-
ENOMEM
;
...
...
@@ -1050,6 +1050,7 @@ static int __devinit pcxhr_create(struct pcxhr_mgr *mgr, struct snd_card *card,
return
err
;
}
mgr
->
chip
[
idx
]
=
chip
;
snd_card_set_dev
(
card
,
&
mgr
->
pci
->
dev
);
return
0
;
...
...
@@ -1310,6 +1311,7 @@ static int __devinit pcxhr_probe(struct pci_dev *pci, const struct pci_device_id
sprintf
(
card
->
longname
,
"%s [PCM #%d]"
,
mgr
->
longname
,
i
);
if
((
err
=
pcxhr_create
(
mgr
,
card
,
i
))
<
0
)
{
snd_card_free
(
card
);
pcxhr_free
(
mgr
);
return
err
;
}
...
...
sound/pci/riptide/riptide.c
View file @
86b3aa39
...
...
@@ -172,7 +172,7 @@ MODULE_PARM_DESC(opl3_port, "OPL3 port # for Riptide driver.");
#define MAX_WRITE_RETRY 10
/* cmd interface limits */
#define MAX_ERROR_COUNT 10
#define CMDIF_TIMEOUT 50000
0
#define CMDIF_TIMEOUT 50000
#define RESET_TRIES 5
#define READ_PORT_ULONG(p) inl((unsigned long)&(p))
...
...
sound/ppc/pmac.c
View file @
86b3aa39
...
...
@@ -1033,7 +1033,7 @@ static int __init snd_pmac_detect(struct snd_pmac *chip)
}
if
(
of_device_is_compatible
(
sound
,
"tumbler"
))
{
chip
->
model
=
PMAC_TUMBLER
;
chip
->
can_capture
=
0
;
/* no capture */
chip
->
can_capture
=
machine_is_compatible
(
"PowerMac4,2"
);
chip
->
can_duplex
=
0
;
// chip->can_byte_swap = 0; /* FIXME: check this */
chip
->
num_freqs
=
ARRAY_SIZE
(
tumbler_freqs
);
...
...
sound/ppc/tumbler.c
View file @
86b3aa39
...
...
@@ -875,7 +875,8 @@ static struct snd_kcontrol_new snapper_mixers[] __initdata = {
.
put
=
tumbler_put_master_switch
},
DEFINE_SNAPPER_MIX
(
"PCM Playback Volume"
,
0
,
VOL_IDX_PCM
),
DEFINE_SNAPPER_MIX
(
"PCM Playback Volume"
,
1
,
VOL_IDX_PCM2
),
/* Alternative PCM is assigned to Mic analog loopback on iBook G4 */
DEFINE_SNAPPER_MIX
(
"Mic Playback Volume"
,
0
,
VOL_IDX_PCM2
),
DEFINE_SNAPPER_MIX
(
"Monitor Mix Volume"
,
0
,
VOL_IDX_ADC
),
DEFINE_SNAPPER_MONO
(
"Tone Control - Bass"
,
bass
),
DEFINE_SNAPPER_MONO
(
"Tone Control - Treble"
,
treble
),
...
...
sound/usb/caiaq/caiaq-control.c
View file @
86b3aa39
...
...
@@ -247,69 +247,56 @@ static struct caiaq_controller a8dj_controller[] = {
{
"Software lock"
,
40
}
};
int
__devinit
snd_usb_caiaq_control_init
(
struct
snd_usb_caiaqdev
*
dev
)
static
int
__devinit
add_controls
(
struct
caiaq_controller
*
c
,
int
num
,
struct
snd_usb_caiaqdev
*
dev
)
{
int
i
;
int
i
,
ret
;
struct
snd_kcontrol
*
kc
;
for
(
i
=
0
;
i
<
num
;
i
++
,
c
++
)
{
kcontrol_template
.
name
=
c
->
name
;
kcontrol_template
.
private_value
=
c
->
index
;
kc
=
snd_ctl_new1
(
&
kcontrol_template
,
dev
);
ret
=
snd_ctl_add
(
dev
->
chip
.
card
,
kc
);
if
(
ret
<
0
)
return
ret
;
}
return
0
;
}
int
__devinit
snd_usb_caiaq_control_init
(
struct
snd_usb_caiaqdev
*
dev
)
{
int
ret
=
0
;
switch
(
dev
->
chip
.
usb_id
)
{
case
USB_ID
(
USB_VID_NATIVEINSTRUMENTS
,
USB_PID_AK1
):
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
ak1_controller
);
i
++
)
{
struct
caiaq_controller
*
c
=
ak1_controller
+
i
;
kcontrol_template
.
name
=
c
->
name
;
kcontrol_template
.
private_value
=
c
->
index
;
kc
=
snd_ctl_new1
(
&
kcontrol_template
,
dev
);
snd_ctl_add
(
dev
->
chip
.
card
,
kc
);
}
ret
=
add_controls
(
ak1_controller
,
ARRAY_SIZE
(
ak1_controller
),
dev
);
break
;
case
USB_ID
(
USB_VID_NATIVEINSTRUMENTS
,
USB_PID_RIGKONTROL2
):
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
rk2_controller
);
i
++
)
{
struct
caiaq_controller
*
c
=
rk2_controller
+
i
;
kcontrol_template
.
name
=
c
->
name
;
kcontrol_template
.
private_value
=
c
->
index
;
kc
=
snd_ctl_new1
(
&
kcontrol_template
,
dev
);
snd_ctl_add
(
dev
->
chip
.
card
,
kc
);
}
ret
=
add_controls
(
rk2_controller
,
ARRAY_SIZE
(
rk2_controller
),
dev
);
break
;
case
USB_ID
(
USB_VID_NATIVEINSTRUMENTS
,
USB_PID_RIGKONTROL3
):
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
rk3_controller
);
i
++
)
{
struct
caiaq_controller
*
c
=
rk3_controller
+
i
;
kcontrol_template
.
name
=
c
->
name
;
kcontrol_template
.
private_value
=
c
->
index
;
kc
=
snd_ctl_new1
(
&
kcontrol_template
,
dev
);
snd_ctl_add
(
dev
->
chip
.
card
,
kc
);
}
ret
=
add_controls
(
rk3_controller
,
ARRAY_SIZE
(
rk3_controller
),
dev
);
break
;
case
USB_ID
(
USB_VID_NATIVEINSTRUMENTS
,
USB_PID_KORECONTROLLER
):
case
USB_ID
(
USB_VID_NATIVEINSTRUMENTS
,
USB_PID_KORECONTROLLER2
):
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
kore_controller
);
i
++
)
{
struct
caiaq_controller
*
c
=
kore_controller
+
i
;
kcontrol_template
.
name
=
c
->
name
;
kcontrol_template
.
private_value
=
c
->
index
;
kc
=
snd_ctl_new1
(
&
kcontrol_template
,
dev
);
snd_ctl_add
(
dev
->
chip
.
card
,
kc
);
}
ret
=
add_controls
(
kore_controller
,
ARRAY_SIZE
(
kore_controller
),
dev
);
break
;
case
USB_ID
(
USB_VID_NATIVEINSTRUMENTS
,
USB_PID_AUDIO8DJ
):
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
a8dj_controller
);
i
++
)
{
struct
caiaq_controller
*
c
=
a8dj_controller
+
i
;
kcontrol_template
.
name
=
c
->
name
;
kcontrol_template
.
private_value
=
c
->
index
;
kc
=
snd_ctl_new1
(
&
kcontrol_template
,
dev
);
snd_ctl_add
(
dev
->
chip
.
card
,
kc
);
}
ret
=
add_controls
(
a8dj_controller
,
ARRAY_SIZE
(
a8dj_controller
),
dev
);
break
;
}
return
0
;
return
ret
;
}
sound/usb/caiaq/caiaq-device.c
View file @
86b3aa39
...
...
@@ -42,7 +42,7 @@
#endif
MODULE_AUTHOR
(
"Daniel Mack <daniel@caiaq.de>"
);
MODULE_DESCRIPTION
(
"caiaq USB audio, version 1.3.
8
"
);
MODULE_DESCRIPTION
(
"caiaq USB audio, version 1.3.
9
"
);
MODULE_LICENSE
(
"GPL"
);
MODULE_SUPPORTED_DEVICE
(
"{{Native Instruments, RigKontrol2},"
"{Native Instruments, RigKontrol3},"
...
...
sound/usb/usx2y/usb_stream.c
View file @
86b3aa39
...
...
@@ -276,7 +276,8 @@ static void subs_set_complete(struct urb **urbs, void (*complete)(struct urb *))
}
}
int
usb_stream_prepare_playback
(
struct
usb_stream_kernel
*
sk
,
struct
urb
*
inurb
)
static
int
usb_stream_prepare_playback
(
struct
usb_stream_kernel
*
sk
,
struct
urb
*
inurb
)
{
struct
usb_stream
*
s
=
sk
->
s
;
struct
urb
*
io
;
...
...
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