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
84526820
Commit
84526820
authored
Jul 01, 2014
by
Takashi Iwai
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'topic/hda-cleanup' into for-next
parents
e8750940
fb1d8ac2
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
422 additions
and
394 deletions
+422
-394
sound/pci/hda/hda_auto_parser.c
sound/pci/hda/hda_auto_parser.c
+0
-2
sound/pci/hda/hda_controller.c
sound/pci/hda/hda_controller.c
+70
-130
sound/pci/hda/hda_controller.h
sound/pci/hda/hda_controller.h
+6
-3
sound/pci/hda/hda_intel.c
sound/pci/hda/hda_intel.c
+251
-70
sound/pci/hda/hda_priv.h
sound/pci/hda/hda_priv.h
+93
-160
sound/pci/hda/hda_tegra.c
sound/pci/hda/hda_tegra.c
+2
-29
No files found.
sound/pci/hda/hda_auto_parser.c
View file @
84526820
...
...
@@ -17,8 +17,6 @@
#include "hda_local.h"
#include "hda_auto_parser.h"
#define SFX "hda_codec: "
/*
* Helper for automatic pin configuration
*/
...
...
sound/pci/hda/hda_controller.c
View file @
84526820
...
...
@@ -27,6 +27,7 @@
#include <linux/module.h>
#include <linux/pm_runtime.h>
#include <linux/slab.h>
#include <linux/reboot.h>
#include <sound/core.h>
#include <sound/initval.h>
#include "hda_priv.h"
...
...
@@ -152,11 +153,11 @@ static int azx_setup_controller(struct azx *chip, struct azx_dev *azx_dev)
upper_32_bits
(
azx_dev
->
bdl
.
addr
));
/* enable the position buffer */
if
(
chip
->
position_fix
[
0
]
!=
POS_FIX_LPIB
||
chip
->
position_fix
[
1
]
!=
POS_FIX_LPIB
)
{
if
(
!
(
azx_readl
(
chip
,
DPLBASE
)
&
ICH6
_DPLBASE_ENABLE
))
if
(
chip
->
get_position
[
0
]
!=
azx_get_pos_lpib
||
chip
->
get_position
[
1
]
!=
azx_get_pos_lpib
)
{
if
(
!
(
azx_readl
(
chip
,
DPLBASE
)
&
AZX
_DPLBASE_ENABLE
))
azx_writel
(
chip
,
DPLBASE
,
(
u32
)
chip
->
posbuf
.
addr
|
ICH6
_DPLBASE_ENABLE
);
(
u32
)
chip
->
posbuf
.
addr
|
AZX
_DPLBASE_ENABLE
);
}
/* set the interrupt enable bits in the descriptor control register */
...
...
@@ -673,125 +674,40 @@ static int azx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
return
0
;
}
/* get the current DMA position with correction on VIA chips */
static
unsigned
int
azx_via_get_position
(
struct
azx
*
chip
,
struct
azx_dev
*
azx_dev
)
unsigned
int
azx_get_pos_lpib
(
struct
azx
*
chip
,
struct
azx_dev
*
azx_dev
)
{
unsigned
int
link_pos
,
mini_pos
,
bound_pos
;
unsigned
int
mod_link_pos
,
mod_dma_pos
,
mod_mini_pos
;
unsigned
int
fifo_size
;
link_pos
=
azx_sd_readl
(
chip
,
azx_dev
,
SD_LPIB
);
if
(
azx_dev
->
substream
->
stream
==
SNDRV_PCM_STREAM_PLAYBACK
)
{
/* Playback, no problem using link position */
return
link_pos
;
}
/* Capture */
/* For new chipset,
* use mod to get the DMA position just like old chipset
*/
mod_dma_pos
=
le32_to_cpu
(
*
azx_dev
->
posbuf
);
mod_dma_pos
%=
azx_dev
->
period_bytes
;
/* azx_dev->fifo_size can't get FIFO size of in stream.
* Get from base address + offset.
*/
fifo_size
=
readw
(
chip
->
remap_addr
+
VIA_IN_STREAM0_FIFO_SIZE_OFFSET
);
if
(
azx_dev
->
insufficient
)
{
/* Link position never gather than FIFO size */
if
(
link_pos
<=
fifo_size
)
return
0
;
azx_dev
->
insufficient
=
0
;
}
if
(
link_pos
<=
fifo_size
)
mini_pos
=
azx_dev
->
bufsize
+
link_pos
-
fifo_size
;
else
mini_pos
=
link_pos
-
fifo_size
;
/* Find nearest previous boudary */
mod_mini_pos
=
mini_pos
%
azx_dev
->
period_bytes
;
mod_link_pos
=
link_pos
%
azx_dev
->
period_bytes
;
if
(
mod_link_pos
>=
fifo_size
)
bound_pos
=
link_pos
-
mod_link_pos
;
else
if
(
mod_dma_pos
>=
mod_mini_pos
)
bound_pos
=
mini_pos
-
mod_mini_pos
;
else
{
bound_pos
=
mini_pos
-
mod_mini_pos
+
azx_dev
->
period_bytes
;
if
(
bound_pos
>=
azx_dev
->
bufsize
)
bound_pos
=
0
;
}
return
azx_sd_readl
(
chip
,
azx_dev
,
SD_LPIB
);
}
EXPORT_SYMBOL_GPL
(
azx_get_pos_lpib
);
/* Calculate real DMA position we want */
return
bound_pos
+
mod_dma_pos
;
unsigned
int
azx_get_pos_posbuf
(
struct
azx
*
chip
,
struct
azx_dev
*
azx_dev
)
{
return
le32_to_cpu
(
*
azx_dev
->
posbuf
);
}
EXPORT_SYMBOL_GPL
(
azx_get_pos_posbuf
);
unsigned
int
azx_get_position
(
struct
azx
*
chip
,
struct
azx_dev
*
azx_dev
,
bool
with_check
)
struct
azx_dev
*
azx_dev
)
{
struct
snd_pcm_substream
*
substream
=
azx_dev
->
substream
;
struct
azx_pcm
*
apcm
=
snd_pcm_substream_chip
(
substream
);
unsigned
int
pos
;
int
stream
=
substream
->
stream
;
struct
hda_pcm_stream
*
hinfo
=
apcm
->
hinfo
[
stream
];
int
delay
=
0
;
switch
(
chip
->
position_fix
[
stream
])
{
case
POS_FIX_LPIB
:
/* read LPIB */
pos
=
azx_sd_readl
(
chip
,
azx_dev
,
SD_LPIB
);
break
;
case
POS_FIX_VIACOMBO
:
pos
=
azx_via_get_position
(
chip
,
azx_dev
);
break
;
default:
/* use the position buffer */
pos
=
le32_to_cpu
(
*
azx_dev
->
posbuf
);
if
(
with_check
&&
chip
->
position_fix
[
stream
]
==
POS_FIX_AUTO
)
{
if
(
!
pos
||
pos
==
(
u32
)
-
1
)
{
dev_info
(
chip
->
card
->
dev
,
"Invalid position buffer, using LPIB read method instead.
\n
"
);
chip
->
position_fix
[
stream
]
=
POS_FIX_LPIB
;
pos
=
azx_sd_readl
(
chip
,
azx_dev
,
SD_LPIB
);
}
else
chip
->
position_fix
[
stream
]
=
POS_FIX_POSBUF
;
}
break
;
}
if
(
chip
->
get_position
[
stream
])
pos
=
chip
->
get_position
[
stream
](
chip
,
azx_dev
);
else
/* use the position buffer as default */
pos
=
azx_get_pos_posbuf
(
chip
,
azx_dev
);
if
(
pos
>=
azx_dev
->
bufsize
)
pos
=
0
;
/* calculate runtime delay from LPIB */
if
(
substream
->
runtime
&&
chip
->
position_fix
[
stream
]
==
POS_FIX_POSBUF
&&
(
chip
->
driver_caps
&
AZX_DCAPS_COUNT_LPIB_DELAY
))
{
unsigned
int
lpib_pos
=
azx_sd_readl
(
chip
,
azx_dev
,
SD_LPIB
);
if
(
stream
==
SNDRV_PCM_STREAM_PLAYBACK
)
delay
=
pos
-
lpib_pos
;
else
delay
=
lpib_pos
-
pos
;
if
(
delay
<
0
)
{
if
(
delay
>=
azx_dev
->
delay_negative_threshold
)
delay
=
0
;
else
delay
+=
azx_dev
->
bufsize
;
}
if
(
delay
>=
azx_dev
->
period_bytes
)
{
dev_info
(
chip
->
card
->
dev
,
"Unstable LPIB (%d >= %d); disabling LPIB delay counting
\n
"
,
delay
,
azx_dev
->
period_bytes
);
delay
=
0
;
chip
->
driver_caps
&=
~
AZX_DCAPS_COUNT_LPIB_DELAY
;
}
delay
=
bytes_to_frames
(
substream
->
runtime
,
delay
);
}
if
(
substream
->
runtime
)
{
struct
azx_pcm
*
apcm
=
snd_pcm_substream_chip
(
substream
);
struct
hda_pcm_stream
*
hinfo
=
apcm
->
hinfo
[
stream
];
if
(
chip
->
get_delay
[
stream
])
delay
+=
chip
->
get_delay
[
stream
](
chip
,
azx_dev
,
pos
);
if
(
hinfo
->
ops
.
get_delay
)
delay
+=
hinfo
->
ops
.
get_delay
(
hinfo
,
apcm
->
codec
,
substream
);
...
...
@@ -809,7 +725,7 @@ static snd_pcm_uframes_t azx_pcm_pointer(struct snd_pcm_substream *substream)
struct
azx
*
chip
=
apcm
->
chip
;
struct
azx_dev
*
azx_dev
=
get_azx_dev
(
substream
);
return
bytes_to_frames
(
substream
->
runtime
,
azx_get_position
(
chip
,
azx_dev
,
false
));
azx_get_position
(
chip
,
azx_dev
));
}
static
int
azx_get_wallclock_tstamp
(
struct
snd_pcm_substream
*
substream
,
...
...
@@ -1059,10 +975,10 @@ static void azx_init_cmd_io(struct azx *chip)
azx_writew
(
chip
,
CORBWP
,
0
);
/* reset the corb hw read pointer */
azx_writew
(
chip
,
CORBRP
,
ICH6
_CORBRP_RST
);
azx_writew
(
chip
,
CORBRP
,
AZX
_CORBRP_RST
);
if
(
!
(
chip
->
driver_caps
&
AZX_DCAPS_CORBRP_SELF_CLEAR
))
{
for
(
timeout
=
1000
;
timeout
>
0
;
timeout
--
)
{
if
((
azx_readw
(
chip
,
CORBRP
)
&
ICH6_CORBRP_RST
)
==
ICH6
_CORBRP_RST
)
if
((
azx_readw
(
chip
,
CORBRP
)
&
AZX_CORBRP_RST
)
==
AZX
_CORBRP_RST
)
break
;
udelay
(
1
);
}
...
...
@@ -1082,7 +998,7 @@ static void azx_init_cmd_io(struct azx *chip)
}
/* enable corb dma */
azx_writeb
(
chip
,
CORBCTL
,
ICH6
_CORBCTL_RUN
);
azx_writeb
(
chip
,
CORBCTL
,
AZX
_CORBCTL_RUN
);
/* RIRB set up */
chip
->
rirb
.
addr
=
chip
->
rb
.
addr
+
2048
;
...
...
@@ -1095,14 +1011,14 @@ static void azx_init_cmd_io(struct azx *chip)
/* set the rirb size to 256 entries (ULI requires explicitly) */
azx_writeb
(
chip
,
RIRBSIZE
,
0x02
);
/* reset the rirb hw write pointer */
azx_writew
(
chip
,
RIRBWP
,
ICH6
_RIRBWP_RST
);
azx_writew
(
chip
,
RIRBWP
,
AZX
_RIRBWP_RST
);
/* set N=1, get RIRB response interrupt for new entry */
if
(
chip
->
driver_caps
&
AZX_DCAPS_CTX_WORKAROUND
)
azx_writew
(
chip
,
RINTCNT
,
0xc0
);
else
azx_writew
(
chip
,
RINTCNT
,
1
);
/* enable rirb dma and response irq */
azx_writeb
(
chip
,
RIRBCTL
,
ICH6_RBCTL_DMA_EN
|
ICH6
_RBCTL_IRQ_EN
);
azx_writeb
(
chip
,
RIRBCTL
,
AZX_RBCTL_DMA_EN
|
AZX
_RBCTL_IRQ_EN
);
spin_unlock_irq
(
&
chip
->
reg_lock
);
}
EXPORT_SYMBOL_GPL
(
azx_init_cmd_io
);
...
...
@@ -1146,7 +1062,7 @@ static int azx_corb_send_cmd(struct hda_bus *bus, u32 val)
return
-
EIO
;
}
wp
++
;
wp
%=
ICH6
_MAX_CORB_ENTRIES
;
wp
%=
AZX
_MAX_CORB_ENTRIES
;
rp
=
azx_readw
(
chip
,
CORBRP
);
if
(
wp
==
rp
)
{
...
...
@@ -1164,7 +1080,7 @@ static int azx_corb_send_cmd(struct hda_bus *bus, u32 val)
return
0
;
}
#define
ICH6
_RIRB_EX_UNSOL_EV (1<<4)
#define
AZX
_RIRB_EX_UNSOL_EV (1<<4)
/* retrieve RIRB entry - called from interrupt handler */
static
void
azx_update_rirb
(
struct
azx
*
chip
)
...
...
@@ -1185,7 +1101,7 @@ static void azx_update_rirb(struct azx *chip)
while
(
chip
->
rirb
.
rp
!=
wp
)
{
chip
->
rirb
.
rp
++
;
chip
->
rirb
.
rp
%=
ICH6
_MAX_RIRB_ENTRIES
;
chip
->
rirb
.
rp
%=
AZX
_MAX_RIRB_ENTRIES
;
rp
=
chip
->
rirb
.
rp
<<
1
;
/* an RIRB entry is 8-bytes */
res_ex
=
le32_to_cpu
(
chip
->
rirb
.
buf
[
rp
+
1
]);
...
...
@@ -1196,8 +1112,7 @@ static void azx_update_rirb(struct azx *chip)
res
,
res_ex
,
chip
->
rirb
.
rp
,
wp
);
snd_BUG
();
}
else
if
(
res_ex
&
ICH6_RIRB_EX_UNSOL_EV
)
}
else
if
(
res_ex
&
AZX_RIRB_EX_UNSOL_EV
)
snd_hda_queue_unsol_event
(
chip
->
bus
,
res
,
res_ex
);
else
if
(
chip
->
rirb
.
cmds
[
addr
])
{
chip
->
rirb
.
res
[
addr
]
=
res
;
...
...
@@ -1305,7 +1220,7 @@ static unsigned int azx_rirb_get_response(struct hda_bus *bus,
/* release CORB/RIRB */
azx_free_cmd_io
(
chip
);
/* disable unsolicited responses */
azx_writel
(
chip
,
GCTL
,
azx_readl
(
chip
,
GCTL
)
&
~
ICH6
_GCTL_UNSOL
);
azx_writel
(
chip
,
GCTL
,
azx_readl
(
chip
,
GCTL
)
&
~
AZX
_GCTL_UNSOL
);
return
-
1
;
}
...
...
@@ -1326,7 +1241,7 @@ static int azx_single_wait_for_response(struct azx *chip, unsigned int addr)
while
(
timeout
--
)
{
/* check IRV busy bit */
if
(
azx_readw
(
chip
,
IRS
)
&
ICH6
_IRS_VALID
)
{
if
(
azx_readw
(
chip
,
IRS
)
&
AZX
_IRS_VALID
)
{
/* reuse rirb.res as the response return value */
chip
->
rirb
.
res
[
addr
]
=
azx_readl
(
chip
,
IR
);
return
0
;
...
...
@@ -1350,13 +1265,13 @@ static int azx_single_send_cmd(struct hda_bus *bus, u32 val)
bus
->
rirb_error
=
0
;
while
(
timeout
--
)
{
/* check ICB busy bit */
if
(
!
((
azx_readw
(
chip
,
IRS
)
&
ICH6
_IRS_BUSY
)))
{
if
(
!
((
azx_readw
(
chip
,
IRS
)
&
AZX
_IRS_BUSY
)))
{
/* Clear IRV valid bit */
azx_writew
(
chip
,
IRS
,
azx_readw
(
chip
,
IRS
)
|
ICH6
_IRS_VALID
);
AZX
_IRS_VALID
);
azx_writel
(
chip
,
IC
,
val
);
azx_writew
(
chip
,
IRS
,
azx_readw
(
chip
,
IRS
)
|
ICH6
_IRS_BUSY
);
AZX
_IRS_BUSY
);
return
azx_single_wait_for_response
(
chip
,
addr
);
}
udelay
(
1
);
...
...
@@ -1585,10 +1500,10 @@ void azx_enter_link_reset(struct azx *chip)
unsigned
long
timeout
;
/* reset controller */
azx_writel
(
chip
,
GCTL
,
azx_readl
(
chip
,
GCTL
)
&
~
ICH6
_GCTL_RESET
);
azx_writel
(
chip
,
GCTL
,
azx_readl
(
chip
,
GCTL
)
&
~
AZX
_GCTL_RESET
);
timeout
=
jiffies
+
msecs_to_jiffies
(
100
);
while
((
azx_readb
(
chip
,
GCTL
)
&
ICH6
_GCTL_RESET
)
&&
while
((
azx_readb
(
chip
,
GCTL
)
&
AZX
_GCTL_RESET
)
&&
time_before
(
jiffies
,
timeout
))
usleep_range
(
500
,
1000
);
}
...
...
@@ -1599,7 +1514,7 @@ static void azx_exit_link_reset(struct azx *chip)
{
unsigned
long
timeout
;
azx_writeb
(
chip
,
GCTL
,
azx_readb
(
chip
,
GCTL
)
|
ICH6
_GCTL_RESET
);
azx_writeb
(
chip
,
GCTL
,
azx_readb
(
chip
,
GCTL
)
|
AZX
_GCTL_RESET
);
timeout
=
jiffies
+
msecs_to_jiffies
(
100
);
while
(
!
azx_readb
(
chip
,
GCTL
)
&&
...
...
@@ -1640,7 +1555,7 @@ static int azx_reset(struct azx *chip, bool full_reset)
/* Accept unsolicited responses */
if
(
!
chip
->
single_cmd
)
azx_writel
(
chip
,
GCTL
,
azx_readl
(
chip
,
GCTL
)
|
ICH6
_GCTL_UNSOL
);
AZX
_GCTL_UNSOL
);
/* detect codecs */
if
(
!
chip
->
codec_mask
)
{
...
...
@@ -1657,7 +1572,7 @@ static void azx_int_enable(struct azx *chip)
{
/* enable controller CIE and GIE */
azx_writel
(
chip
,
INTCTL
,
azx_readl
(
chip
,
INTCTL
)
|
ICH6_INT_CTRL_EN
|
ICH6
_INT_GLOBAL_EN
);
AZX_INT_CTRL_EN
|
AZX
_INT_GLOBAL_EN
);
}
/* disable interrupts */
...
...
@@ -1678,7 +1593,7 @@ static void azx_int_disable(struct azx *chip)
/* disable controller CIE and GIE */
azx_writel
(
chip
,
INTCTL
,
azx_readl
(
chip
,
INTCTL
)
&
~
(
ICH6_INT_CTRL_EN
|
ICH6
_INT_GLOBAL_EN
));
~
(
AZX_INT_CTRL_EN
|
AZX
_INT_GLOBAL_EN
));
}
/* clear interrupts */
...
...
@@ -1699,7 +1614,7 @@ static void azx_int_clear(struct azx *chip)
azx_writeb
(
chip
,
RIRBSTS
,
RIRB_INT_MASK
);
/* clear int status */
azx_writel
(
chip
,
INTSTS
,
ICH6_INT_CTRL_EN
|
ICH6
_INT_ALL_STREAM
);
azx_writel
(
chip
,
INTSTS
,
AZX_INT_CTRL_EN
|
AZX
_INT_ALL_STREAM
);
}
/*
...
...
@@ -2031,5 +1946,30 @@ int azx_init_stream(struct azx *chip)
}
EXPORT_SYMBOL_GPL
(
azx_init_stream
);
/*
* reboot notifier for hang-up problem at power-down
*/
static
int
azx_halt
(
struct
notifier_block
*
nb
,
unsigned
long
event
,
void
*
buf
)
{
struct
azx
*
chip
=
container_of
(
nb
,
struct
azx
,
reboot_notifier
);
snd_hda_bus_reboot_notify
(
chip
->
bus
);
azx_stop_chip
(
chip
);
return
NOTIFY_OK
;
}
void
azx_notifier_register
(
struct
azx
*
chip
)
{
chip
->
reboot_notifier
.
notifier_call
=
azx_halt
;
register_reboot_notifier
(
&
chip
->
reboot_notifier
);
}
EXPORT_SYMBOL_GPL
(
azx_notifier_register
);
void
azx_notifier_unregister
(
struct
azx
*
chip
)
{
if
(
chip
->
reboot_notifier
.
notifier_call
)
unregister_reboot_notifier
(
&
chip
->
reboot_notifier
);
}
EXPORT_SYMBOL_GPL
(
azx_notifier_unregister
);
MODULE_LICENSE
(
"GPL"
);
MODULE_DESCRIPTION
(
"Common HDA driver funcitons"
);
sound/pci/hda/hda_controller.h
View file @
84526820
...
...
@@ -25,9 +25,9 @@ static inline struct azx_dev *get_azx_dev(struct snd_pcm_substream *substream)
{
return
substream
->
runtime
->
private_data
;
}
unsigned
int
azx_get_position
(
struct
azx
*
chip
,
struct
azx_dev
*
azx_dev
,
bool
with_check
);
unsigned
int
azx_get_position
(
struct
azx
*
chip
,
struct
azx_dev
*
azx_dev
);
unsigned
int
azx_get_pos_lpib
(
struct
azx
*
chip
,
struct
azx_dev
*
azx_dev
);
unsigned
int
azx_get_pos_posbuf
(
struct
azx
*
chip
,
struct
azx_dev
*
azx_dev
);
/* Stream control. */
void
azx_stream_stop
(
struct
azx
*
chip
,
struct
azx_dev
*
azx_dev
);
...
...
@@ -50,4 +50,7 @@ int azx_codec_configure(struct azx *chip);
int
azx_mixer_create
(
struct
azx
*
chip
);
int
azx_init_stream
(
struct
azx
*
chip
);
void
azx_notifier_register
(
struct
azx
*
chip
);
void
azx_notifier_unregister
(
struct
azx
*
chip
);
#endif
/* __SOUND_HDA_CONTROLLER_H */
sound/pci/hda/hda_intel.c
View file @
84526820
...
...
@@ -44,7 +44,6 @@
#include <linux/slab.h>
#include <linux/pci.h>
#include <linux/mutex.h>
#include <linux/reboot.h>
#include <linux/io.h>
#include <linux/pm_runtime.h>
#include <linux/clocksource.h>
...
...
@@ -66,6 +65,52 @@
#include "hda_controller.h"
#include "hda_priv.h"
/* position fix mode */
enum
{
POS_FIX_AUTO
,
POS_FIX_LPIB
,
POS_FIX_POSBUF
,
POS_FIX_VIACOMBO
,
POS_FIX_COMBO
,
};
/* Defines for ATI HD Audio support in SB450 south bridge */
#define ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR 0x42
#define ATI_SB450_HDAUDIO_ENABLE_SNOOP 0x02
/* Defines for Nvidia HDA support */
#define NVIDIA_HDA_TRANSREG_ADDR 0x4e
#define NVIDIA_HDA_ENABLE_COHBITS 0x0f
#define NVIDIA_HDA_ISTRM_COH 0x4d
#define NVIDIA_HDA_OSTRM_COH 0x4c
#define NVIDIA_HDA_ENABLE_COHBIT 0x01
/* Defines for Intel SCH HDA snoop control */
#define INTEL_SCH_HDA_DEVC 0x78
#define INTEL_SCH_HDA_DEVC_NOSNOOP (0x1<<11)
/* Define IN stream 0 FIFO size offset in VIA controller */
#define VIA_IN_STREAM0_FIFO_SIZE_OFFSET 0x90
/* Define VIA HD Audio Device ID*/
#define VIA_HDAC_DEVICE_ID 0x3288
/* max number of SDs */
/* ICH, ATI and VIA have 4 playback and 4 capture */
#define ICH6_NUM_CAPTURE 4
#define ICH6_NUM_PLAYBACK 4
/* ULI has 6 playback and 5 capture */
#define ULI_NUM_CAPTURE 5
#define ULI_NUM_PLAYBACK 6
/* ATI HDMI may have up to 8 playbacks and 0 capture */
#define ATIHDMI_NUM_CAPTURE 0
#define ATIHDMI_NUM_PLAYBACK 8
/* TERA has 4 playback and 3 capture */
#define TERA_NUM_CAPTURE 3
#define TERA_NUM_PLAYBACK 4
static
int
index
[
SNDRV_CARDS
]
=
SNDRV_DEFAULT_IDX
;
static
char
*
id
[
SNDRV_CARDS
]
=
SNDRV_DEFAULT_STR
;
...
...
@@ -294,8 +339,8 @@ static char *driver_short_names[] = {
* Clock) to 24MHz BCLK: BCLK = CDCLK * M / N
* The values will be lost when the display power well is disabled.
*/
#define
ICH6
_REG_EM4 0x100c
#define
ICH6
_REG_EM5 0x1010
#define
AZX
_REG_EM4 0x100c
#define
AZX
_REG_EM5 0x1010
struct
hda_intel
{
struct
azx
chip
;
...
...
@@ -303,8 +348,28 @@ struct hda_intel {
/* HSW/BDW display HDA controller to restore BCLK from CDCLK */
unsigned
int
bclk_m
;
unsigned
int
bclk_n
;
};
/* for pending irqs */
struct
work_struct
irq_pending_work
;
/* sync probing */
struct
completion
probe_wait
;
struct
work_struct
probe_work
;
/* card list (for power_save trigger) */
struct
list_head
list
;
/* extra flags */
unsigned
int
irq_pending_warned
:
1
;
/* VGA-switcheroo setup */
unsigned
int
use_vga_switcheroo
:
1
;
unsigned
int
vga_switcheroo_registered
:
1
;
unsigned
int
init_failed
:
1
;
/* delayed init failed */
/* secondary power domain for hdmi audio under vga device */
struct
dev_pm_domain
hdmi_pm_domain
;
};
#ifdef CONFIG_X86
static
void
__mark_pages_wc
(
struct
azx
*
chip
,
struct
snd_dma_buffer
*
dmab
,
bool
on
)
...
...
@@ -386,7 +451,7 @@ static void azx_init_pci(struct azx *chip)
*/
if
(
!
(
chip
->
driver_caps
&
AZX_DCAPS_NO_TCSEL
))
{
dev_dbg
(
chip
->
card
->
dev
,
"Clearing TCSEL
\n
"
);
update_pci_byte
(
chip
->
pci
,
ICH6
_PCIREG_TCSEL
,
0x07
,
0
);
update_pci_byte
(
chip
->
pci
,
AZX
_PCIREG_TCSEL
,
0x07
,
0
);
}
/* For ATI SB450/600/700/800/900 and AMD Hudson azalia HD audio,
...
...
@@ -434,11 +499,44 @@ static void azx_init_pci(struct azx *chip)
}
}
/* calculate runtime delay from LPIB */
static
int
azx_get_delay_from_lpib
(
struct
azx
*
chip
,
struct
azx_dev
*
azx_dev
,
unsigned
int
pos
)
{
struct
snd_pcm_substream
*
substream
=
azx_dev
->
substream
;
int
stream
=
substream
->
stream
;
unsigned
int
lpib_pos
=
azx_get_pos_lpib
(
chip
,
azx_dev
);
int
delay
;
if
(
stream
==
SNDRV_PCM_STREAM_PLAYBACK
)
delay
=
pos
-
lpib_pos
;
else
delay
=
lpib_pos
-
pos
;
if
(
delay
<
0
)
{
if
(
delay
>=
azx_dev
->
delay_negative_threshold
)
delay
=
0
;
else
delay
+=
azx_dev
->
bufsize
;
}
if
(
delay
>=
azx_dev
->
period_bytes
)
{
dev_info
(
chip
->
card
->
dev
,
"Unstable LPIB (%d >= %d); disabling LPIB delay counting
\n
"
,
delay
,
azx_dev
->
period_bytes
);
delay
=
0
;
chip
->
driver_caps
&=
~
AZX_DCAPS_COUNT_LPIB_DELAY
;
chip
->
get_delay
[
stream
]
=
NULL
;
}
return
bytes_to_frames
(
substream
->
runtime
,
delay
);
}
static
int
azx_position_ok
(
struct
azx
*
chip
,
struct
azx_dev
*
azx_dev
);
/* called from IRQ */
static
int
azx_position_check
(
struct
azx
*
chip
,
struct
azx_dev
*
azx_dev
)
{
struct
hda_intel
*
hda
=
container_of
(
chip
,
struct
hda_intel
,
chip
);
int
ok
;
ok
=
azx_position_ok
(
chip
,
azx_dev
);
...
...
@@ -448,7 +546,7 @@ static int azx_position_check(struct azx *chip, struct azx_dev *azx_dev)
}
else
if
(
ok
==
0
&&
chip
->
bus
&&
chip
->
bus
->
workq
)
{
/* bogus IRQ, process it later */
azx_dev
->
irq_pending
=
1
;
queue_work
(
chip
->
bus
->
workq
,
&
chip
->
irq_pending_work
);
queue_work
(
chip
->
bus
->
workq
,
&
hda
->
irq_pending_work
);
}
return
0
;
}
...
...
@@ -464,6 +562,8 @@ static int azx_position_check(struct azx *chip, struct azx_dev *azx_dev)
*/
static
int
azx_position_ok
(
struct
azx
*
chip
,
struct
azx_dev
*
azx_dev
)
{
struct
snd_pcm_substream
*
substream
=
azx_dev
->
substream
;
int
stream
=
substream
->
stream
;
u32
wallclk
;
unsigned
int
pos
;
...
...
@@ -471,7 +571,25 @@ static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev)
if
(
wallclk
<
(
azx_dev
->
period_wallclk
*
2
)
/
3
)
return
-
1
;
/* bogus (too early) interrupt */
pos
=
azx_get_position
(
chip
,
azx_dev
,
true
);
if
(
chip
->
get_position
[
stream
])
pos
=
chip
->
get_position
[
stream
](
chip
,
azx_dev
);
else
{
/* use the position buffer as default */
pos
=
azx_get_pos_posbuf
(
chip
,
azx_dev
);
if
(
!
pos
||
pos
==
(
u32
)
-
1
)
{
dev_info
(
chip
->
card
->
dev
,
"Invalid position buffer, using LPIB read method instead.
\n
"
);
chip
->
get_position
[
stream
]
=
azx_get_pos_lpib
;
pos
=
azx_get_pos_lpib
(
chip
,
azx_dev
);
chip
->
get_delay
[
stream
]
=
NULL
;
}
else
{
chip
->
get_position
[
stream
]
=
azx_get_pos_posbuf
;
if
(
chip
->
driver_caps
&
AZX_DCAPS_COUNT_LPIB_DELAY
)
chip
->
get_delay
[
stream
]
=
azx_get_delay_from_lpib
;
}
}
if
(
pos
>=
azx_dev
->
bufsize
)
pos
=
0
;
if
(
WARN_ONCE
(
!
azx_dev
->
period_bytes
,
"hda-intel: zero azx_dev->period_bytes"
))
...
...
@@ -489,14 +607,15 @@ static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev)
*/
static
void
azx_irq_pending_work
(
struct
work_struct
*
work
)
{
struct
azx
*
chip
=
container_of
(
work
,
struct
azx
,
irq_pending_work
);
struct
hda_intel
*
hda
=
container_of
(
work
,
struct
hda_intel
,
irq_pending_work
);
struct
azx
*
chip
=
&
hda
->
chip
;
int
i
,
pending
,
ok
;
if
(
!
chip
->
irq_pending_warned
)
{
if
(
!
hda
->
irq_pending_warned
)
{
dev_info
(
chip
->
card
->
dev
,
"IRQ timing workaround is activated for card #%d. Suggest a bigger bdl_pos_adj.
\n
"
,
chip
->
card
->
number
);
chip
->
irq_pending_warned
=
1
;
hda
->
irq_pending_warned
=
1
;
}
for
(;;)
{
...
...
@@ -554,27 +673,86 @@ static int azx_acquire_irq(struct azx *chip, int do_disconnect)
return
0
;
}
/* get the current DMA position with correction on VIA chips */
static
unsigned
int
azx_via_get_position
(
struct
azx
*
chip
,
struct
azx_dev
*
azx_dev
)
{
unsigned
int
link_pos
,
mini_pos
,
bound_pos
;
unsigned
int
mod_link_pos
,
mod_dma_pos
,
mod_mini_pos
;
unsigned
int
fifo_size
;
link_pos
=
azx_sd_readl
(
chip
,
azx_dev
,
SD_LPIB
);
if
(
azx_dev
->
substream
->
stream
==
SNDRV_PCM_STREAM_PLAYBACK
)
{
/* Playback, no problem using link position */
return
link_pos
;
}
/* Capture */
/* For new chipset,
* use mod to get the DMA position just like old chipset
*/
mod_dma_pos
=
le32_to_cpu
(
*
azx_dev
->
posbuf
);
mod_dma_pos
%=
azx_dev
->
period_bytes
;
/* azx_dev->fifo_size can't get FIFO size of in stream.
* Get from base address + offset.
*/
fifo_size
=
readw
(
chip
->
remap_addr
+
VIA_IN_STREAM0_FIFO_SIZE_OFFSET
);
if
(
azx_dev
->
insufficient
)
{
/* Link position never gather than FIFO size */
if
(
link_pos
<=
fifo_size
)
return
0
;
azx_dev
->
insufficient
=
0
;
}
if
(
link_pos
<=
fifo_size
)
mini_pos
=
azx_dev
->
bufsize
+
link_pos
-
fifo_size
;
else
mini_pos
=
link_pos
-
fifo_size
;
/* Find nearest previous boudary */
mod_mini_pos
=
mini_pos
%
azx_dev
->
period_bytes
;
mod_link_pos
=
link_pos
%
azx_dev
->
period_bytes
;
if
(
mod_link_pos
>=
fifo_size
)
bound_pos
=
link_pos
-
mod_link_pos
;
else
if
(
mod_dma_pos
>=
mod_mini_pos
)
bound_pos
=
mini_pos
-
mod_mini_pos
;
else
{
bound_pos
=
mini_pos
-
mod_mini_pos
+
azx_dev
->
period_bytes
;
if
(
bound_pos
>=
azx_dev
->
bufsize
)
bound_pos
=
0
;
}
/* Calculate real DMA position we want */
return
bound_pos
+
mod_dma_pos
;
}
#ifdef CONFIG_PM
static
DEFINE_MUTEX
(
card_list_lock
);
static
LIST_HEAD
(
card_list
);
static
void
azx_add_card_list
(
struct
azx
*
chip
)
{
struct
hda_intel
*
hda
=
container_of
(
chip
,
struct
hda_intel
,
chip
);
mutex_lock
(
&
card_list_lock
);
list_add
(
&
chip
->
list
,
&
card_list
);
list_add
(
&
hda
->
list
,
&
card_list
);
mutex_unlock
(
&
card_list_lock
);
}
static
void
azx_del_card_list
(
struct
azx
*
chip
)
{
struct
hda_intel
*
hda
=
container_of
(
chip
,
struct
hda_intel
,
chip
);
mutex_lock
(
&
card_list_lock
);
list_del_init
(
&
chip
->
list
);
list_del_init
(
&
hda
->
list
);
mutex_unlock
(
&
card_list_lock
);
}
/* trigger power-save check at writing parameter */
static
int
param_set_xint
(
const
char
*
val
,
const
struct
kernel_param
*
kp
)
{
struct
hda_intel
*
hda
;
struct
azx
*
chip
;
struct
hda_codec
*
c
;
int
prev
=
power_save
;
...
...
@@ -584,7 +762,8 @@ static int param_set_xint(const char *val, const struct kernel_param *kp)
return
ret
;
mutex_lock
(
&
card_list_lock
);
list_for_each_entry
(
chip
,
&
card_list
,
list
)
{
list_for_each_entry
(
hda
,
&
card_list
,
list
)
{
chip
=
&
hda
->
chip
;
if
(
!
chip
->
bus
||
chip
->
disabled
)
continue
;
list_for_each_entry
(
c
,
&
chip
->
bus
->
codec_list
,
list
)
...
...
@@ -789,29 +968,6 @@ static const struct dev_pm_ops azx_pm = {
#endif
/* CONFIG_PM */
/*
* reboot notifier for hang-up problem at power-down
*/
static
int
azx_halt
(
struct
notifier_block
*
nb
,
unsigned
long
event
,
void
*
buf
)
{
struct
azx
*
chip
=
container_of
(
nb
,
struct
azx
,
reboot_notifier
);
snd_hda_bus_reboot_notify
(
chip
->
bus
);
azx_stop_chip
(
chip
);
return
NOTIFY_OK
;
}
static
void
azx_notifier_register
(
struct
azx
*
chip
)
{
chip
->
reboot_notifier
.
notifier_call
=
azx_halt
;
register_reboot_notifier
(
&
chip
->
reboot_notifier
);
}
static
void
azx_notifier_unregister
(
struct
azx
*
chip
)
{
if
(
chip
->
reboot_notifier
.
notifier_call
)
unregister_reboot_notifier
(
&
chip
->
reboot_notifier
);
}
static
int
azx_probe_continue
(
struct
azx
*
chip
);
#ifdef SUPPORT_VGA_SWITCHEROO
...
...
@@ -822,10 +978,11 @@ static void azx_vs_set_state(struct pci_dev *pci,
{
struct
snd_card
*
card
=
pci_get_drvdata
(
pci
);
struct
azx
*
chip
=
card
->
private_data
;
struct
hda_intel
*
hda
=
container_of
(
chip
,
struct
hda_intel
,
chip
);
bool
disabled
;
wait_for_completion
(
&
chip
->
probe_wait
);
if
(
chip
->
init_failed
)
wait_for_completion
(
&
hda
->
probe_wait
);
if
(
hda
->
init_failed
)
return
;
disabled
=
(
state
==
VGA_SWITCHEROO_OFF
);
...
...
@@ -839,7 +996,7 @@ static void azx_vs_set_state(struct pci_dev *pci,
"Start delayed initialization
\n
"
);
if
(
azx_probe_continue
(
chip
)
<
0
)
{
dev_err
(
chip
->
card
->
dev
,
"initialization error
\n
"
);
chip
->
init_failed
=
true
;
hda
->
init_failed
=
true
;
}
}
}
else
{
...
...
@@ -869,9 +1026,10 @@ static bool azx_vs_can_switch(struct pci_dev *pci)
{
struct
snd_card
*
card
=
pci_get_drvdata
(
pci
);
struct
azx
*
chip
=
card
->
private_data
;
struct
hda_intel
*
hda
=
container_of
(
chip
,
struct
hda_intel
,
chip
);
wait_for_completion
(
&
chip
->
probe_wait
);
if
(
chip
->
init_failed
)
wait_for_completion
(
&
hda
->
probe_wait
);
if
(
hda
->
init_failed
)
return
false
;
if
(
chip
->
disabled
||
!
chip
->
bus
)
return
true
;
...
...
@@ -883,11 +1041,12 @@ static bool azx_vs_can_switch(struct pci_dev *pci)
static
void
init_vga_switcheroo
(
struct
azx
*
chip
)
{
struct
hda_intel
*
hda
=
container_of
(
chip
,
struct
hda_intel
,
chip
);
struct
pci_dev
*
p
=
get_bound_vga
(
chip
->
pci
);
if
(
p
)
{
dev_info
(
chip
->
card
->
dev
,
"Handle VGA-switcheroo audio client
\n
"
);
chip
->
use_vga_switcheroo
=
1
;
hda
->
use_vga_switcheroo
=
1
;
pci_dev_put
(
p
);
}
}
...
...
@@ -899,9 +1058,10 @@ static const struct vga_switcheroo_client_ops azx_vs_ops = {
static
int
register_vga_switcheroo
(
struct
azx
*
chip
)
{
struct
hda_intel
*
hda
=
container_of
(
chip
,
struct
hda_intel
,
chip
);
int
err
;
if
(
!
chip
->
use_vga_switcheroo
)
if
(
!
hda
->
use_vga_switcheroo
)
return
0
;
/* FIXME: currently only handling DIS controller
* is there any machine with two switchable HDMI audio controllers?
...
...
@@ -911,11 +1071,11 @@ static int register_vga_switcheroo(struct azx *chip)
chip
->
bus
!=
NULL
);
if
(
err
<
0
)
return
err
;
chip
->
vga_switcheroo_registered
=
1
;
hda
->
vga_switcheroo_registered
=
1
;
/* register as an optimus hdmi audio power domain */
vga_switcheroo_init_domain_pm_optimus_hdmi_audio
(
chip
->
card
->
dev
,
&
chip
->
hdmi_pm_domain
);
&
hda
->
hdmi_pm_domain
);
return
0
;
}
#else
...
...
@@ -931,7 +1091,6 @@ static int azx_free(struct azx *chip)
{
struct
pci_dev
*
pci
=
chip
->
pci
;
struct
hda_intel
*
hda
=
container_of
(
chip
,
struct
hda_intel
,
chip
);
int
i
;
if
((
chip
->
driver_caps
&
AZX_DCAPS_PM_RUNTIME
)
...
...
@@ -942,13 +1101,13 @@ static int azx_free(struct azx *chip)
azx_notifier_unregister
(
chip
);
chip
->
init_failed
=
1
;
/* to be sure */
complete_all
(
&
chip
->
probe_wait
);
hda
->
init_failed
=
1
;
/* to be sure */
complete_all
(
&
hda
->
probe_wait
);
if
(
use_vga_switcheroo
(
chip
))
{
if
(
use_vga_switcheroo
(
hda
))
{
if
(
chip
->
disabled
&&
chip
->
bus
)
snd_hda_unlock_devices
(
chip
->
bus
);
if
(
chip
->
vga_switcheroo_registered
)
if
(
hda
->
vga_switcheroo_registered
)
vga_switcheroo_unregister_client
(
chip
->
pci
);
}
...
...
@@ -1084,6 +1243,30 @@ static int check_position_fix(struct azx *chip, int fix)
return
POS_FIX_AUTO
;
}
static
void
assign_position_fix
(
struct
azx
*
chip
,
int
fix
)
{
static
azx_get_pos_callback_t
callbacks
[]
=
{
[
POS_FIX_AUTO
]
=
NULL
,
[
POS_FIX_LPIB
]
=
azx_get_pos_lpib
,
[
POS_FIX_POSBUF
]
=
azx_get_pos_posbuf
,
[
POS_FIX_VIACOMBO
]
=
azx_via_get_position
,
[
POS_FIX_COMBO
]
=
azx_get_pos_lpib
,
};
chip
->
get_position
[
0
]
=
chip
->
get_position
[
1
]
=
callbacks
[
fix
];
/* combo mode uses LPIB only for playback */
if
(
fix
==
POS_FIX_COMBO
)
chip
->
get_position
[
1
]
=
NULL
;
if
(
fix
==
POS_FIX_POSBUF
&&
(
chip
->
driver_caps
&
AZX_DCAPS_COUNT_LPIB_DELAY
))
{
chip
->
get_delay
[
0
]
=
chip
->
get_delay
[
1
]
=
azx_get_delay_from_lpib
;
}
}
/*
* black-lists for probe_mask
*/
...
...
@@ -1209,7 +1392,8 @@ static void azx_check_snoop_available(struct azx *chip)
static
void
azx_probe_work
(
struct
work_struct
*
work
)
{
azx_probe_continue
(
container_of
(
work
,
struct
azx
,
probe_work
));
struct
hda_intel
*
hda
=
container_of
(
work
,
struct
hda_intel
,
probe_work
);
azx_probe_continue
(
&
hda
->
chip
);
}
/*
...
...
@@ -1252,19 +1436,13 @@ static int azx_create(struct snd_card *card, struct pci_dev *pci,
check_msi
(
chip
);
chip
->
dev_index
=
dev
;
chip
->
jackpoll_ms
=
jackpoll_ms
;
INIT_WORK
(
&
chip
->
irq_pending_work
,
azx_irq_pending_work
);
INIT_LIST_HEAD
(
&
chip
->
pcm_list
);
INIT_LIST_HEAD
(
&
chip
->
list
);
INIT_WORK
(
&
hda
->
irq_pending_work
,
azx_irq_pending_work
);
INIT_LIST_HEAD
(
&
hda
->
list
);
init_vga_switcheroo
(
chip
);
init_completion
(
&
chip
->
probe_wait
);
init_completion
(
&
hda
->
probe_wait
);
chip
->
position_fix
[
0
]
=
chip
->
position_fix
[
1
]
=
check_position_fix
(
chip
,
position_fix
[
dev
]);
/* combo mode uses LPIB for playback */
if
(
chip
->
position_fix
[
0
]
==
POS_FIX_COMBO
)
{
chip
->
position_fix
[
0
]
=
POS_FIX_LPIB
;
chip
->
position_fix
[
1
]
=
POS_FIX_AUTO
;
}
assign_position_fix
(
chip
,
check_position_fix
(
chip
,
position_fix
[
dev
]));
check_probe_mask
(
chip
,
dev
);
...
...
@@ -1293,7 +1471,7 @@ static int azx_create(struct snd_card *card, struct pci_dev *pci,
}
/* continue probing in work context as may trigger request module */
INIT_WORK
(
&
chip
->
probe_work
,
azx_probe_work
);
INIT_WORK
(
&
hda
->
probe_work
,
azx_probe_work
);
*
rchip
=
chip
;
...
...
@@ -1351,7 +1529,7 @@ static int azx_first_init(struct azx *chip)
NULL
);
if
(
p_smbus
)
{
if
(
p_smbus
->
revision
<
0x30
)
gcap
&=
~
ICH6
_GCAP_64OK
;
gcap
&=
~
AZX
_GCAP_64OK
;
pci_dev_put
(
p_smbus
);
}
}
...
...
@@ -1359,7 +1537,7 @@ static int azx_first_init(struct azx *chip)
/* disable 64bit DMA address on some devices */
if
(
chip
->
driver_caps
&
AZX_DCAPS_NO_64BIT
)
{
dev_dbg
(
card
->
dev
,
"Disabling 64bit DMA
\n
"
);
gcap
&=
~
ICH6
_GCAP_64OK
;
gcap
&=
~
AZX
_GCAP_64OK
;
}
/* disable buffer size rounding to 128-byte multiples if supported */
...
...
@@ -1375,7 +1553,7 @@ static int azx_first_init(struct azx *chip)
}
/* allow 64bit DMA address if supported by H/W */
if
((
gcap
&
ICH6
_GCAP_64OK
)
&&
!
pci_set_dma_mask
(
pci
,
DMA_BIT_MASK
(
64
)))
if
((
gcap
&
AZX
_GCAP_64OK
)
&&
!
pci_set_dma_mask
(
pci
,
DMA_BIT_MASK
(
64
)))
pci_set_consistent_dma_mask
(
pci
,
DMA_BIT_MASK
(
64
));
else
{
pci_set_dma_mask
(
pci
,
DMA_BIT_MASK
(
32
));
...
...
@@ -1615,6 +1793,7 @@ static int azx_probe(struct pci_dev *pci,
{
static
int
dev
;
struct
snd_card
*
card
;
struct
hda_intel
*
hda
;
struct
azx
*
chip
;
bool
schedule_probe
;
int
err
;
...
...
@@ -1638,6 +1817,7 @@ static int azx_probe(struct pci_dev *pci,
if
(
err
<
0
)
goto
out_free
;
card
->
private_data
=
chip
;
hda
=
container_of
(
chip
,
struct
hda_intel
,
chip
);
pci_set_drvdata
(
pci
,
card
);
...
...
@@ -1674,11 +1854,11 @@ static int azx_probe(struct pci_dev *pci,
#endif
if
(
schedule_probe
)
schedule_work
(
&
chip
->
probe_work
);
schedule_work
(
&
hda
->
probe_work
);
dev
++
;
if
(
chip
->
disabled
)
complete_all
(
&
chip
->
probe_wait
);
complete_all
(
&
hda
->
probe_wait
);
return
0
;
out_free:
...
...
@@ -1694,6 +1874,7 @@ static unsigned int azx_max_codecs[AZX_NUM_DRIVERS] = {
static
int
azx_probe_continue
(
struct
azx
*
chip
)
{
struct
hda_intel
*
hda
=
container_of
(
chip
,
struct
hda_intel
,
chip
);
struct
pci_dev
*
pci
=
chip
->
pci
;
int
dev
=
chip
->
dev_index
;
int
err
;
...
...
@@ -1767,13 +1948,13 @@ static int azx_probe_continue(struct azx *chip)
power_down_all_codecs
(
chip
);
azx_notifier_register
(
chip
);
azx_add_card_list
(
chip
);
if
((
chip
->
driver_caps
&
AZX_DCAPS_PM_RUNTIME
)
||
chip
->
use_vga_switcheroo
)
if
((
chip
->
driver_caps
&
AZX_DCAPS_PM_RUNTIME
)
||
hda
->
use_vga_switcheroo
)
pm_runtime_put_noidle
(
&
pci
->
dev
);
out_free:
if
(
err
<
0
)
chip
->
init_failed
=
1
;
complete_all
(
&
chip
->
probe_wait
);
hda
->
init_failed
=
1
;
complete_all
(
&
hda
->
probe_wait
);
return
err
;
}
...
...
sound/pci/hda/hda_priv.h
View file @
84526820
...
...
@@ -22,107 +22,87 @@
/*
* registers
*/
#define
ICH6
_REG_GCAP 0x00
#define
ICH6_GCAP_64OK
(1 << 0)
/* 64bit address support */
#define
ICH6_GCAP_NSDO
(3 << 1)
/* # of serial data out signals */
#define
ICH6
_GCAP_BSS (31 << 3)
/* # of bidirectional streams */
#define
ICH6
_GCAP_ISS (15 << 8)
/* # of input streams */
#define
ICH6
_GCAP_OSS (15 << 12)
/* # of output streams */
#define
ICH6
_REG_VMIN 0x02
#define
ICH6
_REG_VMAJ 0x03
#define
ICH6
_REG_OUTPAY 0x04
#define
ICH6
_REG_INPAY 0x06
#define
ICH6
_REG_GCTL 0x08
#define
ICH6
_GCTL_RESET (1 << 0)
/* controller reset */
#define
ICH6
_GCTL_FCNTRL (1 << 1)
/* flush control */
#define
ICH6
_GCTL_UNSOL (1 << 8)
/* accept unsol. response enable */
#define
ICH6
_REG_WAKEEN 0x0c
#define
ICH6
_REG_STATESTS 0x0e
#define
ICH6
_REG_GSTS 0x10
#define
ICH6_GSTS_FSTS
(1 << 1)
/* flush status */
#define
ICH6
_REG_INTCTL 0x20
#define
ICH6
_REG_INTSTS 0x24
#define
ICH6_REG_WALLCLK
0x30
/* 24Mhz source */
#define
ICH6
_REG_OLD_SSYNC 0x34
/* SSYNC for old ICH */
#define
ICH6
_REG_SSYNC 0x38
#define
ICH6
_REG_CORBLBASE 0x40
#define
ICH6
_REG_CORBUBASE 0x44
#define
ICH6
_REG_CORBWP 0x48
#define
ICH6
_REG_CORBRP 0x4a
#define
ICH6
_CORBRP_RST (1 << 15)
/* read pointer reset */
#define
ICH6_REG_CORBCTL
0x4c
#define
ICH6
_CORBCTL_RUN (1 << 1)
/* enable DMA */
#define
ICH6
_CORBCTL_CMEIE (1 << 0)
/* enable memory error irq */
#define
ICH6_REG_CORBSTS
0x4d
#define
ICH6
_CORBSTS_CMEI (1 << 0)
/* memory error indication */
#define
ICH6
_REG_CORBSIZE 0x4e
#define
ICH6
_REG_RIRBLBASE 0x50
#define
ICH6
_REG_RIRBUBASE 0x54
#define
ICH6
_REG_RIRBWP 0x58
#define
ICH6
_RIRBWP_RST (1 << 15)
/* write pointer reset */
#define
ICH6_REG_RINTCNT
0x5a
#define
ICH6_REG_RIRBCTL
0x5c
#define
ICH6
_RBCTL_IRQ_EN (1 << 0)
/* enable IRQ */
#define
ICH6
_RBCTL_DMA_EN (1 << 1)
/* enable DMA */
#define
ICH6
_RBCTL_OVERRUN_EN (1 << 2)
/* enable overrun irq */
#define
ICH6_REG_RIRBSTS
0x5d
#define
ICH6_RBSTS_IRQ
(1 << 0)
/* response irq */
#define
ICH6
_RBSTS_OVERRUN (1 << 2)
/* overrun irq */
#define
ICH6
_REG_RIRBSIZE 0x5e
#define
ICH6
_REG_IC 0x60
#define
ICH6
_REG_IR 0x64
#define
ICH6
_REG_IRS 0x68
#define
ICH6_IRS_VALID
(1<<1)
#define
ICH6
_IRS_BUSY (1<<0)
#define
ICH6_REG_DPLBASE
0x70
#define
ICH6_REG_DPUBASE
0x74
#define
ICH6
_DPLBASE_ENABLE 0x1
/* Enable position buffer */
#define
AZX
_REG_GCAP 0x00
#define
AZX_GCAP_64OK
(1 << 0)
/* 64bit address support */
#define
AZX_GCAP_NSDO
(3 << 1)
/* # of serial data out signals */
#define
AZX
_GCAP_BSS (31 << 3)
/* # of bidirectional streams */
#define
AZX
_GCAP_ISS (15 << 8)
/* # of input streams */
#define
AZX
_GCAP_OSS (15 << 12)
/* # of output streams */
#define
AZX
_REG_VMIN 0x02
#define
AZX
_REG_VMAJ 0x03
#define
AZX
_REG_OUTPAY 0x04
#define
AZX
_REG_INPAY 0x06
#define
AZX
_REG_GCTL 0x08
#define
AZX
_GCTL_RESET (1 << 0)
/* controller reset */
#define
AZX
_GCTL_FCNTRL (1 << 1)
/* flush control */
#define
AZX
_GCTL_UNSOL (1 << 8)
/* accept unsol. response enable */
#define
AZX
_REG_WAKEEN 0x0c
#define
AZX
_REG_STATESTS 0x0e
#define
AZX
_REG_GSTS 0x10
#define
AZX_GSTS_FSTS
(1 << 1)
/* flush status */
#define
AZX
_REG_INTCTL 0x20
#define
AZX
_REG_INTSTS 0x24
#define
AZX_REG_WALLCLK
0x30
/* 24Mhz source */
#define
AZX
_REG_OLD_SSYNC 0x34
/* SSYNC for old ICH */
#define
AZX
_REG_SSYNC 0x38
#define
AZX
_REG_CORBLBASE 0x40
#define
AZX
_REG_CORBUBASE 0x44
#define
AZX
_REG_CORBWP 0x48
#define
AZX
_REG_CORBRP 0x4a
#define
AZX
_CORBRP_RST (1 << 15)
/* read pointer reset */
#define
AZX_REG_CORBCTL
0x4c
#define
AZX
_CORBCTL_RUN (1 << 1)
/* enable DMA */
#define
AZX
_CORBCTL_CMEIE (1 << 0)
/* enable memory error irq */
#define
AZX_REG_CORBSTS
0x4d
#define
AZX
_CORBSTS_CMEI (1 << 0)
/* memory error indication */
#define
AZX
_REG_CORBSIZE 0x4e
#define
AZX
_REG_RIRBLBASE 0x50
#define
AZX
_REG_RIRBUBASE 0x54
#define
AZX
_REG_RIRBWP 0x58
#define
AZX
_RIRBWP_RST (1 << 15)
/* write pointer reset */
#define
AZX_REG_RINTCNT
0x5a
#define
AZX_REG_RIRBCTL
0x5c
#define
AZX
_RBCTL_IRQ_EN (1 << 0)
/* enable IRQ */
#define
AZX
_RBCTL_DMA_EN (1 << 1)
/* enable DMA */
#define
AZX
_RBCTL_OVERRUN_EN (1 << 2)
/* enable overrun irq */
#define
AZX_REG_RIRBSTS
0x5d
#define
AZX_RBSTS_IRQ
(1 << 0)
/* response irq */
#define
AZX
_RBSTS_OVERRUN (1 << 2)
/* overrun irq */
#define
AZX
_REG_RIRBSIZE 0x5e
#define
AZX
_REG_IC 0x60
#define
AZX
_REG_IR 0x64
#define
AZX
_REG_IRS 0x68
#define
AZX_IRS_VALID
(1<<1)
#define
AZX
_IRS_BUSY (1<<0)
#define
AZX_REG_DPLBASE
0x70
#define
AZX_REG_DPUBASE
0x74
#define
AZX
_DPLBASE_ENABLE 0x1
/* Enable position buffer */
/* SD offset: SDI0=0x80, SDI1=0xa0, ... SDO3=0x160 */
enum
{
SDI0
,
SDI1
,
SDI2
,
SDI3
,
SDO0
,
SDO1
,
SDO2
,
SDO3
};
/* stream register offsets from stream base */
#define
ICH6
_REG_SD_CTL 0x00
#define
ICH6
_REG_SD_STS 0x03
#define
ICH6_REG_SD_LPIB
0x04
#define
ICH6
_REG_SD_CBL 0x08
#define
ICH6
_REG_SD_LVI 0x0c
#define
ICH6
_REG_SD_FIFOW 0x0e
#define
ICH6
_REG_SD_FIFOSIZE 0x10
#define
ICH6
_REG_SD_FORMAT 0x12
#define
ICH6
_REG_SD_BDLPL 0x18
#define
ICH6
_REG_SD_BDLPU 0x1c
#define
AZX
_REG_SD_CTL 0x00
#define
AZX
_REG_SD_STS 0x03
#define
AZX_REG_SD_LPIB
0x04
#define
AZX
_REG_SD_CBL 0x08
#define
AZX
_REG_SD_LVI 0x0c
#define
AZX
_REG_SD_FIFOW 0x0e
#define
AZX
_REG_SD_FIFOSIZE 0x10
#define
AZX
_REG_SD_FORMAT 0x12
#define
AZX
_REG_SD_BDLPL 0x18
#define
AZX
_REG_SD_BDLPU 0x1c
/* PCI space */
#define
ICH6_PCIREG_TCSEL
0x44
#define
AZX_PCIREG_TCSEL
0x44
/*
* other constants
*/
/* max number of SDs */
/* ICH, ATI and VIA have 4 playback and 4 capture */
#define ICH6_NUM_CAPTURE 4
#define ICH6_NUM_PLAYBACK 4
/* ULI has 6 playback and 5 capture */
#define ULI_NUM_CAPTURE 5
#define ULI_NUM_PLAYBACK 6
/* ATI HDMI may have up to 8 playbacks and 0 capture */
#define ATIHDMI_NUM_CAPTURE 0
#define ATIHDMI_NUM_PLAYBACK 8
/* TERA has 4 playback and 3 capture */
#define TERA_NUM_CAPTURE 3
#define TERA_NUM_PLAYBACK 4
/* this number is statically defined for simplicity */
#define MAX_AZX_DEV 16
/* max number of fragments - we may use more if allocating more pages for BDL */
#define BDL_SIZE 4096
#define AZX_MAX_BDL_ENTRIES (BDL_SIZE / 16)
...
...
@@ -160,13 +140,13 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 };
#define SD_STS_FIFO_READY 0x20
/* FIFO ready */
/* INTCTL and INTSTS */
#define
ICH6
_INT_ALL_STREAM 0xff
/* all stream interrupts */
#define
ICH6
_INT_CTRL_EN 0x40000000
/* controller interrupt enable bit */
#define
ICH6
_INT_GLOBAL_EN 0x80000000
/* global interrupt enable bit */
#define
AZX
_INT_ALL_STREAM 0xff
/* all stream interrupts */
#define
AZX
_INT_CTRL_EN 0x40000000
/* controller interrupt enable bit */
#define
AZX
_INT_GLOBAL_EN 0x80000000
/* global interrupt enable bit */
/* below are so far hardcoded - should read registers in future */
#define
ICH6
_MAX_CORB_ENTRIES 256
#define
ICH6
_MAX_RIRB_ENTRIES 256
#define
AZX
_MAX_CORB_ENTRIES 256
#define
AZX
_MAX_RIRB_ENTRIES 256
/* driver quirks (capabilities) */
/* bits 0-7 are used for indicating driver type */
...
...
@@ -191,35 +171,6 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 };
#define AZX_DCAPS_I915_POWERWELL (1 << 27)
/* HSW i915 powerwell support */
#define AZX_DCAPS_CORBRP_SELF_CLEAR (1 << 28)
/* CORBRP clears itself after reset */
/* position fix mode */
enum
{
POS_FIX_AUTO
,
POS_FIX_LPIB
,
POS_FIX_POSBUF
,
POS_FIX_VIACOMBO
,
POS_FIX_COMBO
,
};
/* Defines for ATI HD Audio support in SB450 south bridge */
#define ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR 0x42
#define ATI_SB450_HDAUDIO_ENABLE_SNOOP 0x02
/* Defines for Nvidia HDA support */
#define NVIDIA_HDA_TRANSREG_ADDR 0x4e
#define NVIDIA_HDA_ENABLE_COHBITS 0x0f
#define NVIDIA_HDA_ISTRM_COH 0x4d
#define NVIDIA_HDA_OSTRM_COH 0x4c
#define NVIDIA_HDA_ENABLE_COHBIT 0x01
/* Defines for Intel SCH HDA snoop control */
#define INTEL_SCH_HDA_DEVC 0x78
#define INTEL_SCH_HDA_DEVC_NOSNOOP (0x1<<11)
/* Define IN stream 0 FIFO size offset in VIA controller */
#define VIA_IN_STREAM0_FIFO_SIZE_OFFSET 0x90
/* Define VIA HD Audio Device ID*/
#define VIA_HDAC_DEVICE_ID 0x3288
/* HD Audio class code */
#define PCI_CLASS_MULTIMEDIA_HD_AUDIO 0x0403
...
...
@@ -324,6 +275,9 @@ struct azx_pcm {
struct
list_head
list
;
};
typedef
unsigned
int
(
*
azx_get_pos_callback_t
)(
struct
azx
*
,
struct
azx_dev
*
);
typedef
int
(
*
azx_get_delay_callback_t
)(
struct
azx
*
,
struct
azx_dev
*
,
unsigned
int
pos
);
struct
azx
{
struct
snd_card
*
card
;
struct
pci_dev
*
pci
;
...
...
@@ -342,6 +296,10 @@ struct azx {
/* Register interaction. */
const
struct
hda_controller_ops
*
ops
;
/* position adjustment callbacks */
azx_get_pos_callback_t
get_position
[
2
];
azx_get_delay_callback_t
get_delay
[
2
];
/* pci resources */
unsigned
long
addr
;
void
__iomem
*
remap_addr
;
...
...
@@ -350,7 +308,6 @@ struct azx {
/* locks */
spinlock_t
reg_lock
;
struct
mutex
open_mutex
;
/* Prevents concurrent open/close operations */
struct
completion
probe_wait
;
/* streams (x num_streams) */
struct
azx_dev
*
azx_dev
;
...
...
@@ -377,7 +334,6 @@ struct azx {
#endif
/* flags */
int
position_fix
[
2
];
/* for both playback/capture streams */
const
int
*
bdl_pos_adj
;
int
poll_count
;
unsigned
int
running
:
1
;
...
...
@@ -385,46 +341,23 @@ struct azx {
unsigned
int
single_cmd
:
1
;
unsigned
int
polling_mode
:
1
;
unsigned
int
msi
:
1
;
unsigned
int
irq_pending_warned
:
1
;
unsigned
int
probing
:
1
;
/* codec probing phase */
unsigned
int
snoop
:
1
;
unsigned
int
align_buffer_size
:
1
;
unsigned
int
region_requested
:
1
;
/* VGA-switcheroo setup */
unsigned
int
use_vga_switcheroo
:
1
;
unsigned
int
vga_switcheroo_registered
:
1
;
unsigned
int
init_failed
:
1
;
/* delayed init failed */
unsigned
int
disabled
:
1
;
/* disabled by VGA-switcher */
/* for debugging */
unsigned
int
last_cmd
[
AZX_MAX_CODECS
];
/* for pending irqs */
struct
work_struct
irq_pending_work
;
struct
work_struct
probe_work
;
/* reboot notifier (for mysterious hangup problem at power-down) */
struct
notifier_block
reboot_notifier
;
/* card list (for power_save trigger) */
struct
list_head
list
;
#ifdef CONFIG_SND_HDA_DSP_LOADER
struct
azx_dev
saved_azx_dev
;
#endif
/* secondary power domain for hdmi audio under vga device */
struct
dev_pm_domain
hdmi_pm_domain
;
};
#ifdef CONFIG_SND_VERBOSE_PRINTK
#define SFX
/* nop */
#else
#define SFX "hda-intel "
#endif
#ifdef CONFIG_X86
#define azx_snoop(chip) ((chip)->snoop)
#else
...
...
@@ -436,29 +369,29 @@ struct azx {
*/
#define azx_writel(chip, reg, value) \
((chip)->ops->reg_writel(value, (chip)->remap_addr +
ICH6
_REG_##reg))
((chip)->ops->reg_writel(value, (chip)->remap_addr +
AZX
_REG_##reg))
#define azx_readl(chip, reg) \
((chip)->ops->reg_readl((chip)->remap_addr +
ICH6
_REG_##reg))
((chip)->ops->reg_readl((chip)->remap_addr +
AZX
_REG_##reg))
#define azx_writew(chip, reg, value) \
((chip)->ops->reg_writew(value, (chip)->remap_addr +
ICH6
_REG_##reg))
((chip)->ops->reg_writew(value, (chip)->remap_addr +
AZX
_REG_##reg))
#define azx_readw(chip, reg) \
((chip)->ops->reg_readw((chip)->remap_addr +
ICH6
_REG_##reg))
((chip)->ops->reg_readw((chip)->remap_addr +
AZX
_REG_##reg))
#define azx_writeb(chip, reg, value) \
((chip)->ops->reg_writeb(value, (chip)->remap_addr +
ICH6
_REG_##reg))
((chip)->ops->reg_writeb(value, (chip)->remap_addr +
AZX
_REG_##reg))
#define azx_readb(chip, reg) \
((chip)->ops->reg_readb((chip)->remap_addr +
ICH6
_REG_##reg))
((chip)->ops->reg_readb((chip)->remap_addr +
AZX
_REG_##reg))
#define azx_sd_writel(chip, dev, reg, value) \
((chip)->ops->reg_writel(value, (dev)->sd_addr +
ICH6
_REG_##reg))
((chip)->ops->reg_writel(value, (dev)->sd_addr +
AZX
_REG_##reg))
#define azx_sd_readl(chip, dev, reg) \
((chip)->ops->reg_readl((dev)->sd_addr +
ICH6
_REG_##reg))
((chip)->ops->reg_readl((dev)->sd_addr +
AZX
_REG_##reg))
#define azx_sd_writew(chip, dev, reg, value) \
((chip)->ops->reg_writew(value, (dev)->sd_addr +
ICH6
_REG_##reg))
((chip)->ops->reg_writew(value, (dev)->sd_addr +
AZX
_REG_##reg))
#define azx_sd_readw(chip, dev, reg) \
((chip)->ops->reg_readw((dev)->sd_addr +
ICH6
_REG_##reg))
((chip)->ops->reg_readw((dev)->sd_addr +
AZX
_REG_##reg))
#define azx_sd_writeb(chip, dev, reg, value) \
((chip)->ops->reg_writeb(value, (dev)->sd_addr +
ICH6
_REG_##reg))
((chip)->ops->reg_writeb(value, (dev)->sd_addr +
AZX
_REG_##reg))
#define azx_sd_readb(chip, dev, reg) \
((chip)->ops->reg_readb((dev)->sd_addr +
ICH6
_REG_##reg))
((chip)->ops->reg_readb((dev)->sd_addr +
AZX
_REG_##reg))
#endif
/* __SOUND_HDA_PRIV_H */
sound/pci/hda/hda_tegra.c
View file @
84526820
...
...
@@ -29,7 +29,6 @@
#include <linux/moduleparam.h>
#include <linux/mutex.h>
#include <linux/of_device.h>
#include <linux/reboot.h>
#include <linux/slab.h>
#include <linux/time.h>
...
...
@@ -294,30 +293,6 @@ static const struct dev_pm_ops hda_tegra_pm = {
SET_SYSTEM_SLEEP_PM_OPS
(
hda_tegra_suspend
,
hda_tegra_resume
)
};
/*
* reboot notifier for hang-up problem at power-down
*/
static
int
hda_tegra_halt
(
struct
notifier_block
*
nb
,
unsigned
long
event
,
void
*
buf
)
{
struct
azx
*
chip
=
container_of
(
nb
,
struct
azx
,
reboot_notifier
);
snd_hda_bus_reboot_notify
(
chip
->
bus
);
azx_stop_chip
(
chip
);
return
NOTIFY_OK
;
}
static
void
hda_tegra_notifier_register
(
struct
azx
*
chip
)
{
chip
->
reboot_notifier
.
notifier_call
=
hda_tegra_halt
;
register_reboot_notifier
(
&
chip
->
reboot_notifier
);
}
static
void
hda_tegra_notifier_unregister
(
struct
azx
*
chip
)
{
if
(
chip
->
reboot_notifier
.
notifier_call
)
unregister_reboot_notifier
(
&
chip
->
reboot_notifier
);
}
/*
* destructor
*/
...
...
@@ -326,7 +301,7 @@ static int hda_tegra_dev_free(struct snd_device *device)
int
i
;
struct
azx
*
chip
=
device
->
device_data
;
hda_tegra
_notifier_unregister
(
chip
);
azx
_notifier_unregister
(
chip
);
if
(
chip
->
initialized
)
{
for
(
i
=
0
;
i
<
chip
->
num_streams
;
i
++
)
...
...
@@ -480,8 +455,6 @@ static int hda_tegra_create(struct snd_card *card,
INIT_LIST_HEAD
(
&
chip
->
pcm_list
);
INIT_LIST_HEAD
(
&
chip
->
list
);
chip
->
position_fix
[
0
]
=
POS_FIX_AUTO
;
chip
->
position_fix
[
1
]
=
POS_FIX_AUTO
;
chip
->
codec_probe_mask
=
-
1
;
chip
->
single_cmd
=
false
;
...
...
@@ -559,7 +532,7 @@ static int hda_tegra_probe(struct platform_device *pdev)
chip
->
running
=
1
;
power_down_all_codecs
(
chip
);
hda_tegra
_notifier_register
(
chip
);
azx
_notifier_register
(
chip
);
return
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