2005-04-17 02:20:36 +04:00
/*
*
2007-07-27 18:52:19 +04:00
* hda_intel . c - Implementation of primary alsa driver code base
* for Intel HD Audio .
2005-04-17 02:20:36 +04:00
*
* Copyright ( c ) 2004 Intel Corporation . All rights reserved .
*
* Copyright ( c ) 2004 Takashi Iwai < tiwai @ suse . de >
* PeiSen Hou < pshou @ realtek . com . tw >
*
* This program is free software ; you can redistribute it and / or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation ; either version 2 of the License , or ( at your option )
* any later version .
*
* This program is distributed in the hope that it will be useful , but WITHOUT
* ANY WARRANTY ; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE . See the GNU General Public License for
* more details .
*
* You should have received a copy of the GNU General Public License along with
* this program ; if not , write to the Free Software Foundation , Inc . , 59
* Temple Place - Suite 330 , Boston , MA 02111 - 1307 , USA .
*
* CONTACTS :
*
* Matt Jared matt . jared @ intel . com
* Andy Kopp andy . kopp @ intel . com
* Dan Kogan dan . d . kogan @ intel . com
*
* CHANGES :
*
* 2004.12 .01 Major rewrite by tiwai , merged the work of pshou
*
*/
# include <linux/delay.h>
# include <linux/interrupt.h>
2005-11-07 16:43:23 +03:00
# include <linux/kernel.h>
2005-04-17 02:20:36 +04:00
# include <linux/module.h>
2008-03-04 12:08:58 +03:00
# include <linux/dma-mapping.h>
2005-04-17 02:20:36 +04:00
# include <linux/moduleparam.h>
# include <linux/init.h>
# include <linux/slab.h>
# include <linux/pci.h>
2006-01-16 18:34:20 +03:00
# include <linux/mutex.h>
2011-09-28 19:16:09 +04:00
# include <linux/io.h>
2012-08-23 13:32:30 +04:00
# include <linux/pm_runtime.h>
2012-10-23 01:42:16 +04:00
# include <linux/clocksource.h>
# include <linux/time.h>
2012-12-04 18:09:23 +04:00
# include <linux/completion.h>
2012-10-23 01:42:16 +04:00
2011-09-28 19:16:09 +04:00
# ifdef CONFIG_X86
/* for snoop control */
# include <asm/pgtable.h>
# include <asm/cacheflush.h>
# endif
2005-04-17 02:20:36 +04:00
# include <sound/core.h>
# include <sound/initval.h>
2015-05-19 17:29:30 +03:00
# include <sound/hdaudio.h>
# include <sound/hda_i915.h>
2012-04-26 14:13:25 +04:00
# include <linux/vgaarb.h>
2012-04-26 14:23:42 +04:00
# include <linux/vga_switcheroo.h>
2012-08-09 14:33:28 +04:00
# include <linux/firmware.h>
2005-04-17 02:20:36 +04:00
# include "hda_codec.h"
2014-03-01 03:41:22 +04:00
# include "hda_controller.h"
2015-01-08 18:54:15 +03:00
# include "hda_intel.h"
2005-04-17 02:20:36 +04:00
2015-05-12 04:43:22 +03:00
# define CREATE_TRACE_POINTS
# include "hda_intel_trace.h"
2014-06-26 18:50:16 +04:00
/* position fix mode */
enum {
POS_FIX_AUTO ,
POS_FIX_LPIB ,
POS_FIX_POSBUF ,
POS_FIX_VIACOMBO ,
POS_FIX_COMBO ,
} ;
2014-06-26 19:19:20 +04:00
/* 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
2014-06-26 19:28:06 +04:00
/* 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
2005-04-17 02:20:36 +04:00
2008-01-07 17:16:37 +03:00
static int index [ SNDRV_CARDS ] = SNDRV_DEFAULT_IDX ;
static char * id [ SNDRV_CARDS ] = SNDRV_DEFAULT_STR ;
2011-12-15 07:19:36 +04:00
static bool enable [ SNDRV_CARDS ] = SNDRV_DEFAULT_ENABLE_PNP ;
2008-01-07 17:16:37 +03:00
static char * model [ SNDRV_CARDS ] ;
2012-09-13 16:59:47 +04:00
static int position_fix [ SNDRV_CARDS ] = { [ 0 . . . ( SNDRV_CARDS - 1 ) ] = - 1 } ;
2008-06-10 19:53:35 +04:00
static int bdl_pos_adj [ SNDRV_CARDS ] = { [ 0 . . . ( SNDRV_CARDS - 1 ) ] = - 1 } ;
2008-01-07 17:16:37 +03:00
static int probe_mask [ SNDRV_CARDS ] = { [ 0 . . . ( SNDRV_CARDS - 1 ) ] = - 1 } ;
2008-12-19 17:19:11 +03:00
static int probe_only [ SNDRV_CARDS ] ;
2012-10-09 17:04:21 +04:00
static int jackpoll_ms [ SNDRV_CARDS ] ;
2011-12-15 07:19:36 +04:00
static bool single_cmd ;
2009-09-28 15:14:04 +04:00
static int enable_msi = - 1 ;
2009-06-17 11:52:54 +04:00
# ifdef CONFIG_SND_HDA_PATCH_LOADER
static char * patch [ SNDRV_CARDS ] ;
# endif
2009-11-13 20:41:52 +03:00
# ifdef CONFIG_SND_HDA_INPUT_BEEP
2012-07-03 18:58:48 +04:00
static bool beep_mode [ SNDRV_CARDS ] = { [ 0 . . . ( SNDRV_CARDS - 1 ) ] =
2009-11-13 20:41:52 +03:00
CONFIG_SND_HDA_INPUT_BEEP_MODE } ;
# endif
2005-04-17 02:20:36 +04:00
2008-01-07 17:16:37 +03:00
module_param_array ( index , int , NULL , 0444 ) ;
2005-04-17 02:20:36 +04:00
MODULE_PARM_DESC ( index , " Index value for Intel HD audio interface. " ) ;
2008-01-07 17:16:37 +03:00
module_param_array ( id , charp , NULL , 0444 ) ;
2005-04-17 02:20:36 +04:00
MODULE_PARM_DESC ( id , " ID string for Intel HD audio interface. " ) ;
2008-01-07 17:16:37 +03:00
module_param_array ( enable , bool , NULL , 0444 ) ;
MODULE_PARM_DESC ( enable , " Enable Intel HD audio interface. " ) ;
module_param_array ( model , charp , NULL , 0444 ) ;
2005-04-17 02:20:36 +04:00
MODULE_PARM_DESC ( model , " Use the given board model. " ) ;
2008-01-07 17:16:37 +03:00
module_param_array ( position_fix , int , NULL , 0444 ) ;
2010-09-30 12:12:50 +04:00
MODULE_PARM_DESC ( position_fix , " DMA pointer read method. "
2012-09-13 16:59:47 +04:00
" (-1 = system default, 0 = auto, 1 = LPIB, 2 = POSBUF, 3 = VIACOMBO, 4 = COMBO). " ) ;
2008-06-10 19:53:34 +04:00
module_param_array ( bdl_pos_adj , int , NULL , 0644 ) ;
MODULE_PARM_DESC ( bdl_pos_adj , " BDL position adjustment offset. " ) ;
2008-01-07 17:16:37 +03:00
module_param_array ( probe_mask , int , NULL , 0444 ) ;
2005-11-24 18:03:40 +03:00
MODULE_PARM_DESC ( probe_mask , " Bitmask to probe codecs (default = -1). " ) ;
2010-03-26 13:16:59 +03:00
module_param_array ( probe_only , int , NULL , 0444 ) ;
2008-12-19 17:19:11 +03:00
MODULE_PARM_DESC ( probe_only , " Only probing and no codec initialization. " ) ;
2012-10-09 17:04:21 +04:00
module_param_array ( jackpoll_ms , int , NULL , 0444 ) ;
MODULE_PARM_DESC ( jackpoll_ms , " Ms between polling for jack events (default = 0, using unsol events only) " ) ;
2006-01-12 20:28:44 +03:00
module_param ( single_cmd , bool , 0444 ) ;
2007-07-27 18:52:19 +04:00
MODULE_PARM_DESC ( single_cmd , " Use single command to communicate with codecs "
" (for debugging only). " ) ;
2012-01-20 15:08:44 +04:00
module_param ( enable_msi , bint , 0444 ) ;
2006-11-10 14:08:37 +03:00
MODULE_PARM_DESC ( enable_msi , " Enable Message Signaled Interrupt (MSI) " ) ;
2009-06-17 11:52:54 +04:00
# ifdef CONFIG_SND_HDA_PATCH_LOADER
module_param_array ( patch , charp , NULL , 0444 ) ;
MODULE_PARM_DESC ( patch , " Patch file for Intel HD audio interface. " ) ;
# endif
2009-11-13 20:41:52 +03:00
# ifdef CONFIG_SND_HDA_INPUT_BEEP
2012-07-03 18:58:48 +04:00
module_param_array ( beep_mode , bool , NULL , 0444 ) ;
2009-11-13 20:41:52 +03:00
MODULE_PARM_DESC ( beep_mode , " Select HDA Beep registration mode "
2012-07-03 18:58:48 +04:00
" (0=off, 1=on) (default=1). " ) ;
2009-11-13 20:41:52 +03:00
# endif
2005-11-24 18:03:40 +03:00
2012-08-24 20:38:08 +04:00
# ifdef CONFIG_PM
2012-08-14 19:13:32 +04:00
static int param_set_xint ( const char * val , const struct kernel_param * kp ) ;
2015-05-27 04:39:38 +03:00
static const struct kernel_param_ops param_ops_xint = {
2012-08-14 19:13:32 +04:00
. set = param_set_xint ,
. get = param_get_int ,
} ;
# define param_check_xint param_check_int
2008-11-27 14:43:28 +03:00
static int power_save = CONFIG_SND_HDA_POWER_SAVE_DEFAULT ;
2012-08-14 19:13:32 +04:00
module_param ( power_save , xint , 0644 ) ;
2008-11-27 14:43:28 +03:00
MODULE_PARM_DESC ( power_save , " Automatic power-saving timeout "
" (in second, 0 = disable). " ) ;
2005-04-17 02:20:36 +04:00
2007-08-13 18:10:30 +04:00
/* reset the HD-audio controller in power save mode.
* this may give more power - saving , but will take longer time to
* wake up .
*/
2013-04-04 17:35:24 +04:00
static bool power_save_controller = 1 ;
module_param ( power_save_controller , bool , 0644 ) ;
2007-08-13 18:10:30 +04:00
MODULE_PARM_DESC ( power_save_controller , " Reset controller in power save mode. " ) ;
2014-03-01 03:41:19 +04:00
# else
2015-02-20 11:26:04 +03:00
# define power_save 0
2012-08-24 20:38:08 +04:00
# endif /* CONFIG_PM */
2007-08-13 18:10:30 +04:00
2012-01-23 20:53:39 +04:00
static int align_buffer_size = - 1 ;
module_param ( align_buffer_size , bint , 0644 ) ;
2011-08-04 19:12:56 +04:00
MODULE_PARM_DESC ( align_buffer_size ,
" Force buffer and period sizes to be multiple of 128 bytes. " ) ;
2011-09-28 19:16:09 +04:00
# ifdef CONFIG_X86
2014-11-25 14:54:16 +03:00
static int hda_snoop = - 1 ;
module_param_named ( snoop , hda_snoop , bint , 0444 ) ;
2011-09-28 19:16:09 +04:00
MODULE_PARM_DESC ( snoop , " Enable/disable snooping " ) ;
# else
# define hda_snoop true
# endif
2005-04-17 02:20:36 +04:00
MODULE_LICENSE ( " GPL " ) ;
MODULE_SUPPORTED_DEVICE ( " {{Intel, ICH6}, "
" {Intel, ICH6M}, "
2005-05-01 19:58:50 +04:00
" {Intel, ICH7}, "
2005-05-12 16:55:20 +04:00
" {Intel, ESB2}, "
2006-01-10 13:07:37 +03:00
" {Intel, ICH8}, "
2006-11-22 13:53:52 +03:00
" {Intel, ICH9}, "
2008-01-29 14:38:49 +03:00
" {Intel, ICH10}, "
2008-08-09 02:56:39 +04:00
" {Intel, PCH}, "
2010-01-13 04:03:35 +03:00
" {Intel, CPT}, "
2011-04-20 21:59:57 +04:00
" {Intel, PPT}, "
2012-01-24 04:24:31 +04:00
" {Intel, LPT}, "
2012-08-09 20:38:59 +04:00
" {Intel, LPT_LP}, "
2013-11-04 21:27:45 +04:00
" {Intel, WPT_LP}, "
2014-10-14 02:22:03 +04:00
" {Intel, SPT}, "
2014-11-08 02:02:47 +03:00
" {Intel, SPT_LP}, "
2012-06-13 06:23:51 +04:00
" {Intel, HPT}, "
2010-09-11 03:29:56 +04:00
" {Intel, PBG}, "
2008-01-30 10:13:55 +03:00
" {Intel, SCH}, "
2005-05-12 17:00:41 +04:00
" {ATI, SB450}, "
2006-03-31 14:33:59 +04:00
" {ATI, SB600}, "
2006-05-17 13:22:21 +04:00
" {ATI, RS600}, "
2006-10-16 14:49:47 +04:00
" {ATI, RS690}, "
2007-04-27 14:20:57 +04:00
" {ATI, RS780}, "
" {ATI, R600}, "
2007-11-05 20:21:56 +03:00
" {ATI, RV630}, "
" {ATI, RV610}, "
2007-11-16 13:06:30 +03:00
" {ATI, RV670}, "
" {ATI, RV635}, "
" {ATI, RV620}, "
" {ATI, RV770}, "
2005-05-12 17:00:41 +04:00
" {VIA, VT8251}, "
2005-08-12 18:44:04 +04:00
" {VIA, VT8237A}, "
2005-08-24 16:14:57 +04:00
" {SiS, SIS966}, "
" {ULI, M5461}} " ) ;
2005-04-17 02:20:36 +04:00
MODULE_DESCRIPTION ( " Intel HDA driver " ) ;
2012-04-26 14:23:42 +04:00
# if defined(CONFIG_PM) && defined(CONFIG_VGA_SWITCHEROO)
2014-02-06 21:14:03 +04:00
# if IS_ENABLED(CONFIG_SND_HDA_CODEC_HDMI)
2012-04-26 14:23:42 +04:00
# define SUPPORT_VGA_SWITCHEROO
# endif
# endif
2005-04-17 02:20:36 +04:00
/*
*/
2005-08-24 16:14:57 +04:00
/* driver types */
enum {
AZX_DRIVER_ICH ,
2010-02-23 04:31:09 +03:00
AZX_DRIVER_PCH ,
2008-01-30 10:13:55 +03:00
AZX_DRIVER_SCH ,
2013-11-05 20:54:05 +04:00
AZX_DRIVER_HDMI ,
2005-08-24 16:14:57 +04:00
AZX_DRIVER_ATI ,
2006-05-17 13:22:21 +04:00
AZX_DRIVER_ATIHDMI ,
2011-12-14 12:10:27 +04:00
AZX_DRIVER_ATIHDMI_NS ,
2005-08-24 16:14:57 +04:00
AZX_DRIVER_VIA ,
AZX_DRIVER_SIS ,
AZX_DRIVER_ULI ,
2005-09-13 20:49:12 +04:00
AZX_DRIVER_NVIDIA ,
2008-05-27 13:44:55 +04:00
AZX_DRIVER_TERA ,
2010-10-21 11:03:25 +04:00
AZX_DRIVER_CTX ,
2012-05-08 12:34:08 +04:00
AZX_DRIVER_CTHDA ,
2014-08-06 16:27:42 +04:00
AZX_DRIVER_CMEDIA ,
2008-11-13 13:07:07 +03:00
AZX_DRIVER_GENERIC ,
2008-09-03 18:00:44 +04:00
AZX_NUM_DRIVERS , /* keep this as last entry */
2005-08-24 16:14:57 +04:00
} ;
2014-11-25 13:28:07 +03:00
# define azx_get_snoop_type(chip) \
( ( ( chip ) - > driver_caps & AZX_DCAPS_SNOOP_MASK ) > > 10 )
# define AZX_DCAPS_SNOOP_TYPE(type) ((AZX_SNOOP_TYPE_ ## type) << 10)
2014-12-03 11:47:20 +03:00
/* quirks for old Intel chipsets */
# define AZX_DCAPS_INTEL_ICH \
2014-12-03 11:56:20 +03:00
( AZX_DCAPS_OLD_SSYNC | AZX_DCAPS_NO_ALIGN_BUFSIZE )
2014-12-03 11:47:20 +03:00
2012-11-19 23:03:37 +04:00
/* quirks for Intel PCH */
2013-01-08 16:51:30 +04:00
# define AZX_DCAPS_INTEL_PCH_NOPM \
2014-12-03 11:56:20 +03:00
( AZX_DCAPS_NO_ALIGN_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY | \
2014-11-25 13:28:07 +03:00
AZX_DCAPS_REVERSE_ASSIGN | AZX_DCAPS_SNOOP_TYPE ( SCH ) )
2013-01-08 16:51:30 +04:00
# define AZX_DCAPS_INTEL_PCH \
( AZX_DCAPS_INTEL_PCH_NOPM | AZX_DCAPS_PM_RUNTIME )
2011-05-25 11:11:37 +04:00
2013-11-05 20:34:46 +04:00
# define AZX_DCAPS_INTEL_HASWELL \
2014-12-03 11:56:20 +03:00
( /*AZX_DCAPS_ALIGN_BUFSIZE |*/ AZX_DCAPS_COUNT_LPIB_DELAY | \
2014-11-25 13:28:07 +03:00
AZX_DCAPS_PM_RUNTIME | AZX_DCAPS_I915_POWERWELL | \
AZX_DCAPS_SNOOP_TYPE ( SCH ) )
2013-11-05 20:34:46 +04:00
2014-06-09 11:28:59 +04:00
/* Broadwell HDMI can't use position buffer reliably, force to use LPIB */
# define AZX_DCAPS_INTEL_BROADWELL \
2014-12-03 11:56:20 +03:00
( /*AZX_DCAPS_ALIGN_BUFSIZE |*/ AZX_DCAPS_POSFIX_LPIB | \
2014-11-25 13:28:07 +03:00
AZX_DCAPS_PM_RUNTIME | AZX_DCAPS_I915_POWERWELL | \
AZX_DCAPS_SNOOP_TYPE ( SCH ) )
2014-06-09 11:28:59 +04:00
2015-04-21 08:12:23 +03:00
# define AZX_DCAPS_INTEL_BAYTRAIL \
( AZX_DCAPS_INTEL_PCH_NOPM | AZX_DCAPS_I915_POWERWELL )
2015-04-07 15:32:20 +03:00
# define AZX_DCAPS_INTEL_BRASWELL \
( AZX_DCAPS_INTEL_PCH | AZX_DCAPS_I915_POWERWELL )
2014-12-19 03:44:31 +03:00
# define AZX_DCAPS_INTEL_SKYLAKE \
2015-04-07 15:32:20 +03:00
( AZX_DCAPS_INTEL_PCH | AZX_DCAPS_SEPARATE_STREAM_TAG | \
AZX_DCAPS_I915_POWERWELL )
2014-12-19 03:44:31 +03:00
2015-11-19 18:25:12 +03:00
# define AZX_DCAPS_INTEL_BROXTON \
( AZX_DCAPS_INTEL_PCH | AZX_DCAPS_SEPARATE_STREAM_TAG | \
AZX_DCAPS_I915_POWERWELL )
2011-05-25 11:11:37 +04:00
/* quirks for ATI SB / AMD Hudson */
# define AZX_DCAPS_PRESET_ATI_SB \
2014-11-25 13:28:07 +03:00
( AZX_DCAPS_NO_TCSEL | AZX_DCAPS_SYNC_WRITE | AZX_DCAPS_POSFIX_LPIB | \
AZX_DCAPS_SNOOP_TYPE ( ATI ) )
2011-05-25 11:11:37 +04:00
/* quirks for ATI/AMD HDMI */
# define AZX_DCAPS_PRESET_ATI_HDMI \
2014-11-24 06:17:08 +03:00
( AZX_DCAPS_NO_TCSEL | AZX_DCAPS_SYNC_WRITE | AZX_DCAPS_POSFIX_LPIB | \
AZX_DCAPS_NO_MSI64 )
2011-05-25 11:11:37 +04:00
2014-11-25 13:28:07 +03:00
/* quirks for ATI HDMI with snoop off */
# define AZX_DCAPS_PRESET_ATI_HDMI_NS \
( AZX_DCAPS_PRESET_ATI_HDMI | AZX_DCAPS_SNOOP_OFF )
2011-05-25 11:11:37 +04:00
/* quirks for Nvidia */
# define AZX_DCAPS_PRESET_NVIDIA \
2014-12-03 11:56:20 +03:00
( AZX_DCAPS_RIRB_DELAY | AZX_DCAPS_NO_MSI | /*AZX_DCAPS_ALIGN_BUFSIZE |*/ \
2014-11-25 13:28:07 +03:00
AZX_DCAPS_NO_64BIT | AZX_DCAPS_CORBRP_SELF_CLEAR | \
AZX_DCAPS_SNOOP_TYPE ( NVIDIA ) )
2011-05-25 11:11:37 +04:00
2012-05-08 12:34:08 +04:00
# define AZX_DCAPS_PRESET_CTHDA \
2014-11-25 13:28:07 +03:00
( AZX_DCAPS_NO_MSI | AZX_DCAPS_POSFIX_LPIB | \
2015-10-27 16:21:51 +03:00
AZX_DCAPS_NO_64BIT | \
2014-11-25 13:28:07 +03:00
AZX_DCAPS_4K_BDLE_BOUNDARY | AZX_DCAPS_SNOOP_OFF )
2012-05-08 12:34:08 +04:00
2012-04-26 14:23:42 +04:00
/*
2015-09-04 21:49:36 +03:00
* vga_switcheroo support
2012-04-26 14:23:42 +04:00
*/
# ifdef SUPPORT_VGA_SWITCHEROO
2012-08-09 15:49:23 +04:00
# define use_vga_switcheroo(chip) ((chip)->use_vga_switcheroo)
# else
# define use_vga_switcheroo(chip) 0
# endif
2015-06-03 04:30:15 +03:00
# define CONTROLLER_IN_GPU(pci) (((pci)->device == 0x0a0c) || \
( ( pci ) - > device = = 0x0c0c ) | | \
( ( pci ) - > device = = 0x0d0c ) | | \
( ( pci ) - > device = = 0x160c ) )
2012-12-07 10:40:35 +04:00
static char * driver_short_names [ ] = {
2005-08-24 16:14:57 +04:00
[ AZX_DRIVER_ICH ] = " HDA Intel " ,
2010-02-23 04:31:09 +03:00
[ AZX_DRIVER_PCH ] = " HDA Intel PCH " ,
2008-01-30 10:13:55 +03:00
[ AZX_DRIVER_SCH ] = " HDA Intel MID " ,
2013-11-05 20:54:05 +04:00
[ AZX_DRIVER_HDMI ] = " HDA Intel HDMI " ,
2005-08-24 16:14:57 +04:00
[ AZX_DRIVER_ATI ] = " HDA ATI SB " ,
2006-05-17 13:22:21 +04:00
[ AZX_DRIVER_ATIHDMI ] = " HDA ATI HDMI " ,
2011-12-14 12:10:27 +04:00
[ AZX_DRIVER_ATIHDMI_NS ] = " HDA ATI HDMI " ,
2005-08-24 16:14:57 +04:00
[ AZX_DRIVER_VIA ] = " HDA VIA VT82xx " ,
[ AZX_DRIVER_SIS ] = " HDA SIS966 " ,
2005-09-13 20:49:12 +04:00
[ AZX_DRIVER_ULI ] = " HDA ULI M5461 " ,
[ AZX_DRIVER_NVIDIA ] = " HDA NVidia " ,
2008-05-27 13:44:55 +04:00
[ AZX_DRIVER_TERA ] = " HDA Teradici " ,
2010-10-21 11:03:25 +04:00
[ AZX_DRIVER_CTX ] = " HDA Creative " ,
2012-05-08 12:34:08 +04:00
[ AZX_DRIVER_CTHDA ] = " HDA Creative " ,
2014-08-06 16:27:42 +04:00
[ AZX_DRIVER_CMEDIA ] = " HDA C-Media " ,
2008-11-13 13:07:07 +03:00
[ AZX_DRIVER_GENERIC ] = " HD-Audio Generic " ,
2005-08-24 16:14:57 +04:00
} ;
2011-09-28 19:16:09 +04:00
# ifdef CONFIG_X86
2013-01-29 21:07:22 +04:00
static void __mark_pages_wc ( struct azx * chip , struct snd_dma_buffer * dmab , bool on )
2011-09-28 19:16:09 +04:00
{
2013-01-29 21:07:22 +04:00
int pages ;
2011-09-28 19:16:09 +04:00
if ( azx_snoop ( chip ) )
return ;
2013-01-29 21:07:22 +04:00
if ( ! dmab | | ! dmab - > area | | ! dmab - > bytes )
return ;
# ifdef CONFIG_SND_DMA_SGBUF
if ( dmab - > dev . type = = SNDRV_DMA_TYPE_DEV_SG ) {
struct snd_sg_buf * sgbuf = dmab - > private_data ;
2014-10-29 18:13:05 +03:00
if ( chip - > driver_type = = AZX_DRIVER_CMEDIA )
return ; /* deal with only CORB/RIRB buffers */
2011-09-28 19:16:09 +04:00
if ( on )
2013-01-29 21:07:22 +04:00
set_pages_array_wc ( sgbuf - > page_table , sgbuf - > pages ) ;
2011-09-28 19:16:09 +04:00
else
2013-01-29 21:07:22 +04:00
set_pages_array_wb ( sgbuf - > page_table , sgbuf - > pages ) ;
return ;
2011-09-28 19:16:09 +04:00
}
2013-01-29 21:07:22 +04:00
# endif
pages = ( dmab - > bytes + PAGE_SIZE - 1 ) > > PAGE_SHIFT ;
if ( on )
set_memory_wc ( ( unsigned long ) dmab - > area , pages ) ;
else
set_memory_wb ( ( unsigned long ) dmab - > area , pages ) ;
2011-09-28 19:16:09 +04:00
}
static inline void mark_pages_wc ( struct azx * chip , struct snd_dma_buffer * buf ,
bool on )
{
2013-01-29 21:07:22 +04:00
__mark_pages_wc ( chip , buf , on ) ;
2011-09-28 19:16:09 +04:00
}
static inline void mark_runtime_wc ( struct azx * chip , struct azx_dev * azx_dev ,
2013-01-29 21:07:22 +04:00
struct snd_pcm_substream * substream , bool on )
2011-09-28 19:16:09 +04:00
{
if ( azx_dev - > wc_marked ! = on ) {
2013-01-29 21:07:22 +04:00
__mark_pages_wc ( chip , snd_pcm_get_dma_buf ( substream ) , on ) ;
2011-09-28 19:16:09 +04:00
azx_dev - > wc_marked = on ;
}
}
# else
/* NOP for other archs */
static inline void mark_pages_wc ( struct azx * chip , struct snd_dma_buffer * buf ,
bool on )
{
}
static inline void mark_runtime_wc ( struct azx * chip , struct azx_dev * azx_dev ,
2013-01-29 21:07:22 +04:00
struct snd_pcm_substream * substream , bool on )
2011-09-28 19:16:09 +04:00
{
}
# endif
2006-10-23 15:40:59 +04:00
static int azx_acquire_irq ( struct azx * chip , int do_disconnect ) ;
2006-02-16 20:17:58 +03:00
2007-08-10 19:21:45 +04:00
/*
* initialize the PCI registers
*/
/* update bits in a PCI register byte */
static void update_pci_byte ( struct pci_dev * pci , unsigned int reg ,
unsigned char mask , unsigned char val )
{
unsigned char data ;
pci_read_config_byte ( pci , reg , & data ) ;
data & = ~ mask ;
data | = ( val & mask ) ;
pci_write_config_byte ( pci , reg , data ) ;
}
static void azx_init_pci ( struct azx * chip )
{
2014-11-25 13:28:07 +03:00
int snoop_type = azx_get_snoop_type ( chip ) ;
2007-08-10 19:21:45 +04:00
/* Clear bits 0-2 of PCI register TCSEL (at offset 0x44)
* TCSEL = = Traffic Class Select Register , which sets PCI express QOS
* Ensuring these bits are 0 clears playback static on some HD Audio
2011-03-10 19:41:56 +03:00
* codecs .
* The PCI register TCSEL is defined in the Intel manuals .
2007-08-10 19:21:45 +04:00
*/
2011-05-28 06:45:28 +04:00
if ( ! ( chip - > driver_caps & AZX_DCAPS_NO_TCSEL ) ) {
2014-02-25 15:21:03 +04:00
dev_dbg ( chip - > card - > dev , " Clearing TCSEL \n " ) ;
2014-06-26 19:54:37 +04:00
update_pci_byte ( chip - > pci , AZX_PCIREG_TCSEL , 0x07 , 0 ) ;
2011-05-25 11:11:37 +04:00
}
2007-08-10 19:21:45 +04:00
2011-05-25 11:11:37 +04:00
/* For ATI SB450/600/700/800/900 and AMD Hudson azalia HD audio,
* we need to enable snoop .
*/
2014-11-25 13:28:07 +03:00
if ( snoop_type = = AZX_SNOOP_TYPE_ATI ) {
2014-02-25 15:21:03 +04:00
dev_dbg ( chip - > card - > dev , " Setting ATI snoop: %d \n " ,
azx_snoop ( chip ) ) ;
2007-08-10 19:21:45 +04:00
update_pci_byte ( chip - > pci ,
2011-09-28 19:16:09 +04:00
ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR , 0x07 ,
azx_snoop ( chip ) ? ATI_SB450_HDAUDIO_ENABLE_SNOOP : 0 ) ;
2011-05-25 11:11:37 +04:00
}
/* For NVIDIA HDA, enable snoop */
2014-11-25 13:28:07 +03:00
if ( snoop_type = = AZX_SNOOP_TYPE_NVIDIA ) {
2014-02-25 15:21:03 +04:00
dev_dbg ( chip - > card - > dev , " Setting Nvidia snoop: %d \n " ,
azx_snoop ( chip ) ) ;
2007-08-10 19:21:45 +04:00
update_pci_byte ( chip - > pci ,
NVIDIA_HDA_TRANSREG_ADDR ,
0x0f , NVIDIA_HDA_ENABLE_COHBITS ) ;
2008-08-21 03:43:24 +04:00
update_pci_byte ( chip - > pci ,
NVIDIA_HDA_ISTRM_COH ,
0x01 , NVIDIA_HDA_ENABLE_COHBIT ) ;
update_pci_byte ( chip - > pci ,
NVIDIA_HDA_OSTRM_COH ,
0x01 , NVIDIA_HDA_ENABLE_COHBIT ) ;
2011-05-25 11:11:37 +04:00
}
/* Enable SCH/PCH snoop if needed */
2014-11-25 13:28:07 +03:00
if ( snoop_type = = AZX_SNOOP_TYPE_SCH ) {
2011-09-28 19:16:09 +04:00
unsigned short snoop ;
2008-02-22 20:36:22 +03:00
pci_read_config_word ( chip - > pci , INTEL_SCH_HDA_DEVC , & snoop ) ;
2011-09-28 19:16:09 +04:00
if ( ( ! azx_snoop ( chip ) & & ! ( snoop & INTEL_SCH_HDA_DEVC_NOSNOOP ) ) | |
( azx_snoop ( chip ) & & ( snoop & INTEL_SCH_HDA_DEVC_NOSNOOP ) ) ) {
snoop & = ~ INTEL_SCH_HDA_DEVC_NOSNOOP ;
if ( ! azx_snoop ( chip ) )
snoop | = INTEL_SCH_HDA_DEVC_NOSNOOP ;
pci_write_config_word ( chip - > pci , INTEL_SCH_HDA_DEVC , snoop ) ;
2008-02-22 20:36:22 +03:00
pci_read_config_word ( chip - > pci ,
INTEL_SCH_HDA_DEVC , & snoop ) ;
}
2014-02-25 15:21:03 +04:00
dev_dbg ( chip - > card - > dev , " SCH snoop: %s \n " ,
( snoop & INTEL_SCH_HDA_DEVC_NOSNOOP ) ?
" Disabled " : " Enabled " ) ;
2005-09-13 20:49:12 +04:00
}
2005-04-17 02:20:36 +04:00
}
2015-05-05 04:05:48 +03:00
static void hda_intel_init_chip ( struct azx * chip , bool full_reset )
{
2015-05-19 17:29:30 +03:00
struct hdac_bus * bus = azx_bus ( chip ) ;
2015-05-05 04:05:48 +03:00
if ( chip - > driver_caps & AZX_DCAPS_I915_POWERWELL )
2015-05-19 17:29:30 +03:00
snd_hdac_set_codec_wakeup ( bus , true ) ;
2015-05-05 04:05:48 +03:00
azx_init_chip ( chip , full_reset ) ;
if ( chip - > driver_caps & AZX_DCAPS_I915_POWERWELL )
2015-05-19 17:29:30 +03:00
snd_hdac_set_codec_wakeup ( bus , false ) ;
2015-05-05 04:05:48 +03:00
}
2014-06-26 18:50:16 +04:00
/* calculate runtime delay from LPIB */
static int azx_get_delay_from_lpib ( struct azx * chip , struct azx_dev * azx_dev ,
unsigned int pos )
{
2015-04-14 19:13:13 +03:00
struct snd_pcm_substream * substream = azx_dev - > core . substream ;
2014-06-26 18:50:16 +04:00
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 ) {
2015-04-14 19:13:13 +03:00
if ( delay > = azx_dev - > core . delay_negative_threshold )
2014-06-26 18:50:16 +04:00
delay = 0 ;
else
2015-04-14 19:13:13 +03:00
delay + = azx_dev - > core . bufsize ;
2014-06-26 18:50:16 +04:00
}
2015-04-14 19:13:13 +03:00
if ( delay > = azx_dev - > core . period_bytes ) {
2014-06-26 18:50:16 +04:00
dev_info ( chip - > card - > dev ,
" Unstable LPIB (%d >= %d); disabling LPIB delay counting \n " ,
2015-04-14 19:13:13 +03:00
delay , azx_dev - > core . period_bytes ) ;
2014-06-26 18:50:16 +04:00
delay = 0 ;
chip - > driver_caps & = ~ AZX_DCAPS_COUNT_LPIB_DELAY ;
chip - > get_delay [ stream ] = NULL ;
}
return bytes_to_frames ( substream - > runtime , delay ) ;
}
2008-05-16 14:34:47 +04:00
static int azx_position_ok ( struct azx * chip , struct azx_dev * azx_dev ) ;
2014-03-01 03:41:28 +04:00
/* called from IRQ */
static int azx_position_check ( struct azx * chip , struct azx_dev * azx_dev )
{
2014-06-26 19:19:20 +04:00
struct hda_intel * hda = container_of ( chip , struct hda_intel , chip ) ;
2014-03-01 03:41:28 +04:00
int ok ;
ok = azx_position_ok ( chip , azx_dev ) ;
if ( ok = = 1 ) {
azx_dev - > irq_pending = 0 ;
return ok ;
2015-02-28 00:43:26 +03:00
} else if ( ok = = 0 ) {
2014-03-01 03:41:28 +04:00
/* bogus IRQ, process it later */
azx_dev - > irq_pending = 1 ;
2015-02-28 00:43:26 +03:00
schedule_work ( & hda - > irq_pending_work ) ;
2014-03-01 03:41:28 +04:00
}
return 0 ;
}
2015-04-29 12:43:29 +03:00
/* Enable/disable i915 display power for the link */
static int azx_intel_link_power ( struct azx * chip , bool enable )
{
2015-05-19 17:29:30 +03:00
struct hdac_bus * bus = azx_bus ( chip ) ;
2015-04-29 12:43:29 +03:00
2015-05-19 17:29:30 +03:00
return snd_hdac_display_power ( bus , enable ) ;
2015-04-29 12:43:29 +03:00
}
2008-05-16 14:34:47 +04:00
/*
* Check whether the current DMA position is acceptable for updating
* periods . Returns non - zero if it ' s OK .
*
* Many HD - audio controllers appear pretty inaccurate about
* the update - IRQ timing . The IRQ is issued before actually the
* data is processed . So , we need to process it afterwords in a
* workqueue .
*/
static int azx_position_ok ( struct azx * chip , struct azx_dev * azx_dev )
{
2015-04-14 19:13:13 +03:00
struct snd_pcm_substream * substream = azx_dev - > core . substream ;
2014-06-26 18:50:16 +04:00
int stream = substream - > stream ;
2010-05-11 12:21:46 +04:00
u32 wallclk ;
2008-05-16 14:34:47 +04:00
unsigned int pos ;
2015-04-14 19:13:13 +03:00
wallclk = azx_readl ( chip , WALLCLK ) - azx_dev - > core . start_wallclk ;
if ( wallclk < ( azx_dev - > core . period_wallclk * 2 ) / 3 )
2009-04-10 14:20:45 +04:00
return - 1 ; /* bogus (too early) interrupt */
2014-06-26 18:50:16 +04:00
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 ;
2015-04-14 23:06:53 +03:00
if ( chip - > get_position [ 0 ] = = azx_get_pos_lpib & &
chip - > get_position [ 1 ] = = azx_get_pos_lpib )
azx_bus ( chip ) - > use_posbuf = false ;
2014-06-26 18:50:16 +04:00
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 ;
}
}
2015-04-14 19:13:13 +03:00
if ( pos > = azx_dev - > core . bufsize )
2014-06-26 18:50:16 +04:00
pos = 0 ;
2008-05-16 14:34:47 +04:00
2015-04-14 19:13:13 +03:00
if ( WARN_ONCE ( ! azx_dev - > core . period_bytes ,
2010-02-12 20:17:06 +03:00
" hda-intel: zero azx_dev->period_bytes " ) )
2010-05-11 14:10:47 +04:00
return - 1 ; /* this shouldn't happen! */
2015-04-14 19:13:13 +03:00
if ( wallclk < ( azx_dev - > core . period_wallclk * 5 ) / 4 & &
pos % azx_dev - > core . period_bytes > azx_dev - > core . period_bytes / 2 )
2010-05-11 14:10:47 +04:00
/* NG - it's below the first next period boundary */
2014-03-01 03:41:14 +04:00
return chip - > bdl_pos_adj [ chip - > dev_index ] ? 0 : - 1 ;
2015-04-14 19:13:13 +03:00
azx_dev - > core . start_wallclk + = wallclk ;
2008-05-16 14:34:47 +04:00
return 1 ; /* OK, it's fine */
}
/*
* The work for pending PCM period updates .
*/
static void azx_irq_pending_work ( struct work_struct * work )
{
2014-06-26 19:19:20 +04:00
struct hda_intel * hda = container_of ( work , struct hda_intel , irq_pending_work ) ;
struct azx * chip = & hda - > chip ;
2015-04-14 19:13:13 +03:00
struct hdac_bus * bus = azx_bus ( chip ) ;
struct hdac_stream * s ;
int pending , ok ;
2008-05-16 14:34:47 +04:00
2014-06-26 19:19:20 +04:00
if ( ! hda - > irq_pending_warned ) {
2014-02-25 15:21:03 +04:00
dev_info ( chip - > card - > dev ,
" IRQ timing workaround is activated for card #%d. Suggest a bigger bdl_pos_adj. \n " ,
chip - > card - > number ) ;
2014-06-26 19:19:20 +04:00
hda - > irq_pending_warned = 1 ;
2008-06-10 19:53:35 +04:00
}
2008-05-16 14:34:47 +04:00
for ( ; ; ) {
pending = 0 ;
2015-04-14 23:13:18 +03:00
spin_lock_irq ( & bus - > reg_lock ) ;
2015-04-14 19:13:13 +03:00
list_for_each_entry ( s , & bus - > stream_list , list ) {
struct azx_dev * azx_dev = stream_to_azx_dev ( s ) ;
2008-05-16 14:34:47 +04:00
if ( ! azx_dev - > irq_pending | |
2015-04-14 19:13:13 +03:00
! s - > substream | |
! s - > running )
2008-05-16 14:34:47 +04:00
continue ;
2010-05-11 12:21:46 +04:00
ok = azx_position_ok ( chip , azx_dev ) ;
if ( ok > 0 ) {
2008-05-16 14:34:47 +04:00
azx_dev - > irq_pending = 0 ;
2015-04-14 23:13:18 +03:00
spin_unlock ( & bus - > reg_lock ) ;
2015-04-14 19:13:13 +03:00
snd_pcm_period_elapsed ( s - > substream ) ;
2015-04-14 23:13:18 +03:00
spin_lock ( & bus - > reg_lock ) ;
2010-05-11 12:21:46 +04:00
} else if ( ok < 0 ) {
pending = 0 ; /* too early */
2008-05-16 14:34:47 +04:00
} else
pending + + ;
}
2015-04-14 23:13:18 +03:00
spin_unlock_irq ( & bus - > reg_lock ) ;
2008-05-16 14:34:47 +04:00
if ( ! pending )
return ;
2010-08-03 16:39:04 +04:00
msleep ( 1 ) ;
2008-05-16 14:34:47 +04:00
}
}
/* clear irq_pending flags and assure no on-going workq */
static void azx_clear_irq_pending ( struct azx * chip )
{
2015-04-14 19:13:13 +03:00
struct hdac_bus * bus = azx_bus ( chip ) ;
struct hdac_stream * s ;
2008-05-16 14:34:47 +04:00
2015-04-14 23:13:18 +03:00
spin_lock_irq ( & bus - > reg_lock ) ;
2015-04-14 19:13:13 +03:00
list_for_each_entry ( s , & bus - > stream_list , list ) {
struct azx_dev * azx_dev = stream_to_azx_dev ( s ) ;
azx_dev - > irq_pending = 0 ;
}
2015-04-14 23:13:18 +03:00
spin_unlock_irq ( & bus - > reg_lock ) ;
2005-04-17 02:20:36 +04:00
}
2006-10-23 15:40:59 +04:00
static int azx_acquire_irq ( struct azx * chip , int do_disconnect )
{
2015-04-14 23:13:18 +03:00
struct hdac_bus * bus = azx_bus ( chip ) ;
2006-11-21 14:14:23 +03:00
if ( request_irq ( chip - > pci - > irq , azx_interrupt ,
chip - > msi ? 0 : IRQF_SHARED ,
2011-06-10 18:36:37 +04:00
KBUILD_MODNAME , chip ) ) {
2014-02-25 15:21:03 +04:00
dev_err ( chip - > card - > dev ,
" unable to grab IRQ %d, disabling device \n " ,
chip - > pci - > irq ) ;
2006-10-23 15:40:59 +04:00
if ( do_disconnect )
snd_card_disconnect ( chip - > card ) ;
return - 1 ;
}
2015-04-14 23:13:18 +03:00
bus - > irq = chip - > pci - > irq ;
2006-11-21 14:10:55 +03:00
pci_intx ( chip - > pci , ! chip - > msi ) ;
2006-10-23 15:40:59 +04:00
return 0 ;
}
2014-06-26 18:50:16 +04:00
/* 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 ;
2015-04-16 13:14:17 +03:00
link_pos = snd_hdac_stream_get_pos_lpib ( azx_stream ( azx_dev ) ) ;
2015-04-14 19:13:13 +03:00
if ( azx_dev - > core . substream - > stream = = SNDRV_PCM_STREAM_PLAYBACK ) {
2014-06-26 18:50:16 +04:00
/* Playback, no problem using link position */
return link_pos ;
}
/* Capture */
/* For new chipset,
* use mod to get the DMA position just like old chipset
*/
2015-04-14 19:13:13 +03:00
mod_dma_pos = le32_to_cpu ( * azx_dev - > core . posbuf ) ;
mod_dma_pos % = azx_dev - > core . period_bytes ;
2014-06-26 18:50:16 +04:00
/* azx_dev->fifo_size can't get FIFO size of in stream.
* Get from base address + offset .
*/
2015-04-14 23:13:18 +03:00
fifo_size = readw ( azx_bus ( chip ) - > remap_addr +
VIA_IN_STREAM0_FIFO_SIZE_OFFSET ) ;
2014-06-26 18:50:16 +04:00
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 )
2015-04-14 19:13:13 +03:00
mini_pos = azx_dev - > core . bufsize + link_pos - fifo_size ;
2014-06-26 18:50:16 +04:00
else
mini_pos = link_pos - fifo_size ;
/* Find nearest previous boudary */
2015-04-14 19:13:13 +03:00
mod_mini_pos = mini_pos % azx_dev - > core . period_bytes ;
mod_link_pos = link_pos % azx_dev - > core . period_bytes ;
2014-06-26 18:50:16 +04:00
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 {
2015-04-14 19:13:13 +03:00
bound_pos = mini_pos - mod_mini_pos + azx_dev - > core . period_bytes ;
if ( bound_pos > = azx_dev - > core . bufsize )
2014-06-26 18:50:16 +04:00
bound_pos = 0 ;
}
/* Calculate real DMA position we want */
return bound_pos + mod_dma_pos ;
}
2012-08-24 20:38:08 +04:00
# ifdef CONFIG_PM
2012-08-14 19:13:32 +04:00
static DEFINE_MUTEX ( card_list_lock ) ;
static LIST_HEAD ( card_list ) ;
static void azx_add_card_list ( struct azx * chip )
{
2014-06-26 19:19:20 +04:00
struct hda_intel * hda = container_of ( chip , struct hda_intel , chip ) ;
2012-08-14 19:13:32 +04:00
mutex_lock ( & card_list_lock ) ;
2014-06-26 19:19:20 +04:00
list_add ( & hda - > list , & card_list ) ;
2012-08-14 19:13:32 +04:00
mutex_unlock ( & card_list_lock ) ;
}
static void azx_del_card_list ( struct azx * chip )
{
2014-06-26 19:19:20 +04:00
struct hda_intel * hda = container_of ( chip , struct hda_intel , chip ) ;
2012-08-14 19:13:32 +04:00
mutex_lock ( & card_list_lock ) ;
2014-06-26 19:19:20 +04:00
list_del_init ( & hda - > list ) ;
2012-08-14 19:13:32 +04:00
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 )
{
2014-06-26 19:19:20 +04:00
struct hda_intel * hda ;
2012-08-14 19:13:32 +04:00
struct azx * chip ;
int prev = power_save ;
int ret = param_set_int ( val , kp ) ;
if ( ret | | prev = = power_save )
return ret ;
mutex_lock ( & card_list_lock ) ;
2014-06-26 19:19:20 +04:00
list_for_each_entry ( hda , & card_list , list ) {
chip = & hda - > chip ;
2015-04-14 23:13:18 +03:00
if ( ! hda - > probe_continued | | chip - > disabled )
2012-08-14 19:13:32 +04:00
continue ;
2015-04-14 23:13:18 +03:00
snd_hda_set_power_save ( & chip - > bus , power_save * 1000 ) ;
2012-08-14 19:13:32 +04:00
}
mutex_unlock ( & card_list_lock ) ;
return 0 ;
}
# else
# define azx_add_card_list(chip) /* NOP */
# define azx_del_card_list(chip) /* NOP */
2012-08-24 20:38:08 +04:00
# endif /* CONFIG_PM */
2008-12-11 13:47:17 +03:00
2015-05-19 17:29:30 +03:00
/* Intel HSW/BDW display HDA controller is in GPU. Both its power and link BCLK
* depends on GPU . Two Extended Mode registers EM4 ( M value ) and EM5 ( N Value )
* are used to convert CDClk ( Core Display Clock ) to 24 MHz BCLK :
* BCLK = CDCLK * M / N
* The values will be lost when the display power well is disabled and need to
* be restored to avoid abnormal playback speed .
*/
static void haswell_set_bclk ( struct hda_intel * hda )
{
struct azx * chip = & hda - > chip ;
int cdclk_freq ;
unsigned int bclk_m , bclk_n ;
if ( ! hda - > need_i915_power )
return ;
cdclk_freq = snd_hdac_get_display_clk ( azx_bus ( chip ) ) ;
switch ( cdclk_freq ) {
case 337500 :
bclk_m = 16 ;
bclk_n = 225 ;
break ;
case 450000 :
default : /* default CDCLK 450MHz */
bclk_m = 4 ;
bclk_n = 75 ;
break ;
case 540000 :
bclk_m = 4 ;
bclk_n = 90 ;
break ;
case 675000 :
bclk_m = 8 ;
bclk_n = 225 ;
break ;
}
azx_writew ( chip , HSW_EM4 , bclk_m ) ;
azx_writew ( chip , HSW_EM5 , bclk_n ) ;
}
2012-08-14 20:10:09 +04:00
# if defined(CONFIG_PM_SLEEP) || defined(SUPPORT_VGA_SWITCHEROO)
2008-12-11 13:47:17 +03:00
/*
* power management
*/
2012-07-02 17:20:37 +04:00
static int azx_suspend ( struct device * dev )
2005-04-17 02:20:36 +04:00
{
2012-07-02 17:20:37 +04:00
struct snd_card * card = dev_get_drvdata ( dev ) ;
2014-07-16 18:31:04 +04:00
struct azx * chip ;
struct hda_intel * hda ;
2015-04-14 23:13:18 +03:00
struct hdac_bus * bus ;
2005-04-17 02:20:36 +04:00
2014-07-16 18:31:04 +04:00
if ( ! card )
return 0 ;
chip = card - > private_data ;
hda = container_of ( chip , struct hda_intel , chip ) ;
2015-07-28 23:29:56 +03:00
if ( chip - > disabled | | hda - > init_failed | | ! chip - > running )
2012-12-04 20:01:25 +04:00
return 0 ;
2015-04-14 23:13:18 +03:00
bus = azx_bus ( chip ) ;
2005-11-17 18:11:09 +03:00
snd_power_change_state ( card , SNDRV_CTL_POWER_D3hot ) ;
2008-05-16 14:34:47 +04:00
azx_clear_irq_pending ( chip ) ;
2007-08-10 19:21:45 +04:00
azx_stop_chip ( chip ) ;
2013-06-25 13:58:49 +04:00
azx_enter_link_reset ( chip ) ;
2015-04-14 23:13:18 +03:00
if ( bus - > irq > = 0 ) {
free_irq ( bus - > irq , chip ) ;
bus - > irq = - 1 ;
2006-10-11 20:52:53 +04:00
}
2014-06-26 14:45:16 +04:00
2006-10-23 15:40:59 +04:00
if ( chip - > msi )
2006-09-08 14:30:03 +04:00
pci_disable_msi ( chip - > pci ) ;
2015-04-29 12:43:36 +03:00
if ( chip - > driver_caps & AZX_DCAPS_I915_POWERWELL
& & hda - > need_i915_power )
2015-05-19 17:29:30 +03:00
snd_hdac_display_power ( bus , false ) ;
2015-05-12 04:43:22 +03:00
trace_azx_suspend ( chip ) ;
2005-04-17 02:20:36 +04:00
return 0 ;
}
2012-07-02 17:20:37 +04:00
static int azx_resume ( struct device * dev )
2005-04-17 02:20:36 +04:00
{
2012-07-02 17:20:37 +04:00
struct pci_dev * pci = to_pci_dev ( dev ) ;
struct snd_card * card = dev_get_drvdata ( dev ) ;
2014-07-16 18:31:04 +04:00
struct azx * chip ;
struct hda_intel * hda ;
if ( ! card )
return 0 ;
2005-04-17 02:20:36 +04:00
2014-07-16 18:31:04 +04:00
chip = card - > private_data ;
hda = container_of ( chip , struct hda_intel , chip ) ;
2015-07-28 23:29:56 +03:00
if ( chip - > disabled | | hda - > init_failed | | ! chip - > running )
2012-12-04 20:01:25 +04:00
return 0 ;
2015-04-29 12:43:36 +03:00
if ( chip - > driver_caps & AZX_DCAPS_I915_POWERWELL
& & hda - > need_i915_power ) {
2015-05-19 17:29:30 +03:00
snd_hdac_display_power ( azx_bus ( chip ) , true ) ;
2015-01-08 18:54:16 +03:00
haswell_set_bclk ( hda ) ;
2014-06-26 14:45:16 +04:00
}
2006-10-23 15:40:59 +04:00
if ( chip - > msi )
if ( pci_enable_msi ( pci ) < 0 )
chip - > msi = 0 ;
if ( azx_acquire_irq ( chip , 1 ) < 0 )
2006-10-11 20:52:53 +04:00
return - EIO ;
2007-08-10 19:21:45 +04:00
azx_init_pci ( chip ) ;
2007-09-03 17:28:04 +04:00
2015-05-05 04:05:48 +03:00
hda_intel_init_chip ( chip , true ) ;
2007-09-03 17:28:04 +04:00
2005-11-17 18:11:09 +03:00
snd_power_change_state ( card , SNDRV_CTL_POWER_D0 ) ;
2015-05-12 04:43:22 +03:00
trace_azx_resume ( chip ) ;
2005-04-17 02:20:36 +04:00
return 0 ;
}
2012-08-23 13:32:30 +04:00
# endif /* CONFIG_PM_SLEEP || SUPPORT_VGA_SWITCHEROO */
2014-12-13 02:42:18 +03:00
# ifdef CONFIG_PM
2012-08-23 13:32:30 +04:00
static int azx_runtime_suspend ( struct device * dev )
{
struct snd_card * card = dev_get_drvdata ( dev ) ;
2014-07-16 18:31:04 +04:00
struct azx * chip ;
struct hda_intel * hda ;
2012-08-23 13:32:30 +04:00
2014-07-16 18:31:04 +04:00
if ( ! card )
return 0 ;
chip = card - > private_data ;
hda = container_of ( chip , struct hda_intel , chip ) ;
2014-07-15 17:27:19 +04:00
if ( chip - > disabled | | hda - > init_failed )
2013-07-29 09:19:29 +04:00
return 0 ;
2015-02-19 18:51:17 +03:00
if ( ! azx_has_pm_runtime ( chip ) )
2013-07-29 09:19:29 +04:00
return 0 ;
2013-07-26 07:34:46 +04:00
/* enable controller wake up event */
azx_writew ( chip , WAKEEN , azx_readw ( chip , WAKEEN ) |
STATESTS_INT_MASK ) ;
2012-08-23 13:32:30 +04:00
azx_stop_chip ( chip ) ;
2013-11-26 14:58:40 +04:00
azx_enter_link_reset ( chip ) ;
2012-08-23 13:32:30 +04:00
azx_clear_irq_pending ( chip ) ;
2015-04-29 12:43:36 +03:00
if ( chip - > driver_caps & AZX_DCAPS_I915_POWERWELL
& & hda - > need_i915_power )
2015-05-19 17:29:30 +03:00
snd_hdac_display_power ( azx_bus ( chip ) , false ) ;
2014-07-03 13:02:23 +04:00
2015-05-12 04:43:22 +03:00
trace_azx_runtime_suspend ( chip ) ;
2012-08-23 13:32:30 +04:00
return 0 ;
}
static int azx_runtime_resume ( struct device * dev )
{
struct snd_card * card = dev_get_drvdata ( dev ) ;
2014-07-16 18:31:04 +04:00
struct azx * chip ;
struct hda_intel * hda ;
2015-05-19 17:29:30 +03:00
struct hdac_bus * bus ;
2013-07-26 07:34:46 +04:00
struct hda_codec * codec ;
int status ;
2012-08-23 13:32:30 +04:00
2014-07-16 18:31:04 +04:00
if ( ! card )
return 0 ;
chip = card - > private_data ;
hda = container_of ( chip , struct hda_intel , chip ) ;
2014-07-15 17:27:19 +04:00
if ( chip - > disabled | | hda - > init_failed )
2013-07-29 09:19:29 +04:00
return 0 ;
2015-02-19 18:51:17 +03:00
if ( ! azx_has_pm_runtime ( chip ) )
2013-07-29 09:19:29 +04:00
return 0 ;
2015-07-16 11:39:24 +03:00
if ( chip - > driver_caps & AZX_DCAPS_I915_POWERWELL ) {
bus = azx_bus ( chip ) ;
if ( hda - > need_i915_power ) {
snd_hdac_display_power ( bus , true ) ;
haswell_set_bclk ( hda ) ;
} else {
/* toggle codec wakeup bit for STATESTS read */
snd_hdac_set_codec_wakeup ( bus , true ) ;
snd_hdac_set_codec_wakeup ( bus , false ) ;
}
2014-06-26 14:45:16 +04:00
}
2013-07-26 07:34:46 +04:00
/* Read STATESTS before controller reset */
status = azx_readw ( chip , STATESTS ) ;
2012-08-23 13:32:30 +04:00
azx_init_pci ( chip ) ;
2015-05-05 04:05:48 +03:00
hda_intel_init_chip ( chip , true ) ;
2013-07-26 07:34:46 +04:00
2015-04-14 23:13:18 +03:00
if ( status ) {
list_for_each_codec ( codec , & chip - > bus )
2013-07-26 07:34:46 +04:00
if ( status & ( 1 < < codec - > addr ) )
2015-02-28 00:43:26 +03:00
schedule_delayed_work ( & codec - > jackpoll_work ,
codec - > jackpoll_interval ) ;
2013-07-26 07:34:46 +04:00
}
/* disable controller Wake Up event*/
azx_writew ( chip , WAKEEN , azx_readw ( chip , WAKEEN ) &
~ STATESTS_INT_MASK ) ;
2015-05-12 04:43:22 +03:00
trace_azx_runtime_resume ( chip ) ;
2012-08-23 13:32:30 +04:00
return 0 ;
}
2012-12-12 14:50:12 +04:00
static int azx_runtime_idle ( struct device * dev )
{
struct snd_card * card = dev_get_drvdata ( dev ) ;
2014-07-16 18:31:04 +04:00
struct azx * chip ;
struct hda_intel * hda ;
if ( ! card )
return 0 ;
2012-12-12 14:50:12 +04:00
2014-07-16 18:31:04 +04:00
chip = card - > private_data ;
hda = container_of ( chip , struct hda_intel , chip ) ;
2014-07-15 17:27:19 +04:00
if ( chip - > disabled | | hda - > init_failed )
2013-07-29 09:19:29 +04:00
return 0 ;
2015-02-19 19:35:32 +03:00
if ( ! power_save_controller | | ! azx_has_pm_runtime ( chip ) | |
2015-07-28 23:29:56 +03:00
azx_bus ( chip ) - > codec_powered | | ! chip - > running )
2012-12-12 14:50:12 +04:00
return - EBUSY ;
return 0 ;
}
2012-08-23 13:32:30 +04:00
static const struct dev_pm_ops azx_pm = {
SET_SYSTEM_SLEEP_PM_OPS ( azx_suspend , azx_resume )
2012-12-12 14:50:12 +04:00
SET_RUNTIME_PM_OPS ( azx_runtime_suspend , azx_runtime_resume , azx_runtime_idle )
2012-08-23 13:32:30 +04:00
} ;
2012-07-02 17:20:37 +04:00
# define AZX_PM_OPS &azx_pm
# else
# define AZX_PM_OPS NULL
2012-08-23 13:32:30 +04:00
# endif /* CONFIG_PM */
2005-04-17 02:20:36 +04:00
2012-12-07 10:40:35 +04:00
static int azx_probe_continue ( struct azx * chip ) ;
2012-04-26 14:23:42 +04:00
2012-06-08 15:06:29 +04:00
# ifdef SUPPORT_VGA_SWITCHEROO
2012-12-06 21:35:10 +04:00
static struct pci_dev * get_bound_vga ( struct pci_dev * pci ) ;
2012-04-26 14:23:42 +04:00
static void azx_vs_set_state ( struct pci_dev * pci ,
enum vga_switcheroo_state state )
{
struct snd_card * card = pci_get_drvdata ( pci ) ;
struct azx * chip = card - > private_data ;
2014-06-26 19:19:20 +04:00
struct hda_intel * hda = container_of ( chip , struct hda_intel , chip ) ;
2012-04-26 14:23:42 +04:00
bool disabled ;
2014-06-26 19:19:20 +04:00
wait_for_completion ( & hda - > probe_wait ) ;
if ( hda - > init_failed )
2012-04-26 14:23:42 +04:00
return ;
disabled = ( state = = VGA_SWITCHEROO_OFF ) ;
if ( chip - > disabled = = disabled )
return ;
2015-04-14 23:13:18 +03:00
if ( ! hda - > probe_continued ) {
2012-04-26 14:23:42 +04:00
chip - > disabled = disabled ;
if ( ! disabled ) {
2014-02-25 15:21:03 +04:00
dev_info ( chip - > card - > dev ,
" Start delayed initialization \n " ) ;
2013-05-30 18:07:09 +04:00
if ( azx_probe_continue ( chip ) < 0 ) {
2014-02-25 15:21:03 +04:00
dev_err ( chip - > card - > dev , " initialization error \n " ) ;
2014-06-26 19:19:20 +04:00
hda - > init_failed = true ;
2012-04-26 14:23:42 +04:00
}
}
} else {
2015-09-04 21:49:36 +03:00
dev_info ( chip - > card - > dev , " %s via vga_switcheroo \n " ,
2014-02-25 15:21:03 +04:00
disabled ? " Disabling " : " Enabling " ) ;
2012-04-26 14:23:42 +04:00
if ( disabled ) {
2014-03-01 03:41:15 +04:00
pm_runtime_put_sync_suspend ( card - > dev ) ;
azx_suspend ( card - > dev ) ;
2015-09-04 21:49:36 +03:00
/* when we get suspended by vga_switcheroo we end up in D3cold,
2013-07-29 09:19:29 +04:00
* however we have no ACPI handle , so pci / acpi can ' t put us there ,
* put ourselves there */
pci - > current_state = PCI_D3cold ;
2012-04-26 14:23:42 +04:00
chip - > disabled = true ;
2015-04-14 23:13:18 +03:00
if ( snd_hda_lock_devices ( & chip - > bus ) )
2014-02-25 15:21:03 +04:00
dev_warn ( chip - > card - > dev ,
" Cannot lock devices! \n " ) ;
2012-04-26 14:23:42 +04:00
} else {
2015-04-14 23:13:18 +03:00
snd_hda_unlock_devices ( & chip - > bus ) ;
2014-03-01 03:41:15 +04:00
pm_runtime_get_noresume ( card - > dev ) ;
2012-04-26 14:23:42 +04:00
chip - > disabled = false ;
2014-03-01 03:41:15 +04:00
azx_resume ( card - > dev ) ;
2012-04-26 14:23:42 +04:00
}
}
}
static bool azx_vs_can_switch ( struct pci_dev * pci )
{
struct snd_card * card = pci_get_drvdata ( pci ) ;
struct azx * chip = card - > private_data ;
2014-06-26 19:19:20 +04:00
struct hda_intel * hda = container_of ( chip , struct hda_intel , chip ) ;
2012-04-26 14:23:42 +04:00
2014-06-26 19:19:20 +04:00
wait_for_completion ( & hda - > probe_wait ) ;
if ( hda - > init_failed )
2012-04-26 14:23:42 +04:00
return false ;
2015-04-14 23:13:18 +03:00
if ( chip - > disabled | | ! hda - > probe_continued )
2012-04-26 14:23:42 +04:00
return true ;
2015-04-14 23:13:18 +03:00
if ( snd_hda_lock_devices ( & chip - > bus ) )
2012-04-26 14:23:42 +04:00
return false ;
2015-04-14 23:13:18 +03:00
snd_hda_unlock_devices ( & chip - > bus ) ;
2012-04-26 14:23:42 +04:00
return true ;
}
2012-12-06 21:35:10 +04:00
static void init_vga_switcheroo ( struct azx * chip )
2012-04-26 14:23:42 +04:00
{
2014-06-26 19:19:20 +04:00
struct hda_intel * hda = container_of ( chip , struct hda_intel , chip ) ;
2012-04-26 14:23:42 +04:00
struct pci_dev * p = get_bound_vga ( chip - > pci ) ;
if ( p ) {
2014-02-25 15:21:03 +04:00
dev_info ( chip - > card - > dev ,
2015-09-04 21:49:36 +03:00
" Handle vga_switcheroo audio client \n " ) ;
2014-06-26 19:19:20 +04:00
hda - > use_vga_switcheroo = 1 ;
2012-04-26 14:23:42 +04:00
pci_dev_put ( p ) ;
}
}
static const struct vga_switcheroo_client_ops azx_vs_ops = {
. set_gpu_state = azx_vs_set_state ,
. can_switch = azx_vs_can_switch ,
} ;
2012-12-06 21:35:10 +04:00
static int register_vga_switcheroo ( struct azx * chip )
2012-04-26 14:23:42 +04:00
{
2014-06-26 19:19:20 +04:00
struct hda_intel * hda = container_of ( chip , struct hda_intel , chip ) ;
2012-10-12 19:28:18 +04:00
int err ;
2014-06-26 19:19:20 +04:00
if ( ! hda - > use_vga_switcheroo )
2012-04-26 14:23:42 +04:00
return 0 ;
/* FIXME: currently only handling DIS controller
* is there any machine with two switchable HDMI audio controllers ?
*/
2012-10-12 19:28:18 +04:00
err = vga_switcheroo_register_audio_client ( chip - > pci , & azx_vs_ops ,
2015-08-27 17:43:43 +03:00
VGA_SWITCHEROO_DIS ) ;
2012-10-12 19:28:18 +04:00
if ( err < 0 )
return err ;
2014-06-26 19:19:20 +04:00
hda - > vga_switcheroo_registered = 1 ;
2013-07-29 09:19:29 +04:00
/* register as an optimus hdmi audio power domain */
2014-03-01 03:41:15 +04:00
vga_switcheroo_init_domain_pm_optimus_hdmi_audio ( chip - > card - > dev ,
2014-06-26 19:19:20 +04:00
& hda - > hdmi_pm_domain ) ;
2012-10-12 19:28:18 +04:00
return 0 ;
2012-04-26 14:23:42 +04:00
}
# else
# define init_vga_switcheroo(chip) /* NOP */
# define register_vga_switcheroo(chip) 0
2012-06-08 15:06:29 +04:00
# define check_hdmi_disabled(pci) false
2012-04-26 14:23:42 +04:00
# endif /* SUPPORT_VGA_SWITCHER */
2005-04-17 02:20:36 +04:00
/*
* destructor
*/
2005-11-17 16:59:02 +03:00
static int azx_free ( struct azx * chip )
2005-04-17 02:20:36 +04:00
{
2013-05-30 18:07:08 +04:00
struct pci_dev * pci = chip - > pci ;
2014-06-26 14:45:16 +04:00
struct hda_intel * hda = container_of ( chip , struct hda_intel , chip ) ;
2015-04-14 23:13:18 +03:00
struct hdac_bus * bus = azx_bus ( chip ) ;
2008-02-06 16:50:19 +03:00
2015-02-19 18:51:17 +03:00
if ( azx_has_pm_runtime ( chip ) & & chip - > running )
2013-05-30 18:07:08 +04:00
pm_runtime_get_noresume ( & pci - > dev ) ;
2012-08-14 19:13:32 +04:00
azx_del_card_list ( chip ) ;
2014-06-26 19:19:20 +04:00
hda - > init_failed = 1 ; /* to be sure */
complete_all ( & hda - > probe_wait ) ;
2012-12-04 18:09:23 +04:00
2014-06-26 19:19:20 +04:00
if ( use_vga_switcheroo ( hda ) ) {
2015-04-14 23:13:18 +03:00
if ( chip - > disabled & & hda - > probe_continued )
snd_hda_unlock_devices ( & chip - > bus ) ;
2014-06-26 19:19:20 +04:00
if ( hda - > vga_switcheroo_registered )
2012-10-12 19:28:18 +04:00
vga_switcheroo_unregister_client ( chip - > pci ) ;
2012-04-26 14:23:42 +04:00
}
2015-04-14 23:13:18 +03:00
if ( bus - > chip_init ) {
2008-05-16 14:34:47 +04:00
azx_clear_irq_pending ( chip ) ;
2015-04-14 19:13:13 +03:00
azx_stop_all_streams ( chip ) ;
2007-08-10 19:21:45 +04:00
azx_stop_chip ( chip ) ;
2005-04-17 02:20:36 +04:00
}
2015-04-14 23:13:18 +03:00
if ( bus - > irq > = 0 )
free_irq ( bus - > irq , ( void * ) chip ) ;
2006-10-23 15:40:59 +04:00
if ( chip - > msi )
2006-10-11 20:52:53 +04:00
pci_disable_msi ( chip - > pci ) ;
2015-04-14 23:13:18 +03:00
iounmap ( bus - > remap_addr ) ;
2005-04-17 02:20:36 +04:00
2014-03-01 03:41:23 +04:00
azx_free_stream_pages ( chip ) ;
2015-04-14 23:13:18 +03:00
azx_free_streams ( chip ) ;
snd_hdac_bus_exit ( bus ) ;
2012-04-26 14:23:42 +04:00
if ( chip - > region_requested )
pci_release_regions ( chip - > pci ) ;
2015-04-14 23:13:18 +03:00
2005-04-17 02:20:36 +04:00
pci_disable_device ( chip - > pci ) ;
2012-08-09 14:33:28 +04:00
# ifdef CONFIG_SND_HDA_PATCH_LOADER
2014-11-17 12:44:33 +03:00
release_firmware ( chip - > fw ) ;
2012-08-09 14:33:28 +04:00
# endif
2015-05-19 17:29:30 +03:00
2013-05-30 18:07:10 +04:00
if ( chip - > driver_caps & AZX_DCAPS_I915_POWERWELL ) {
2015-04-29 12:43:36 +03:00
if ( hda - > need_i915_power )
2015-05-19 17:29:30 +03:00
snd_hdac_display_power ( bus , false ) ;
snd_hdac_i915_exit ( bus ) ;
2013-05-30 18:07:10 +04:00
}
2014-06-26 14:45:16 +04:00
kfree ( hda ) ;
2005-04-17 02:20:36 +04:00
return 0 ;
}
2015-04-14 23:13:18 +03:00
static int azx_dev_disconnect ( struct snd_device * device )
{
struct azx * chip = device - > device_data ;
chip - > bus . shutdown = 1 ;
return 0 ;
}
2005-11-17 16:59:02 +03:00
static int azx_dev_free ( struct snd_device * device )
2005-04-17 02:20:36 +04:00
{
return azx_free ( device - > device_data ) ;
}
2012-06-08 15:06:29 +04:00
# ifdef SUPPORT_VGA_SWITCHEROO
2012-04-26 14:13:25 +04:00
/*
2015-09-04 21:49:36 +03:00
* Check of disabled HDMI controller by vga_switcheroo
2012-04-26 14:13:25 +04:00
*/
2012-12-06 21:35:10 +04:00
static struct pci_dev * get_bound_vga ( struct pci_dev * pci )
2012-04-26 14:13:25 +04:00
{
struct pci_dev * p ;
/* check only discrete GPU */
switch ( pci - > vendor ) {
case PCI_VENDOR_ID_ATI :
case PCI_VENDOR_ID_AMD :
case PCI_VENDOR_ID_NVIDIA :
if ( pci - > devfn = = 1 ) {
p = pci_get_domain_bus_and_slot ( pci_domain_nr ( pci - > bus ) ,
pci - > bus - > number , 0 ) ;
if ( p ) {
if ( ( p - > class > > 8 ) = = PCI_CLASS_DISPLAY_VGA )
return p ;
pci_dev_put ( p ) ;
}
}
break ;
}
return NULL ;
}
2012-12-06 21:35:10 +04:00
static bool check_hdmi_disabled ( struct pci_dev * pci )
2012-04-26 14:13:25 +04:00
{
bool vga_inactive = false ;
struct pci_dev * p = get_bound_vga ( pci ) ;
if ( p ) {
2012-06-07 14:15:16 +04:00
if ( vga_switcheroo_get_client_state ( p ) = = VGA_SWITCHEROO_OFF )
2012-04-26 14:13:25 +04:00
vga_inactive = true ;
pci_dev_put ( p ) ;
}
return vga_inactive ;
}
2012-06-08 15:06:29 +04:00
# endif /* SUPPORT_VGA_SWITCHEROO */
2012-04-26 14:13:25 +04:00
2007-02-01 17:46:50 +03:00
/*
* white / black - listing for position_fix
*/
2012-12-06 21:35:10 +04:00
static struct snd_pci_quirk position_fix_list [ ] = {
2008-06-10 19:53:34 +04:00
SND_PCI_QUIRK ( 0x1028 , 0x01cc , " Dell D820 " , POS_FIX_LPIB ) ,
SND_PCI_QUIRK ( 0x1028 , 0x01de , " Dell Precision 390 " , POS_FIX_LPIB ) ,
2009-12-01 16:17:37 +03:00
SND_PCI_QUIRK ( 0x103c , 0x306d , " HP dv3 " , POS_FIX_LPIB ) ,
2008-06-10 19:53:34 +04:00
SND_PCI_QUIRK ( 0x1043 , 0x813d , " ASUS P5AD2 " , POS_FIX_LPIB ) ,
2010-05-30 09:17:03 +04:00
SND_PCI_QUIRK ( 0x1043 , 0x81b3 , " ASUS " , POS_FIX_LPIB ) ,
2010-05-30 21:08:41 +04:00
SND_PCI_QUIRK ( 0x1043 , 0x81e7 , " ASUS M2V " , POS_FIX_LPIB ) ,
2010-05-28 02:32:18 +04:00
SND_PCI_QUIRK ( 0x104d , 0x9069 , " Sony VPCS11V9E " , POS_FIX_LPIB ) ,
2012-01-12 19:31:14 +04:00
SND_PCI_QUIRK ( 0x10de , 0xcb89 , " Macbook Pro 7,1 " , POS_FIX_LPIB ) ,
2010-05-29 19:04:11 +04:00
SND_PCI_QUIRK ( 0x1297 , 0x3166 , " Shuttle " , POS_FIX_LPIB ) ,
2010-03-28 10:34:40 +04:00
SND_PCI_QUIRK ( 0x1458 , 0xa022 , " ga-ma770-ud3 " , POS_FIX_LPIB ) ,
2009-11-30 13:58:30 +03:00
SND_PCI_QUIRK ( 0x1462 , 0x1002 , " MSI Wind U115 " , POS_FIX_LPIB ) ,
2010-04-15 11:02:41 +04:00
SND_PCI_QUIRK ( 0x1565 , 0x8218 , " Biostar Microtech " , POS_FIX_LPIB ) ,
2010-05-31 03:31:41 +04:00
SND_PCI_QUIRK ( 0x1849 , 0x0888 , " 775Dual-VSTA " , POS_FIX_LPIB ) ,
2010-04-22 03:55:43 +04:00
SND_PCI_QUIRK ( 0x8086 , 0x2503 , " DG965OT AAD63733-203 " , POS_FIX_LPIB ) ,
2007-02-01 17:46:50 +03:00
{ }
} ;
2012-12-06 21:35:10 +04:00
static int check_position_fix ( struct azx * chip , int fix )
2007-02-01 17:46:50 +03:00
{
const struct snd_pci_quirk * q ;
2009-03-17 09:49:14 +03:00
switch ( fix ) {
2012-09-13 16:59:47 +04:00
case POS_FIX_AUTO :
2009-03-17 09:49:14 +03:00
case POS_FIX_LPIB :
case POS_FIX_POSBUF :
2010-09-30 12:12:50 +04:00
case POS_FIX_VIACOMBO :
2012-02-28 14:58:40 +04:00
case POS_FIX_COMBO :
2009-03-17 09:49:14 +03:00
return fix ;
}
q = snd_pci_quirk_lookup ( chip - > pci , position_fix_list ) ;
if ( q ) {
2014-02-25 15:21:03 +04:00
dev_info ( chip - > card - > dev ,
" position_fix set to %d for device %04x:%04x \n " ,
q - > value , q - > subvendor , q - > subdevice ) ;
2009-03-17 09:49:14 +03:00
return q - > value ;
2007-02-01 17:46:50 +03:00
}
2010-10-04 14:02:14 +04:00
/* Check VIA/ATI HD Audio Controller exist */
2011-05-25 11:11:37 +04:00
if ( chip - > driver_caps & AZX_DCAPS_POSFIX_VIA ) {
2014-02-25 15:21:03 +04:00
dev_dbg ( chip - > card - > dev , " Using VIACOMBO position fix \n " ) ;
2010-10-04 14:02:14 +04:00
return POS_FIX_VIACOMBO ;
2011-05-25 11:11:37 +04:00
}
if ( chip - > driver_caps & AZX_DCAPS_POSFIX_LPIB ) {
2014-02-25 15:21:03 +04:00
dev_dbg ( chip - > card - > dev , " Using LPIB position fix \n " ) ;
2011-05-20 18:29:09 +04:00
return POS_FIX_LPIB ;
2010-10-04 14:02:14 +04:00
}
2009-03-17 09:49:14 +03:00
return POS_FIX_AUTO ;
2007-02-01 17:46:50 +03:00
}
2014-06-26 18:50:16 +04:00
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 ;
}
}
2007-08-17 11:17:36 +04:00
/*
* black - lists for probe_mask
*/
2012-12-06 21:35:10 +04:00
static struct snd_pci_quirk probe_mask_list [ ] = {
2007-08-17 11:17:36 +04:00
/* Thinkpad often breaks the controller communication when accessing
* to the non - working ( or non - existing ) modem codec slot .
*/
SND_PCI_QUIRK ( 0x1014 , 0x05b7 , " Thinkpad Z60 " , 0x01 ) ,
SND_PCI_QUIRK ( 0x17aa , 0x2010 , " Thinkpad X/T/R60 " , 0x01 ) ,
SND_PCI_QUIRK ( 0x17aa , 0x20ac , " Thinkpad X/T/R61 " , 0x01 ) ,
2008-11-07 16:53:09 +03:00
/* broken BIOS */
SND_PCI_QUIRK ( 0x1028 , 0x20ac , " Dell Studio Desktop " , 0x01 ) ,
2008-11-24 19:29:28 +03:00
/* including bogus ALC268 in slot#2 that conflicts with ALC888 */
SND_PCI_QUIRK ( 0x17c0 , 0x4085 , " Medion MD96630 " , 0x01 ) ,
2009-02-13 10:18:48 +03:00
/* forced codec slots */
2009-05-23 16:00:04 +04:00
SND_PCI_QUIRK ( 0x1043 , 0x1262 , " ASUS W5Fm " , 0x103 ) ,
2009-02-13 10:18:48 +03:00
SND_PCI_QUIRK ( 0x1046 , 0x1262 , " ASUS W5F " , 0x103 ) ,
2012-04-26 19:52:35 +04:00
/* WinFast VP200 H (Teradici) user reported broken communication */
SND_PCI_QUIRK ( 0x3a21 , 0x040d , " WinFast VP200 H " , 0x101 ) ,
2007-08-17 11:17:36 +04:00
{ }
} ;
2009-02-13 10:16:55 +03:00
# define AZX_FORCE_CODEC_MASK 0x100
2012-12-06 21:35:10 +04:00
static void check_probe_mask ( struct azx * chip , int dev )
2007-08-17 11:17:36 +04:00
{
const struct snd_pci_quirk * q ;
2009-02-13 10:16:55 +03:00
chip - > codec_probe_mask = probe_mask [ dev ] ;
if ( chip - > codec_probe_mask = = - 1 ) {
2007-08-17 11:17:36 +04:00
q = snd_pci_quirk_lookup ( chip - > pci , probe_mask_list ) ;
if ( q ) {
2014-02-25 15:21:03 +04:00
dev_info ( chip - > card - > dev ,
" probe_mask set to 0x%x for device %04x:%04x \n " ,
q - > value , q - > subvendor , q - > subdevice ) ;
2009-02-13 10:16:55 +03:00
chip - > codec_probe_mask = q - > value ;
2007-08-17 11:17:36 +04:00
}
}
2009-02-13 10:16:55 +03:00
/* check forced option */
if ( chip - > codec_probe_mask ! = - 1 & &
( chip - > codec_probe_mask & AZX_FORCE_CODEC_MASK ) ) {
2015-04-14 23:13:18 +03:00
azx_bus ( chip ) - > codec_mask = chip - > codec_probe_mask & 0xff ;
2014-02-25 15:21:03 +04:00
dev_info ( chip - > card - > dev , " codec_mask forced to 0x%x \n " ,
2015-04-14 23:13:18 +03:00
( int ) azx_bus ( chip ) - > codec_mask ) ;
2009-02-13 10:16:55 +03:00
}
2007-08-17 11:17:36 +04:00
}
2009-08-11 16:21:26 +04:00
/*
2009-09-28 15:14:04 +04:00
* white / black - list for enable_msi
2009-08-11 16:21:26 +04:00
*/
2012-12-06 21:35:10 +04:00
static struct snd_pci_quirk msi_black_list [ ] = {
2013-12-12 12:52:03 +04:00
SND_PCI_QUIRK ( 0x103c , 0x2191 , " HP " , 0 ) , /* AMD Hudson */
SND_PCI_QUIRK ( 0x103c , 0x2192 , " HP " , 0 ) , /* AMD Hudson */
SND_PCI_QUIRK ( 0x103c , 0x21f7 , " HP " , 0 ) , /* AMD Hudson */
SND_PCI_QUIRK ( 0x103c , 0x21fa , " HP " , 0 ) , /* AMD Hudson */
2009-12-22 10:15:01 +03:00
SND_PCI_QUIRK ( 0x1043 , 0x81f2 , " ASUS " , 0 ) , /* Athlon64 X2 + nvidia */
2010-02-15 19:05:28 +03:00
SND_PCI_QUIRK ( 0x1043 , 0x81f6 , " ASUS " , 0 ) , /* nvidia */
2010-03-09 20:25:47 +03:00
SND_PCI_QUIRK ( 0x1043 , 0x822d , " ASUS " , 0 ) , /* Athlon64 X2 + nvidia MCP55 */
2013-09-09 12:20:48 +04:00
SND_PCI_QUIRK ( 0x1179 , 0xfb44 , " Toshiba Satellite C870 " , 0 ) , /* AMD Hudson */
2010-03-06 23:06:46 +03:00
SND_PCI_QUIRK ( 0x1849 , 0x0888 , " ASRock " , 0 ) , /* Athlon64 X2 + nvidia */
2010-04-04 14:14:03 +04:00
SND_PCI_QUIRK ( 0xa0a0 , 0x0575 , " Aopen MZ915-M " , 0 ) , /* ICH6 */
2009-08-11 16:21:26 +04:00
{ }
} ;
2012-12-06 21:35:10 +04:00
static void check_msi ( struct azx * chip )
2009-08-11 16:21:26 +04:00
{
const struct snd_pci_quirk * q ;
2009-09-28 15:14:04 +04:00
if ( enable_msi > = 0 ) {
chip - > msi = ! ! enable_msi ;
2009-08-11 16:21:26 +04:00
return ;
2009-09-28 15:14:04 +04:00
}
chip - > msi = 1 ; /* enable MSI as default */
q = snd_pci_quirk_lookup ( chip - > pci , msi_black_list ) ;
2009-08-11 16:21:26 +04:00
if ( q ) {
2014-02-25 15:21:03 +04:00
dev_info ( chip - > card - > dev ,
" msi for device %04x:%04x set to %d \n " ,
q - > subvendor , q - > subdevice , q - > value ) ;
2009-08-11 16:21:26 +04:00
chip - > msi = q - > value ;
2010-03-15 17:51:53 +03:00
return ;
}
/* NVidia chipsets seem to cause troubles with MSI */
2011-05-25 11:11:37 +04:00
if ( chip - > driver_caps & AZX_DCAPS_NO_MSI ) {
2014-02-25 15:21:03 +04:00
dev_info ( chip - > card - > dev , " Disabling MSI \n " ) ;
2010-03-15 17:51:53 +03:00
chip - > msi = 0 ;
2009-08-11 16:21:26 +04:00
}
}
2011-12-14 12:27:04 +04:00
/* check the snoop mode availability */
2012-12-06 21:35:10 +04:00
static void azx_check_snoop_available ( struct azx * chip )
2011-12-14 12:27:04 +04:00
{
2014-11-25 14:54:16 +03:00
int snoop = hda_snoop ;
2011-12-14 12:27:04 +04:00
2014-11-25 14:54:16 +03:00
if ( snoop > = 0 ) {
dev_info ( chip - > card - > dev , " Force to %s mode by module option \n " ,
snoop ? " snoop " : " non-snoop " ) ;
chip - > snoop = snoop ;
return ;
}
snoop = true ;
2014-11-25 13:28:07 +03:00
if ( azx_get_snoop_type ( chip ) = = AZX_SNOOP_TYPE_NONE & &
chip - > driver_type = = AZX_DRIVER_VIA ) {
2011-12-14 12:27:04 +04:00
/* force to non-snoop mode for a new VIA controller
* when BIOS is set
*/
2014-11-25 14:54:16 +03:00
u8 val ;
pci_read_config_byte ( chip - > pci , 0x42 , & val ) ;
if ( ! ( val & 0x80 ) & & chip - > pci - > revision = = 0x30 )
snoop = false ;
2011-12-14 12:27:04 +04:00
}
2014-11-25 13:28:07 +03:00
if ( chip - > driver_caps & AZX_DCAPS_SNOOP_OFF )
snoop = false ;
2014-11-25 14:54:16 +03:00
chip - > snoop = snoop ;
if ( ! snoop )
dev_info ( chip - > card - > dev , " Force to non-snoop mode \n " ) ;
2011-12-14 12:27:04 +04:00
}
2007-08-17 11:17:36 +04:00
2013-05-30 18:07:10 +04:00
static void azx_probe_work ( struct work_struct * work )
{
2014-06-26 19:19:20 +04:00
struct hda_intel * hda = container_of ( work , struct hda_intel , probe_work ) ;
azx_probe_continue ( & hda - > chip ) ;
2013-05-30 18:07:10 +04:00
}
2005-04-17 02:20:36 +04:00
/*
* constructor
*/
2015-04-14 18:26:00 +03:00
static const struct hdac_io_ops pci_hda_io_ops ;
static const struct hda_controller_ops pci_hda_ops ;
2012-12-06 21:35:10 +04:00
static int azx_create ( struct snd_card * card , struct pci_dev * pci ,
int dev , unsigned int driver_caps ,
struct azx * * rchip )
2005-04-17 02:20:36 +04:00
{
2005-11-17 16:59:02 +03:00
static struct snd_device_ops ops = {
2015-04-14 23:13:18 +03:00
. dev_disconnect = azx_dev_disconnect ,
2005-04-17 02:20:36 +04:00
. dev_free = azx_dev_free ,
} ;
2014-06-26 14:45:16 +04:00
struct hda_intel * hda ;
2012-04-26 14:23:42 +04:00
struct azx * chip ;
int err ;
2005-04-17 02:20:36 +04:00
* rchip = NULL ;
2008-01-15 13:23:55 +03:00
2006-08-31 19:03:43 +04:00
err = pci_enable_device ( pci ) ;
if ( err < 0 )
2005-04-17 02:20:36 +04:00
return err ;
2014-06-26 14:45:16 +04:00
hda = kzalloc ( sizeof ( * hda ) , GFP_KERNEL ) ;
if ( ! hda ) {
2005-04-17 02:20:36 +04:00
pci_disable_device ( pci ) ;
return - ENOMEM ;
}
2014-06-26 14:45:16 +04:00
chip = & hda - > chip ;
2006-01-16 18:34:20 +03:00
mutex_init ( & chip - > open_mutex ) ;
2005-04-17 02:20:36 +04:00
chip - > card = card ;
chip - > pci = pci ;
2015-04-14 18:26:00 +03:00
chip - > ops = & pci_hda_ops ;
2011-05-25 11:11:37 +04:00
chip - > driver_caps = driver_caps ;
chip - > driver_type = driver_caps & 0xff ;
2009-08-11 16:21:26 +04:00
check_msi ( chip ) ;
2008-06-10 19:53:34 +04:00
chip - > dev_index = dev ;
2014-03-01 03:41:18 +04:00
chip - > jackpoll_ms = jackpoll_ms ;
2011-11-24 17:31:46 +04:00
INIT_LIST_HEAD ( & chip - > pcm_list ) ;
2014-06-26 19:19:20 +04:00
INIT_WORK ( & hda - > irq_pending_work , azx_irq_pending_work ) ;
INIT_LIST_HEAD ( & hda - > list ) ;
2012-04-26 14:23:42 +04:00
init_vga_switcheroo ( chip ) ;
2014-06-26 19:19:20 +04:00
init_completion ( & hda - > probe_wait ) ;
2005-04-17 02:20:36 +04:00
2014-06-26 18:50:16 +04:00
assign_position_fix ( chip , check_position_fix ( chip , position_fix [ dev ] ) ) ;
2012-02-28 14:58:40 +04:00
2008-01-07 17:16:37 +03:00
check_probe_mask ( chip , dev ) ;
2007-02-01 17:46:50 +03:00
2006-01-12 20:28:44 +03:00
chip - > single_cmd = single_cmd ;
2011-12-14 12:27:04 +04:00
azx_check_snoop_available ( chip ) ;
2005-05-12 16:26:27 +04:00
2008-06-10 19:53:35 +04:00
if ( bdl_pos_adj [ dev ] < 0 ) {
switch ( chip - > driver_type ) {
2008-06-13 22:50:27 +04:00
case AZX_DRIVER_ICH :
2010-02-23 04:31:09 +03:00
case AZX_DRIVER_PCH :
2008-06-13 22:50:27 +04:00
bdl_pos_adj [ dev ] = 1 ;
2008-06-10 19:53:35 +04:00
break ;
default :
2008-06-13 22:50:27 +04:00
bdl_pos_adj [ dev ] = 32 ;
2008-06-10 19:53:35 +04:00
break ;
}
}
2014-03-01 03:41:14 +04:00
chip - > bdl_pos_adj = bdl_pos_adj ;
2008-06-10 19:53:35 +04:00
2015-04-14 23:13:18 +03:00
err = azx_bus_init ( chip , model [ dev ] , & pci_hda_io_ops ) ;
if ( err < 0 ) {
kfree ( hda ) ;
pci_disable_device ( pci ) ;
return err ;
}
2012-04-26 14:23:42 +04:00
err = snd_device_new ( card , SNDRV_DEV_LOWLEVEL , chip , & ops ) ;
if ( err < 0 ) {
2014-02-25 15:21:03 +04:00
dev_err ( card - > dev , " Error creating device [card]! \n " ) ;
2012-04-26 14:23:42 +04:00
azx_free ( chip ) ;
return err ;
}
2013-05-30 18:07:10 +04:00
/* continue probing in work context as may trigger request module */
2014-06-26 19:19:20 +04:00
INIT_WORK ( & hda - > probe_work , azx_probe_work ) ;
2013-05-30 18:07:10 +04:00
2012-04-26 14:23:42 +04:00
* rchip = chip ;
2013-05-30 18:07:10 +04:00
2012-04-26 14:23:42 +04:00
return 0 ;
}
2012-12-07 10:40:35 +04:00
static int azx_first_init ( struct azx * chip )
2012-04-26 14:23:42 +04:00
{
int dev = chip - > dev_index ;
struct pci_dev * pci = chip - > pci ;
struct snd_card * card = chip - > card ;
2015-04-14 23:13:18 +03:00
struct hdac_bus * bus = azx_bus ( chip ) ;
2014-03-01 03:41:23 +04:00
int err ;
2012-04-26 14:23:42 +04:00
unsigned short gcap ;
2014-10-01 12:30:53 +04:00
unsigned int dma_bits = 64 ;
2012-04-26 14:23:42 +04:00
2005-08-24 16:14:57 +04:00
# if BITS_PER_LONG != 64
/* Fix up base address on ULI M5461 */
if ( chip - > driver_type = = AZX_DRIVER_ULI ) {
u16 tmp3 ;
pci_read_config_word ( pci , 0x40 , & tmp3 ) ;
pci_write_config_word ( pci , 0x40 , tmp3 | 0x10 ) ;
pci_write_config_dword ( pci , PCI_BASE_ADDRESS_1 , 0 ) ;
}
# endif
2006-08-31 19:03:43 +04:00
err = pci_request_regions ( pci , " ICH HD audio " ) ;
2012-04-26 14:23:42 +04:00
if ( err < 0 )
2005-04-17 02:20:36 +04:00
return err ;
2012-04-26 14:23:42 +04:00
chip - > region_requested = 1 ;
2005-04-17 02:20:36 +04:00
2015-04-14 23:13:18 +03:00
bus - > addr = pci_resource_start ( pci , 0 ) ;
bus - > remap_addr = pci_ioremap_bar ( pci , 0 ) ;
if ( bus - > remap_addr = = NULL ) {
2014-02-25 15:21:03 +04:00
dev_err ( card - > dev , " ioremap error \n " ) ;
2012-04-26 14:23:42 +04:00
return - ENXIO ;
2005-04-17 02:20:36 +04:00
}
2014-11-24 06:17:08 +03:00
if ( chip - > msi ) {
if ( chip - > driver_caps & AZX_DCAPS_NO_MSI64 ) {
dev_dbg ( card - > dev , " Disabling 64bit MSI \n " ) ;
pci - > no_64bit_msi = true ;
}
2006-10-23 15:40:59 +04:00
if ( pci_enable_msi ( pci ) < 0 )
chip - > msi = 0 ;
2014-11-24 06:17:08 +03:00
}
2006-08-21 21:17:46 +04:00
2012-04-26 14:23:42 +04:00
if ( azx_acquire_irq ( chip , 0 ) < 0 )
return - EBUSY ;
2005-04-17 02:20:36 +04:00
pci_set_master ( pci ) ;
2015-04-14 23:13:18 +03:00
synchronize_irq ( bus - > irq ) ;
2005-04-17 02:20:36 +04:00
2008-01-15 13:23:55 +03:00
gcap = azx_readw ( chip , GCAP ) ;
2014-02-25 15:21:03 +04:00
dev_dbg ( card - > dev , " chipset global capabilities = 0x%x \n " , gcap ) ;
2008-01-15 13:23:55 +03:00
2014-10-01 12:30:53 +04:00
/* AMD devices support 40 or 48bit DMA, take the safe one */
if ( chip - > pci - > vendor = = PCI_VENDOR_ID_AMD )
dma_bits = 40 ;
2009-07-08 09:55:31 +04:00
/* disable SB600 64bit support for safety */
2011-05-25 11:11:37 +04:00
if ( chip - > pci - > vendor = = PCI_VENDOR_ID_ATI ) {
2009-07-08 09:55:31 +04:00
struct pci_dev * p_smbus ;
2014-10-01 12:30:53 +04:00
dma_bits = 40 ;
2009-07-08 09:55:31 +04:00
p_smbus = pci_get_device ( PCI_VENDOR_ID_ATI ,
PCI_DEVICE_ID_ATI_SBX00_SMBUS ,
NULL ) ;
if ( p_smbus ) {
if ( p_smbus - > revision < 0x30 )
2014-06-26 19:54:37 +04:00
gcap & = ~ AZX_GCAP_64OK ;
2009-07-08 09:55:31 +04:00
pci_dev_put ( p_smbus ) ;
}
}
2009-03-17 09:47:18 +03:00
2011-05-25 11:11:37 +04:00
/* disable 64bit DMA address on some devices */
if ( chip - > driver_caps & AZX_DCAPS_NO_64BIT ) {
2014-02-25 15:21:03 +04:00
dev_dbg ( card - > dev , " Disabling 64bit DMA \n " ) ;
2014-06-26 19:54:37 +04:00
gcap & = ~ AZX_GCAP_64OK ;
2011-05-25 11:11:37 +04:00
}
2009-12-09 12:44:47 +03:00
2011-08-04 19:12:56 +04:00
/* disable buffer size rounding to 128-byte multiples if supported */
2012-01-23 20:53:39 +04:00
if ( align_buffer_size > = 0 )
chip - > align_buffer_size = ! ! align_buffer_size ;
else {
2014-12-03 11:56:20 +03:00
if ( chip - > driver_caps & AZX_DCAPS_NO_ALIGN_BUFSIZE )
2012-01-23 20:53:39 +04:00
chip - > align_buffer_size = 0 ;
else
chip - > align_buffer_size = 1 ;
}
2011-08-04 19:12:56 +04:00
2008-02-06 17:05:57 +03:00
/* allow 64bit DMA address if supported by H/W */
2014-10-01 12:30:53 +04:00
if ( ! ( gcap & AZX_GCAP_64OK ) )
dma_bits = 32 ;
ALSA: remove deprecated use of pci api
Replace occurences of the pci api by appropriate call to the dma api.
A simplified version of the semantic patch that finds this problem is as
follows: (http://coccinelle.lip6.fr)
@deprecated@
idexpression id;
position p;
@@
(
pci_dma_supported@p ( id, ...)
|
pci_alloc_consistent@p ( id, ...)
)
@bad1@
idexpression id;
position deprecated.p;
@@
...when != &id->dev
when != pci_get_drvdata ( id )
when != pci_enable_device ( id )
(
pci_dma_supported@p ( id, ...)
|
pci_alloc_consistent@p ( id, ...)
)
@depends on !bad1@
idexpression id;
expression direction;
position deprecated.p;
@@
(
- pci_dma_supported@p ( id,
+ dma_supported ( &id->dev,
...
+ , GFP_ATOMIC
)
|
- pci_alloc_consistent@p ( id,
+ dma_alloc_coherent ( &id->dev,
...
+ , GFP_ATOMIC
)
)
Signed-off-by: Quentin Lambert <lambert.quentin@gmail.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2015-04-15 17:10:17 +03:00
if ( ! dma_set_mask ( & pci - > dev , DMA_BIT_MASK ( dma_bits ) ) ) {
dma_set_coherent_mask ( & pci - > dev , DMA_BIT_MASK ( dma_bits ) ) ;
2014-10-01 12:30:53 +04:00
} else {
ALSA: remove deprecated use of pci api
Replace occurences of the pci api by appropriate call to the dma api.
A simplified version of the semantic patch that finds this problem is as
follows: (http://coccinelle.lip6.fr)
@deprecated@
idexpression id;
position p;
@@
(
pci_dma_supported@p ( id, ...)
|
pci_alloc_consistent@p ( id, ...)
)
@bad1@
idexpression id;
position deprecated.p;
@@
...when != &id->dev
when != pci_get_drvdata ( id )
when != pci_enable_device ( id )
(
pci_dma_supported@p ( id, ...)
|
pci_alloc_consistent@p ( id, ...)
)
@depends on !bad1@
idexpression id;
expression direction;
position deprecated.p;
@@
(
- pci_dma_supported@p ( id,
+ dma_supported ( &id->dev,
...
+ , GFP_ATOMIC
)
|
- pci_alloc_consistent@p ( id,
+ dma_alloc_coherent ( &id->dev,
...
+ , GFP_ATOMIC
)
)
Signed-off-by: Quentin Lambert <lambert.quentin@gmail.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2015-04-15 17:10:17 +03:00
dma_set_mask ( & pci - > dev , DMA_BIT_MASK ( 32 ) ) ;
dma_set_coherent_mask ( & pci - > dev , DMA_BIT_MASK ( 32 ) ) ;
2009-03-17 09:47:18 +03:00
}
2008-02-06 17:05:57 +03:00
2008-02-19 13:36:35 +03:00
/* read number of streams from GCAP register instead of using
* hardcoded value
*/
chip - > capture_streams = ( gcap > > 8 ) & 0x0f ;
chip - > playback_streams = ( gcap > > 12 ) & 0x0f ;
if ( ! chip - > playback_streams & & ! chip - > capture_streams ) {
2008-01-15 13:23:55 +03:00
/* gcap didn't give any info, switching to old method */
switch ( chip - > driver_type ) {
case AZX_DRIVER_ULI :
chip - > playback_streams = ULI_NUM_PLAYBACK ;
chip - > capture_streams = ULI_NUM_CAPTURE ;
break ;
case AZX_DRIVER_ATIHDMI :
2011-12-14 12:10:27 +04:00
case AZX_DRIVER_ATIHDMI_NS :
2008-01-15 13:23:55 +03:00
chip - > playback_streams = ATIHDMI_NUM_PLAYBACK ;
chip - > capture_streams = ATIHDMI_NUM_CAPTURE ;
break ;
2008-11-13 13:07:07 +03:00
case AZX_DRIVER_GENERIC :
2008-01-15 13:23:55 +03:00
default :
chip - > playback_streams = ICH6_NUM_PLAYBACK ;
chip - > capture_streams = ICH6_NUM_CAPTURE ;
break ;
}
2005-08-24 16:14:57 +04:00
}
2008-02-19 13:36:35 +03:00
chip - > capture_index_offset = 0 ;
chip - > playback_index_offset = chip - > capture_streams ;
2005-08-24 16:14:57 +04:00
chip - > num_streams = chip - > playback_streams + chip - > capture_streams ;
2015-04-14 23:13:18 +03:00
/* initialize streams */
err = azx_init_streams ( chip ) ;
2009-05-26 17:22:00 +04:00
if ( err < 0 )
2012-04-26 14:23:42 +04:00
return err ;
2005-04-17 02:20:36 +04:00
2015-04-14 23:13:18 +03:00
err = azx_alloc_stream_pages ( chip ) ;
if ( err < 0 )
return err ;
2005-04-17 02:20:36 +04:00
/* initialize chip */
2007-08-10 19:21:45 +04:00
azx_init_pci ( chip ) ;
2014-07-03 13:02:23 +04:00
2015-01-08 18:54:16 +03:00
if ( chip - > driver_caps & AZX_DCAPS_I915_POWERWELL ) {
struct hda_intel * hda ;
hda = container_of ( chip , struct hda_intel , chip ) ;
haswell_set_bclk ( hda ) ;
}
2014-07-03 13:02:23 +04:00
2015-05-05 04:05:48 +03:00
hda_intel_init_chip ( chip , ( probe_only [ dev ] & 2 ) = = 0 ) ;
2005-04-17 02:20:36 +04:00
/* codec detection */
2015-04-14 23:13:18 +03:00
if ( ! azx_bus ( chip ) - > codec_mask ) {
2014-02-25 15:21:03 +04:00
dev_err ( card - > dev , " no codecs found! \n " ) ;
2012-04-26 14:23:42 +04:00
return - ENODEV ;
2005-04-17 02:20:36 +04:00
}
2005-08-24 16:14:57 +04:00
strcpy ( card - > driver , " HDA-Intel " ) ;
2009-04-16 12:22:24 +04:00
strlcpy ( card - > shortname , driver_short_names [ chip - > driver_type ] ,
sizeof ( card - > shortname ) ) ;
snprintf ( card - > longname , sizeof ( card - > longname ) ,
" %s at 0x%lx irq %i " ,
2015-04-14 23:13:18 +03:00
card - > shortname , bus - > addr , bus - > irq ) ;
2005-08-24 16:14:57 +04:00
2005-04-17 02:20:36 +04:00
return 0 ;
}
2012-08-09 19:40:46 +04:00
# ifdef CONFIG_SND_HDA_PATCH_LOADER
2012-08-09 15:49:23 +04:00
/* callback from request_firmware_nowait() */
static void azx_firmware_cb ( const struct firmware * fw , void * context )
{
struct snd_card * card = context ;
struct azx * chip = card - > private_data ;
struct pci_dev * pci = chip - > pci ;
if ( ! fw ) {
2014-02-25 15:21:03 +04:00
dev_err ( card - > dev , " Cannot load firmware, aborting \n " ) ;
2012-08-09 15:49:23 +04:00
goto error ;
}
chip - > fw = fw ;
if ( ! chip - > disabled ) {
/* continue probing */
if ( azx_probe_continue ( chip ) )
goto error ;
}
return ; /* OK */
error :
snd_card_free ( card ) ;
pci_set_drvdata ( pci , NULL ) ;
}
2012-08-09 19:40:46 +04:00
# endif
2012-08-09 15:49:23 +04:00
2014-03-01 03:41:13 +04:00
/*
* HDA controller ops .
*/
/* PCI register access. */
2014-03-03 08:44:01 +04:00
static void pci_azx_writel ( u32 value , u32 __iomem * addr )
2014-03-01 03:41:13 +04:00
{
writel ( value , addr ) ;
}
2014-03-03 08:44:01 +04:00
static u32 pci_azx_readl ( u32 __iomem * addr )
2014-03-01 03:41:13 +04:00
{
return readl ( addr ) ;
}
2014-03-03 08:44:01 +04:00
static void pci_azx_writew ( u16 value , u16 __iomem * addr )
2014-03-01 03:41:13 +04:00
{
writew ( value , addr ) ;
}
2014-03-03 08:44:01 +04:00
static u16 pci_azx_readw ( u16 __iomem * addr )
2014-03-01 03:41:13 +04:00
{
return readw ( addr ) ;
}
2014-03-03 08:44:01 +04:00
static void pci_azx_writeb ( u8 value , u8 __iomem * addr )
2014-03-01 03:41:13 +04:00
{
writeb ( value , addr ) ;
}
2014-03-03 08:44:01 +04:00
static u8 pci_azx_readb ( u8 __iomem * addr )
2014-03-01 03:41:13 +04:00
{
return readb ( addr ) ;
}
2014-03-01 03:41:16 +04:00
static int disable_msi_reset_irq ( struct azx * chip )
{
2015-04-14 23:13:18 +03:00
struct hdac_bus * bus = azx_bus ( chip ) ;
2014-03-01 03:41:16 +04:00
int err ;
2015-04-14 23:13:18 +03:00
free_irq ( bus - > irq , chip ) ;
bus - > irq = - 1 ;
2014-03-01 03:41:16 +04:00
pci_disable_msi ( chip - > pci ) ;
chip - > msi = 0 ;
err = azx_acquire_irq ( chip , 1 ) ;
if ( err < 0 )
return err ;
return 0 ;
}
2014-03-01 03:41:20 +04:00
/* DMA page allocation helpers. */
2015-04-14 18:26:00 +03:00
static int dma_alloc_pages ( struct hdac_bus * bus ,
2014-03-01 03:41:20 +04:00
int type ,
size_t size ,
struct snd_dma_buffer * buf )
{
2015-04-14 23:13:18 +03:00
struct azx * chip = bus_to_azx ( bus ) ;
2014-03-01 03:41:20 +04:00
int err ;
err = snd_dma_alloc_pages ( type ,
2015-04-14 18:26:00 +03:00
bus - > dev ,
2014-03-01 03:41:20 +04:00
size , buf ) ;
if ( err < 0 )
return err ;
mark_pages_wc ( chip , buf , true ) ;
return 0 ;
}
2015-04-14 18:26:00 +03:00
static void dma_free_pages ( struct hdac_bus * bus , struct snd_dma_buffer * buf )
2014-03-01 03:41:20 +04:00
{
2015-04-14 23:13:18 +03:00
struct azx * chip = bus_to_azx ( bus ) ;
2015-04-14 18:26:00 +03:00
2014-03-01 03:41:20 +04:00
mark_pages_wc ( chip , buf , false ) ;
snd_dma_free_pages ( buf ) ;
}
static int substream_alloc_pages ( struct azx * chip ,
struct snd_pcm_substream * substream ,
size_t size )
{
struct azx_dev * azx_dev = get_azx_dev ( substream ) ;
int ret ;
mark_runtime_wc ( chip , azx_dev , substream , false ) ;
ret = snd_pcm_lib_malloc_pages ( substream , size ) ;
if ( ret < 0 )
return ret ;
mark_runtime_wc ( chip , azx_dev , substream , true ) ;
return 0 ;
}
static int substream_free_pages ( struct azx * chip ,
struct snd_pcm_substream * substream )
{
struct azx_dev * azx_dev = get_azx_dev ( substream ) ;
mark_runtime_wc ( chip , azx_dev , substream , false ) ;
return snd_pcm_lib_free_pages ( substream ) ;
}
2014-03-01 03:41:21 +04:00
static void pcm_mmap_prepare ( struct snd_pcm_substream * substream ,
struct vm_area_struct * area )
{
# ifdef CONFIG_X86
struct azx_pcm * apcm = snd_pcm_substream_chip ( substream ) ;
struct azx * chip = apcm - > chip ;
2014-10-29 18:13:05 +03:00
if ( ! azx_snoop ( chip ) & & chip - > driver_type ! = AZX_DRIVER_CMEDIA )
2014-03-01 03:41:21 +04:00
area - > vm_page_prot = pgprot_writecombine ( area - > vm_page_prot ) ;
# endif
}
2015-04-14 18:26:00 +03:00
static const struct hdac_io_ops pci_hda_io_ops = {
2014-03-03 08:44:00 +04:00
. reg_writel = pci_azx_writel ,
. reg_readl = pci_azx_readl ,
. reg_writew = pci_azx_writew ,
. reg_readw = pci_azx_readw ,
. reg_writeb = pci_azx_writeb ,
. reg_readb = pci_azx_readb ,
2014-03-01 03:41:20 +04:00
. dma_alloc_pages = dma_alloc_pages ,
. dma_free_pages = dma_free_pages ,
2015-04-14 18:26:00 +03:00
} ;
static const struct hda_controller_ops pci_hda_ops = {
. disable_msi_reset_irq = disable_msi_reset_irq ,
2014-03-01 03:41:20 +04:00
. substream_alloc_pages = substream_alloc_pages ,
. substream_free_pages = substream_free_pages ,
2014-03-01 03:41:21 +04:00
. pcm_mmap_prepare = pcm_mmap_prepare ,
2014-03-01 03:41:28 +04:00
. position_check = azx_position_check ,
2015-04-29 12:43:29 +03:00
. link_power = azx_intel_link_power ,
2014-03-01 03:41:13 +04:00
} ;
2012-12-06 21:35:10 +04:00
static int azx_probe ( struct pci_dev * pci ,
const struct pci_device_id * pci_id )
2005-04-17 02:20:36 +04:00
{
2008-01-07 17:16:37 +03:00
static int dev ;
2005-11-17 16:59:02 +03:00
struct snd_card * card ;
2014-06-26 19:19:20 +04:00
struct hda_intel * hda ;
2005-11-17 16:59:02 +03:00
struct azx * chip ;
2013-12-02 16:33:57 +04:00
bool schedule_probe ;
2006-08-31 19:03:43 +04:00
int err ;
2005-04-17 02:20:36 +04:00
2008-01-07 17:16:37 +03:00
if ( dev > = SNDRV_CARDS )
return - ENODEV ;
if ( ! enable [ dev ] ) {
dev + + ;
return - ENOENT ;
}
2014-01-29 17:20:19 +04:00
err = snd_card_new ( & pci - > dev , index [ dev ] , id [ dev ] , THIS_MODULE ,
0 , & card ) ;
2008-12-28 18:44:30 +03:00
if ( err < 0 ) {
2014-02-25 15:21:03 +04:00
dev_err ( & pci - > dev , " Error creating card! \n " ) ;
2008-12-28 18:44:30 +03:00
return err ;
2005-04-17 02:20:36 +04:00
}
2015-04-14 18:26:00 +03:00
err = azx_create ( card , pci , dev , pci_id - > driver_data , & chip ) ;
2008-11-20 04:24:52 +03:00
if ( err < 0 )
goto out_free ;
2005-11-17 18:11:09 +03:00
card - > private_data = chip ;
2014-06-26 19:19:20 +04:00
hda = container_of ( chip , struct hda_intel , chip ) ;
2012-12-04 18:09:23 +04:00
pci_set_drvdata ( pci , card ) ;
err = register_vga_switcheroo ( chip ) ;
if ( err < 0 ) {
2015-09-04 21:49:36 +03:00
dev_err ( card - > dev , " Error registering vga_switcheroo client \n " ) ;
2012-12-04 18:09:23 +04:00
goto out_free ;
}
if ( check_hdmi_disabled ( pci ) ) {
2014-02-25 15:21:03 +04:00
dev_info ( card - > dev , " VGA controller is disabled \n " ) ;
dev_info ( card - > dev , " Delaying initialization \n " ) ;
2012-12-04 18:09:23 +04:00
chip - > disabled = true ;
}
2013-12-02 16:33:57 +04:00
schedule_probe = ! chip - > disabled ;
2005-04-17 02:20:36 +04:00
2012-08-09 14:33:28 +04:00
# ifdef CONFIG_SND_HDA_PATCH_LOADER
if ( patch [ dev ] & & * patch [ dev ] ) {
2014-02-25 15:21:03 +04:00
dev_info ( card - > dev , " Applying patch firmware '%s' \n " ,
patch [ dev ] ) ;
2012-08-09 15:49:23 +04:00
err = request_firmware_nowait ( THIS_MODULE , true , patch [ dev ] ,
& pci - > dev , GFP_KERNEL , card ,
azx_firmware_cb ) ;
2012-08-09 14:33:28 +04:00
if ( err < 0 )
goto out_free ;
2013-12-02 16:33:57 +04:00
schedule_probe = false ; /* continued in azx_firmware_cb() */
2012-08-09 14:33:28 +04:00
}
# endif /* CONFIG_SND_HDA_PATCH_LOADER */
2013-12-02 16:33:57 +04:00
# ifndef CONFIG_SND_HDA_I915
if ( chip - > driver_caps & AZX_DCAPS_I915_POWERWELL )
2014-02-25 15:21:03 +04:00
dev_err ( card - > dev , " Haswell must build in CONFIG_SND_HDA_I915 \n " ) ;
2013-05-30 18:07:10 +04:00
# endif
2013-12-02 16:33:57 +04:00
if ( schedule_probe )
2014-06-26 19:19:20 +04:00
schedule_work ( & hda - > probe_work ) ;
2012-04-26 14:23:42 +04:00
dev + + ;
2013-12-02 14:12:28 +04:00
if ( chip - > disabled )
2014-06-26 19:19:20 +04:00
complete_all ( & hda - > probe_wait ) ;
2012-04-26 14:23:42 +04:00
return 0 ;
out_free :
snd_card_free ( card ) ;
return err ;
}
2014-03-01 03:41:19 +04:00
/* number of codec slots for each chipset: 0 = default slots (i.e. 4) */
static unsigned int azx_max_codecs [ AZX_NUM_DRIVERS ] = {
[ AZX_DRIVER_NVIDIA ] = 8 ,
[ AZX_DRIVER_TERA ] = 1 ,
} ;
2012-12-07 10:40:35 +04:00
static int azx_probe_continue ( struct azx * chip )
2012-04-26 14:23:42 +04:00
{
2014-06-26 19:19:20 +04:00
struct hda_intel * hda = container_of ( chip , struct hda_intel , chip ) ;
2015-05-19 17:29:30 +03:00
struct hdac_bus * bus = azx_bus ( chip ) ;
2013-05-30 18:07:08 +04:00
struct pci_dev * pci = chip - > pci ;
2012-04-26 14:23:42 +04:00
int dev = chip - > dev_index ;
int err ;
2015-04-14 23:13:18 +03:00
hda - > probe_continued = 1 ;
2015-04-29 12:43:36 +03:00
/* Request display power well for the HDA controller or codec. For
* Haswell / Broadwell , both the display HDA controller and codec need
* this power . For other platforms , like Baytrail / Braswell , only the
* display codec needs the power and it can be released after probe .
*/
2013-05-30 18:07:10 +04:00
if ( chip - > driver_caps & AZX_DCAPS_I915_POWERWELL ) {
2015-06-03 04:30:15 +03:00
/* HSW/BDW controllers need this power */
if ( CONTROLLER_IN_GPU ( pci ) )
2015-04-29 12:43:43 +03:00
hda - > need_i915_power = 1 ;
2015-05-19 17:29:30 +03:00
err = snd_hdac_i915_init ( bus ) ;
2015-06-12 08:53:58 +03:00
if ( err < 0 ) {
/* if the controller is bound only with HDMI/DP
* ( for HSW and BDW ) , we need to abort the probe ;
* for other chips , still continue probing as other
* codecs can be on the same link .
*/
if ( CONTROLLER_IN_GPU ( pci ) )
goto out_free ;
else
goto skip_i915 ;
}
2015-04-29 12:43:36 +03:00
2015-05-19 17:29:30 +03:00
err = snd_hdac_display_power ( bus , true ) ;
2014-06-13 17:14:34 +04:00
if ( err < 0 ) {
dev_err ( chip - > card - > dev ,
" Cannot turn on display power on i915 \n " ) ;
2015-04-29 12:43:36 +03:00
goto i915_power_fail ;
2014-06-13 17:14:34 +04:00
}
2013-05-30 18:07:10 +04:00
}
2015-06-10 13:03:49 +03:00
skip_i915 :
2013-05-30 18:07:09 +04:00
err = azx_first_init ( chip ) ;
if ( err < 0 )
goto out_free ;
2009-11-13 20:41:52 +03:00
# ifdef CONFIG_SND_HDA_INPUT_BEEP
chip - > beep_mode = beep_mode [ dev ] ;
# endif
2005-04-17 02:20:36 +04:00
/* create codec instances */
2015-02-19 20:12:22 +03:00
err = azx_probe_codecs ( chip , azx_max_codecs [ chip - > driver_type ] ) ;
2008-11-20 04:24:52 +03:00
if ( err < 0 )
goto out_free ;
2015-02-19 20:12:22 +03:00
2009-06-17 11:52:54 +04:00
# ifdef CONFIG_SND_HDA_PATCH_LOADER
2012-08-09 14:33:28 +04:00
if ( chip - > fw ) {
2015-04-14 23:13:18 +03:00
err = snd_hda_load_patch ( & chip - > bus , chip - > fw - > size ,
2012-08-09 14:33:28 +04:00
chip - > fw - > data ) ;
2009-06-17 11:52:54 +04:00
if ( err < 0 )
goto out_free ;
2012-11-22 19:18:13 +04:00
# ifndef CONFIG_PM
2012-08-09 14:33:28 +04:00
release_firmware ( chip - > fw ) ; /* no longer needed */
chip - > fw = NULL ;
2012-11-22 19:18:13 +04:00
# endif
2009-06-17 11:52:54 +04:00
}
# endif
2010-03-26 13:04:38 +03:00
if ( ( probe_only [ dev ] & 1 ) = = 0 ) {
2009-06-17 11:33:52 +04:00
err = azx_codec_configure ( chip ) ;
if ( err < 0 )
goto out_free ;
}
2005-04-17 02:20:36 +04:00
2012-04-26 14:23:42 +04:00
err = snd_card_register ( chip - > card ) ;
2008-11-20 04:24:52 +03:00
if ( err < 0 )
goto out_free ;
2005-04-17 02:20:36 +04:00
2007-08-10 19:21:45 +04:00
chip - > running = 1 ;
2012-08-14 19:13:32 +04:00
azx_add_card_list ( chip ) ;
2015-04-14 23:13:18 +03:00
snd_hda_set_power_save ( & chip - > bus , power_save * 1000 ) ;
2015-02-19 18:51:17 +03:00
if ( azx_has_pm_runtime ( chip ) | | hda - > use_vga_switcheroo )
2013-05-30 18:07:08 +04:00
pm_runtime_put_noidle ( & pci - > dev ) ;
2005-04-17 02:20:36 +04:00
2008-11-20 04:24:52 +03:00
out_free :
2015-04-29 12:43:36 +03:00
if ( chip - > driver_caps & AZX_DCAPS_I915_POWERWELL
& & ! hda - > need_i915_power )
2015-05-19 17:29:30 +03:00
snd_hdac_display_power ( bus , false ) ;
2015-04-29 12:43:36 +03:00
i915_power_fail :
2013-12-02 14:12:28 +04:00
if ( err < 0 )
2014-06-26 19:19:20 +04:00
hda - > init_failed = 1 ;
complete_all ( & hda - > probe_wait ) ;
2008-11-20 04:24:52 +03:00
return err ;
2005-04-17 02:20:36 +04:00
}
2012-12-06 21:35:10 +04:00
static void azx_remove ( struct pci_dev * pci )
2005-04-17 02:20:36 +04:00
{
2012-04-26 14:13:25 +04:00
struct snd_card * card = pci_get_drvdata ( pci ) ;
2012-08-23 13:32:30 +04:00
2012-04-26 14:13:25 +04:00
if ( card )
snd_card_free ( card ) ;
2005-04-17 02:20:36 +04:00
}
2015-03-05 19:21:32 +03:00
static void azx_shutdown ( struct pci_dev * pci )
{
struct snd_card * card = pci_get_drvdata ( pci ) ;
struct azx * chip ;
if ( ! card )
return ;
chip = card - > private_data ;
if ( chip & & chip - > running )
azx_stop_chip ( chip ) ;
}
2005-04-17 02:20:36 +04:00
/* PCI IDs */
2014-05-22 19:08:54 +04:00
static const struct pci_device_id azx_ids [ ] = {
2010-01-13 04:03:35 +03:00
/* CPT */
2011-05-25 11:11:37 +04:00
{ PCI_DEVICE ( 0x8086 , 0x1c20 ) ,
2013-01-08 16:51:30 +04:00
. driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH_NOPM } ,
2010-09-11 03:29:56 +04:00
/* PBG */
2011-05-25 11:11:37 +04:00
{ PCI_DEVICE ( 0x8086 , 0x1d20 ) ,
2013-01-08 16:51:30 +04:00
. driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH_NOPM } ,
2011-04-20 21:59:57 +04:00
/* Panther Point */
2011-05-25 11:11:37 +04:00
{ PCI_DEVICE ( 0x8086 , 0x1e20 ) ,
2015-02-25 09:53:31 +03:00
. driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH_NOPM } ,
2012-01-24 04:24:31 +04:00
/* Lynx Point */
{ PCI_DEVICE ( 0x8086 , 0x8c20 ) ,
2012-11-19 23:03:37 +04:00
. driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH } ,
2014-05-23 11:02:44 +04:00
/* 9 Series */
{ PCI_DEVICE ( 0x8086 , 0x8ca0 ) ,
. driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH } ,
2013-02-09 05:29:40 +04:00
/* Wellsburg */
{ PCI_DEVICE ( 0x8086 , 0x8d20 ) ,
. driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH } ,
{ PCI_DEVICE ( 0x8086 , 0x8d21 ) ,
. driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH } ,
2015-11-05 02:56:09 +03:00
/* Lewisburg */
{ PCI_DEVICE ( 0x8086 , 0xa1f0 ) ,
. driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH } ,
{ PCI_DEVICE ( 0x8086 , 0xa270 ) ,
. driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH } ,
2012-08-09 20:38:59 +04:00
/* Lynx Point-LP */
{ PCI_DEVICE ( 0x8086 , 0x9c20 ) ,
2012-11-19 23:03:37 +04:00
. driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH } ,
2012-08-09 20:38:59 +04:00
/* Lynx Point-LP */
{ PCI_DEVICE ( 0x8086 , 0x9c21 ) ,
2012-11-19 23:03:37 +04:00
. driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH } ,
2013-11-04 21:27:45 +04:00
/* Wildcat Point-LP */
{ PCI_DEVICE ( 0x8086 , 0x9ca0 ) ,
. driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH } ,
2014-10-14 02:22:03 +04:00
/* Sunrise Point */
{ PCI_DEVICE ( 0x8086 , 0xa170 ) ,
2015-03-26 08:28:39 +03:00
. driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_SKYLAKE } ,
2014-11-08 02:02:47 +03:00
/* Sunrise Point-LP */
{ PCI_DEVICE ( 0x8086 , 0x9d70 ) ,
2014-12-19 03:44:31 +03:00
. driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_SKYLAKE } ,
2015-11-19 18:25:12 +03:00
/* Broxton-P(Apollolake) */
{ PCI_DEVICE ( 0x8086 , 0x5a98 ) ,
. driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_BROXTON } ,
2012-06-13 06:23:51 +04:00
/* Haswell */
2013-02-01 18:42:19 +04:00
{ PCI_DEVICE ( 0x8086 , 0x0a0c ) ,
2013-11-05 20:54:05 +04:00
. driver_data = AZX_DRIVER_HDMI | AZX_DCAPS_INTEL_HASWELL } ,
2012-06-13 06:23:51 +04:00
{ PCI_DEVICE ( 0x8086 , 0x0c0c ) ,
2013-11-05 20:54:05 +04:00
. driver_data = AZX_DRIVER_HDMI | AZX_DCAPS_INTEL_HASWELL } ,
2012-09-17 09:10:23 +04:00
{ PCI_DEVICE ( 0x8086 , 0x0d0c ) ,
2013-11-05 20:54:05 +04:00
. driver_data = AZX_DRIVER_HDMI | AZX_DCAPS_INTEL_HASWELL } ,
2014-01-09 00:55:14 +04:00
/* Broadwell */
{ PCI_DEVICE ( 0x8086 , 0x160c ) ,
2014-06-09 11:28:59 +04:00
. driver_data = AZX_DRIVER_HDMI | AZX_DCAPS_INTEL_BROADWELL } ,
2012-09-22 03:39:07 +04:00
/* 5 Series/3400 */
{ PCI_DEVICE ( 0x8086 , 0x3b56 ) ,
2013-02-14 12:44:55 +04:00
. driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH_NOPM } ,
2013-01-29 13:12:23 +04:00
/* Poulsbo */
2011-05-25 11:11:37 +04:00
{ PCI_DEVICE ( 0x8086 , 0x811b ) ,
2013-01-29 13:12:23 +04:00
. driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH_NOPM } ,
/* Oaktrail */
2011-12-28 19:17:26 +04:00
{ PCI_DEVICE ( 0x8086 , 0x080a ) ,
2013-01-29 13:12:23 +04:00
. driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH_NOPM } ,
2013-05-16 11:36:12 +04:00
/* BayTrail */
{ PCI_DEVICE ( 0x8086 , 0x0f04 ) ,
2015-04-21 08:12:23 +03:00
. driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_BAYTRAIL } ,
2014-08-04 05:22:44 +04:00
/* Braswell */
{ PCI_DEVICE ( 0x8086 , 0x2284 ) ,
2015-04-07 15:32:20 +03:00
. driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_BRASWELL } ,
2014-12-03 11:47:20 +03:00
/* ICH6 */
2011-06-10 16:56:26 +04:00
{ PCI_DEVICE ( 0x8086 , 0x2668 ) ,
2014-12-03 11:47:20 +03:00
. driver_data = AZX_DRIVER_ICH | AZX_DCAPS_INTEL_ICH } ,
/* ICH7 */
2011-06-10 16:56:26 +04:00
{ PCI_DEVICE ( 0x8086 , 0x27d8 ) ,
2014-12-03 11:47:20 +03:00
. driver_data = AZX_DRIVER_ICH | AZX_DCAPS_INTEL_ICH } ,
/* ESB2 */
2011-06-10 16:56:26 +04:00
{ PCI_DEVICE ( 0x8086 , 0x269a ) ,
2014-12-03 11:47:20 +03:00
. driver_data = AZX_DRIVER_ICH | AZX_DCAPS_INTEL_ICH } ,
/* ICH8 */
2011-06-10 16:56:26 +04:00
{ PCI_DEVICE ( 0x8086 , 0x284b ) ,
2014-12-03 11:47:20 +03:00
. driver_data = AZX_DRIVER_ICH | AZX_DCAPS_INTEL_ICH } ,
/* ICH9 */
2011-06-10 16:56:26 +04:00
{ PCI_DEVICE ( 0x8086 , 0x293e ) ,
2014-12-03 11:47:20 +03:00
. driver_data = AZX_DRIVER_ICH | AZX_DCAPS_INTEL_ICH } ,
/* ICH9 */
2011-06-10 16:56:26 +04:00
{ PCI_DEVICE ( 0x8086 , 0x293f ) ,
2014-12-03 11:47:20 +03:00
. driver_data = AZX_DRIVER_ICH | AZX_DCAPS_INTEL_ICH } ,
/* ICH10 */
2011-06-10 16:56:26 +04:00
{ PCI_DEVICE ( 0x8086 , 0x3a3e ) ,
2014-12-03 11:47:20 +03:00
. driver_data = AZX_DRIVER_ICH | AZX_DCAPS_INTEL_ICH } ,
/* ICH10 */
2011-06-10 16:56:26 +04:00
{ PCI_DEVICE ( 0x8086 , 0x3a6e ) ,
2014-12-03 11:47:20 +03:00
. driver_data = AZX_DRIVER_ICH | AZX_DCAPS_INTEL_ICH } ,
2010-09-15 12:17:26 +04:00
/* Generic Intel */
{ PCI_DEVICE ( PCI_VENDOR_ID_INTEL , PCI_ANY_ID ) ,
. class = PCI_CLASS_MULTIMEDIA_HD_AUDIO < < 8 ,
. class_mask = 0xffffff ,
2014-12-03 11:56:20 +03:00
. driver_data = AZX_DRIVER_ICH | AZX_DCAPS_NO_ALIGN_BUFSIZE } ,
2011-05-25 11:11:37 +04:00
/* ATI SB 450/600/700/800/900 */
{ PCI_DEVICE ( 0x1002 , 0x437b ) ,
. driver_data = AZX_DRIVER_ATI | AZX_DCAPS_PRESET_ATI_SB } ,
{ PCI_DEVICE ( 0x1002 , 0x4383 ) ,
. driver_data = AZX_DRIVER_ATI | AZX_DCAPS_PRESET_ATI_SB } ,
/* AMD Hudson */
{ PCI_DEVICE ( 0x1022 , 0x780d ) ,
. driver_data = AZX_DRIVER_GENERIC | AZX_DCAPS_PRESET_ATI_SB } ,
2008-02-21 10:13:11 +03:00
/* ATI HDMI */
2015-06-24 21:37:18 +03:00
{ PCI_DEVICE ( 0x1002 , 0x1308 ) ,
. driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS } ,
2015-07-20 17:26:18 +03:00
{ PCI_DEVICE ( 0x1002 , 0x157a ) ,
. driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS } ,
2011-05-25 11:11:37 +04:00
{ PCI_DEVICE ( 0x1002 , 0x793b ) ,
. driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI } ,
{ PCI_DEVICE ( 0x1002 , 0x7919 ) ,
. driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI } ,
{ PCI_DEVICE ( 0x1002 , 0x960f ) ,
. driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI } ,
{ PCI_DEVICE ( 0x1002 , 0x970f ) ,
. driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI } ,
2015-06-24 21:37:18 +03:00
{ PCI_DEVICE ( 0x1002 , 0x9840 ) ,
. driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS } ,
2011-05-25 11:11:37 +04:00
{ PCI_DEVICE ( 0x1002 , 0xaa00 ) ,
. driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI } ,
{ PCI_DEVICE ( 0x1002 , 0xaa08 ) ,
. driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI } ,
{ PCI_DEVICE ( 0x1002 , 0xaa10 ) ,
. driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI } ,
{ PCI_DEVICE ( 0x1002 , 0xaa18 ) ,
. driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI } ,
{ PCI_DEVICE ( 0x1002 , 0xaa20 ) ,
. driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI } ,
{ PCI_DEVICE ( 0x1002 , 0xaa28 ) ,
. driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI } ,
{ PCI_DEVICE ( 0x1002 , 0xaa30 ) ,
. driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI } ,
{ PCI_DEVICE ( 0x1002 , 0xaa38 ) ,
. driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI } ,
{ PCI_DEVICE ( 0x1002 , 0xaa40 ) ,
. driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI } ,
{ PCI_DEVICE ( 0x1002 , 0xaa48 ) ,
. driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI } ,
2013-11-05 12:27:10 +04:00
{ PCI_DEVICE ( 0x1002 , 0xaa50 ) ,
. driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI } ,
{ PCI_DEVICE ( 0x1002 , 0xaa58 ) ,
. driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI } ,
{ PCI_DEVICE ( 0x1002 , 0xaa60 ) ,
. driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI } ,
{ PCI_DEVICE ( 0x1002 , 0xaa68 ) ,
. driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI } ,
{ PCI_DEVICE ( 0x1002 , 0xaa80 ) ,
. driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI } ,
{ PCI_DEVICE ( 0x1002 , 0xaa88 ) ,
. driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI } ,
{ PCI_DEVICE ( 0x1002 , 0xaa90 ) ,
. driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI } ,
{ PCI_DEVICE ( 0x1002 , 0xaa98 ) ,
. driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI } ,
2011-12-14 12:10:27 +04:00
{ PCI_DEVICE ( 0x1002 , 0x9902 ) ,
2014-11-25 13:28:07 +03:00
. driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS } ,
2011-12-14 12:10:27 +04:00
{ PCI_DEVICE ( 0x1002 , 0xaaa0 ) ,
2014-11-25 13:28:07 +03:00
. driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS } ,
2011-12-14 12:10:27 +04:00
{ PCI_DEVICE ( 0x1002 , 0xaaa8 ) ,
2014-11-25 13:28:07 +03:00
. driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS } ,
2011-12-14 12:10:27 +04:00
{ PCI_DEVICE ( 0x1002 , 0xaab0 ) ,
2014-11-25 13:28:07 +03:00
. driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS } ,
2015-07-20 17:26:18 +03:00
{ PCI_DEVICE ( 0x1002 , 0xaac0 ) ,
. driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS } ,
2015-05-27 17:17:19 +03:00
{ PCI_DEVICE ( 0x1002 , 0xaac8 ) ,
. driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS } ,
2015-07-20 17:26:18 +03:00
{ PCI_DEVICE ( 0x1002 , 0xaad8 ) ,
. driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS } ,
{ PCI_DEVICE ( 0x1002 , 0xaae8 ) ,
. driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS } ,
2008-02-21 10:13:11 +03:00
/* VIA VT8251/VT8237A */
2011-05-25 11:11:37 +04:00
{ PCI_DEVICE ( 0x1106 , 0x3288 ) ,
. driver_data = AZX_DRIVER_VIA | AZX_DCAPS_POSFIX_VIA } ,
2012-06-08 15:18:39 +04:00
/* VIA GFX VT7122/VX900 */
{ PCI_DEVICE ( 0x1106 , 0x9170 ) , . driver_data = AZX_DRIVER_GENERIC } ,
/* VIA GFX VT6122/VX11 */
{ PCI_DEVICE ( 0x1106 , 0x9140 ) , . driver_data = AZX_DRIVER_GENERIC } ,
2008-02-21 10:13:11 +03:00
/* SIS966 */
{ PCI_DEVICE ( 0x1039 , 0x7502 ) , . driver_data = AZX_DRIVER_SIS } ,
/* ULI M5461 */
{ PCI_DEVICE ( 0x10b9 , 0x5461 ) , . driver_data = AZX_DRIVER_ULI } ,
/* NVIDIA MCP */
2009-12-18 18:41:39 +03:00
{ PCI_DEVICE ( PCI_VENDOR_ID_NVIDIA , PCI_ANY_ID ) ,
. class = PCI_CLASS_MULTIMEDIA_HD_AUDIO < < 8 ,
. class_mask = 0xffffff ,
2011-05-25 11:11:37 +04:00
. driver_data = AZX_DRIVER_NVIDIA | AZX_DCAPS_PRESET_NVIDIA } ,
2008-05-27 13:44:55 +04:00
/* Teradici */
2011-05-25 11:11:37 +04:00
{ PCI_DEVICE ( 0x6549 , 0x1200 ) ,
. driver_data = AZX_DRIVER_TERA | AZX_DCAPS_NO_64BIT } ,
2012-11-03 00:10:39 +04:00
{ PCI_DEVICE ( 0x6549 , 0x2200 ) ,
. driver_data = AZX_DRIVER_TERA | AZX_DCAPS_NO_64BIT } ,
2009-04-16 10:53:34 +04:00
/* Creative X-Fi (CA0110-IBG) */
2012-06-11 17:51:54 +04:00
/* CTHDA chips */
{ PCI_DEVICE ( 0x1102 , 0x0010 ) ,
. driver_data = AZX_DRIVER_CTHDA | AZX_DCAPS_PRESET_CTHDA } ,
{ PCI_DEVICE ( 0x1102 , 0x0012 ) ,
. driver_data = AZX_DRIVER_CTHDA | AZX_DCAPS_PRESET_CTHDA } ,
2014-02-10 12:48:47 +04:00
# if !IS_ENABLED(CONFIG_SND_CTXFI)
2009-05-18 14:40:52 +04:00
/* the following entry conflicts with snd-ctxfi driver,
* as ctxfi driver mutates from HD - audio to native mode with
* a special command sequence .
*/
2009-04-16 10:53:34 +04:00
{ PCI_DEVICE ( PCI_VENDOR_ID_CREATIVE , PCI_ANY_ID ) ,
. class = PCI_CLASS_MULTIMEDIA_HD_AUDIO < < 8 ,
. class_mask = 0xffffff ,
2011-05-25 11:11:37 +04:00
. driver_data = AZX_DRIVER_CTX | AZX_DCAPS_CTX_WORKAROUND |
2015-10-27 16:21:51 +03:00
AZX_DCAPS_NO_64BIT |
2011-11-06 16:49:13 +04:00
AZX_DCAPS_RIRB_PRE_DELAY | AZX_DCAPS_POSFIX_LPIB } ,
2009-05-18 14:40:52 +04:00
# else
/* this entry seems still valid -- i.e. without emu20kx chip */
2011-05-25 11:11:37 +04:00
{ PCI_DEVICE ( 0x1102 , 0x0009 ) ,
. driver_data = AZX_DRIVER_CTX | AZX_DCAPS_CTX_WORKAROUND |
2015-10-27 16:21:51 +03:00
AZX_DCAPS_NO_64BIT |
2011-11-06 16:49:13 +04:00
AZX_DCAPS_RIRB_PRE_DELAY | AZX_DCAPS_POSFIX_LPIB } ,
2009-05-18 14:40:52 +04:00
# endif
2014-08-06 16:27:42 +04:00
/* CM8888 */
{ PCI_DEVICE ( 0x13f6 , 0x5011 ) ,
. driver_data = AZX_DRIVER_CMEDIA |
2014-11-25 13:28:07 +03:00
AZX_DCAPS_NO_MSI | AZX_DCAPS_POSFIX_LPIB | AZX_DCAPS_SNOOP_OFF } ,
2010-09-27 06:35:06 +04:00
/* Vortex86MX */
{ PCI_DEVICE ( 0x17f3 , 0x3010 ) , . driver_data = AZX_DRIVER_GENERIC } ,
2011-01-17 17:23:21 +03:00
/* VMware HDAudio */
{ PCI_DEVICE ( 0x15ad , 0x1977 ) , . driver_data = AZX_DRIVER_GENERIC } ,
2009-07-17 07:32:32 +04:00
/* AMD/ATI Generic, PCI class code and Vendor ID for HD Audio */
2008-11-13 13:07:07 +03:00
{ PCI_DEVICE ( PCI_VENDOR_ID_ATI , PCI_ANY_ID ) ,
. class = PCI_CLASS_MULTIMEDIA_HD_AUDIO < < 8 ,
. class_mask = 0xffffff ,
2011-05-25 11:11:37 +04:00
. driver_data = AZX_DRIVER_GENERIC | AZX_DCAPS_PRESET_ATI_HDMI } ,
2009-07-17 07:32:32 +04:00
{ PCI_DEVICE ( PCI_VENDOR_ID_AMD , PCI_ANY_ID ) ,
. class = PCI_CLASS_MULTIMEDIA_HD_AUDIO < < 8 ,
. class_mask = 0xffffff ,
2011-05-25 11:11:37 +04:00
. driver_data = AZX_DRIVER_GENERIC | AZX_DCAPS_PRESET_ATI_HDMI } ,
2005-04-17 02:20:36 +04:00
{ 0 , }
} ;
MODULE_DEVICE_TABLE ( pci , azx_ids ) ;
/* pci_driver definition */
2012-04-24 14:25:00 +04:00
static struct pci_driver azx_driver = {
2011-06-10 18:20:20 +04:00
. name = KBUILD_MODNAME ,
2005-04-17 02:20:36 +04:00
. id_table = azx_ids ,
. probe = azx_probe ,
2012-12-06 21:35:10 +04:00
. remove = azx_remove ,
2015-03-05 19:21:32 +03:00
. shutdown = azx_shutdown ,
2012-07-02 17:20:37 +04:00
. driver = {
. pm = AZX_PM_OPS ,
} ,
2005-04-17 02:20:36 +04:00
} ;
2012-04-24 14:25:00 +04:00
module_pci_driver ( azx_driver ) ;