Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
3c4dbda0
Commit
3c4dbda0
authored
Jun 02, 2009
by
Takashi Iwai
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'topic/hda-ctl-reset' into topic/hda
parents
3b315d70
b20f3b83
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
69 additions
and
33 deletions
+69
-33
sound/pci/hda/hda_codec.c
sound/pci/hda/hda_codec.c
+18
-26
sound/pci/hda/hda_codec.h
sound/pci/hda/hda_codec.h
+8
-1
sound/pci/hda/hda_intel.c
sound/pci/hda/hda_intel.c
+34
-6
sound/pci/hda/patch_sigmatel.c
sound/pci/hda/patch_sigmatel.c
+9
-0
No files found.
sound/pci/hda/hda_codec.c
View file @
3c4dbda0
...
@@ -165,28 +165,29 @@ static int codec_exec_verb(struct hda_codec *codec, unsigned int cmd,
...
@@ -165,28 +165,29 @@ static int codec_exec_verb(struct hda_codec *codec, unsigned int cmd,
unsigned
int
*
res
)
unsigned
int
*
res
)
{
{
struct
hda_bus
*
bus
=
codec
->
bus
;
struct
hda_bus
*
bus
=
codec
->
bus
;
int
err
,
repeated
=
0
;
int
err
;
if
(
res
)
if
(
res
)
*
res
=
-
1
;
*
res
=
-
1
;
again:
snd_hda_power_up
(
codec
);
snd_hda_power_up
(
codec
);
mutex_lock
(
&
bus
->
cmd_mutex
);
mutex_lock
(
&
bus
->
cmd_mutex
);
again:
err
=
bus
->
ops
.
command
(
bus
,
cmd
);
err
=
bus
->
ops
.
command
(
bus
,
cmd
);
if
(
!
err
)
{
if
(
!
err
&&
res
)
if
(
res
)
{
*
res
=
bus
->
ops
.
get_response
(
bus
);
*
res
=
bus
->
ops
.
get_response
(
bus
);
if
(
*
res
==
-
1
&&
bus
->
rirb_error
)
{
if
(
repeated
++
<
1
)
{
snd_printd
(
KERN_WARNING
"hda_codec: "
"Trying verb 0x%08x again
\n
"
,
cmd
);
goto
again
;
}
}
}
}
mutex_unlock
(
&
bus
->
cmd_mutex
);
mutex_unlock
(
&
bus
->
cmd_mutex
);
snd_hda_power_down
(
codec
);
snd_hda_power_down
(
codec
);
if
(
res
&&
*
res
==
-
1
&&
bus
->
rirb_error
)
{
if
(
bus
->
response_reset
)
{
snd_printd
(
"hda_codec: resetting BUS due to "
"fatal communication error
\n
"
);
bus
->
ops
.
bus_reset
(
bus
);
}
goto
again
;
}
/* clear reset-flag when the communication gets recovered */
if
(
!
err
)
bus
->
response_reset
=
0
;
return
err
;
return
err
;
}
}
...
@@ -213,11 +214,6 @@ unsigned int snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid,
...
@@ -213,11 +214,6 @@ unsigned int snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid,
}
}
EXPORT_SYMBOL_HDA
(
snd_hda_codec_read
);
EXPORT_SYMBOL_HDA
(
snd_hda_codec_read
);
/* Define the below to send and receive verbs synchronously.
* If you often get any codec communication errors, this is worth to try.
*/
/* #define SND_HDA_SUPPORT_SYNC_WRITE */
/**
/**
* snd_hda_codec_write - send a single command without waiting for response
* snd_hda_codec_write - send a single command without waiting for response
* @codec: the HDA codec
* @codec: the HDA codec
...
@@ -234,12 +230,9 @@ int snd_hda_codec_write(struct hda_codec *codec, hda_nid_t nid, int direct,
...
@@ -234,12 +230,9 @@ int snd_hda_codec_write(struct hda_codec *codec, hda_nid_t nid, int direct,
unsigned
int
verb
,
unsigned
int
parm
)
unsigned
int
verb
,
unsigned
int
parm
)
{
{
unsigned
int
cmd
=
make_codec_cmd
(
codec
,
nid
,
direct
,
verb
,
parm
);
unsigned
int
cmd
=
make_codec_cmd
(
codec
,
nid
,
direct
,
verb
,
parm
);
#ifdef SND_HDA_SUPPORT_SYNC_WRITE
unsigned
int
res
;
unsigned
int
res
;
return
codec_exec_verb
(
codec
,
cmd
,
&
res
);
return
codec_exec_verb
(
codec
,
cmd
,
#else
codec
->
bus
->
sync_write
?
&
res
:
NULL
);
return
codec_exec_verb
(
codec
,
cmd
,
NULL
);
#endif
}
}
EXPORT_SYMBOL_HDA
(
snd_hda_codec_write
);
EXPORT_SYMBOL_HDA
(
snd_hda_codec_write
);
...
@@ -3894,11 +3887,10 @@ EXPORT_SYMBOL_HDA(auto_pin_cfg_labels);
...
@@ -3894,11 +3887,10 @@ EXPORT_SYMBOL_HDA(auto_pin_cfg_labels);
/**
/**
* snd_hda_suspend - suspend the codecs
* snd_hda_suspend - suspend the codecs
* @bus: the HDA bus
* @bus: the HDA bus
* @state: suspsend state
*
*
* Returns 0 if successful.
* Returns 0 if successful.
*/
*/
int
snd_hda_suspend
(
struct
hda_bus
*
bus
,
pm_message_t
state
)
int
snd_hda_suspend
(
struct
hda_bus
*
bus
)
{
{
struct
hda_codec
*
codec
;
struct
hda_codec
*
codec
;
...
...
sound/pci/hda/hda_codec.h
View file @
3c4dbda0
...
@@ -574,6 +574,8 @@ struct hda_bus_ops {
...
@@ -574,6 +574,8 @@ struct hda_bus_ops {
/* attach a PCM stream */
/* attach a PCM stream */
int
(
*
attach_pcm
)(
struct
hda_bus
*
bus
,
struct
hda_codec
*
codec
,
int
(
*
attach_pcm
)(
struct
hda_bus
*
bus
,
struct
hda_codec
*
codec
,
struct
hda_pcm
*
pcm
);
struct
hda_pcm
*
pcm
);
/* reset bus for retry verb */
void
(
*
bus_reset
)(
struct
hda_bus
*
bus
);
#ifdef CONFIG_SND_HDA_POWER_SAVE
#ifdef CONFIG_SND_HDA_POWER_SAVE
/* notify power-up/down from codec to controller */
/* notify power-up/down from codec to controller */
void
(
*
pm_notify
)(
struct
hda_bus
*
bus
);
void
(
*
pm_notify
)(
struct
hda_bus
*
bus
);
...
@@ -622,8 +624,13 @@ struct hda_bus {
...
@@ -622,8 +624,13 @@ struct hda_bus {
/* misc op flags */
/* misc op flags */
unsigned
int
needs_damn_long_delay
:
1
;
unsigned
int
needs_damn_long_delay
:
1
;
unsigned
int
allow_bus_reset
:
1
;
/* allow bus reset at fatal error */
unsigned
int
sync_write
:
1
;
/* sync after verb write */
/* status for codec/controller */
unsigned
int
shutdown
:
1
;
/* being unloaded */
unsigned
int
shutdown
:
1
;
/* being unloaded */
unsigned
int
rirb_error
:
1
;
/* error in codec communication */
unsigned
int
rirb_error
:
1
;
/* error in codec communication */
unsigned
int
response_reset
:
1
;
/* controller was reset */
unsigned
int
in_reset
:
1
;
/* during reset operation */
};
};
/*
/*
...
@@ -907,7 +914,7 @@ void snd_hda_get_codec_name(struct hda_codec *codec, char *name, int namelen);
...
@@ -907,7 +914,7 @@ void snd_hda_get_codec_name(struct hda_codec *codec, char *name, int namelen);
* power management
* power management
*/
*/
#ifdef CONFIG_PM
#ifdef CONFIG_PM
int
snd_hda_suspend
(
struct
hda_bus
*
bus
,
pm_message_t
state
);
int
snd_hda_suspend
(
struct
hda_bus
*
bus
);
int
snd_hda_resume
(
struct
hda_bus
*
bus
);
int
snd_hda_resume
(
struct
hda_bus
*
bus
);
#endif
#endif
...
...
sound/pci/hda/hda_intel.c
View file @
3c4dbda0
...
@@ -661,14 +661,23 @@ static unsigned int azx_rirb_get_response(struct hda_bus *bus)
...
@@ -661,14 +661,23 @@ static unsigned int azx_rirb_get_response(struct hda_bus *bus)
return
-
1
;
return
-
1
;
}
}
snd_printk
(
KERN_ERR
SFX
"azx_get_response timeout (ERROR): "
/* a fatal communication error; need either to reset or to fallback
"last cmd=0x%08x
\n
"
,
chip
->
last_cmd
);
* to the single_cmd mode
/* re-initialize CORB/RIRB */
*/
spin_lock_irq
(
&
chip
->
reg_lock
);
bus
->
rirb_error
=
1
;
bus
->
rirb_error
=
1
;
if
(
bus
->
allow_bus_reset
&&
!
bus
->
response_reset
&&
!
bus
->
in_reset
)
{
bus
->
response_reset
=
1
;
return
-
1
;
/* give a chance to retry */
}
snd_printk
(
KERN_ERR
"hda_intel: azx_get_response timeout, "
"switching to single_cmd mode: last cmd=0x%08x
\n
"
,
chip
->
last_cmd
);
chip
->
single_cmd
=
1
;
bus
->
response_reset
=
0
;
/* re-initialize CORB/RIRB */
azx_free_cmd_io
(
chip
);
azx_free_cmd_io
(
chip
);
azx_init_cmd_io
(
chip
);
azx_init_cmd_io
(
chip
);
spin_unlock_irq
(
&
chip
->
reg_lock
);
return
-
1
;
return
-
1
;
}
}
...
@@ -709,6 +718,7 @@ static int azx_single_send_cmd(struct hda_bus *bus, u32 val)
...
@@ -709,6 +718,7 @@ static int azx_single_send_cmd(struct hda_bus *bus, u32 val)
struct
azx
*
chip
=
bus
->
private_data
;
struct
azx
*
chip
=
bus
->
private_data
;
int
timeout
=
50
;
int
timeout
=
50
;
bus
->
rirb_error
=
0
;
while
(
timeout
--
)
{
while
(
timeout
--
)
{
/* check ICB busy bit */
/* check ICB busy bit */
if
(
!
((
azx_readw
(
chip
,
IRS
)
&
ICH6_IRS_BUSY
)))
{
if
(
!
((
azx_readw
(
chip
,
IRS
)
&
ICH6_IRS_BUSY
)))
{
...
@@ -1247,6 +1257,23 @@ static int azx_attach_pcm_stream(struct hda_bus *bus, struct hda_codec *codec,
...
@@ -1247,6 +1257,23 @@ static int azx_attach_pcm_stream(struct hda_bus *bus, struct hda_codec *codec,
struct
hda_pcm
*
cpcm
);
struct
hda_pcm
*
cpcm
);
static
void
azx_stop_chip
(
struct
azx
*
chip
);
static
void
azx_stop_chip
(
struct
azx
*
chip
);
static
void
azx_bus_reset
(
struct
hda_bus
*
bus
)
{
struct
azx
*
chip
=
bus
->
private_data
;
int
i
;
bus
->
in_reset
=
1
;
azx_stop_chip
(
chip
);
azx_init_chip
(
chip
);
if
(
chip
->
initialized
)
{
for
(
i
=
0
;
i
<
AZX_MAX_PCMS
;
i
++
)
snd_pcm_suspend_all
(
chip
->
pcm
[
i
]);
snd_hda_suspend
(
chip
->
bus
);
snd_hda_resume
(
chip
->
bus
);
}
bus
->
in_reset
=
0
;
}
/*
/*
* Codec initialization
* Codec initialization
*/
*/
...
@@ -1270,6 +1297,7 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model,
...
@@ -1270,6 +1297,7 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model,
bus_temp
.
ops
.
command
=
azx_send_cmd
;
bus_temp
.
ops
.
command
=
azx_send_cmd
;
bus_temp
.
ops
.
get_response
=
azx_get_response
;
bus_temp
.
ops
.
get_response
=
azx_get_response
;
bus_temp
.
ops
.
attach_pcm
=
azx_attach_pcm_stream
;
bus_temp
.
ops
.
attach_pcm
=
azx_attach_pcm_stream
;
bus_temp
.
ops
.
bus_reset
=
azx_bus_reset
;
#ifdef CONFIG_SND_HDA_POWER_SAVE
#ifdef CONFIG_SND_HDA_POWER_SAVE
bus_temp
.
power_save
=
&
power_save
;
bus_temp
.
power_save
=
&
power_save
;
bus_temp
.
ops
.
pm_notify
=
azx_power_notify
;
bus_temp
.
ops
.
pm_notify
=
azx_power_notify
;
...
@@ -1997,7 +2025,7 @@ static int azx_suspend(struct pci_dev *pci, pm_message_t state)
...
@@ -1997,7 +2025,7 @@ static int azx_suspend(struct pci_dev *pci, pm_message_t state)
for
(
i
=
0
;
i
<
AZX_MAX_PCMS
;
i
++
)
for
(
i
=
0
;
i
<
AZX_MAX_PCMS
;
i
++
)
snd_pcm_suspend_all
(
chip
->
pcm
[
i
]);
snd_pcm_suspend_all
(
chip
->
pcm
[
i
]);
if
(
chip
->
initialized
)
if
(
chip
->
initialized
)
snd_hda_suspend
(
chip
->
bus
,
state
);
snd_hda_suspend
(
chip
->
bus
);
azx_stop_chip
(
chip
);
azx_stop_chip
(
chip
);
if
(
chip
->
irq
>=
0
)
{
if
(
chip
->
irq
>=
0
)
{
free_irq
(
chip
->
irq
,
chip
);
free_irq
(
chip
->
irq
,
chip
);
...
...
sound/pci/hda/patch_sigmatel.c
View file @
3c4dbda0
...
@@ -5375,6 +5375,15 @@ static int patch_stac92hd71bxx(struct hda_codec *codec)
...
@@ -5375,6 +5375,15 @@ static int patch_stac92hd71bxx(struct hda_codec *codec)
if
(
get_wcaps
(
codec
,
0xa
)
&
AC_WCAP_IN_AMP
)
if
(
get_wcaps
(
codec
,
0xa
)
&
AC_WCAP_IN_AMP
)
snd_hda_sequence_write_cache
(
codec
,
unmute_init
);
snd_hda_sequence_write_cache
(
codec
,
unmute_init
);
/* Some HP machines seem to have unstable codec communications
* especially with ATI fglrx driver. For recovering from the
* CORB/RIRB stall, allow the BUS reset and keep always sync
*/
if
(
spec
->
board_config
==
STAC_HP_DV5
)
{
codec
->
bus
->
sync_write
=
1
;
codec
->
bus
->
allow_bus_reset
=
1
;
}
spec
->
aloopback_ctl
=
stac92hd71bxx_loopback
;
spec
->
aloopback_ctl
=
stac92hd71bxx_loopback
;
spec
->
aloopback_mask
=
0x50
;
spec
->
aloopback_mask
=
0x50
;
spec
->
aloopback_shift
=
0
;
spec
->
aloopback_shift
=
0
;
...
...
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