mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-18 09:16:55 +07:00
Sound update for 3.6-rc1
This is a fairly quiet release in all sound area. Only a little bit of changes in the core side while most of changes are seen in the drivers. HD-audio: - A few new codec additions for Nvidia, Realtek and VIA - Intel Haswell audio support - Support for "phantom" jacks for consistent jack reporting - Major clean-ups in HDMI/DP driver codes - A workaround for inverted digital-mic pins with Realtek codecs - Removal of beep_mode=2 option ASoC: - Added the ability to add and remove DAPM paths dynamically, mostly for reparenting on clock changes - New machine drivers for Marvell Brownstone, ST-Ericsson Ux500 reference platform and ttc-dkp - New CPU drivers for Blackfin BF6xx SPORTs in I2S mode, Marvell MMP, Synopsis Designware I2S controllers, and SPEAr DMA and S/PDIF - New CODEC drivers for Dialog DA732x, ST STA529, ST-Ericsson AB8500, TI Isabelle and Wolfson Microelectronics WM5102 and WM5110 - DAPM fixes for the recent locking changes - Fix for _PRE and _POST widgets (which have been broken for a few releases now) - A couple of minor driver updates Misc - Conversion to new dev_pm_ops in platform and PCI drivers - LTC support and some fixes in PCXHR driver - A few fixes and PM support for ISA OPti9xx and WSS cards - Some TLV code cleanup - Move driver-specific headers from include/sound to local dirs -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.19 (GNU/Linux) iQIcBAABAgAGBQJQDmlZAAoJEGwxgFQ9KSmkbZgQAJ8PzD1qFu/P+ARCtzWiWaun EPPiZeM8U4FW7S8jMpMnO03Cd98zjafNv4I3JJkkhVpK3nnqehNuqkLhWjKz9mY9 d8nX1AlCohHlnnrdDDOmSpKHFPIkfoLZGBHMxWZF7OvYrvSSfb40Or8eC/zMcvxq ULcL3/rQtQh2ybZOGxBtESJhIvl1DZAkRoGKUb3+/yLrrz6ziAwXWq04yvINuZQm YxSxxe545Xz5wyCQS730yk7bH4+MbXR0ltaId4ZGlWrj6t1MYrUO67PywNqMf9iC HgdzdvfwGy+DCrX+eILc+macpzpdg5FQJi84WmcBP5CQKQ9lH9Jdqe8G14QVRS4t 9Zv8lzatfjAnRnz5PY43sFBunG+82VRXsZ51SW//9EpiNcHEdA6KmNZRMAtu/NYq c9zqMEPSDSrch/BI901JJBDRuJs0IEB81CEBsjLyauJFM0rUkUBOLZRAgeR2Noft GEK4gh22r0+I3dsMsKmO6jr6UWUbG44ZKoRV0zmg1QKdqfnT1T2PdXo+3MBa/uKO MpBFWnw/JOjQZo3+oZ8FOCqNNDtHcvju4kHbmI+DksvSHH0m/NsY8tqG6uhpwN5t BDQX3a8Z6I6AbuyLIWNgHC+gjYLPN/vu7UjdZ1O78ztB/qUkatfHvzW24ez1BOUJ 1fDDG1mkdVvnKRO06Sat =N0aj -----END PGP SIGNATURE----- Merge tag 'sound-3.6' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound Pull sound update from Takashi Iwai: "This is a fairly quiet release in all sound area. Only a little bit of changes in the core side while most of changes are seen in the drivers. HD-audio: - A few new codec additions for Nvidia, Realtek and VIA - Intel Haswell audio support - Support for "phantom" jacks for consistent jack reporting - Major clean-ups in HDMI/DP driver codes - A workaround for inverted digital-mic pins with Realtek codecs - Removal of beep_mode=2 option ASoC: - Added the ability to add and remove DAPM paths dynamically, mostly for reparenting on clock changes - New machine drivers for Marvell Brownstone, ST-Ericsson Ux500 reference platform and ttc-dkp - New CPU drivers for Blackfin BF6xx SPORTs in I2S mode, Marvell MMP, Synopsis Designware I2S controllers, and SPEAr DMA and S/PDIF - New CODEC drivers for Dialog DA732x, ST STA529, ST-Ericsson AB8500, TI Isabelle and Wolfson Microelectronics WM5102 and WM5110 - DAPM fixes for the recent locking changes - Fix for _PRE and _POST widgets (which have been broken for a few releases now) - A couple of minor driver updates Misc - Conversion to new dev_pm_ops in platform and PCI drivers - LTC support and some fixes in PCXHR driver - A few fixes and PM support for ISA OPti9xx and WSS cards - Some TLV code cleanup - Move driver-specific headers from include/sound to local dirs" * tag 'sound-3.6' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (212 commits) ASoC: dapm: Fix _PRE and _POST events for DAPM performance improvements ALSA: hda - add dock support for Thinkpad X230 Tablet ALSA: hda - Turn on PIN_OUT from hdmi playback prepare. ASoC imx-audmux: add MX31_AUDMUX_PORT7_SSI_PINS_7 define ASoC: littlemill: Add userspace control of the WM1250 I/O ASoC: wm8994: Update micdet for irqdomain conversion ALSA: hda - make sure alc268 does not OOPS on codec parse ALSA: hda - Add support for Realtek ALC282 ALSA: hda - Fix index number conflicts of phantom jacks ALSA: opti9xx: Fix section mismatch by PM support ALSA: snd-opti9xx: Implement suspend/resume ALSA: hda - Add new GPU codec ID to snd-hda ALSA: hda - Fix driver type of Haswell controller to AZX_DRIVER_SCH ALSA: hda - add Haswell HDMI codec id ALSA: hda - Add DeviceID for Haswell HDA ALSA: wss_lib: Fix resume on Yamaha OPL3-SAx ALSA: wss_lib: fix suspend/resume ALSA: es1938: replace TLV_DB_RANGE_HEAD with DECLARE_TLV_DB_RANGE ALSA: tlv: add DECLARE_TLV_DB_RANGE() ALSA: tlv: add DECLARE_TLV_CONTAINER() ...
This commit is contained in:
commit
dbf7b5915b
@ -875,8 +875,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
||||
setup before initializing the codecs. This option is
|
||||
available only when CONFIG_SND_HDA_PATCH_LOADER=y is set.
|
||||
See HD-Audio.txt for details.
|
||||
beep_mode - Selects the beep registration mode (0=off, 1=on, 2=
|
||||
dynamic registration via mute switch on/off); the default
|
||||
beep_mode - Selects the beep registration mode (0=off, 1=on); default
|
||||
value is set via CONFIG_SND_HDA_INPUT_BEEP_MODE kconfig.
|
||||
|
||||
[Single (global) options]
|
||||
|
@ -15,19 +15,24 @@ ALC260
|
||||
|
||||
ALC262
|
||||
======
|
||||
N/A
|
||||
inv-dmic Inverted internal mic workaround
|
||||
|
||||
ALC267/268
|
||||
==========
|
||||
N/A
|
||||
inv-dmic Inverted internal mic workaround
|
||||
|
||||
ALC269
|
||||
ALC269/270/275/276/280/282
|
||||
======
|
||||
laptop-amic Laptops with analog-mic input
|
||||
laptop-dmic Laptops with digital-mic input
|
||||
alc269-dmic Enable ALC269(VA) digital mic workaround
|
||||
alc271-dmic Enable ALC271X digital mic workaround
|
||||
inv-dmic Inverted internal mic workaround
|
||||
lenovo-dock Enables docking station I/O for some Lenovos
|
||||
|
||||
ALC662/663/272
|
||||
==============
|
||||
mario Chromebook mario model fixup
|
||||
asus-mode1 ASUS
|
||||
asus-mode2 ASUS
|
||||
asus-mode3 ASUS
|
||||
@ -36,6 +41,7 @@ ALC662/663/272
|
||||
asus-mode6 ASUS
|
||||
asus-mode7 ASUS
|
||||
asus-mode8 ASUS
|
||||
inv-dmic Inverted internal mic workaround
|
||||
|
||||
ALC680
|
||||
======
|
||||
@ -46,6 +52,7 @@ ALC882/883/885/888/889
|
||||
acer-aspire-4930g Acer Aspire 4930G/5930G/6530G/6930G/7730G
|
||||
acer-aspire-8930g Acer Aspire 8330G/6935G
|
||||
acer-aspire Acer Aspire others
|
||||
inv-dmic Inverted internal mic workaround
|
||||
|
||||
ALC861/660
|
||||
==========
|
||||
|
@ -6765,9 +6765,11 @@ F: include/linux/tifm.h
|
||||
|
||||
TI LM49xxx FAMILY ASoC CODEC DRIVERS
|
||||
M: M R Swami Reddy <mr.swami.reddy@ti.com>
|
||||
M: Vishwas A Deshpande <vishwas.a.deshpande@ti.com>
|
||||
L: alsa-devel@alsa-project.org (moderated for non-subscribers)
|
||||
S: Maintained
|
||||
F: sound/soc/codecs/lm49453*
|
||||
F: sound/soc/codecs/isabelle*
|
||||
|
||||
TI TWL4030 SERIES SOC CODEC DRIVER
|
||||
M: Peter Ujfalusi <peter.ujfalusi@ti.com>
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include <linux/mfd/tc3589x.h>
|
||||
#include <linux/mfd/tps6105x.h>
|
||||
#include <linux/mfd/abx500/ab8500-gpio.h>
|
||||
#include <linux/mfd/abx500/ab8500-codec.h>
|
||||
#include <linux/leds-lp5521.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/smsc911x.h>
|
||||
@ -97,6 +98,18 @@ static struct ab8500_gpio_platform_data ab8500_gpio_pdata = {
|
||||
0x7A, 0x00, 0x00},
|
||||
};
|
||||
|
||||
/* ab8500-codec */
|
||||
static struct ab8500_codec_platform_data ab8500_codec_pdata = {
|
||||
.amics = {
|
||||
.mic1_type = AMIC_TYPE_DIFFERENTIAL,
|
||||
.mic2_type = AMIC_TYPE_DIFFERENTIAL,
|
||||
.mic1a_micbias = AMIC_MICBIAS_VAMIC1,
|
||||
.mic1b_micbias = AMIC_MICBIAS_VAMIC1,
|
||||
.mic2_micbias = AMIC_MICBIAS_VAMIC2
|
||||
},
|
||||
.ear_cmv = EAR_CMV_0_95V
|
||||
};
|
||||
|
||||
static struct gpio_keys_button snowball_key_array[] = {
|
||||
{
|
||||
.gpio = 32,
|
||||
@ -195,6 +208,7 @@ static struct ab8500_platform_data ab8500_platdata = {
|
||||
.regulator = ab8500_regulators,
|
||||
.num_regulator = ARRAY_SIZE(ab8500_regulators),
|
||||
.gpio = &ab8500_gpio_pdata,
|
||||
.codec = &ab8500_codec_pdata,
|
||||
};
|
||||
|
||||
static struct resource ab8500_resources[] = {
|
||||
|
@ -1,362 +0,0 @@
|
||||
#ifndef _AC97_CODEC_H_
|
||||
#define _AC97_CODEC_H_
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/soundcard.h>
|
||||
|
||||
/* AC97 1.0 */
|
||||
#define AC97_RESET 0x0000 //
|
||||
#define AC97_MASTER_VOL_STEREO 0x0002 // Line Out
|
||||
#define AC97_HEADPHONE_VOL 0x0004 //
|
||||
#define AC97_MASTER_VOL_MONO 0x0006 // TAD Output
|
||||
#define AC97_MASTER_TONE 0x0008 //
|
||||
#define AC97_PCBEEP_VOL 0x000a // none
|
||||
#define AC97_PHONE_VOL 0x000c // TAD Input (mono)
|
||||
#define AC97_MIC_VOL 0x000e // MIC Input (mono)
|
||||
#define AC97_LINEIN_VOL 0x0010 // Line Input (stereo)
|
||||
#define AC97_CD_VOL 0x0012 // CD Input (stereo)
|
||||
#define AC97_VIDEO_VOL 0x0014 // none
|
||||
#define AC97_AUX_VOL 0x0016 // Aux Input (stereo)
|
||||
#define AC97_PCMOUT_VOL 0x0018 // Wave Output (stereo)
|
||||
#define AC97_RECORD_SELECT 0x001a //
|
||||
#define AC97_RECORD_GAIN 0x001c
|
||||
#define AC97_RECORD_GAIN_MIC 0x001e
|
||||
#define AC97_GENERAL_PURPOSE 0x0020
|
||||
#define AC97_3D_CONTROL 0x0022
|
||||
#define AC97_MODEM_RATE 0x0024
|
||||
#define AC97_POWER_CONTROL 0x0026
|
||||
|
||||
/* AC'97 2.0 */
|
||||
#define AC97_EXTENDED_ID 0x0028 /* Extended Audio ID */
|
||||
#define AC97_EXTENDED_STATUS 0x002A /* Extended Audio Status */
|
||||
#define AC97_PCM_FRONT_DAC_RATE 0x002C /* PCM Front DAC Rate */
|
||||
#define AC97_PCM_SURR_DAC_RATE 0x002E /* PCM Surround DAC Rate */
|
||||
#define AC97_PCM_LFE_DAC_RATE 0x0030 /* PCM LFE DAC Rate */
|
||||
#define AC97_PCM_LR_ADC_RATE 0x0032 /* PCM LR ADC Rate */
|
||||
#define AC97_PCM_MIC_ADC_RATE 0x0034 /* PCM MIC ADC Rate */
|
||||
#define AC97_CENTER_LFE_MASTER 0x0036 /* Center + LFE Master Volume */
|
||||
#define AC97_SURROUND_MASTER 0x0038 /* Surround (Rear) Master Volume */
|
||||
#define AC97_RESERVED_3A 0x003A /* Reserved in AC '97 < 2.2 */
|
||||
|
||||
/* AC'97 2.2 */
|
||||
#define AC97_SPDIF_CONTROL 0x003A /* S/PDIF Control */
|
||||
|
||||
/* range 0x3c-0x58 - MODEM */
|
||||
#define AC97_EXTENDED_MODEM_ID 0x003C
|
||||
#define AC97_EXTEND_MODEM_STAT 0x003E
|
||||
#define AC97_LINE1_RATE 0x0040
|
||||
#define AC97_LINE2_RATE 0x0042
|
||||
#define AC97_HANDSET_RATE 0x0044
|
||||
#define AC97_LINE1_LEVEL 0x0046
|
||||
#define AC97_LINE2_LEVEL 0x0048
|
||||
#define AC97_HANDSET_LEVEL 0x004A
|
||||
#define AC97_GPIO_CONFIG 0x004C
|
||||
#define AC97_GPIO_POLARITY 0x004E
|
||||
#define AC97_GPIO_STICKY 0x0050
|
||||
#define AC97_GPIO_WAKE_UP 0x0052
|
||||
#define AC97_GPIO_STATUS 0x0054
|
||||
#define AC97_MISC_MODEM_STAT 0x0056
|
||||
#define AC97_RESERVED_58 0x0058
|
||||
|
||||
/* registers 0x005a - 0x007a are vendor reserved */
|
||||
|
||||
#define AC97_VENDOR_ID1 0x007c
|
||||
#define AC97_VENDOR_ID2 0x007e
|
||||
|
||||
/* volume control bit defines */
|
||||
#define AC97_MUTE 0x8000
|
||||
#define AC97_MICBOOST 0x0040
|
||||
#define AC97_LEFTVOL 0x3f00
|
||||
#define AC97_RIGHTVOL 0x003f
|
||||
|
||||
/* record mux defines */
|
||||
#define AC97_RECMUX_MIC 0x0000
|
||||
#define AC97_RECMUX_CD 0x0101
|
||||
#define AC97_RECMUX_VIDEO 0x0202
|
||||
#define AC97_RECMUX_AUX 0x0303
|
||||
#define AC97_RECMUX_LINE 0x0404
|
||||
#define AC97_RECMUX_STEREO_MIX 0x0505
|
||||
#define AC97_RECMUX_MONO_MIX 0x0606
|
||||
#define AC97_RECMUX_PHONE 0x0707
|
||||
|
||||
/* general purpose register bit defines */
|
||||
#define AC97_GP_LPBK 0x0080 /* Loopback mode */
|
||||
#define AC97_GP_MS 0x0100 /* Mic Select 0=Mic1, 1=Mic2 */
|
||||
#define AC97_GP_MIX 0x0200 /* Mono output select 0=Mix, 1=Mic */
|
||||
#define AC97_GP_RLBK 0x0400 /* Remote Loopback - Modem line codec */
|
||||
#define AC97_GP_LLBK 0x0800 /* Local Loopback - Modem Line codec */
|
||||
#define AC97_GP_LD 0x1000 /* Loudness 1=on */
|
||||
#define AC97_GP_3D 0x2000 /* 3D Enhancement 1=on */
|
||||
#define AC97_GP_ST 0x4000 /* Stereo Enhancement 1=on */
|
||||
#define AC97_GP_POP 0x8000 /* Pcm Out Path, 0=pre 3D, 1=post 3D */
|
||||
|
||||
/* extended audio status and control bit defines */
|
||||
#define AC97_EA_VRA 0x0001 /* Variable bit rate enable bit */
|
||||
#define AC97_EA_DRA 0x0002 /* Double-rate audio enable bit */
|
||||
#define AC97_EA_SPDIF 0x0004 /* S/PDIF Enable bit */
|
||||
#define AC97_EA_VRM 0x0008 /* Variable bit rate for MIC enable bit */
|
||||
#define AC97_EA_CDAC 0x0040 /* PCM Center DAC is ready (Read only) */
|
||||
#define AC97_EA_SDAC 0x0040 /* PCM Surround DACs are ready (Read only) */
|
||||
#define AC97_EA_LDAC 0x0080 /* PCM LFE DAC is ready (Read only) */
|
||||
#define AC97_EA_MDAC 0x0100 /* MIC ADC is ready (Read only) */
|
||||
#define AC97_EA_SPCV 0x0400 /* S/PDIF configuration valid (Read only) */
|
||||
#define AC97_EA_PRI 0x0800 /* Turns the PCM Center DAC off */
|
||||
#define AC97_EA_PRJ 0x1000 /* Turns the PCM Surround DACs off */
|
||||
#define AC97_EA_PRK 0x2000 /* Turns the PCM LFE DAC off */
|
||||
#define AC97_EA_PRL 0x4000 /* Turns the MIC ADC off */
|
||||
#define AC97_EA_SLOT_MASK 0xffcf /* Mask for slot assignment bits */
|
||||
#define AC97_EA_SPSA_3_4 0x0000 /* Slot assigned to 3 & 4 */
|
||||
#define AC97_EA_SPSA_7_8 0x0010 /* Slot assigned to 7 & 8 */
|
||||
#define AC97_EA_SPSA_6_9 0x0020 /* Slot assigned to 6 & 9 */
|
||||
#define AC97_EA_SPSA_10_11 0x0030 /* Slot assigned to 10 & 11 */
|
||||
|
||||
/* S/PDIF control bit defines */
|
||||
#define AC97_SC_PRO 0x0001 /* Professional status */
|
||||
#define AC97_SC_NAUDIO 0x0002 /* Non audio stream */
|
||||
#define AC97_SC_COPY 0x0004 /* Copyright status */
|
||||
#define AC97_SC_PRE 0x0008 /* Preemphasis status */
|
||||
#define AC97_SC_CC_MASK 0x07f0 /* Category Code mask */
|
||||
#define AC97_SC_L 0x0800 /* Generation Level status */
|
||||
#define AC97_SC_SPSR_MASK 0xcfff /* S/PDIF Sample Rate bits */
|
||||
#define AC97_SC_SPSR_44K 0x0000 /* Use 44.1kHz Sample rate */
|
||||
#define AC97_SC_SPSR_48K 0x2000 /* Use 48kHz Sample rate */
|
||||
#define AC97_SC_SPSR_32K 0x3000 /* Use 32kHz Sample rate */
|
||||
#define AC97_SC_DRS 0x4000 /* Double Rate S/PDIF */
|
||||
#define AC97_SC_V 0x8000 /* Validity status */
|
||||
|
||||
/* powerdown control and status bit defines */
|
||||
|
||||
/* status */
|
||||
#define AC97_PWR_MDM 0x0010 /* Modem section ready */
|
||||
#define AC97_PWR_REF 0x0008 /* Vref nominal */
|
||||
#define AC97_PWR_ANL 0x0004 /* Analog section ready */
|
||||
#define AC97_PWR_DAC 0x0002 /* DAC section ready */
|
||||
#define AC97_PWR_ADC 0x0001 /* ADC section ready */
|
||||
|
||||
/* control */
|
||||
#define AC97_PWR_PR0 0x0100 /* ADC and Mux powerdown */
|
||||
#define AC97_PWR_PR1 0x0200 /* DAC powerdown */
|
||||
#define AC97_PWR_PR2 0x0400 /* Output mixer powerdown (Vref on) */
|
||||
#define AC97_PWR_PR3 0x0800 /* Output mixer powerdown (Vref off) */
|
||||
#define AC97_PWR_PR4 0x1000 /* AC-link powerdown */
|
||||
#define AC97_PWR_PR5 0x2000 /* Internal Clk disable */
|
||||
#define AC97_PWR_PR6 0x4000 /* HP amp powerdown */
|
||||
#define AC97_PWR_PR7 0x8000 /* Modem off - if supported */
|
||||
|
||||
/* extended audio ID register bit defines */
|
||||
#define AC97_EXTID_VRA 0x0001
|
||||
#define AC97_EXTID_DRA 0x0002
|
||||
#define AC97_EXTID_SPDIF 0x0004
|
||||
#define AC97_EXTID_VRM 0x0008
|
||||
#define AC97_EXTID_DSA0 0x0010
|
||||
#define AC97_EXTID_DSA1 0x0020
|
||||
#define AC97_EXTID_CDAC 0x0040
|
||||
#define AC97_EXTID_SDAC 0x0080
|
||||
#define AC97_EXTID_LDAC 0x0100
|
||||
#define AC97_EXTID_AMAP 0x0200
|
||||
#define AC97_EXTID_REV0 0x0400
|
||||
#define AC97_EXTID_REV1 0x0800
|
||||
#define AC97_EXTID_ID0 0x4000
|
||||
#define AC97_EXTID_ID1 0x8000
|
||||
|
||||
/* extended status register bit defines */
|
||||
#define AC97_EXTSTAT_VRA 0x0001
|
||||
#define AC97_EXTSTAT_DRA 0x0002
|
||||
#define AC97_EXTSTAT_SPDIF 0x0004
|
||||
#define AC97_EXTSTAT_VRM 0x0008
|
||||
#define AC97_EXTSTAT_SPSA0 0x0010
|
||||
#define AC97_EXTSTAT_SPSA1 0x0020
|
||||
#define AC97_EXTSTAT_CDAC 0x0040
|
||||
#define AC97_EXTSTAT_SDAC 0x0080
|
||||
#define AC97_EXTSTAT_LDAC 0x0100
|
||||
#define AC97_EXTSTAT_MADC 0x0200
|
||||
#define AC97_EXTSTAT_SPCV 0x0400
|
||||
#define AC97_EXTSTAT_PRI 0x0800
|
||||
#define AC97_EXTSTAT_PRJ 0x1000
|
||||
#define AC97_EXTSTAT_PRK 0x2000
|
||||
#define AC97_EXTSTAT_PRL 0x4000
|
||||
|
||||
/* extended audio ID register bit defines */
|
||||
#define AC97_EXTID_VRA 0x0001
|
||||
#define AC97_EXTID_DRA 0x0002
|
||||
#define AC97_EXTID_SPDIF 0x0004
|
||||
#define AC97_EXTID_VRM 0x0008
|
||||
#define AC97_EXTID_DSA0 0x0010
|
||||
#define AC97_EXTID_DSA1 0x0020
|
||||
#define AC97_EXTID_CDAC 0x0040
|
||||
#define AC97_EXTID_SDAC 0x0080
|
||||
#define AC97_EXTID_LDAC 0x0100
|
||||
#define AC97_EXTID_AMAP 0x0200
|
||||
#define AC97_EXTID_REV0 0x0400
|
||||
#define AC97_EXTID_REV1 0x0800
|
||||
#define AC97_EXTID_ID0 0x4000
|
||||
#define AC97_EXTID_ID1 0x8000
|
||||
|
||||
/* extended status register bit defines */
|
||||
#define AC97_EXTSTAT_VRA 0x0001
|
||||
#define AC97_EXTSTAT_DRA 0x0002
|
||||
#define AC97_EXTSTAT_SPDIF 0x0004
|
||||
#define AC97_EXTSTAT_VRM 0x0008
|
||||
#define AC97_EXTSTAT_SPSA0 0x0010
|
||||
#define AC97_EXTSTAT_SPSA1 0x0020
|
||||
#define AC97_EXTSTAT_CDAC 0x0040
|
||||
#define AC97_EXTSTAT_SDAC 0x0080
|
||||
#define AC97_EXTSTAT_LDAC 0x0100
|
||||
#define AC97_EXTSTAT_MADC 0x0200
|
||||
#define AC97_EXTSTAT_SPCV 0x0400
|
||||
#define AC97_EXTSTAT_PRI 0x0800
|
||||
#define AC97_EXTSTAT_PRJ 0x1000
|
||||
#define AC97_EXTSTAT_PRK 0x2000
|
||||
#define AC97_EXTSTAT_PRL 0x4000
|
||||
|
||||
/* useful power states */
|
||||
#define AC97_PWR_D0 0x0000 /* everything on */
|
||||
#define AC97_PWR_D1 AC97_PWR_PR0|AC97_PWR_PR1|AC97_PWR_PR4
|
||||
#define AC97_PWR_D2 AC97_PWR_PR0|AC97_PWR_PR1|AC97_PWR_PR2|AC97_PWR_PR3|AC97_PWR_PR4
|
||||
#define AC97_PWR_D3 AC97_PWR_PR0|AC97_PWR_PR1|AC97_PWR_PR2|AC97_PWR_PR3|AC97_PWR_PR4
|
||||
#define AC97_PWR_ANLOFF AC97_PWR_PR2|AC97_PWR_PR3 /* analog section off */
|
||||
|
||||
/* Total number of defined registers. */
|
||||
#define AC97_REG_CNT 64
|
||||
|
||||
|
||||
/* OSS interface to the ac97s.. */
|
||||
#define AC97_STEREO_MASK (SOUND_MASK_VOLUME|SOUND_MASK_PCM|\
|
||||
SOUND_MASK_LINE|SOUND_MASK_CD|\
|
||||
SOUND_MASK_ALTPCM|SOUND_MASK_IGAIN|\
|
||||
SOUND_MASK_LINE1|SOUND_MASK_VIDEO)
|
||||
|
||||
#define AC97_SUPPORTED_MASK (AC97_STEREO_MASK | \
|
||||
SOUND_MASK_BASS|SOUND_MASK_TREBLE|\
|
||||
SOUND_MASK_SPEAKER|SOUND_MASK_MIC|\
|
||||
SOUND_MASK_PHONEIN|SOUND_MASK_PHONEOUT)
|
||||
|
||||
#define AC97_RECORD_MASK (SOUND_MASK_MIC|\
|
||||
SOUND_MASK_CD|SOUND_MASK_IGAIN|SOUND_MASK_VIDEO|\
|
||||
SOUND_MASK_LINE1| SOUND_MASK_LINE|\
|
||||
SOUND_MASK_PHONEIN)
|
||||
|
||||
/* original check is not good enough in case FOO is greater than
|
||||
* SOUND_MIXER_NRDEVICES because the supported_mixers has exactly
|
||||
* SOUND_MIXER_NRDEVICES elements.
|
||||
* before matching the given mixer against the bitmask in supported_mixers we
|
||||
* check if mixer number exceeds maximum allowed size which is as mentioned
|
||||
* above SOUND_MIXER_NRDEVICES */
|
||||
#define supported_mixer(CODEC,FOO) ((FOO >= 0) && \
|
||||
(FOO < SOUND_MIXER_NRDEVICES) && \
|
||||
(CODEC)->supported_mixers & (1<<FOO) )
|
||||
|
||||
struct ac97_codec {
|
||||
/* Linked list of codecs */
|
||||
struct list_head list;
|
||||
|
||||
/* AC97 controller connected with */
|
||||
void *private_data;
|
||||
|
||||
char *name;
|
||||
int id;
|
||||
int dev_mixer;
|
||||
int type;
|
||||
u32 model;
|
||||
|
||||
unsigned int modem:1;
|
||||
|
||||
struct ac97_ops *codec_ops;
|
||||
|
||||
/* controller specific lower leverl ac97 accessing routines.
|
||||
must be re-entrant safe */
|
||||
u16 (*codec_read) (struct ac97_codec *codec, u8 reg);
|
||||
void (*codec_write) (struct ac97_codec *codec, u8 reg, u16 val);
|
||||
|
||||
/* Wait for codec-ready. Ok to sleep here. */
|
||||
void (*codec_wait) (struct ac97_codec *codec);
|
||||
|
||||
/* callback used by helper drivers for interesting ac97 setups */
|
||||
void (*codec_unregister) (struct ac97_codec *codec);
|
||||
|
||||
struct ac97_driver *driver;
|
||||
void *driver_private; /* Private data for the driver */
|
||||
|
||||
spinlock_t lock;
|
||||
|
||||
/* OSS mixer masks */
|
||||
int modcnt;
|
||||
int supported_mixers;
|
||||
int stereo_mixers;
|
||||
int record_sources;
|
||||
|
||||
/* Property flags */
|
||||
int flags;
|
||||
|
||||
int bit_resolution;
|
||||
|
||||
/* OSS mixer interface */
|
||||
int (*read_mixer) (struct ac97_codec *codec, int oss_channel);
|
||||
void (*write_mixer)(struct ac97_codec *codec, int oss_channel,
|
||||
unsigned int left, unsigned int right);
|
||||
int (*recmask_io) (struct ac97_codec *codec, int rw, int mask);
|
||||
int (*mixer_ioctl)(struct ac97_codec *codec, unsigned int cmd, unsigned long arg);
|
||||
|
||||
/* saved OSS mixer states */
|
||||
unsigned int mixer_state[SOUND_MIXER_NRDEVICES];
|
||||
|
||||
/* Software Modem interface */
|
||||
int (*modem_ioctl)(struct ac97_codec *codec, unsigned int cmd, unsigned long arg);
|
||||
};
|
||||
|
||||
/*
|
||||
* Operation structures for each known AC97 chip
|
||||
*/
|
||||
|
||||
struct ac97_ops
|
||||
{
|
||||
/* Initialise */
|
||||
int (*init)(struct ac97_codec *c);
|
||||
/* Amplifier control */
|
||||
int (*amplifier)(struct ac97_codec *codec, int on);
|
||||
/* Digital mode control */
|
||||
int (*digital)(struct ac97_codec *codec, int slots, int rate, int mode);
|
||||
#define AUDIO_DIGITAL 0x8000
|
||||
#define AUDIO_PRO 0x4000
|
||||
#define AUDIO_DRS 0x2000
|
||||
#define AUDIO_CCMASK 0x003F
|
||||
|
||||
#define AC97_DELUDED_MODEM 1 /* Audio codec reports its a modem */
|
||||
#define AC97_NO_PCM_VOLUME 2 /* Volume control is missing */
|
||||
#define AC97_DEFAULT_POWER_OFF 4 /* Needs warm reset to power up */
|
||||
};
|
||||
|
||||
extern int ac97_probe_codec(struct ac97_codec *);
|
||||
|
||||
extern struct ac97_codec *ac97_alloc_codec(void);
|
||||
extern void ac97_release_codec(struct ac97_codec *codec);
|
||||
|
||||
struct ac97_driver {
|
||||
struct list_head list;
|
||||
char *name;
|
||||
u32 codec_id;
|
||||
u32 codec_mask;
|
||||
int (*probe) (struct ac97_codec *codec, struct ac97_driver *driver);
|
||||
void (*remove) (struct ac97_codec *codec, struct ac97_driver *driver);
|
||||
};
|
||||
|
||||
/* quirk types */
|
||||
enum {
|
||||
AC97_TUNE_DEFAULT = -1, /* use default from quirk list (not valid in list) */
|
||||
AC97_TUNE_NONE = 0, /* nothing extra to do */
|
||||
AC97_TUNE_HP_ONLY, /* headphone (true line-out) control as master only */
|
||||
AC97_TUNE_SWAP_HP, /* swap headphone and master controls */
|
||||
AC97_TUNE_SWAP_SURROUND, /* swap master and surround controls */
|
||||
AC97_TUNE_AD_SHARING, /* for AD1985, turn on OMS bit and use headphone */
|
||||
AC97_TUNE_ALC_JACK, /* for Realtek, enable JACK detection */
|
||||
};
|
||||
|
||||
struct ac97_quirk {
|
||||
unsigned short vendor; /* PCI vendor id */
|
||||
unsigned short device; /* PCI device id */
|
||||
unsigned short mask; /* device id bit mask, 0 = accept all */
|
||||
const char *name; /* name shown as info */
|
||||
int type; /* quirk type above */
|
||||
};
|
||||
|
||||
#endif /* _AC97_CODEC_H_ */
|
@ -670,6 +670,12 @@ static inline int dmaengine_resume(struct dma_chan *chan)
|
||||
return dmaengine_device_control(chan, DMA_RESUME, 0);
|
||||
}
|
||||
|
||||
static inline enum dma_status dmaengine_tx_status(struct dma_chan *chan,
|
||||
dma_cookie_t cookie, struct dma_tx_state *state)
|
||||
{
|
||||
return chan->device->device_tx_status(chan, cookie, state);
|
||||
}
|
||||
|
||||
static inline dma_cookie_t dmaengine_submit(struct dma_async_tx_descriptor *desc)
|
||||
{
|
||||
return desc->tx_submit(desc);
|
||||
|
52
include/linux/mfd/abx500/ab8500-codec.h
Normal file
52
include/linux/mfd/abx500/ab8500-codec.h
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (C) ST-Ericsson SA 2012
|
||||
*
|
||||
* Author: Ola Lilja <ola.o.lilja@stericsson.com>
|
||||
* for ST-Ericsson.
|
||||
*
|
||||
* License terms:
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 as published
|
||||
* by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#ifndef AB8500_CORE_CODEC_H
|
||||
#define AB8500_CORE_CODEC_H
|
||||
|
||||
/* Mic-types */
|
||||
enum amic_type {
|
||||
AMIC_TYPE_SINGLE_ENDED,
|
||||
AMIC_TYPE_DIFFERENTIAL
|
||||
};
|
||||
|
||||
/* Mic-biases */
|
||||
enum amic_micbias {
|
||||
AMIC_MICBIAS_VAMIC1,
|
||||
AMIC_MICBIAS_VAMIC2
|
||||
};
|
||||
|
||||
/* Bias-voltage */
|
||||
enum ear_cm_voltage {
|
||||
EAR_CMV_0_95V,
|
||||
EAR_CMV_1_10V,
|
||||
EAR_CMV_1_27V,
|
||||
EAR_CMV_1_58V
|
||||
};
|
||||
|
||||
/* Analog microphone settings */
|
||||
struct amic_settings {
|
||||
enum amic_type mic1_type;
|
||||
enum amic_type mic2_type;
|
||||
enum amic_micbias mic1a_micbias;
|
||||
enum amic_micbias mic1b_micbias;
|
||||
enum amic_micbias mic2_micbias;
|
||||
};
|
||||
|
||||
/* Platform data structure for the audio-parts of the AB8500 */
|
||||
struct ab8500_codec_platform_data {
|
||||
struct amic_settings amics;
|
||||
enum ear_cm_voltage ear_cmv;
|
||||
};
|
||||
|
||||
#endif
|
@ -266,6 +266,7 @@ struct ab8500 {
|
||||
struct regulator_reg_init;
|
||||
struct regulator_init_data;
|
||||
struct ab8500_gpio_platform_data;
|
||||
struct ab8500_codec_platform_data;
|
||||
|
||||
/**
|
||||
* struct ab8500_platform_data - AB8500 platform data
|
||||
@ -284,6 +285,7 @@ struct ab8500_platform_data {
|
||||
int num_regulator;
|
||||
struct regulator_init_data *regulator;
|
||||
struct ab8500_gpio_platform_data *gpio;
|
||||
struct ab8500_codec_platform_data *codec;
|
||||
};
|
||||
|
||||
extern int __devinit ab8500_init(struct ab8500 *ab8500,
|
||||
|
22
include/linux/platform_data/mmp_audio.h
Normal file
22
include/linux/platform_data/mmp_audio.h
Normal file
@ -0,0 +1,22 @@
|
||||
/*
|
||||
* MMP Platform AUDIO Management
|
||||
*
|
||||
* Copyright (c) 2011 Marvell Semiconductors Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef MMP_AUDIO_H
|
||||
#define MMP_AUDIO_H
|
||||
|
||||
struct mmp_audio_platdata {
|
||||
u32 period_max_capture;
|
||||
u32 buffer_max_capture;
|
||||
u32 period_max_playback;
|
||||
u32 buffer_max_playback;
|
||||
};
|
||||
|
||||
#endif /* MMP_AUDIO_H */
|
69
include/sound/designware_i2s.h
Normal file
69
include/sound/designware_i2s.h
Normal file
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (ST) 2012 Rajeev Kumar (rajeev-dlh.kumar@st.com)
|
||||
*
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __SOUND_DESIGNWARE_I2S_H
|
||||
#define __SOUND_DESIGNWARE_I2S_H
|
||||
|
||||
#include <linux/dmaengine.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
/*
|
||||
* struct i2s_clk_config_data - represent i2s clk configuration data
|
||||
* @chan_nr: number of channel
|
||||
* @data_width: number of bits per sample (8/16/24/32 bit)
|
||||
* @sample_rate: sampling frequency (8Khz, 16Khz, 32Khz, 44Khz, 48Khz)
|
||||
*/
|
||||
struct i2s_clk_config_data {
|
||||
int chan_nr;
|
||||
u32 data_width;
|
||||
u32 sample_rate;
|
||||
};
|
||||
|
||||
struct i2s_platform_data {
|
||||
#define DWC_I2S_PLAY (1 << 0)
|
||||
#define DWC_I2S_RECORD (1 << 1)
|
||||
unsigned int cap;
|
||||
int channel;
|
||||
u32 snd_fmts;
|
||||
u32 snd_rates;
|
||||
|
||||
void *play_dma_data;
|
||||
void *capture_dma_data;
|
||||
bool (*filter)(struct dma_chan *chan, void *slave);
|
||||
int (*i2s_clk_cfg)(struct i2s_clk_config_data *config);
|
||||
};
|
||||
|
||||
struct i2s_dma_data {
|
||||
void *data;
|
||||
dma_addr_t addr;
|
||||
u32 max_burst;
|
||||
enum dma_slave_buswidth addr_width;
|
||||
bool (*filter)(struct dma_chan *chan, void *slave);
|
||||
};
|
||||
|
||||
/* I2S DMA registers */
|
||||
#define I2S_RXDMA 0x01C0
|
||||
#define I2S_TXDMA 0x01C8
|
||||
|
||||
#define TWO_CHANNEL_SUPPORT 2 /* up to 2.0 */
|
||||
#define FOUR_CHANNEL_SUPPORT 4 /* up to 3.1 */
|
||||
#define SIX_CHANNEL_SUPPORT 6 /* up to 5.1 */
|
||||
#define EIGHT_CHANNEL_SUPPORT 8 /* up to 7.1 */
|
||||
|
||||
#endif /* __SOUND_DESIGNWARE_I2S_H */
|
@ -39,6 +39,7 @@ int snd_hwparams_to_dma_slave_config(const struct snd_pcm_substream *substream,
|
||||
const struct snd_pcm_hw_params *params, struct dma_slave_config *slave_config);
|
||||
int snd_dmaengine_pcm_trigger(struct snd_pcm_substream *substream, int cmd);
|
||||
snd_pcm_uframes_t snd_dmaengine_pcm_pointer(struct snd_pcm_substream *substream);
|
||||
snd_pcm_uframes_t snd_dmaengine_pcm_pointer_no_residue(struct snd_pcm_substream *substream);
|
||||
|
||||
int snd_dmaengine_pcm_open(struct snd_pcm_substream *substream,
|
||||
dma_filter_fn filter_fn, void *filter_data);
|
||||
|
@ -810,7 +810,7 @@ int snd_pcm_hw_constraint_integer(struct snd_pcm_runtime *runtime, snd_pcm_hw_pa
|
||||
int snd_pcm_hw_constraint_list(struct snd_pcm_runtime *runtime,
|
||||
unsigned int cond,
|
||||
snd_pcm_hw_param_t var,
|
||||
struct snd_pcm_hw_constraint_list *l);
|
||||
const struct snd_pcm_hw_constraint_list *l);
|
||||
int snd_pcm_hw_constraint_ratnums(struct snd_pcm_runtime *runtime,
|
||||
unsigned int cond,
|
||||
snd_pcm_hw_param_t var,
|
||||
@ -893,6 +893,7 @@ extern const struct snd_pcm_hw_constraint_list snd_pcm_known_rates;
|
||||
|
||||
int snd_pcm_limit_hw_rates(struct snd_pcm_runtime *runtime);
|
||||
unsigned int snd_pcm_rate_to_rate_bit(unsigned int rate);
|
||||
unsigned int snd_pcm_rate_bit_to_rate(unsigned int rate_bit);
|
||||
|
||||
static inline void snd_pcm_set_runtime_buffer(struct snd_pcm_substream *substream,
|
||||
struct snd_dma_buffer *bufp)
|
||||
@ -1073,4 +1074,15 @@ static inline void snd_pcm_limit_isa_dma_size(int dma, size_t *max)
|
||||
|
||||
const char *snd_pcm_format_name(snd_pcm_format_t format);
|
||||
|
||||
/**
|
||||
* Get a string naming the direction of a stream
|
||||
*/
|
||||
static inline const char *snd_pcm_stream_str(struct snd_pcm_substream *substream)
|
||||
{
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
|
||||
return "Playback";
|
||||
else
|
||||
return "Capture";
|
||||
}
|
||||
|
||||
#endif /* __SOUND_PCM_H */
|
||||
|
@ -22,6 +22,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sound/pcm.h>
|
||||
|
||||
int snd_pcm_hw_param_first(struct snd_pcm_substream *pcm,
|
||||
struct snd_pcm_hw_params *params,
|
||||
snd_pcm_hw_param_t var, int *dir);
|
||||
|
@ -229,6 +229,10 @@ struct device;
|
||||
{ .id = snd_soc_dapm_adc, .name = wname, .sname = stname, .reg = wreg, \
|
||||
.shift = wshift, .invert = winvert, \
|
||||
.event = wevent, .event_flags = wflags}
|
||||
#define SND_SOC_DAPM_CLOCK_SUPPLY(wname) \
|
||||
{ .id = snd_soc_dapm_clock_supply, .name = wname, \
|
||||
.reg = SND_SOC_NOPM, .event = dapm_clock_event, \
|
||||
.event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD }
|
||||
|
||||
/* generic widgets */
|
||||
#define SND_SOC_DAPM_REG(wid, wname, wreg, wshift, wmask, won_val, woff_val) \
|
||||
@ -245,6 +249,7 @@ struct device;
|
||||
.reg = SND_SOC_NOPM, .shift = wdelay, .event = dapm_regulator_event, \
|
||||
.event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD }
|
||||
|
||||
|
||||
/* dapm kcontrol types */
|
||||
#define SOC_DAPM_SINGLE(xname, reg, shift, max, invert) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
|
||||
@ -327,6 +332,8 @@ int dapm_reg_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event);
|
||||
int dapm_regulator_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event);
|
||||
int dapm_clock_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event);
|
||||
|
||||
/* dapm controls */
|
||||
int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
|
||||
@ -367,6 +374,8 @@ int snd_soc_dapm_new_widgets(struct snd_soc_dapm_context *dapm);
|
||||
void snd_soc_dapm_free(struct snd_soc_dapm_context *dapm);
|
||||
int snd_soc_dapm_add_routes(struct snd_soc_dapm_context *dapm,
|
||||
const struct snd_soc_dapm_route *route, int num);
|
||||
int snd_soc_dapm_del_routes(struct snd_soc_dapm_context *dapm,
|
||||
const struct snd_soc_dapm_route *route, int num);
|
||||
int snd_soc_dapm_weak_routes(struct snd_soc_dapm_context *dapm,
|
||||
const struct snd_soc_dapm_route *route, int num);
|
||||
|
||||
@ -432,6 +441,7 @@ enum snd_soc_dapm_type {
|
||||
snd_soc_dapm_post, /* machine specific post widget - exec last */
|
||||
snd_soc_dapm_supply, /* power/clock supply */
|
||||
snd_soc_dapm_regulator_supply, /* external regulator */
|
||||
snd_soc_dapm_clock_supply, /* external clock */
|
||||
snd_soc_dapm_aif_in, /* audio interface input */
|
||||
snd_soc_dapm_aif_out, /* audio interface output */
|
||||
snd_soc_dapm_siggen, /* signal generator */
|
||||
@ -537,6 +547,8 @@ struct snd_soc_dapm_widget {
|
||||
struct list_head dirty;
|
||||
int inputs;
|
||||
int outputs;
|
||||
|
||||
struct clk *clk;
|
||||
};
|
||||
|
||||
struct snd_soc_dapm_update {
|
||||
|
@ -42,11 +42,22 @@
|
||||
((unsigned long)&(struct soc_mixer_control) \
|
||||
{.reg = xlreg, .rreg = xrreg, .shift = xshift, .rshift = xshift, \
|
||||
.max = xmax, .platform_max = xmax, .invert = xinvert})
|
||||
#define SOC_DOUBLE_R_RANGE_VALUE(xlreg, xrreg, xshift, xmin, xmax, xinvert) \
|
||||
((unsigned long)&(struct soc_mixer_control) \
|
||||
{.reg = xlreg, .rreg = xrreg, .shift = xshift, .rshift = xshift, \
|
||||
.min = xmin, .max = xmax, .platform_max = xmax, .invert = xinvert})
|
||||
#define SOC_SINGLE(xname, reg, shift, max, invert) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
|
||||
.info = snd_soc_info_volsw, .get = snd_soc_get_volsw,\
|
||||
.put = snd_soc_put_volsw, \
|
||||
.private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) }
|
||||
#define SOC_SINGLE_RANGE(xname, xreg, xshift, xmin, xmax, xinvert) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
|
||||
.info = snd_soc_info_volsw_range, .get = snd_soc_get_volsw_range, \
|
||||
.put = snd_soc_put_volsw_range, \
|
||||
.private_value = (unsigned long)&(struct soc_mixer_control) \
|
||||
{.reg = xreg, .shift = xshift, .min = xmin,\
|
||||
.max = xmax, .platform_max = xmax, .invert = xinvert} }
|
||||
#define SOC_SINGLE_TLV(xname, reg, shift, max, invert, tlv_array) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
|
||||
.access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
|
||||
@ -67,6 +78,16 @@
|
||||
{.reg = xreg, .rreg = xreg, \
|
||||
.shift = xshift, .rshift = xshift, \
|
||||
.max = xmax, .min = xmin} }
|
||||
#define SOC_SINGLE_RANGE_TLV(xname, xreg, xshift, xmin, xmax, xinvert, tlv_array) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
|
||||
.access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
|
||||
SNDRV_CTL_ELEM_ACCESS_READWRITE,\
|
||||
.tlv.p = (tlv_array), \
|
||||
.info = snd_soc_info_volsw_range, \
|
||||
.get = snd_soc_get_volsw_range, .put = snd_soc_put_volsw_range, \
|
||||
.private_value = (unsigned long)&(struct soc_mixer_control) \
|
||||
{.reg = xreg, .shift = xshift, .min = xmin,\
|
||||
.max = xmax, .platform_max = xmax, .invert = xinvert} }
|
||||
#define SOC_DOUBLE(xname, reg, shift_left, shift_right, max, invert) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
|
||||
.info = snd_soc_info_volsw, .get = snd_soc_get_volsw, \
|
||||
@ -79,6 +100,13 @@
|
||||
.get = snd_soc_get_volsw, .put = snd_soc_put_volsw, \
|
||||
.private_value = SOC_DOUBLE_R_VALUE(reg_left, reg_right, xshift, \
|
||||
xmax, xinvert) }
|
||||
#define SOC_DOUBLE_R_RANGE(xname, reg_left, reg_right, xshift, xmin, \
|
||||
xmax, xinvert) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
|
||||
.info = snd_soc_info_volsw_range, \
|
||||
.get = snd_soc_get_volsw_range, .put = snd_soc_put_volsw_range, \
|
||||
.private_value = SOC_DOUBLE_R_RANGE_VALUE(reg_left, reg_right, \
|
||||
xshift, xmin, xmax, xinvert) }
|
||||
#define SOC_DOUBLE_TLV(xname, reg, shift_left, shift_right, max, invert, tlv_array) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
|
||||
.access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
|
||||
@ -97,6 +125,16 @@
|
||||
.get = snd_soc_get_volsw, .put = snd_soc_put_volsw, \
|
||||
.private_value = SOC_DOUBLE_R_VALUE(reg_left, reg_right, xshift, \
|
||||
xmax, xinvert) }
|
||||
#define SOC_DOUBLE_R_RANGE_TLV(xname, reg_left, reg_right, xshift, xmin, \
|
||||
xmax, xinvert, tlv_array) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
|
||||
.access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
|
||||
SNDRV_CTL_ELEM_ACCESS_READWRITE,\
|
||||
.tlv.p = (tlv_array), \
|
||||
.info = snd_soc_info_volsw_range, \
|
||||
.get = snd_soc_get_volsw_range, .put = snd_soc_put_volsw_range, \
|
||||
.private_value = SOC_DOUBLE_R_RANGE_VALUE(reg_left, reg_right, \
|
||||
xshift, xmin, xmax, xinvert) }
|
||||
#define SOC_DOUBLE_R_SX_TLV(xname, xreg, xrreg, xshift, xmin, xmax, tlv_array) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
|
||||
.access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
|
||||
@ -460,6 +498,12 @@ int snd_soc_get_volsw_s8(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
int snd_soc_put_volsw_s8(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
int snd_soc_info_volsw_range(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_info *uinfo);
|
||||
int snd_soc_put_volsw_range(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
int snd_soc_get_volsw_range(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
int snd_soc_limit_volume(struct snd_soc_codec *codec,
|
||||
const char *name, int max);
|
||||
int snd_soc_bytes_info(struct snd_kcontrol *kcontrol,
|
||||
@ -785,13 +829,36 @@ struct snd_soc_dai_link {
|
||||
/* config - must be set by machine driver */
|
||||
const char *name; /* Codec name */
|
||||
const char *stream_name; /* Stream name */
|
||||
const char *codec_name; /* for multi-codec */
|
||||
const struct device_node *codec_of_node;
|
||||
const char *platform_name; /* for multi-platform */
|
||||
const struct device_node *platform_of_node;
|
||||
/*
|
||||
* You MAY specify the link's CPU-side device, either by device name,
|
||||
* or by DT/OF node, but not both. If this information is omitted,
|
||||
* the CPU-side DAI is matched using .cpu_dai_name only, which hence
|
||||
* must be globally unique. These fields are currently typically used
|
||||
* only for codec to codec links, or systems using device tree.
|
||||
*/
|
||||
const char *cpu_name;
|
||||
const struct device_node *cpu_of_node;
|
||||
/*
|
||||
* You MAY specify the DAI name of the CPU DAI. If this information is
|
||||
* omitted, the CPU-side DAI is matched using .cpu_name/.cpu_of_node
|
||||
* only, which only works well when that device exposes a single DAI.
|
||||
*/
|
||||
const char *cpu_dai_name;
|
||||
const struct device_node *cpu_dai_of_node;
|
||||
/*
|
||||
* You MUST specify the link's codec, either by device name, or by
|
||||
* DT/OF node, but not both.
|
||||
*/
|
||||
const char *codec_name;
|
||||
const struct device_node *codec_of_node;
|
||||
/* You MUST specify the DAI name within the codec */
|
||||
const char *codec_dai_name;
|
||||
/*
|
||||
* You MAY specify the link's platform/PCM/DMA driver, either by
|
||||
* device name, or by DT/OF node, but not both. Some forms of link
|
||||
* do not need a platform.
|
||||
*/
|
||||
const char *platform_name;
|
||||
const struct device_node *platform_of_node;
|
||||
int be_id; /* optional ID for machine driver BE identification */
|
||||
|
||||
const struct snd_soc_pcm_stream *params;
|
||||
|
35
include/sound/spear_dma.h
Normal file
35
include/sound/spear_dma.h
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* linux/spear_dma.h
|
||||
*
|
||||
* Copyright (ST) 2012 Rajeev Kumar (rajeev-dlh.kumar@st.com)
|
||||
*
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SPEAR_DMA_H
|
||||
#define SPEAR_DMA_H
|
||||
|
||||
#include <linux/dmaengine.h>
|
||||
|
||||
struct spear_dma_data {
|
||||
void *data;
|
||||
dma_addr_t addr;
|
||||
u32 max_burst;
|
||||
enum dma_slave_buswidth addr_width;
|
||||
bool (*filter)(struct dma_chan *chan, void *slave);
|
||||
};
|
||||
|
||||
#endif /* SPEAR_DMA_H */
|
29
include/sound/spear_spdif.h
Normal file
29
include/sound/spear_spdif.h
Normal file
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (ST) 2012 Vipin Kumar (vipin.kumar@st.com)
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef __SOUND_SPDIF_H
|
||||
#define __SOUND_SPDIF_H
|
||||
|
||||
struct spear_spdif_platform_data {
|
||||
/* DMA params */
|
||||
void *dma_params;
|
||||
bool (*filter)(struct dma_chan *chan, void *slave);
|
||||
void (*reset_perip)(void);
|
||||
};
|
||||
|
||||
#endif /* SOUND_SPDIF_H */
|
@ -38,21 +38,31 @@
|
||||
#define SNDRV_CTL_TLVT_DB_MINMAX 4 /* dB scale with min/max */
|
||||
#define SNDRV_CTL_TLVT_DB_MINMAX_MUTE 5 /* dB scale with min/max with mute */
|
||||
|
||||
#define TLV_ITEM(type, ...) \
|
||||
(type), TLV_LENGTH(__VA_ARGS__), __VA_ARGS__
|
||||
#define TLV_LENGTH(...) \
|
||||
((unsigned int)sizeof((const unsigned int[]) { __VA_ARGS__ }))
|
||||
|
||||
#define TLV_CONTAINER_ITEM(...) \
|
||||
TLV_ITEM(SNDRV_CTL_TLVT_CONTAINER, __VA_ARGS__)
|
||||
#define DECLARE_TLV_CONTAINER(name, ...) \
|
||||
unsigned int name[] = { TLV_CONTAINER_ITEM(__VA_ARGS__) }
|
||||
|
||||
#define TLV_DB_SCALE_MASK 0xffff
|
||||
#define TLV_DB_SCALE_MUTE 0x10000
|
||||
#define TLV_DB_SCALE_ITEM(min, step, mute) \
|
||||
SNDRV_CTL_TLVT_DB_SCALE, 2 * sizeof(unsigned int), \
|
||||
(min), ((step) & TLV_DB_SCALE_MASK) | ((mute) ? TLV_DB_SCALE_MUTE : 0)
|
||||
TLV_ITEM(SNDRV_CTL_TLVT_DB_SCALE, \
|
||||
(min), \
|
||||
((step) & TLV_DB_SCALE_MASK) | \
|
||||
((mute) ? TLV_DB_SCALE_MUTE : 0))
|
||||
#define DECLARE_TLV_DB_SCALE(name, min, step, mute) \
|
||||
unsigned int name[] = { TLV_DB_SCALE_ITEM(min, step, mute) }
|
||||
|
||||
/* dB scale specified with min/max values instead of step */
|
||||
#define TLV_DB_MINMAX_ITEM(min_dB, max_dB) \
|
||||
SNDRV_CTL_TLVT_DB_MINMAX, 2 * sizeof(unsigned int), \
|
||||
(min_dB), (max_dB)
|
||||
TLV_ITEM(SNDRV_CTL_TLVT_DB_MINMAX, (min_dB), (max_dB))
|
||||
#define TLV_DB_MINMAX_MUTE_ITEM(min_dB, max_dB) \
|
||||
SNDRV_CTL_TLVT_DB_MINMAX_MUTE, 2 * sizeof(unsigned int), \
|
||||
(min_dB), (max_dB)
|
||||
TLV_ITEM(SNDRV_CTL_TLVT_DB_MINMAX_MUTE, (min_dB), (max_dB))
|
||||
#define DECLARE_TLV_DB_MINMAX(name, min_dB, max_dB) \
|
||||
unsigned int name[] = { TLV_DB_MINMAX_ITEM(min_dB, max_dB) }
|
||||
#define DECLARE_TLV_DB_MINMAX_MUTE(name, min_dB, max_dB) \
|
||||
@ -60,13 +70,16 @@
|
||||
|
||||
/* linear volume between min_dB and max_dB (.01dB unit) */
|
||||
#define TLV_DB_LINEAR_ITEM(min_dB, max_dB) \
|
||||
SNDRV_CTL_TLVT_DB_LINEAR, 2 * sizeof(unsigned int), \
|
||||
(min_dB), (max_dB)
|
||||
TLV_ITEM(SNDRV_CTL_TLVT_DB_LINEAR, (min_dB), (max_dB))
|
||||
#define DECLARE_TLV_DB_LINEAR(name, min_dB, max_dB) \
|
||||
unsigned int name[] = { TLV_DB_LINEAR_ITEM(min_dB, max_dB) }
|
||||
|
||||
/* dB range container */
|
||||
/* Each item is: <min> <max> <TLV> */
|
||||
#define TLV_DB_RANGE_ITEM(...) \
|
||||
TLV_ITEM(SNDRV_CTL_TLVT_DB_RANGE, __VA_ARGS__)
|
||||
#define DECLARE_TLV_DB_RANGE(name, ...) \
|
||||
unsigned int name[] = { TLV_DB_RANGE_ITEM(__VA_ARGS__) }
|
||||
/* The below assumes that each item TLV is 4 words like DB_SCALE or LINEAR */
|
||||
#define TLV_DB_RANGE_HEAD(num) \
|
||||
SNDRV_CTL_TLVT_DB_RANGE, 6 * (num) * sizeof(unsigned int)
|
||||
|
@ -341,7 +341,7 @@ int vx_change_frequency(struct vx_core *chip);
|
||||
/*
|
||||
* PM
|
||||
*/
|
||||
int snd_vx_suspend(struct vx_core *card, pm_message_t state);
|
||||
int snd_vx_suspend(struct vx_core *card);
|
||||
int snd_vx_resume(struct vx_core *card);
|
||||
|
||||
/*
|
||||
|
@ -108,7 +108,7 @@ static struct pxa2xx_pcm_client pxa2xx_ac97_pcm_client = {
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
|
||||
static int pxa2xx_ac97_do_suspend(struct snd_card *card, pm_message_t state)
|
||||
static int pxa2xx_ac97_do_suspend(struct snd_card *card)
|
||||
{
|
||||
pxa2xx_audio_ops_t *platform_ops = card->dev->platform_data;
|
||||
|
||||
@ -144,7 +144,7 @@ static int pxa2xx_ac97_suspend(struct device *dev)
|
||||
int ret = 0;
|
||||
|
||||
if (card)
|
||||
ret = pxa2xx_ac97_do_suspend(card, PMSG_SUSPEND);
|
||||
ret = pxa2xx_ac97_do_suspend(card);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -160,10 +160,7 @@ static int pxa2xx_ac97_resume(struct device *dev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops pxa2xx_ac97_pm_ops = {
|
||||
.suspend = pxa2xx_ac97_suspend,
|
||||
.resume = pxa2xx_ac97_resume,
|
||||
};
|
||||
static SIMPLE_DEV_PM_OPS(pxa2xx_ac97_pm_ops, pxa2xx_ac97_suspend, pxa2xx_ac97_resume);
|
||||
#endif
|
||||
|
||||
static int __devinit pxa2xx_ac97_probe(struct platform_device *dev)
|
||||
|
@ -535,9 +535,9 @@ static int __devinit atmel_abdac_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int atmel_abdac_suspend(struct platform_device *pdev, pm_message_t msg)
|
||||
static int atmel_abdac_suspend(struct device *pdev)
|
||||
{
|
||||
struct snd_card *card = platform_get_drvdata(pdev);
|
||||
struct snd_card *card = dev_get_drvdata(pdev);
|
||||
struct atmel_abdac *dac = card->private_data;
|
||||
|
||||
dw_dma_cyclic_stop(dac->dma.chan);
|
||||
@ -547,9 +547,9 @@ static int atmel_abdac_suspend(struct platform_device *pdev, pm_message_t msg)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int atmel_abdac_resume(struct platform_device *pdev)
|
||||
static int atmel_abdac_resume(struct device *pdev)
|
||||
{
|
||||
struct snd_card *card = platform_get_drvdata(pdev);
|
||||
struct snd_card *card = dev_get_drvdata(pdev);
|
||||
struct atmel_abdac *dac = card->private_data;
|
||||
|
||||
clk_enable(dac->pclk);
|
||||
@ -559,9 +559,11 @@ static int atmel_abdac_resume(struct platform_device *pdev)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(atmel_abdac_pm, atmel_abdac_suspend, atmel_abdac_resume);
|
||||
#define ATMEL_ABDAC_PM_OPS &atmel_abdac_pm
|
||||
#else
|
||||
#define atmel_abdac_suspend NULL
|
||||
#define atmel_abdac_resume NULL
|
||||
#define ATMEL_ABDAC_PM_OPS NULL
|
||||
#endif
|
||||
|
||||
static int __devexit atmel_abdac_remove(struct platform_device *pdev)
|
||||
@ -589,9 +591,9 @@ static struct platform_driver atmel_abdac_driver = {
|
||||
.remove = __devexit_p(atmel_abdac_remove),
|
||||
.driver = {
|
||||
.name = "atmel_abdac",
|
||||
.owner = THIS_MODULE,
|
||||
.pm = ATMEL_ABDAC_PM_OPS,
|
||||
},
|
||||
.suspend = atmel_abdac_suspend,
|
||||
.resume = atmel_abdac_resume,
|
||||
};
|
||||
|
||||
static int __init atmel_abdac_init(void)
|
||||
|
@ -1135,9 +1135,9 @@ static int __devinit atmel_ac97c_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int atmel_ac97c_suspend(struct platform_device *pdev, pm_message_t msg)
|
||||
static int atmel_ac97c_suspend(struct device *pdev)
|
||||
{
|
||||
struct snd_card *card = platform_get_drvdata(pdev);
|
||||
struct snd_card *card = dev_get_drvdata(pdev);
|
||||
struct atmel_ac97c *chip = card->private_data;
|
||||
|
||||
if (cpu_is_at32ap7000()) {
|
||||
@ -1151,9 +1151,9 @@ static int atmel_ac97c_suspend(struct platform_device *pdev, pm_message_t msg)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int atmel_ac97c_resume(struct platform_device *pdev)
|
||||
static int atmel_ac97c_resume(struct device *pdev)
|
||||
{
|
||||
struct snd_card *card = platform_get_drvdata(pdev);
|
||||
struct snd_card *card = dev_get_drvdata(pdev);
|
||||
struct atmel_ac97c *chip = card->private_data;
|
||||
|
||||
clk_enable(chip->pclk);
|
||||
@ -1165,9 +1165,11 @@ static int atmel_ac97c_resume(struct platform_device *pdev)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(atmel_ac97c_pm, atmel_ac97c_suspend, atmel_ac97c_resume);
|
||||
#define ATMEL_AC97C_PM_OPS &atmel_ac97c_pm
|
||||
#else
|
||||
#define atmel_ac97c_suspend NULL
|
||||
#define atmel_ac97c_resume NULL
|
||||
#define ATMEL_AC97C_PM_OPS NULL
|
||||
#endif
|
||||
|
||||
static int __devexit atmel_ac97c_remove(struct platform_device *pdev)
|
||||
@ -1210,9 +1212,9 @@ static struct platform_driver atmel_ac97c_driver = {
|
||||
.remove = __devexit_p(atmel_ac97c_remove),
|
||||
.driver = {
|
||||
.name = "atmel_ac97c",
|
||||
.owner = THIS_MODULE,
|
||||
.pm = ATMEL_AC97C_PM_OPS,
|
||||
},
|
||||
.suspend = atmel_ac97c_suspend,
|
||||
.resume = atmel_ac97c_resume,
|
||||
};
|
||||
|
||||
static int __init atmel_ac97c_init(void)
|
||||
|
@ -1250,10 +1250,10 @@ static int snd_pcm_hw_rule_list(struct snd_pcm_hw_params *params,
|
||||
int snd_pcm_hw_constraint_list(struct snd_pcm_runtime *runtime,
|
||||
unsigned int cond,
|
||||
snd_pcm_hw_param_t var,
|
||||
struct snd_pcm_hw_constraint_list *l)
|
||||
const struct snd_pcm_hw_constraint_list *l)
|
||||
{
|
||||
return snd_pcm_hw_rule_add(runtime, cond, var,
|
||||
snd_pcm_hw_rule_list, l,
|
||||
snd_pcm_hw_rule_list, (void *)l,
|
||||
var, -1);
|
||||
}
|
||||
|
||||
|
@ -488,3 +488,21 @@ unsigned int snd_pcm_rate_to_rate_bit(unsigned int rate)
|
||||
return SNDRV_PCM_RATE_KNOT;
|
||||
}
|
||||
EXPORT_SYMBOL(snd_pcm_rate_to_rate_bit);
|
||||
|
||||
/**
|
||||
* snd_pcm_rate_bit_to_rate - converts SNDRV_PCM_RATE_xxx bit to sample rate
|
||||
* @rate_bit: the rate bit to convert
|
||||
*
|
||||
* Returns the sample rate that corresponds to the given SNDRV_PCM_RATE_xxx flag
|
||||
* or 0 for an unknown rate bit
|
||||
*/
|
||||
unsigned int snd_pcm_rate_bit_to_rate(unsigned int rate_bit)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < snd_pcm_known_rates.count; i++)
|
||||
if ((1u << i) == rate_bit)
|
||||
return snd_pcm_known_rates.list[i];
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(snd_pcm_rate_bit_to_rate);
|
||||
|
@ -1177,10 +1177,9 @@ static int __devexit loopback_remove(struct platform_device *devptr)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int loopback_suspend(struct platform_device *pdev,
|
||||
pm_message_t state)
|
||||
static int loopback_suspend(struct device *pdev)
|
||||
{
|
||||
struct snd_card *card = platform_get_drvdata(pdev);
|
||||
struct snd_card *card = dev_get_drvdata(pdev);
|
||||
struct loopback *loopback = card->private_data;
|
||||
|
||||
snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
|
||||
@ -1190,13 +1189,18 @@ static int loopback_suspend(struct platform_device *pdev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int loopback_resume(struct platform_device *pdev)
|
||||
static int loopback_resume(struct device *pdev)
|
||||
{
|
||||
struct snd_card *card = platform_get_drvdata(pdev);
|
||||
struct snd_card *card = dev_get_drvdata(pdev);
|
||||
|
||||
snd_power_change_state(card, SNDRV_CTL_POWER_D0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(loopback_pm, loopback_suspend, loopback_resume);
|
||||
#define LOOPBACK_PM_OPS &loopback_pm
|
||||
#else
|
||||
#define LOOPBACK_PM_OPS NULL
|
||||
#endif
|
||||
|
||||
#define SND_LOOPBACK_DRIVER "snd_aloop"
|
||||
@ -1204,12 +1208,10 @@ static int loopback_resume(struct platform_device *pdev)
|
||||
static struct platform_driver loopback_driver = {
|
||||
.probe = loopback_probe,
|
||||
.remove = __devexit_p(loopback_remove),
|
||||
#ifdef CONFIG_PM
|
||||
.suspend = loopback_suspend,
|
||||
.resume = loopback_resume,
|
||||
#endif
|
||||
.driver = {
|
||||
.name = SND_LOOPBACK_DRIVER
|
||||
.name = SND_LOOPBACK_DRIVER,
|
||||
.owner = THIS_MODULE,
|
||||
.pm = LOOPBACK_PM_OPS,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -1065,9 +1065,9 @@ static int __devexit snd_dummy_remove(struct platform_device *devptr)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int snd_dummy_suspend(struct platform_device *pdev, pm_message_t state)
|
||||
static int snd_dummy_suspend(struct device *pdev)
|
||||
{
|
||||
struct snd_card *card = platform_get_drvdata(pdev);
|
||||
struct snd_card *card = dev_get_drvdata(pdev);
|
||||
struct snd_dummy *dummy = card->private_data;
|
||||
|
||||
snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
|
||||
@ -1075,13 +1075,18 @@ static int snd_dummy_suspend(struct platform_device *pdev, pm_message_t state)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_dummy_resume(struct platform_device *pdev)
|
||||
static int snd_dummy_resume(struct device *pdev)
|
||||
{
|
||||
struct snd_card *card = platform_get_drvdata(pdev);
|
||||
struct snd_card *card = dev_get_drvdata(pdev);
|
||||
|
||||
snd_power_change_state(card, SNDRV_CTL_POWER_D0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(snd_dummy_pm, snd_dummy_suspend, snd_dummy_resume);
|
||||
#define SND_DUMMY_PM_OPS &snd_dummy_pm
|
||||
#else
|
||||
#define SND_DUMMY_PM_OPS NULL
|
||||
#endif
|
||||
|
||||
#define SND_DUMMY_DRIVER "snd_dummy"
|
||||
@ -1089,12 +1094,10 @@ static int snd_dummy_resume(struct platform_device *pdev)
|
||||
static struct platform_driver snd_dummy_driver = {
|
||||
.probe = snd_dummy_probe,
|
||||
.remove = __devexit_p(snd_dummy_remove),
|
||||
#ifdef CONFIG_PM
|
||||
.suspend = snd_dummy_suspend,
|
||||
.resume = snd_dummy_resume,
|
||||
#endif
|
||||
.driver = {
|
||||
.name = SND_DUMMY_DRIVER
|
||||
.name = SND_DUMMY_DRIVER,
|
||||
.owner = THIS_MODULE,
|
||||
.pm = SND_DUMMY_PM_OPS,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -139,7 +139,8 @@ static struct platform_driver snd_mpu401_driver = {
|
||||
.probe = snd_mpu401_probe,
|
||||
.remove = __devexit_p(snd_mpu401_remove),
|
||||
.driver = {
|
||||
.name = SND_MPU401_DRIVER
|
||||
.name = SND_MPU401_DRIVER,
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -759,7 +759,8 @@ static struct platform_driver snd_mtpav_driver = {
|
||||
.probe = snd_mtpav_probe,
|
||||
.remove = __devexit_p(snd_mtpav_remove),
|
||||
.driver = {
|
||||
.name = SND_MTPAV_DRIVER
|
||||
.name = SND_MTPAV_DRIVER,
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -1040,7 +1040,8 @@ static struct platform_driver snd_mts64_driver = {
|
||||
.probe = snd_mts64_probe,
|
||||
.remove = __devexit_p(snd_mts64_remove),
|
||||
.driver = {
|
||||
.name = PLATFORM_DRIVER
|
||||
.name = PLATFORM_DRIVER,
|
||||
.owner = THIS_MODULE,
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -200,15 +200,18 @@ static void pcsp_stop_beep(struct snd_pcsp *chip)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int pcsp_suspend(struct platform_device *dev, pm_message_t state)
|
||||
static int pcsp_suspend(struct device *dev)
|
||||
{
|
||||
struct snd_pcsp *chip = platform_get_drvdata(dev);
|
||||
struct snd_pcsp *chip = dev_get_drvdata(dev);
|
||||
pcsp_stop_beep(chip);
|
||||
snd_pcm_suspend_all(chip->pcm);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(pcsp_pm, pcsp_suspend, NULL);
|
||||
#define PCSP_PM_OPS &pcsp_pm
|
||||
#else
|
||||
#define pcsp_suspend NULL
|
||||
#define PCSP_PM_OPS NULL
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
static void pcsp_shutdown(struct platform_device *dev)
|
||||
@ -221,10 +224,10 @@ static struct platform_driver pcsp_platform_driver = {
|
||||
.driver = {
|
||||
.name = "pcspkr",
|
||||
.owner = THIS_MODULE,
|
||||
.pm = PCSP_PM_OPS,
|
||||
},
|
||||
.probe = pcsp_probe,
|
||||
.remove = __devexit_p(pcsp_remove),
|
||||
.suspend = pcsp_suspend,
|
||||
.shutdown = pcsp_shutdown,
|
||||
};
|
||||
|
||||
|
@ -829,7 +829,8 @@ static struct platform_driver snd_portman_driver = {
|
||||
.probe = snd_portman_probe,
|
||||
.remove = __devexit_p(snd_portman_remove),
|
||||
.driver = {
|
||||
.name = PLATFORM_DRIVER
|
||||
.name = PLATFORM_DRIVER,
|
||||
.owner = THIS_MODULE,
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -995,7 +995,8 @@ static struct platform_driver snd_serial_driver = {
|
||||
.probe = snd_serial_probe,
|
||||
.remove = __devexit_p( snd_serial_remove),
|
||||
.driver = {
|
||||
.name = SND_SERIAL_DRIVER
|
||||
.name = SND_SERIAL_DRIVER,
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -142,7 +142,8 @@ static struct platform_driver snd_virmidi_driver = {
|
||||
.probe = snd_virmidi_probe,
|
||||
.remove = __devexit_p(snd_virmidi_remove),
|
||||
.driver = {
|
||||
.name = SND_VIRMIDI_DRIVER
|
||||
.name = SND_VIRMIDI_DRIVER,
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -725,7 +725,7 @@ EXPORT_SYMBOL(snd_vx_dsp_load);
|
||||
/*
|
||||
* suspend
|
||||
*/
|
||||
int snd_vx_suspend(struct vx_core *chip, pm_message_t state)
|
||||
int snd_vx_suspend(struct vx_core *chip)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
|
@ -135,10 +135,9 @@ struct snd_opti9xx {
|
||||
unsigned long mc_base_size;
|
||||
#ifdef OPTi93X
|
||||
unsigned long mc_indir_index;
|
||||
unsigned long mc_indir_size;
|
||||
struct resource *res_mc_indir;
|
||||
struct snd_wss *codec;
|
||||
#endif /* OPTi93X */
|
||||
struct snd_wss *codec;
|
||||
unsigned long pwd_reg;
|
||||
|
||||
spinlock_t lock;
|
||||
@ -245,10 +244,8 @@ static int __devinit snd_opti9xx_init(struct snd_opti9xx *chip,
|
||||
case OPTi9XX_HW_82C931:
|
||||
case OPTi9XX_HW_82C933:
|
||||
chip->mc_base = (hardware == OPTi9XX_HW_82C930) ? 0xf8f : 0xf8d;
|
||||
if (!chip->mc_indir_index) {
|
||||
if (!chip->mc_indir_index)
|
||||
chip->mc_indir_index = 0xe0e;
|
||||
chip->mc_indir_size = 2;
|
||||
}
|
||||
chip->password = 0xe4;
|
||||
chip->pwd_reg = 0;
|
||||
break;
|
||||
@ -351,7 +348,7 @@ static void snd_opti9xx_write(struct snd_opti9xx *chip, unsigned char reg,
|
||||
(snd_opti9xx_read(chip, reg) & ~(mask)) | ((value) & (mask)))
|
||||
|
||||
|
||||
static int __devinit snd_opti9xx_configure(struct snd_opti9xx *chip,
|
||||
static int snd_opti9xx_configure(struct snd_opti9xx *chip,
|
||||
long port,
|
||||
int irq, int dma1, int dma2,
|
||||
long mpu_port, int mpu_irq)
|
||||
@ -403,7 +400,9 @@ static int __devinit snd_opti9xx_configure(struct snd_opti9xx *chip,
|
||||
|
||||
#else /* OPTi93X */
|
||||
case OPTi9XX_HW_82C931:
|
||||
case OPTi9XX_HW_82C933:
|
||||
/* disable 3D sound (set GPIO1 as output, low) */
|
||||
snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(20), 0x04, 0x0c);
|
||||
case OPTi9XX_HW_82C933: /* FALL THROUGH */
|
||||
/*
|
||||
* The BTC 1817DW has QS1000 wavetable which is connected
|
||||
* to the serial digital input of the OPTI931.
|
||||
@ -696,8 +695,7 @@ static int __devinit snd_opti9xx_read_check(struct snd_opti9xx *chip)
|
||||
if (value == snd_opti9xx_read(chip, OPTi9XX_MC_REG(1)))
|
||||
return 0;
|
||||
#else /* OPTi93X */
|
||||
chip->res_mc_indir = request_region(chip->mc_indir_index,
|
||||
chip->mc_indir_size,
|
||||
chip->res_mc_indir = request_region(chip->mc_indir_index, 2,
|
||||
"OPTi93x MC");
|
||||
if (chip->res_mc_indir == NULL)
|
||||
return -EBUSY;
|
||||
@ -770,8 +768,9 @@ static int __devinit snd_card_opti9xx_pnp(struct snd_opti9xx *chip,
|
||||
#ifdef OPTi93X
|
||||
port = pnp_port_start(pdev, 0) - 4;
|
||||
fm_port = pnp_port_start(pdev, 1) + 8;
|
||||
chip->mc_indir_index = pnp_port_start(pdev, 3) + 2;
|
||||
chip->mc_indir_size = pnp_port_len(pdev, 3) - 2;
|
||||
/* adjust mc_indir_index - some cards report it at 0xe?d,
|
||||
other at 0xe?c but it really is always at 0xe?e */
|
||||
chip->mc_indir_index = (pnp_port_start(pdev, 3) & ~0xf) | 0xe;
|
||||
#else
|
||||
devmc = pnp_request_card_device(card, pid->devs[2].id, NULL);
|
||||
if (devmc == NULL)
|
||||
@ -871,9 +870,7 @@ static int __devinit snd_opti9xx_probe(struct snd_card *card)
|
||||
&codec);
|
||||
if (error < 0)
|
||||
return error;
|
||||
#ifdef OPTi93X
|
||||
chip->codec = codec;
|
||||
#endif
|
||||
error = snd_wss_pcm(codec, 0, &pcm);
|
||||
if (error < 0)
|
||||
return error;
|
||||
@ -1054,11 +1051,55 @@ static int __devexit snd_opti9xx_isa_remove(struct device *devptr,
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int snd_opti9xx_suspend(struct snd_card *card)
|
||||
{
|
||||
struct snd_opti9xx *chip = card->private_data;
|
||||
|
||||
snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
|
||||
chip->codec->suspend(chip->codec);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_opti9xx_resume(struct snd_card *card)
|
||||
{
|
||||
struct snd_opti9xx *chip = card->private_data;
|
||||
int error, xdma2;
|
||||
#if defined(CS4231) || defined(OPTi93X)
|
||||
xdma2 = dma2;
|
||||
#else
|
||||
xdma2 = -1;
|
||||
#endif
|
||||
|
||||
error = snd_opti9xx_configure(chip, port, irq, dma1, xdma2,
|
||||
mpu_port, mpu_irq);
|
||||
if (error)
|
||||
return error;
|
||||
chip->codec->resume(chip->codec);
|
||||
snd_power_change_state(card, SNDRV_CTL_POWER_D0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_opti9xx_isa_suspend(struct device *dev, unsigned int n,
|
||||
pm_message_t state)
|
||||
{
|
||||
return snd_opti9xx_suspend(dev_get_drvdata(dev));
|
||||
}
|
||||
|
||||
static int snd_opti9xx_isa_resume(struct device *dev, unsigned int n)
|
||||
{
|
||||
return snd_opti9xx_resume(dev_get_drvdata(dev));
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct isa_driver snd_opti9xx_driver = {
|
||||
.match = snd_opti9xx_isa_match,
|
||||
.probe = snd_opti9xx_isa_probe,
|
||||
.remove = __devexit_p(snd_opti9xx_isa_remove),
|
||||
/* FIXME: suspend/resume */
|
||||
#ifdef CONFIG_PM
|
||||
.suspend = snd_opti9xx_isa_suspend,
|
||||
.resume = snd_opti9xx_isa_resume,
|
||||
#endif
|
||||
.driver = {
|
||||
.name = DEV_NAME
|
||||
},
|
||||
@ -1124,12 +1165,29 @@ static void __devexit snd_opti9xx_pnp_remove(struct pnp_card_link * pcard)
|
||||
snd_opti9xx_pnp_is_probed = 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int snd_opti9xx_pnp_suspend(struct pnp_card_link *pcard,
|
||||
pm_message_t state)
|
||||
{
|
||||
return snd_opti9xx_suspend(pnp_get_card_drvdata(pcard));
|
||||
}
|
||||
|
||||
static int snd_opti9xx_pnp_resume(struct pnp_card_link *pcard)
|
||||
{
|
||||
return snd_opti9xx_resume(pnp_get_card_drvdata(pcard));
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct pnp_card_driver opti9xx_pnpc_driver = {
|
||||
.flags = PNP_DRIVER_RES_DISABLE,
|
||||
.name = "opti9xx",
|
||||
.id_table = snd_opti9xx_pnpids,
|
||||
.probe = snd_opti9xx_pnp_probe,
|
||||
.remove = __devexit_p(snd_opti9xx_pnp_remove),
|
||||
#ifdef CONFIG_PM
|
||||
.suspend = snd_opti9xx_pnp_suspend,
|
||||
.resume = snd_opti9xx_pnp_resume,
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
|
||||
|
@ -1456,7 +1456,6 @@ static struct snd_pcm_hardware snd_wss_playback =
|
||||
{
|
||||
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
|
||||
SNDRV_PCM_INFO_MMAP_VALID |
|
||||
SNDRV_PCM_INFO_RESUME |
|
||||
SNDRV_PCM_INFO_SYNC_START),
|
||||
.formats = (SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW | SNDRV_PCM_FMTBIT_IMA_ADPCM |
|
||||
SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE),
|
||||
@ -1657,6 +1656,10 @@ static void snd_wss_resume(struct snd_wss *chip)
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Yamaha needs this to resume properly */
|
||||
if (chip->hardware == WSS_HW_OPL3SA2)
|
||||
snd_wss_out(chip, CS4231_PLAYBK_FORMAT,
|
||||
chip->image[CS4231_PLAYBK_FORMAT]);
|
||||
spin_unlock_irqrestore(&chip->reg_lock, flags);
|
||||
#if 1
|
||||
snd_wss_mce_down(chip);
|
||||
|
@ -69,7 +69,6 @@
|
||||
#include <linux/sound.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/soundcard.h>
|
||||
#include <linux/ac97_codec.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/interrupt.h>
|
||||
@ -199,6 +198,22 @@ static const char invalid_magic[] =
|
||||
} \
|
||||
})
|
||||
|
||||
/* AC97 registers */
|
||||
#define AC97_MASTER_VOL_STEREO 0x0002 /* Line Out */
|
||||
#define AC97_PCBEEP_VOL 0x000a /* none */
|
||||
#define AC97_PHONE_VOL 0x000c /* TAD Input (mono) */
|
||||
#define AC97_MIC_VOL 0x000e /* MIC Input (mono) */
|
||||
#define AC97_LINEIN_VOL 0x0010 /* Line Input (stereo) */
|
||||
#define AC97_CD_VOL 0x0012 /* CD Input (stereo) */
|
||||
#define AC97_AUX_VOL 0x0016 /* Aux Input (stereo) */
|
||||
#define AC97_PCMOUT_VOL 0x0018 /* Wave Output (stereo) */
|
||||
#define AC97_RECORD_SELECT 0x001a /* */
|
||||
#define AC97_RECORD_GAIN 0x001c
|
||||
#define AC97_GENERAL_PURPOSE 0x0020
|
||||
#define AC97_3D_CONTROL 0x0022
|
||||
#define AC97_POWER_CONTROL 0x0026
|
||||
#define AC97_VENDOR_ID1 0x007c
|
||||
|
||||
struct list_head cs4297a_devs = { &cs4297a_devs, &cs4297a_devs };
|
||||
|
||||
typedef struct serdma_descr_s {
|
||||
|
@ -1884,9 +1884,10 @@ static int __devinit snd_ali_mixer(struct snd_ali * codec)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int ali_suspend(struct pci_dev *pci, pm_message_t state)
|
||||
static int ali_suspend(struct device *dev)
|
||||
{
|
||||
struct snd_card *card = pci_get_drvdata(pci);
|
||||
struct pci_dev *pci = to_pci_dev(dev);
|
||||
struct snd_card *card = dev_get_drvdata(dev);
|
||||
struct snd_ali *chip = card->private_data;
|
||||
struct snd_ali_image *im;
|
||||
int i, j;
|
||||
@ -1929,13 +1930,14 @@ static int ali_suspend(struct pci_dev *pci, pm_message_t state)
|
||||
|
||||
pci_disable_device(pci);
|
||||
pci_save_state(pci);
|
||||
pci_set_power_state(pci, pci_choose_state(pci, state));
|
||||
pci_set_power_state(pci, PCI_D3hot);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ali_resume(struct pci_dev *pci)
|
||||
static int ali_resume(struct device *dev)
|
||||
{
|
||||
struct snd_card *card = pci_get_drvdata(pci);
|
||||
struct pci_dev *pci = to_pci_dev(dev);
|
||||
struct snd_card *card = dev_get_drvdata(dev);
|
||||
struct snd_ali *chip = card->private_data;
|
||||
struct snd_ali_image *im;
|
||||
int i, j;
|
||||
@ -1982,6 +1984,11 @@ static int ali_resume(struct pci_dev *pci)
|
||||
snd_power_change_state(card, SNDRV_CTL_POWER_D0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(ali_pm, ali_suspend, ali_resume);
|
||||
#define ALI_PM_OPS &ali_pm
|
||||
#else
|
||||
#define ALI_PM_OPS NULL
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
static int snd_ali_free(struct snd_ali * codec)
|
||||
@ -2299,10 +2306,9 @@ static struct pci_driver ali5451_driver = {
|
||||
.id_table = snd_ali_ids,
|
||||
.probe = snd_ali_probe,
|
||||
.remove = __devexit_p(snd_ali_remove),
|
||||
#ifdef CONFIG_PM
|
||||
.suspend = ali_suspend,
|
||||
.resume = ali_resume,
|
||||
#endif
|
||||
.driver = {
|
||||
.pm = ALI_PM_OPS,
|
||||
},
|
||||
};
|
||||
|
||||
module_pci_driver(ali5451_driver);
|
||||
|
@ -766,9 +766,10 @@ static int __devinit snd_als300_create(struct snd_card *card,
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int snd_als300_suspend(struct pci_dev *pci, pm_message_t state)
|
||||
static int snd_als300_suspend(struct device *dev)
|
||||
{
|
||||
struct snd_card *card = pci_get_drvdata(pci);
|
||||
struct pci_dev *pci = to_pci_dev(dev);
|
||||
struct snd_card *card = dev_get_drvdata(dev);
|
||||
struct snd_als300 *chip = card->private_data;
|
||||
|
||||
snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
|
||||
@ -777,13 +778,14 @@ static int snd_als300_suspend(struct pci_dev *pci, pm_message_t state)
|
||||
|
||||
pci_disable_device(pci);
|
||||
pci_save_state(pci);
|
||||
pci_set_power_state(pci, pci_choose_state(pci, state));
|
||||
pci_set_power_state(pci, PCI_D3hot);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_als300_resume(struct pci_dev *pci)
|
||||
static int snd_als300_resume(struct device *dev)
|
||||
{
|
||||
struct snd_card *card = pci_get_drvdata(pci);
|
||||
struct pci_dev *pci = to_pci_dev(dev);
|
||||
struct snd_card *card = dev_get_drvdata(dev);
|
||||
struct snd_als300 *chip = card->private_data;
|
||||
|
||||
pci_set_power_state(pci, PCI_D0);
|
||||
@ -802,6 +804,11 @@ static int snd_als300_resume(struct pci_dev *pci)
|
||||
snd_power_change_state(card, SNDRV_CTL_POWER_D0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(snd_als300_pm, snd_als300_suspend, snd_als300_resume);
|
||||
#define SND_ALS300_PM_OPS &snd_als300_pm
|
||||
#else
|
||||
#define SND_ALS300_PM_OPS NULL
|
||||
#endif
|
||||
|
||||
static int __devinit snd_als300_probe(struct pci_dev *pci,
|
||||
@ -857,10 +864,9 @@ static struct pci_driver als300_driver = {
|
||||
.id_table = snd_als300_ids,
|
||||
.probe = snd_als300_probe,
|
||||
.remove = __devexit_p(snd_als300_remove),
|
||||
#ifdef CONFIG_PM
|
||||
.suspend = snd_als300_suspend,
|
||||
.resume = snd_als300_resume,
|
||||
#endif
|
||||
.driver = {
|
||||
.pm = SND_ALS300_PM_OPS,
|
||||
},
|
||||
};
|
||||
|
||||
module_pci_driver(als300_driver);
|
||||
|
@ -988,9 +988,10 @@ static void __devexit snd_card_als4000_remove(struct pci_dev *pci)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int snd_als4000_suspend(struct pci_dev *pci, pm_message_t state)
|
||||
static int snd_als4000_suspend(struct device *dev)
|
||||
{
|
||||
struct snd_card *card = pci_get_drvdata(pci);
|
||||
struct pci_dev *pci = to_pci_dev(dev);
|
||||
struct snd_card *card = dev_get_drvdata(dev);
|
||||
struct snd_card_als4000 *acard = card->private_data;
|
||||
struct snd_sb *chip = acard->chip;
|
||||
|
||||
@ -1001,13 +1002,14 @@ static int snd_als4000_suspend(struct pci_dev *pci, pm_message_t state)
|
||||
|
||||
pci_disable_device(pci);
|
||||
pci_save_state(pci);
|
||||
pci_set_power_state(pci, pci_choose_state(pci, state));
|
||||
pci_set_power_state(pci, PCI_D3hot);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_als4000_resume(struct pci_dev *pci)
|
||||
static int snd_als4000_resume(struct device *dev)
|
||||
{
|
||||
struct snd_card *card = pci_get_drvdata(pci);
|
||||
struct pci_dev *pci = to_pci_dev(dev);
|
||||
struct snd_card *card = dev_get_drvdata(dev);
|
||||
struct snd_card_als4000 *acard = card->private_data;
|
||||
struct snd_sb *chip = acard->chip;
|
||||
|
||||
@ -1033,18 +1035,21 @@ static int snd_als4000_resume(struct pci_dev *pci)
|
||||
snd_power_change_state(card, SNDRV_CTL_POWER_D0);
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(snd_als4000_pm, snd_als4000_suspend, snd_als4000_resume);
|
||||
#define SND_ALS4000_PM_OPS &snd_als4000_pm
|
||||
#else
|
||||
#define SND_ALS4000_PM_OPS NULL
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
static struct pci_driver als4000_driver = {
|
||||
.name = KBUILD_MODNAME,
|
||||
.id_table = snd_als4000_ids,
|
||||
.probe = snd_card_als4000_probe,
|
||||
.remove = __devexit_p(snd_card_als4000_remove),
|
||||
#ifdef CONFIG_PM
|
||||
.suspend = snd_als4000_suspend,
|
||||
.resume = snd_als4000_resume,
|
||||
#endif
|
||||
.driver = {
|
||||
.pm = SND_ALS4000_PM_OPS,
|
||||
},
|
||||
};
|
||||
|
||||
module_pci_driver(als4000_driver);
|
||||
|
@ -1462,9 +1462,10 @@ static int __devinit snd_atiixp_mixer_new(struct atiixp *chip, int clock,
|
||||
/*
|
||||
* power management
|
||||
*/
|
||||
static int snd_atiixp_suspend(struct pci_dev *pci, pm_message_t state)
|
||||
static int snd_atiixp_suspend(struct device *dev)
|
||||
{
|
||||
struct snd_card *card = pci_get_drvdata(pci);
|
||||
struct pci_dev *pci = to_pci_dev(dev);
|
||||
struct snd_card *card = dev_get_drvdata(dev);
|
||||
struct atiixp *chip = card->private_data;
|
||||
int i;
|
||||
|
||||
@ -1484,13 +1485,14 @@ static int snd_atiixp_suspend(struct pci_dev *pci, pm_message_t state)
|
||||
|
||||
pci_disable_device(pci);
|
||||
pci_save_state(pci);
|
||||
pci_set_power_state(pci, pci_choose_state(pci, state));
|
||||
pci_set_power_state(pci, PCI_D3hot);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_atiixp_resume(struct pci_dev *pci)
|
||||
static int snd_atiixp_resume(struct device *dev)
|
||||
{
|
||||
struct snd_card *card = pci_get_drvdata(pci);
|
||||
struct pci_dev *pci = to_pci_dev(dev);
|
||||
struct snd_card *card = dev_get_drvdata(dev);
|
||||
struct atiixp *chip = card->private_data;
|
||||
int i;
|
||||
|
||||
@ -1526,6 +1528,11 @@ static int snd_atiixp_resume(struct pci_dev *pci)
|
||||
snd_power_change_state(card, SNDRV_CTL_POWER_D0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(snd_atiixp_pm, snd_atiixp_suspend, snd_atiixp_resume);
|
||||
#define SND_ATIIXP_PM_OPS &snd_atiixp_pm
|
||||
#else
|
||||
#define SND_ATIIXP_PM_OPS NULL
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
|
||||
@ -1705,10 +1712,9 @@ static struct pci_driver atiixp_driver = {
|
||||
.id_table = snd_atiixp_ids,
|
||||
.probe = snd_atiixp_probe,
|
||||
.remove = __devexit_p(snd_atiixp_remove),
|
||||
#ifdef CONFIG_PM
|
||||
.suspend = snd_atiixp_suspend,
|
||||
.resume = snd_atiixp_resume,
|
||||
#endif
|
||||
.driver = {
|
||||
.pm = SND_ATIIXP_PM_OPS,
|
||||
},
|
||||
};
|
||||
|
||||
module_pci_driver(atiixp_driver);
|
||||
|
@ -1117,9 +1117,10 @@ static int __devinit snd_atiixp_mixer_new(struct atiixp_modem *chip, int clock)
|
||||
/*
|
||||
* power management
|
||||
*/
|
||||
static int snd_atiixp_suspend(struct pci_dev *pci, pm_message_t state)
|
||||
static int snd_atiixp_suspend(struct device *dev)
|
||||
{
|
||||
struct snd_card *card = pci_get_drvdata(pci);
|
||||
struct pci_dev *pci = to_pci_dev(dev);
|
||||
struct snd_card *card = dev_get_drvdata(dev);
|
||||
struct atiixp_modem *chip = card->private_data;
|
||||
int i;
|
||||
|
||||
@ -1133,13 +1134,14 @@ static int snd_atiixp_suspend(struct pci_dev *pci, pm_message_t state)
|
||||
|
||||
pci_disable_device(pci);
|
||||
pci_save_state(pci);
|
||||
pci_set_power_state(pci, pci_choose_state(pci, state));
|
||||
pci_set_power_state(pci, PCI_D3hot);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_atiixp_resume(struct pci_dev *pci)
|
||||
static int snd_atiixp_resume(struct device *dev)
|
||||
{
|
||||
struct snd_card *card = pci_get_drvdata(pci);
|
||||
struct pci_dev *pci = to_pci_dev(dev);
|
||||
struct snd_card *card = dev_get_drvdata(dev);
|
||||
struct atiixp_modem *chip = card->private_data;
|
||||
int i;
|
||||
|
||||
@ -1162,8 +1164,12 @@ static int snd_atiixp_resume(struct pci_dev *pci)
|
||||
snd_power_change_state(card, SNDRV_CTL_POWER_D0);
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(snd_atiixp_pm, snd_atiixp_suspend, snd_atiixp_resume);
|
||||
#define SND_ATIIXP_PM_OPS &snd_atiixp_pm
|
||||
#else
|
||||
#define SND_ATIIXP_PM_OPS NULL
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
#ifdef CONFIG_PROC_FS
|
||||
/*
|
||||
@ -1336,10 +1342,9 @@ static struct pci_driver atiixp_modem_driver = {
|
||||
.id_table = snd_atiixp_ids,
|
||||
.probe = snd_atiixp_probe,
|
||||
.remove = __devexit_p(snd_atiixp_remove),
|
||||
#ifdef CONFIG_PM
|
||||
.suspend = snd_atiixp_suspend,
|
||||
.resume = snd_atiixp_resume,
|
||||
#endif
|
||||
.driver = {
|
||||
.pm = SND_ATIIXP_PM_OPS,
|
||||
},
|
||||
};
|
||||
|
||||
module_pci_driver(atiixp_modem_driver);
|
||||
|
@ -10,6 +10,15 @@
|
||||
#include <sound/core.h>
|
||||
#include "au88x0.h"
|
||||
|
||||
static int remove_ctl(struct snd_card *card, const char *name)
|
||||
{
|
||||
struct snd_ctl_elem_id id;
|
||||
memset(&id, 0, sizeof(id));
|
||||
strcpy(id.name, name);
|
||||
id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
|
||||
return snd_ctl_remove_id(card, &id);
|
||||
}
|
||||
|
||||
static int __devinit snd_vortex_mixer(vortex_t * vortex)
|
||||
{
|
||||
struct snd_ac97_bus *pbus;
|
||||
@ -28,5 +37,7 @@ static int __devinit snd_vortex_mixer(vortex_t * vortex)
|
||||
ac97.scaps = AC97_SCAP_NO_SPDIF;
|
||||
err = snd_ac97_mixer(pbus, &ac97, &vortex->codec);
|
||||
vortex->isquad = ((vortex->codec == NULL) ? 0 : (vortex->codec->ext_id&0x80));
|
||||
remove_ctl(vortex->card, "Master Mono Playback Volume");
|
||||
remove_ctl(vortex->card, "Master Mono Playback Switch");
|
||||
return err;
|
||||
}
|
||||
|
@ -2794,9 +2794,10 @@ snd_azf3328_resume_ac97(const struct snd_azf3328 *chip)
|
||||
}
|
||||
|
||||
static int
|
||||
snd_azf3328_suspend(struct pci_dev *pci, pm_message_t state)
|
||||
snd_azf3328_suspend(struct device *dev)
|
||||
{
|
||||
struct snd_card *card = pci_get_drvdata(pci);
|
||||
struct pci_dev *pci = to_pci_dev(dev);
|
||||
struct snd_card *card = dev_get_drvdata(dev);
|
||||
struct snd_azf3328 *chip = card->private_data;
|
||||
u16 *saved_regs_ctrl_u16;
|
||||
|
||||
@ -2824,14 +2825,15 @@ snd_azf3328_suspend(struct pci_dev *pci, pm_message_t state)
|
||||
|
||||
pci_disable_device(pci);
|
||||
pci_save_state(pci);
|
||||
pci_set_power_state(pci, pci_choose_state(pci, state));
|
||||
pci_set_power_state(pci, PCI_D3hot);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
snd_azf3328_resume(struct pci_dev *pci)
|
||||
snd_azf3328_resume(struct device *dev)
|
||||
{
|
||||
struct snd_card *card = pci_get_drvdata(pci);
|
||||
struct pci_dev *pci = to_pci_dev(dev);
|
||||
struct snd_card *card = dev_get_drvdata(dev);
|
||||
const struct snd_azf3328 *chip = card->private_data;
|
||||
|
||||
pci_set_power_state(pci, PCI_D0);
|
||||
@ -2859,18 +2861,21 @@ snd_azf3328_resume(struct pci_dev *pci)
|
||||
snd_power_change_state(card, SNDRV_CTL_POWER_D0);
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(snd_azf3328_pm, snd_azf3328_suspend, snd_azf3328_resume);
|
||||
#define SND_AZF3328_PM_OPS &snd_azf3328_pm
|
||||
#else
|
||||
#define SND_AZF3328_PM_OPS NULL
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
static struct pci_driver azf3328_driver = {
|
||||
.name = KBUILD_MODNAME,
|
||||
.id_table = snd_azf3328_ids,
|
||||
.probe = snd_azf3328_probe,
|
||||
.remove = __devexit_p(snd_azf3328_remove),
|
||||
#ifdef CONFIG_PM
|
||||
.suspend = snd_azf3328_suspend,
|
||||
.resume = snd_azf3328_resume,
|
||||
#endif
|
||||
.driver = {
|
||||
.pm = SND_AZF3328_PM_OPS,
|
||||
},
|
||||
};
|
||||
|
||||
module_pci_driver(azf3328_driver);
|
||||
|
@ -1872,9 +1872,10 @@ static void __devexit snd_ca0106_remove(struct pci_dev *pci)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int snd_ca0106_suspend(struct pci_dev *pci, pm_message_t state)
|
||||
static int snd_ca0106_suspend(struct device *dev)
|
||||
{
|
||||
struct snd_card *card = pci_get_drvdata(pci);
|
||||
struct pci_dev *pci = to_pci_dev(dev);
|
||||
struct snd_card *card = dev_get_drvdata(dev);
|
||||
struct snd_ca0106 *chip = card->private_data;
|
||||
int i;
|
||||
|
||||
@ -1889,13 +1890,14 @@ static int snd_ca0106_suspend(struct pci_dev *pci, pm_message_t state)
|
||||
|
||||
pci_disable_device(pci);
|
||||
pci_save_state(pci);
|
||||
pci_set_power_state(pci, pci_choose_state(pci, state));
|
||||
pci_set_power_state(pci, PCI_D3hot);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_ca0106_resume(struct pci_dev *pci)
|
||||
static int snd_ca0106_resume(struct device *dev)
|
||||
{
|
||||
struct snd_card *card = pci_get_drvdata(pci);
|
||||
struct pci_dev *pci = to_pci_dev(dev);
|
||||
struct snd_card *card = dev_get_drvdata(dev);
|
||||
struct snd_ca0106 *chip = card->private_data;
|
||||
int i;
|
||||
|
||||
@ -1922,6 +1924,11 @@ static int snd_ca0106_resume(struct pci_dev *pci)
|
||||
snd_power_change_state(card, SNDRV_CTL_POWER_D0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(snd_ca0106_pm, snd_ca0106_suspend, snd_ca0106_resume);
|
||||
#define SND_CA0106_PM_OPS &snd_ca0106_pm
|
||||
#else
|
||||
#define SND_CA0106_PM_OPS NULL
|
||||
#endif
|
||||
|
||||
// PCI IDs
|
||||
@ -1937,10 +1944,9 @@ static struct pci_driver ca0106_driver = {
|
||||
.id_table = snd_ca0106_ids,
|
||||
.probe = snd_ca0106_probe,
|
||||
.remove = __devexit_p(snd_ca0106_remove),
|
||||
#ifdef CONFIG_PM
|
||||
.suspend = snd_ca0106_suspend,
|
||||
.resume = snd_ca0106_resume,
|
||||
#endif
|
||||
.driver = {
|
||||
.pm = SND_CA0106_PM_OPS,
|
||||
},
|
||||
};
|
||||
|
||||
module_pci_driver(ca0106_driver);
|
||||
|
@ -3338,9 +3338,10 @@ static unsigned char saved_mixers[] = {
|
||||
SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT,
|
||||
};
|
||||
|
||||
static int snd_cmipci_suspend(struct pci_dev *pci, pm_message_t state)
|
||||
static int snd_cmipci_suspend(struct device *dev)
|
||||
{
|
||||
struct snd_card *card = pci_get_drvdata(pci);
|
||||
struct pci_dev *pci = to_pci_dev(dev);
|
||||
struct snd_card *card = dev_get_drvdata(dev);
|
||||
struct cmipci *cm = card->private_data;
|
||||
int i;
|
||||
|
||||
@ -3361,13 +3362,14 @@ static int snd_cmipci_suspend(struct pci_dev *pci, pm_message_t state)
|
||||
|
||||
pci_disable_device(pci);
|
||||
pci_save_state(pci);
|
||||
pci_set_power_state(pci, pci_choose_state(pci, state));
|
||||
pci_set_power_state(pci, PCI_D3hot);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_cmipci_resume(struct pci_dev *pci)
|
||||
static int snd_cmipci_resume(struct device *dev)
|
||||
{
|
||||
struct snd_card *card = pci_get_drvdata(pci);
|
||||
struct pci_dev *pci = to_pci_dev(dev);
|
||||
struct snd_card *card = dev_get_drvdata(dev);
|
||||
struct cmipci *cm = card->private_data;
|
||||
int i;
|
||||
|
||||
@ -3396,6 +3398,11 @@ static int snd_cmipci_resume(struct pci_dev *pci)
|
||||
snd_power_change_state(card, SNDRV_CTL_POWER_D0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(snd_cmipci_pm, snd_cmipci_suspend, snd_cmipci_resume);
|
||||
#define SND_CMIPCI_PM_OPS &snd_cmipci_pm
|
||||
#else
|
||||
#define SND_CMIPCI_PM_OPS NULL
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
static struct pci_driver cmipci_driver = {
|
||||
@ -3403,10 +3410,9 @@ static struct pci_driver cmipci_driver = {
|
||||
.id_table = snd_cmipci_ids,
|
||||
.probe = snd_cmipci_probe,
|
||||
.remove = __devexit_p(snd_cmipci_remove),
|
||||
#ifdef CONFIG_PM
|
||||
.suspend = snd_cmipci_suspend,
|
||||
.resume = snd_cmipci_resume,
|
||||
#endif
|
||||
.driver = {
|
||||
.pm = SND_CMIPCI_PM_OPS,
|
||||
},
|
||||
};
|
||||
|
||||
module_pci_driver(cmipci_driver);
|
||||
|
@ -1997,9 +1997,10 @@ static int saved_regs[SUSPEND_REGISTERS] = {
|
||||
|
||||
#define CLKCR1_CKRA 0x00010000L
|
||||
|
||||
static int cs4281_suspend(struct pci_dev *pci, pm_message_t state)
|
||||
static int cs4281_suspend(struct device *dev)
|
||||
{
|
||||
struct snd_card *card = pci_get_drvdata(pci);
|
||||
struct pci_dev *pci = to_pci_dev(dev);
|
||||
struct snd_card *card = dev_get_drvdata(dev);
|
||||
struct cs4281 *chip = card->private_data;
|
||||
u32 ulCLK;
|
||||
unsigned int i;
|
||||
@ -2040,13 +2041,14 @@ static int cs4281_suspend(struct pci_dev *pci, pm_message_t state)
|
||||
|
||||
pci_disable_device(pci);
|
||||
pci_save_state(pci);
|
||||
pci_set_power_state(pci, pci_choose_state(pci, state));
|
||||
pci_set_power_state(pci, PCI_D3hot);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cs4281_resume(struct pci_dev *pci)
|
||||
static int cs4281_resume(struct device *dev)
|
||||
{
|
||||
struct snd_card *card = pci_get_drvdata(pci);
|
||||
struct pci_dev *pci = to_pci_dev(dev);
|
||||
struct snd_card *card = dev_get_drvdata(dev);
|
||||
struct cs4281 *chip = card->private_data;
|
||||
unsigned int i;
|
||||
u32 ulCLK;
|
||||
@ -2082,6 +2084,11 @@ static int cs4281_resume(struct pci_dev *pci)
|
||||
snd_power_change_state(card, SNDRV_CTL_POWER_D0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(cs4281_pm, cs4281_suspend, cs4281_resume);
|
||||
#define CS4281_PM_OPS &cs4281_pm
|
||||
#else
|
||||
#define CS4281_PM_OPS NULL
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
static struct pci_driver cs4281_driver = {
|
||||
@ -2089,10 +2096,9 @@ static struct pci_driver cs4281_driver = {
|
||||
.id_table = snd_cs4281_ids,
|
||||
.probe = snd_cs4281_probe,
|
||||
.remove = __devexit_p(snd_cs4281_remove),
|
||||
#ifdef CONFIG_PM
|
||||
.suspend = cs4281_suspend,
|
||||
.resume = cs4281_resume,
|
||||
#endif
|
||||
.driver = {
|
||||
.pm = CS4281_PM_OPS,
|
||||
},
|
||||
};
|
||||
|
||||
module_pci_driver(cs4281_driver);
|
||||
|
@ -30,7 +30,7 @@
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <sound/core.h>
|
||||
#include <sound/cs46xx.h>
|
||||
#include "cs46xx.h"
|
||||
#include <sound/initval.h>
|
||||
|
||||
MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
|
||||
@ -167,8 +167,9 @@ static struct pci_driver cs46xx_driver = {
|
||||
.probe = snd_card_cs46xx_probe,
|
||||
.remove = __devexit_p(snd_card_cs46xx_remove),
|
||||
#ifdef CONFIG_PM
|
||||
.suspend = snd_cs46xx_suspend,
|
||||
.resume = snd_cs46xx_resume,
|
||||
.driver = {
|
||||
.pm = &snd_cs46xx_pm,
|
||||
},
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@ -23,10 +23,10 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "pcm.h"
|
||||
#include "pcm-indirect.h"
|
||||
#include "rawmidi.h"
|
||||
#include "ac97_codec.h"
|
||||
#include <sound/pcm.h>
|
||||
#include <sound/pcm-indirect.h>
|
||||
#include <sound/rawmidi.h>
|
||||
#include <sound/ac97_codec.h>
|
||||
#include "cs46xx_dsp_spos.h"
|
||||
|
||||
/*
|
||||
@ -1730,8 +1730,7 @@ int snd_cs46xx_create(struct snd_card *card,
|
||||
struct pci_dev *pci,
|
||||
int external_amp, int thinkpad,
|
||||
struct snd_cs46xx **rcodec);
|
||||
int snd_cs46xx_suspend(struct pci_dev *pci, pm_message_t state);
|
||||
int snd_cs46xx_resume(struct pci_dev *pci);
|
||||
extern const struct dev_pm_ops snd_cs46xx_pm;
|
||||
|
||||
int snd_cs46xx_pcm(struct snd_cs46xx *chip, int device, struct snd_pcm **rpcm);
|
||||
int snd_cs46xx_pcm_rear(struct snd_cs46xx *chip, int device, struct snd_pcm **rpcm);
|
@ -61,7 +61,7 @@
|
||||
#include <sound/info.h>
|
||||
#include <sound/pcm.h>
|
||||
#include <sound/pcm_params.h>
|
||||
#include <sound/cs46xx.h>
|
||||
#include "cs46xx.h"
|
||||
|
||||
#include <asm/io.h>
|
||||
|
||||
@ -3599,9 +3599,10 @@ static unsigned int saved_regs[] = {
|
||||
BA1_CVOL,
|
||||
};
|
||||
|
||||
int snd_cs46xx_suspend(struct pci_dev *pci, pm_message_t state)
|
||||
static int snd_cs46xx_suspend(struct device *dev)
|
||||
{
|
||||
struct snd_card *card = pci_get_drvdata(pci);
|
||||
struct pci_dev *pci = to_pci_dev(dev);
|
||||
struct snd_card *card = dev_get_drvdata(dev);
|
||||
struct snd_cs46xx *chip = card->private_data;
|
||||
int i, amp_saved;
|
||||
|
||||
@ -3628,13 +3629,14 @@ int snd_cs46xx_suspend(struct pci_dev *pci, pm_message_t state)
|
||||
|
||||
pci_disable_device(pci);
|
||||
pci_save_state(pci);
|
||||
pci_set_power_state(pci, pci_choose_state(pci, state));
|
||||
pci_set_power_state(pci, PCI_D3hot);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int snd_cs46xx_resume(struct pci_dev *pci)
|
||||
static int snd_cs46xx_resume(struct device *dev)
|
||||
{
|
||||
struct snd_card *card = pci_get_drvdata(pci);
|
||||
struct pci_dev *pci = to_pci_dev(dev);
|
||||
struct snd_card *card = dev_get_drvdata(dev);
|
||||
struct snd_cs46xx *chip = card->private_data;
|
||||
int amp_saved;
|
||||
#ifdef CONFIG_SND_CS46XX_NEW_DSP
|
||||
@ -3707,6 +3709,8 @@ int snd_cs46xx_resume(struct pci_dev *pci)
|
||||
snd_power_change_state(card, SNDRV_CTL_POWER_D0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
SIMPLE_DEV_PM_OPS(snd_cs46xx_pm, snd_cs46xx_suspend, snd_cs46xx_resume);
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
|
||||
|
@ -32,7 +32,7 @@
|
||||
#include <sound/control.h>
|
||||
#include <sound/info.h>
|
||||
#include <sound/asoundef.h>
|
||||
#include <sound/cs46xx.h>
|
||||
#include "cs46xx.h"
|
||||
|
||||
#include "cs46xx_lib.h"
|
||||
#include "dsp_spos.h"
|
||||
|
@ -31,7 +31,7 @@
|
||||
#include <sound/core.h>
|
||||
#include <sound/control.h>
|
||||
#include <sound/info.h>
|
||||
#include <sound/cs46xx.h>
|
||||
#include "cs46xx.h"
|
||||
|
||||
#include "cs46xx_lib.h"
|
||||
#include "dsp_spos.h"
|
||||
|
@ -400,8 +400,9 @@ static struct pci_driver cs5535audio_driver = {
|
||||
.probe = snd_cs5535audio_probe,
|
||||
.remove = __devexit_p(snd_cs5535audio_remove),
|
||||
#ifdef CONFIG_PM
|
||||
.suspend = snd_cs5535audio_suspend,
|
||||
.resume = snd_cs5535audio_resume,
|
||||
.driver = {
|
||||
.pm = &snd_cs5535audio_pm,
|
||||
},
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@ -94,10 +94,7 @@ struct cs5535audio {
|
||||
struct cs5535audio_dma dmas[NUM_CS5535AUDIO_DMAS];
|
||||
};
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
int snd_cs5535audio_suspend(struct pci_dev *pci, pm_message_t state);
|
||||
int snd_cs5535audio_resume(struct pci_dev *pci);
|
||||
#endif
|
||||
extern const struct dev_pm_ops snd_cs5535audio_pm;
|
||||
|
||||
#ifdef CONFIG_OLPC
|
||||
void __devinit olpc_prequirks(struct snd_card *card,
|
||||
|
@ -55,9 +55,10 @@ static void snd_cs5535audio_stop_hardware(struct cs5535audio *cs5535au)
|
||||
|
||||
}
|
||||
|
||||
int snd_cs5535audio_suspend(struct pci_dev *pci, pm_message_t state)
|
||||
static int snd_cs5535audio_suspend(struct device *dev)
|
||||
{
|
||||
struct snd_card *card = pci_get_drvdata(pci);
|
||||
struct pci_dev *pci = to_pci_dev(dev);
|
||||
struct snd_card *card = dev_get_drvdata(dev);
|
||||
struct cs5535audio *cs5535au = card->private_data;
|
||||
int i;
|
||||
|
||||
@ -77,13 +78,14 @@ int snd_cs5535audio_suspend(struct pci_dev *pci, pm_message_t state)
|
||||
return -EIO;
|
||||
}
|
||||
pci_disable_device(pci);
|
||||
pci_set_power_state(pci, pci_choose_state(pci, state));
|
||||
pci_set_power_state(pci, PCI_D3hot);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int snd_cs5535audio_resume(struct pci_dev *pci)
|
||||
static int snd_cs5535audio_resume(struct device *dev)
|
||||
{
|
||||
struct snd_card *card = pci_get_drvdata(pci);
|
||||
struct pci_dev *pci = to_pci_dev(dev);
|
||||
struct snd_card *card = dev_get_drvdata(dev);
|
||||
struct cs5535audio *cs5535au = card->private_data;
|
||||
u32 tmp;
|
||||
int timeout;
|
||||
@ -129,3 +131,4 @@ int snd_cs5535audio_resume(struct pci_dev *pci)
|
||||
return 0;
|
||||
}
|
||||
|
||||
SIMPLE_DEV_PM_OPS(snd_cs5535audio_pm, snd_cs5535audio_suspend, snd_cs5535audio_resume);
|
||||
|
@ -1537,7 +1537,7 @@ static void atc_connect_resources(struct ct_atc *atc)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int atc_suspend(struct ct_atc *atc, pm_message_t state)
|
||||
static int atc_suspend(struct ct_atc *atc)
|
||||
{
|
||||
int i;
|
||||
struct hw *hw = atc->hw;
|
||||
@ -1553,7 +1553,7 @@ static int atc_suspend(struct ct_atc *atc, pm_message_t state)
|
||||
|
||||
atc_release_resources(atc);
|
||||
|
||||
hw->suspend(hw, state);
|
||||
hw->suspend(hw);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -144,7 +144,7 @@ struct ct_atc {
|
||||
struct ct_timer *timer;
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
int (*suspend)(struct ct_atc *atc, pm_message_t state);
|
||||
int (*suspend)(struct ct_atc *atc);
|
||||
int (*resume)(struct ct_atc *atc);
|
||||
#define NUM_PCMS (NUM_CTALSADEVS - 1)
|
||||
struct snd_pcm *pcms[NUM_PCMS];
|
||||
|
@ -73,7 +73,7 @@ struct hw {
|
||||
int (*card_stop)(struct hw *hw);
|
||||
int (*pll_init)(struct hw *hw, unsigned int rsr);
|
||||
#ifdef CONFIG_PM
|
||||
int (*suspend)(struct hw *hw, pm_message_t state);
|
||||
int (*suspend)(struct hw *hw);
|
||||
int (*resume)(struct hw *hw, struct card_conf *info);
|
||||
#endif
|
||||
int (*is_adc_source_selected)(struct hw *hw, enum ADCSRC source);
|
||||
|
@ -2086,7 +2086,7 @@ static int hw_card_init(struct hw *hw, struct card_conf *info)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int hw_suspend(struct hw *hw, pm_message_t state)
|
||||
static int hw_suspend(struct hw *hw)
|
||||
{
|
||||
struct pci_dev *pci = hw->pci;
|
||||
|
||||
@ -2099,7 +2099,7 @@ static int hw_suspend(struct hw *hw, pm_message_t state)
|
||||
|
||||
pci_disable_device(pci);
|
||||
pci_save_state(pci);
|
||||
pci_set_power_state(pci, pci_choose_state(pci, state));
|
||||
pci_set_power_state(pci, PCI_D3hot);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -2202,7 +2202,7 @@ static int hw_card_init(struct hw *hw, struct card_conf *info)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int hw_suspend(struct hw *hw, pm_message_t state)
|
||||
static int hw_suspend(struct hw *hw)
|
||||
{
|
||||
struct pci_dev *pci = hw->pci;
|
||||
|
||||
@ -2210,7 +2210,7 @@ static int hw_suspend(struct hw *hw, pm_message_t state)
|
||||
|
||||
pci_disable_device(pci);
|
||||
pci_save_state(pci);
|
||||
pci_set_power_state(pci, pci_choose_state(pci, state));
|
||||
pci_set_power_state(pci, PCI_D3hot);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -126,21 +126,26 @@ static void __devexit ct_card_remove(struct pci_dev *pci)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int ct_card_suspend(struct pci_dev *pci, pm_message_t state)
|
||||
static int ct_card_suspend(struct device *dev)
|
||||
{
|
||||
struct snd_card *card = pci_get_drvdata(pci);
|
||||
struct snd_card *card = dev_get_drvdata(dev);
|
||||
struct ct_atc *atc = card->private_data;
|
||||
|
||||
return atc->suspend(atc, state);
|
||||
return atc->suspend(atc);
|
||||
}
|
||||
|
||||
static int ct_card_resume(struct pci_dev *pci)
|
||||
static int ct_card_resume(struct device *dev)
|
||||
{
|
||||
struct snd_card *card = pci_get_drvdata(pci);
|
||||
struct snd_card *card = dev_get_drvdata(dev);
|
||||
struct ct_atc *atc = card->private_data;
|
||||
|
||||
return atc->resume(atc);
|
||||
}
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(ct_card_pm, ct_card_suspend, ct_card_resume);
|
||||
#define CT_CARD_PM_OPS &ct_card_pm
|
||||
#else
|
||||
#define CT_CARD_PM_OPS NULL
|
||||
#endif
|
||||
|
||||
static struct pci_driver ct_driver = {
|
||||
@ -148,10 +153,9 @@ static struct pci_driver ct_driver = {
|
||||
.id_table = ct_pci_dev_ids,
|
||||
.probe = ct_card_probe,
|
||||
.remove = __devexit_p(ct_card_remove),
|
||||
#ifdef CONFIG_PM
|
||||
.suspend = ct_card_suspend,
|
||||
.resume = ct_card_resume,
|
||||
#endif
|
||||
.driver = {
|
||||
.pm = CT_CARD_PM_OPS,
|
||||
},
|
||||
};
|
||||
|
||||
module_pci_driver(ct_driver);
|
||||
|
@ -2205,9 +2205,10 @@ static int __devinit snd_echo_probe(struct pci_dev *pci,
|
||||
|
||||
#if defined(CONFIG_PM)
|
||||
|
||||
static int snd_echo_suspend(struct pci_dev *pci, pm_message_t state)
|
||||
static int snd_echo_suspend(struct device *dev)
|
||||
{
|
||||
struct echoaudio *chip = pci_get_drvdata(pci);
|
||||
struct pci_dev *pci = to_pci_dev(dev);
|
||||
struct echoaudio *chip = dev_get_drvdata(dev);
|
||||
|
||||
DE_INIT(("suspend start\n"));
|
||||
snd_pcm_suspend_all(chip->analog_pcm);
|
||||
@ -2242,9 +2243,10 @@ static int snd_echo_suspend(struct pci_dev *pci, pm_message_t state)
|
||||
|
||||
|
||||
|
||||
static int snd_echo_resume(struct pci_dev *pci)
|
||||
static int snd_echo_resume(struct device *dev)
|
||||
{
|
||||
struct echoaudio *chip = pci_get_drvdata(pci);
|
||||
struct pci_dev *pci = to_pci_dev(dev);
|
||||
struct echoaudio *chip = dev_get_drvdata(dev);
|
||||
struct comm_page *commpage, *commpage_bak;
|
||||
u32 pipe_alloc_mask;
|
||||
int err;
|
||||
@ -2307,10 +2309,13 @@ static int snd_echo_resume(struct pci_dev *pci)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(snd_echo_pm, snd_echo_suspend, snd_echo_resume);
|
||||
#define SND_ECHO_PM_OPS &snd_echo_pm
|
||||
#else
|
||||
#define SND_ECHO_PM_OPS NULL
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
|
||||
|
||||
static void __devexit snd_echo_remove(struct pci_dev *pci)
|
||||
{
|
||||
struct echoaudio *chip;
|
||||
@ -2333,10 +2338,9 @@ static struct pci_driver echo_driver = {
|
||||
.id_table = snd_echo_ids,
|
||||
.probe = snd_echo_probe,
|
||||
.remove = __devexit_p(snd_echo_remove),
|
||||
#ifdef CONFIG_PM
|
||||
.suspend = snd_echo_suspend,
|
||||
.resume = snd_echo_resume,
|
||||
#endif /* CONFIG_PM */
|
||||
.driver = {
|
||||
.pm = SND_ECHO_PM_OPS,
|
||||
},
|
||||
};
|
||||
|
||||
module_pci_driver(echo_driver);
|
||||
|
@ -207,9 +207,10 @@ static void __devexit snd_card_emu10k1_remove(struct pci_dev *pci)
|
||||
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int snd_emu10k1_suspend(struct pci_dev *pci, pm_message_t state)
|
||||
static int snd_emu10k1_suspend(struct device *dev)
|
||||
{
|
||||
struct snd_card *card = pci_get_drvdata(pci);
|
||||
struct pci_dev *pci = to_pci_dev(dev);
|
||||
struct snd_card *card = dev_get_drvdata(dev);
|
||||
struct snd_emu10k1 *emu = card->private_data;
|
||||
|
||||
snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
|
||||
@ -231,13 +232,14 @@ static int snd_emu10k1_suspend(struct pci_dev *pci, pm_message_t state)
|
||||
|
||||
pci_disable_device(pci);
|
||||
pci_save_state(pci);
|
||||
pci_set_power_state(pci, pci_choose_state(pci, state));
|
||||
pci_set_power_state(pci, PCI_D3hot);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_emu10k1_resume(struct pci_dev *pci)
|
||||
static int snd_emu10k1_resume(struct device *dev)
|
||||
{
|
||||
struct snd_card *card = pci_get_drvdata(pci);
|
||||
struct pci_dev *pci = to_pci_dev(dev);
|
||||
struct snd_card *card = dev_get_drvdata(dev);
|
||||
struct snd_emu10k1 *emu = card->private_data;
|
||||
|
||||
pci_set_power_state(pci, PCI_D0);
|
||||
@ -261,17 +263,21 @@ static int snd_emu10k1_resume(struct pci_dev *pci)
|
||||
snd_power_change_state(card, SNDRV_CTL_POWER_D0);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(snd_emu10k1_pm, snd_emu10k1_suspend, snd_emu10k1_resume);
|
||||
#define SND_EMU10K1_PM_OPS &snd_emu10k1_pm
|
||||
#else
|
||||
#define SND_EMU10K1_PM_OPS NULL
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
static struct pci_driver emu10k1_driver = {
|
||||
.name = KBUILD_MODNAME,
|
||||
.id_table = snd_emu10k1_ids,
|
||||
.probe = snd_card_emu10k1_probe,
|
||||
.remove = __devexit_p(snd_card_emu10k1_remove),
|
||||
#ifdef CONFIG_PM
|
||||
.suspend = snd_emu10k1_suspend,
|
||||
.resume = snd_emu10k1_resume,
|
||||
#endif
|
||||
.driver = {
|
||||
.pm = SND_EMU10K1_PM_OPS,
|
||||
},
|
||||
};
|
||||
|
||||
module_pci_driver(emu10k1_driver);
|
||||
|
@ -2033,9 +2033,10 @@ static void snd_ensoniq_chip_init(struct ensoniq *ensoniq)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int snd_ensoniq_suspend(struct pci_dev *pci, pm_message_t state)
|
||||
static int snd_ensoniq_suspend(struct device *dev)
|
||||
{
|
||||
struct snd_card *card = pci_get_drvdata(pci);
|
||||
struct pci_dev *pci = to_pci_dev(dev);
|
||||
struct snd_card *card = dev_get_drvdata(dev);
|
||||
struct ensoniq *ensoniq = card->private_data;
|
||||
|
||||
snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
|
||||
@ -2058,13 +2059,14 @@ static int snd_ensoniq_suspend(struct pci_dev *pci, pm_message_t state)
|
||||
|
||||
pci_disable_device(pci);
|
||||
pci_save_state(pci);
|
||||
pci_set_power_state(pci, pci_choose_state(pci, state));
|
||||
pci_set_power_state(pci, PCI_D3hot);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_ensoniq_resume(struct pci_dev *pci)
|
||||
static int snd_ensoniq_resume(struct device *dev)
|
||||
{
|
||||
struct snd_card *card = pci_get_drvdata(pci);
|
||||
struct pci_dev *pci = to_pci_dev(dev);
|
||||
struct snd_card *card = dev_get_drvdata(dev);
|
||||
struct ensoniq *ensoniq = card->private_data;
|
||||
|
||||
pci_set_power_state(pci, PCI_D0);
|
||||
@ -2087,8 +2089,12 @@ static int snd_ensoniq_resume(struct pci_dev *pci)
|
||||
snd_power_change_state(card, SNDRV_CTL_POWER_D0);
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(snd_ensoniq_pm, snd_ensoniq_suspend, snd_ensoniq_resume);
|
||||
#define SND_ENSONIQ_PM_OPS &snd_ensoniq_pm
|
||||
#else
|
||||
#define SND_ENSONIQ_PM_OPS NULL
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
static int __devinit snd_ensoniq_create(struct snd_card *card,
|
||||
struct pci_dev *pci,
|
||||
@ -2493,10 +2499,9 @@ static struct pci_driver ens137x_driver = {
|
||||
.id_table = snd_audiopci_ids,
|
||||
.probe = snd_audiopci_probe,
|
||||
.remove = __devexit_p(snd_audiopci_remove),
|
||||
#ifdef CONFIG_PM
|
||||
.suspend = snd_ensoniq_suspend,
|
||||
.resume = snd_ensoniq_resume,
|
||||
#endif
|
||||
.driver = {
|
||||
.pm = SND_ENSONIQ_PM_OPS,
|
||||
},
|
||||
};
|
||||
|
||||
module_pci_driver(ens137x_driver);
|
||||
|
@ -1321,35 +1321,30 @@ static int snd_es1938_put_double(struct snd_kcontrol *kcontrol,
|
||||
return change;
|
||||
}
|
||||
|
||||
static unsigned int db_scale_master[] = {
|
||||
TLV_DB_RANGE_HEAD(2),
|
||||
static const DECLARE_TLV_DB_RANGE(db_scale_master,
|
||||
0, 54, TLV_DB_SCALE_ITEM(-3600, 50, 1),
|
||||
54, 63, TLV_DB_SCALE_ITEM(-900, 100, 0),
|
||||
};
|
||||
);
|
||||
|
||||
static unsigned int db_scale_audio1[] = {
|
||||
TLV_DB_RANGE_HEAD(2),
|
||||
static const DECLARE_TLV_DB_RANGE(db_scale_audio1,
|
||||
0, 8, TLV_DB_SCALE_ITEM(-3300, 300, 1),
|
||||
8, 15, TLV_DB_SCALE_ITEM(-900, 150, 0),
|
||||
};
|
||||
);
|
||||
|
||||
static unsigned int db_scale_audio2[] = {
|
||||
TLV_DB_RANGE_HEAD(2),
|
||||
static const DECLARE_TLV_DB_RANGE(db_scale_audio2,
|
||||
0, 8, TLV_DB_SCALE_ITEM(-3450, 300, 1),
|
||||
8, 15, TLV_DB_SCALE_ITEM(-1050, 150, 0),
|
||||
};
|
||||
);
|
||||
|
||||
static unsigned int db_scale_mic[] = {
|
||||
TLV_DB_RANGE_HEAD(2),
|
||||
static const DECLARE_TLV_DB_RANGE(db_scale_mic,
|
||||
0, 8, TLV_DB_SCALE_ITEM(-2400, 300, 1),
|
||||
8, 15, TLV_DB_SCALE_ITEM(0, 150, 0),
|
||||
};
|
||||
);
|
||||
|
||||
static unsigned int db_scale_line[] = {
|
||||
TLV_DB_RANGE_HEAD(2),
|
||||
static const DECLARE_TLV_DB_RANGE(db_scale_line,
|
||||
0, 8, TLV_DB_SCALE_ITEM(-3150, 300, 1),
|
||||
8, 15, TLV_DB_SCALE_ITEM(-750, 150, 0),
|
||||
};
|
||||
);
|
||||
|
||||
static const DECLARE_TLV_DB_SCALE(db_scale_capture, 0, 150, 0);
|
||||
|
||||
@ -1474,9 +1469,10 @@ static unsigned char saved_regs[SAVED_REG_SIZE+1] = {
|
||||
};
|
||||
|
||||
|
||||
static int es1938_suspend(struct pci_dev *pci, pm_message_t state)
|
||||
static int es1938_suspend(struct device *dev)
|
||||
{
|
||||
struct snd_card *card = pci_get_drvdata(pci);
|
||||
struct pci_dev *pci = to_pci_dev(dev);
|
||||
struct snd_card *card = dev_get_drvdata(dev);
|
||||
struct es1938 *chip = card->private_data;
|
||||
unsigned char *s, *d;
|
||||
|
||||
@ -1494,13 +1490,14 @@ static int es1938_suspend(struct pci_dev *pci, pm_message_t state)
|
||||
}
|
||||
pci_disable_device(pci);
|
||||
pci_save_state(pci);
|
||||
pci_set_power_state(pci, pci_choose_state(pci, state));
|
||||
pci_set_power_state(pci, PCI_D3hot);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int es1938_resume(struct pci_dev *pci)
|
||||
static int es1938_resume(struct device *dev)
|
||||
{
|
||||
struct snd_card *card = pci_get_drvdata(pci);
|
||||
struct pci_dev *pci = to_pci_dev(dev);
|
||||
struct snd_card *card = dev_get_drvdata(dev);
|
||||
struct es1938 *chip = card->private_data;
|
||||
unsigned char *s, *d;
|
||||
|
||||
@ -1534,6 +1531,11 @@ static int es1938_resume(struct pci_dev *pci)
|
||||
snd_power_change_state(card, SNDRV_CTL_POWER_D0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(es1938_pm, es1938_suspend, es1938_resume);
|
||||
#define ES1938_PM_OPS &es1938_pm
|
||||
#else
|
||||
#define ES1938_PM_OPS NULL
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
#ifdef SUPPORT_JOYSTICK
|
||||
@ -1887,10 +1889,9 @@ static struct pci_driver es1938_driver = {
|
||||
.id_table = snd_es1938_ids,
|
||||
.probe = snd_es1938_probe,
|
||||
.remove = __devexit_p(snd_es1938_remove),
|
||||
#ifdef CONFIG_PM
|
||||
.suspend = es1938_suspend,
|
||||
.resume = es1938_resume,
|
||||
#endif
|
||||
.driver = {
|
||||
.pm = ES1938_PM_OPS,
|
||||
},
|
||||
};
|
||||
|
||||
module_pci_driver(es1938_driver);
|
||||
|
@ -2381,9 +2381,10 @@ static void snd_es1968_start_irq(struct es1968 *chip)
|
||||
/*
|
||||
* PM support
|
||||
*/
|
||||
static int es1968_suspend(struct pci_dev *pci, pm_message_t state)
|
||||
static int es1968_suspend(struct device *dev)
|
||||
{
|
||||
struct snd_card *card = pci_get_drvdata(pci);
|
||||
struct pci_dev *pci = to_pci_dev(dev);
|
||||
struct snd_card *card = dev_get_drvdata(dev);
|
||||
struct es1968 *chip = card->private_data;
|
||||
|
||||
if (! chip->do_pm)
|
||||
@ -2398,13 +2399,14 @@ static int es1968_suspend(struct pci_dev *pci, pm_message_t state)
|
||||
|
||||
pci_disable_device(pci);
|
||||
pci_save_state(pci);
|
||||
pci_set_power_state(pci, pci_choose_state(pci, state));
|
||||
pci_set_power_state(pci, PCI_D3hot);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int es1968_resume(struct pci_dev *pci)
|
||||
static int es1968_resume(struct device *dev)
|
||||
{
|
||||
struct snd_card *card = pci_get_drvdata(pci);
|
||||
struct pci_dev *pci = to_pci_dev(dev);
|
||||
struct snd_card *card = dev_get_drvdata(dev);
|
||||
struct es1968 *chip = card->private_data;
|
||||
struct esschan *es;
|
||||
|
||||
@ -2454,6 +2456,11 @@ static int es1968_resume(struct pci_dev *pci)
|
||||
chip->in_suspend = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(es1968_pm, es1968_suspend, es1968_resume);
|
||||
#define ES1968_PM_OPS &es1968_pm
|
||||
#else
|
||||
#define ES1968_PM_OPS NULL
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
#ifdef SUPPORT_JOYSTICK
|
||||
@ -2903,10 +2910,9 @@ static struct pci_driver es1968_driver = {
|
||||
.id_table = snd_es1968_ids,
|
||||
.probe = snd_es1968_probe,
|
||||
.remove = __devexit_p(snd_es1968_remove),
|
||||
#ifdef CONFIG_PM
|
||||
.suspend = es1968_suspend,
|
||||
.resume = es1968_resume,
|
||||
#endif
|
||||
.driver = {
|
||||
.pm = ES1968_PM_OPS,
|
||||
},
|
||||
};
|
||||
|
||||
module_pci_driver(es1968_driver);
|
||||
|
@ -1369,9 +1369,10 @@ static unsigned char saved_regs[] = {
|
||||
FM801_CODEC_CTRL, FM801_I2S_MODE, FM801_VOLUME, FM801_GEN_CTRL,
|
||||
};
|
||||
|
||||
static int snd_fm801_suspend(struct pci_dev *pci, pm_message_t state)
|
||||
static int snd_fm801_suspend(struct device *dev)
|
||||
{
|
||||
struct snd_card *card = pci_get_drvdata(pci);
|
||||
struct pci_dev *pci = to_pci_dev(dev);
|
||||
struct snd_card *card = dev_get_drvdata(dev);
|
||||
struct fm801 *chip = card->private_data;
|
||||
int i;
|
||||
|
||||
@ -1385,13 +1386,14 @@ static int snd_fm801_suspend(struct pci_dev *pci, pm_message_t state)
|
||||
|
||||
pci_disable_device(pci);
|
||||
pci_save_state(pci);
|
||||
pci_set_power_state(pci, pci_choose_state(pci, state));
|
||||
pci_set_power_state(pci, PCI_D3hot);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_fm801_resume(struct pci_dev *pci)
|
||||
static int snd_fm801_resume(struct device *dev)
|
||||
{
|
||||
struct snd_card *card = pci_get_drvdata(pci);
|
||||
struct pci_dev *pci = to_pci_dev(dev);
|
||||
struct snd_card *card = dev_get_drvdata(dev);
|
||||
struct fm801 *chip = card->private_data;
|
||||
int i;
|
||||
|
||||
@ -1414,17 +1416,21 @@ static int snd_fm801_resume(struct pci_dev *pci)
|
||||
snd_power_change_state(card, SNDRV_CTL_POWER_D0);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(snd_fm801_pm, snd_fm801_suspend, snd_fm801_resume);
|
||||
#define SND_FM801_PM_OPS &snd_fm801_pm
|
||||
#else
|
||||
#define SND_FM801_PM_OPS NULL
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
static struct pci_driver fm801_driver = {
|
||||
.name = KBUILD_MODNAME,
|
||||
.id_table = snd_fm801_ids,
|
||||
.probe = snd_card_fm801_probe,
|
||||
.remove = __devexit_p(snd_card_fm801_remove),
|
||||
#ifdef CONFIG_PM
|
||||
.suspend = snd_fm801_suspend,
|
||||
.resume = snd_fm801_resume,
|
||||
#endif
|
||||
.driver = {
|
||||
.pm = SND_FM801_PM_OPS,
|
||||
},
|
||||
};
|
||||
|
||||
module_pci_driver(fm801_driver);
|
||||
|
@ -53,15 +53,14 @@ config SND_HDA_INPUT_BEEP
|
||||
driver. This interface is used to generate digital beeps.
|
||||
|
||||
config SND_HDA_INPUT_BEEP_MODE
|
||||
int "Digital beep registration mode (0=off, 1=on, 2=mute sw on/off)"
|
||||
int "Digital beep registration mode (0=off, 1=on)"
|
||||
depends on SND_HDA_INPUT_BEEP=y
|
||||
default "1"
|
||||
range 0 2
|
||||
range 0 1
|
||||
help
|
||||
Set 0 to disable the digital beep interface for HD-audio by default.
|
||||
Set 1 to always enable the digital beep interface for HD-audio by
|
||||
default. Set 2 to control the beep device registration to input
|
||||
layer using a "Beep Switch" in mixer applications.
|
||||
default.
|
||||
|
||||
config SND_HDA_INPUT_JACK
|
||||
bool "Support jack plugging notification via input layer"
|
||||
|
@ -727,7 +727,7 @@ void snd_hda_pick_fixup(struct hda_codec *codec,
|
||||
models++;
|
||||
}
|
||||
}
|
||||
if (id < 0) {
|
||||
if (id < 0 && quirk) {
|
||||
q = snd_pci_quirk_lookup(codec->bus->pci, quirk);
|
||||
if (q) {
|
||||
id = q->value;
|
||||
@ -736,7 +736,7 @@ void snd_hda_pick_fixup(struct hda_codec *codec,
|
||||
#endif
|
||||
}
|
||||
}
|
||||
if (id < 0) {
|
||||
if (id < 0 && quirk) {
|
||||
for (q = quirk; q->subvendor; q++) {
|
||||
unsigned int vendorid =
|
||||
q->subdevice | (q->subvendor << 16);
|
||||
|
@ -162,50 +162,20 @@ static int snd_hda_do_attach(struct hda_beep *beep)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void snd_hda_do_register(struct work_struct *work)
|
||||
{
|
||||
struct hda_beep *beep =
|
||||
container_of(work, struct hda_beep, register_work);
|
||||
|
||||
mutex_lock(&beep->mutex);
|
||||
if (beep->enabled && !beep->dev)
|
||||
snd_hda_do_attach(beep);
|
||||
mutex_unlock(&beep->mutex);
|
||||
}
|
||||
|
||||
static void snd_hda_do_unregister(struct work_struct *work)
|
||||
{
|
||||
struct hda_beep *beep =
|
||||
container_of(work, struct hda_beep, unregister_work.work);
|
||||
|
||||
mutex_lock(&beep->mutex);
|
||||
if (!beep->enabled && beep->dev)
|
||||
snd_hda_do_detach(beep);
|
||||
mutex_unlock(&beep->mutex);
|
||||
}
|
||||
|
||||
int snd_hda_enable_beep_device(struct hda_codec *codec, int enable)
|
||||
{
|
||||
struct hda_beep *beep = codec->beep;
|
||||
enable = !!enable;
|
||||
if (beep == NULL)
|
||||
if (!beep)
|
||||
return 0;
|
||||
enable = !!enable;
|
||||
if (beep->enabled != enable) {
|
||||
beep->enabled = enable;
|
||||
if (!enable) {
|
||||
cancel_work_sync(&beep->beep_work);
|
||||
/* turn off beep */
|
||||
snd_hda_codec_write(beep->codec, beep->nid, 0,
|
||||
AC_VERB_SET_BEEP_CONTROL, 0);
|
||||
}
|
||||
if (beep->mode == HDA_BEEP_MODE_SWREG) {
|
||||
if (enable) {
|
||||
cancel_delayed_work(&beep->unregister_work);
|
||||
schedule_work(&beep->register_work);
|
||||
} else {
|
||||
schedule_delayed_work(&beep->unregister_work,
|
||||
HZ);
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
@ -215,6 +185,7 @@ EXPORT_SYMBOL_HDA(snd_hda_enable_beep_device);
|
||||
int snd_hda_attach_beep_device(struct hda_codec *codec, int nid)
|
||||
{
|
||||
struct hda_beep *beep;
|
||||
int err;
|
||||
|
||||
if (!snd_hda_get_bool_hint(codec, "beep"))
|
||||
return 0; /* disabled explicitly by hints */
|
||||
@ -232,21 +203,16 @@ int snd_hda_attach_beep_device(struct hda_codec *codec, int nid)
|
||||
|
||||
beep->nid = nid;
|
||||
beep->codec = codec;
|
||||
beep->mode = codec->beep_mode;
|
||||
codec->beep = beep;
|
||||
|
||||
INIT_WORK(&beep->register_work, &snd_hda_do_register);
|
||||
INIT_DELAYED_WORK(&beep->unregister_work, &snd_hda_do_unregister);
|
||||
INIT_WORK(&beep->beep_work, &snd_hda_generate_beep);
|
||||
mutex_init(&beep->mutex);
|
||||
|
||||
if (beep->mode == HDA_BEEP_MODE_ON) {
|
||||
int err = snd_hda_do_attach(beep);
|
||||
if (err < 0) {
|
||||
kfree(beep);
|
||||
codec->beep = NULL;
|
||||
return err;
|
||||
}
|
||||
err = snd_hda_do_attach(beep);
|
||||
if (err < 0) {
|
||||
kfree(beep);
|
||||
codec->beep = NULL;
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -257,8 +223,6 @@ void snd_hda_detach_beep_device(struct hda_codec *codec)
|
||||
{
|
||||
struct hda_beep *beep = codec->beep;
|
||||
if (beep) {
|
||||
cancel_work_sync(&beep->register_work);
|
||||
cancel_delayed_work(&beep->unregister_work);
|
||||
if (beep->dev)
|
||||
snd_hda_do_detach(beep);
|
||||
codec->beep = NULL;
|
||||
@ -266,3 +230,31 @@ void snd_hda_detach_beep_device(struct hda_codec *codec)
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_HDA(snd_hda_detach_beep_device);
|
||||
|
||||
/* get/put callbacks for beep mute mixer switches */
|
||||
int snd_hda_mixer_amp_switch_get_beep(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
|
||||
struct hda_beep *beep = codec->beep;
|
||||
if (beep) {
|
||||
ucontrol->value.integer.value[0] =
|
||||
ucontrol->value.integer.value[1] =
|
||||
beep->enabled;
|
||||
return 0;
|
||||
}
|
||||
return snd_hda_mixer_amp_switch_get(kcontrol, ucontrol);
|
||||
}
|
||||
EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_switch_get_beep);
|
||||
|
||||
int snd_hda_mixer_amp_switch_put_beep(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
|
||||
struct hda_beep *beep = codec->beep;
|
||||
if (beep)
|
||||
snd_hda_enable_beep_device(codec,
|
||||
*ucontrol->value.integer.value);
|
||||
return snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
|
||||
}
|
||||
EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_switch_put_beep);
|
||||
|
@ -26,21 +26,16 @@
|
||||
|
||||
#define HDA_BEEP_MODE_OFF 0
|
||||
#define HDA_BEEP_MODE_ON 1
|
||||
#define HDA_BEEP_MODE_SWREG 2
|
||||
|
||||
/* beep information */
|
||||
struct hda_beep {
|
||||
struct input_dev *dev;
|
||||
struct hda_codec *codec;
|
||||
unsigned int mode;
|
||||
char phys[32];
|
||||
int tone;
|
||||
hda_nid_t nid;
|
||||
unsigned int enabled:1;
|
||||
unsigned int request_enable:1;
|
||||
unsigned int linear_tone:1; /* linear tone for IDT/STAC codec */
|
||||
struct work_struct register_work; /* registration work */
|
||||
struct delayed_work unregister_work; /* unregistration work */
|
||||
struct work_struct beep_work; /* scheduled task for beep event */
|
||||
struct mutex mutex;
|
||||
};
|
||||
|
@ -2676,25 +2676,6 @@ int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol,
|
||||
}
|
||||
EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_switch_put);
|
||||
|
||||
#ifdef CONFIG_SND_HDA_INPUT_BEEP
|
||||
/**
|
||||
* snd_hda_mixer_amp_switch_put_beep - Put callback for a beep AMP switch
|
||||
*
|
||||
* This function calls snd_hda_enable_beep_device(), which behaves differently
|
||||
* depending on beep_mode option.
|
||||
*/
|
||||
int snd_hda_mixer_amp_switch_put_beep(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
|
||||
long *valp = ucontrol->value.integer.value;
|
||||
|
||||
snd_hda_enable_beep_device(codec, *valp);
|
||||
return snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
|
||||
}
|
||||
EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_switch_put_beep);
|
||||
#endif /* CONFIG_SND_HDA_INPUT_BEEP */
|
||||
|
||||
/*
|
||||
* bound volume controls
|
||||
*
|
||||
@ -3508,23 +3489,53 @@ void snd_hda_codec_set_power_to_all(struct hda_codec *codec, hda_nid_t fg,
|
||||
}
|
||||
EXPORT_SYMBOL_HDA(snd_hda_codec_set_power_to_all);
|
||||
|
||||
/*
|
||||
* supported power states check
|
||||
*/
|
||||
static bool snd_hda_codec_get_supported_ps(struct hda_codec *codec, hda_nid_t fg,
|
||||
unsigned int power_state)
|
||||
{
|
||||
int sup = snd_hda_param_read(codec, fg, AC_PAR_POWER_STATE);
|
||||
|
||||
if (sup < 0)
|
||||
return false;
|
||||
if (sup & power_state)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* set power state of the codec
|
||||
*/
|
||||
static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
|
||||
unsigned int power_state)
|
||||
{
|
||||
int count;
|
||||
unsigned int state;
|
||||
|
||||
if (codec->patch_ops.set_power_state) {
|
||||
codec->patch_ops.set_power_state(codec, fg, power_state);
|
||||
return;
|
||||
}
|
||||
|
||||
/* this delay seems necessary to avoid click noise at power-down */
|
||||
if (power_state == AC_PWRST_D3)
|
||||
msleep(100);
|
||||
snd_hda_codec_read(codec, fg, 0, AC_VERB_SET_POWER_STATE,
|
||||
power_state);
|
||||
snd_hda_codec_set_power_to_all(codec, fg, power_state, true);
|
||||
if (power_state == AC_PWRST_D3) {
|
||||
/* transition time less than 10ms for power down */
|
||||
bool epss = snd_hda_codec_get_supported_ps(codec, fg, AC_PWRST_EPSS);
|
||||
msleep(epss ? 10 : 100);
|
||||
}
|
||||
|
||||
/* repeat power states setting at most 10 times*/
|
||||
for (count = 0; count < 10; count++) {
|
||||
snd_hda_codec_read(codec, fg, 0, AC_VERB_SET_POWER_STATE,
|
||||
power_state);
|
||||
snd_hda_codec_set_power_to_all(codec, fg, power_state, true);
|
||||
state = snd_hda_codec_read(codec, fg, 0,
|
||||
AC_VERB_GET_POWER_STATE, 0);
|
||||
if (!(state & AC_PWRST_ERROR))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SND_HDA_HWDEP
|
||||
@ -3545,7 +3556,7 @@ static inline void hda_exec_init_verbs(struct hda_codec *codec) {}
|
||||
static void hda_call_codec_suspend(struct hda_codec *codec)
|
||||
{
|
||||
if (codec->patch_ops.suspend)
|
||||
codec->patch_ops.suspend(codec, PMSG_SUSPEND);
|
||||
codec->patch_ops.suspend(codec);
|
||||
hda_cleanup_all_streams(codec);
|
||||
hda_set_power_state(codec,
|
||||
codec->afg ? codec->afg : codec->mfg,
|
||||
@ -4418,6 +4429,13 @@ static void __snd_hda_power_up(struct hda_codec *codec, bool wait_power_down)
|
||||
cancel_delayed_work_sync(&codec->power_work);
|
||||
|
||||
spin_lock(&codec->power_lock);
|
||||
/* If the power down delayed work was cancelled above before starting,
|
||||
* then there is no need to go through power up here.
|
||||
*/
|
||||
if (codec->power_on) {
|
||||
spin_unlock(&codec->power_lock);
|
||||
return;
|
||||
}
|
||||
trace_hda_power_up(codec);
|
||||
snd_hda_update_power_acct(codec);
|
||||
codec->power_on = 1;
|
||||
|
@ -323,6 +323,9 @@ enum {
|
||||
#define AC_PWRST_D1 0x01
|
||||
#define AC_PWRST_D2 0x02
|
||||
#define AC_PWRST_D3 0x03
|
||||
#define AC_PWRST_ERROR (1<<8)
|
||||
#define AC_PWRST_CLK_STOP_OK (1<<9)
|
||||
#define AC_PWRST_SETTING_RESET (1<<10)
|
||||
|
||||
/* Processing capabilies */
|
||||
#define AC_PCAP_BENIGN (1<<0)
|
||||
@ -703,7 +706,7 @@ struct hda_codec_ops {
|
||||
void (*set_power_state)(struct hda_codec *codec, hda_nid_t fg,
|
||||
unsigned int power_state);
|
||||
#ifdef CONFIG_PM
|
||||
int (*suspend)(struct hda_codec *codec, pm_message_t state);
|
||||
int (*suspend)(struct hda_codec *codec);
|
||||
int (*resume)(struct hda_codec *codec);
|
||||
#endif
|
||||
#ifdef CONFIG_SND_HDA_POWER_SAVE
|
||||
|
@ -72,7 +72,7 @@ static int enable_msi = -1;
|
||||
static char *patch[SNDRV_CARDS];
|
||||
#endif
|
||||
#ifdef CONFIG_SND_HDA_INPUT_BEEP
|
||||
static int beep_mode[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] =
|
||||
static bool beep_mode[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] =
|
||||
CONFIG_SND_HDA_INPUT_BEEP_MODE};
|
||||
#endif
|
||||
|
||||
@ -103,9 +103,9 @@ module_param_array(patch, charp, NULL, 0444);
|
||||
MODULE_PARM_DESC(patch, "Patch file for Intel HD audio interface.");
|
||||
#endif
|
||||
#ifdef CONFIG_SND_HDA_INPUT_BEEP
|
||||
module_param_array(beep_mode, int, NULL, 0444);
|
||||
module_param_array(beep_mode, bool, NULL, 0444);
|
||||
MODULE_PARM_DESC(beep_mode, "Select HDA Beep registration mode "
|
||||
"(0=off, 1=on, 2=mute switch on/off) (default=1).");
|
||||
"(0=off, 1=on) (default=1).");
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SND_HDA_POWER_SAVE
|
||||
@ -151,6 +151,7 @@ MODULE_SUPPORTED_DEVICE("{{Intel, ICH6},"
|
||||
"{Intel, CPT},"
|
||||
"{Intel, PPT},"
|
||||
"{Intel, LPT},"
|
||||
"{Intel, HPT},"
|
||||
"{Intel, PBG},"
|
||||
"{Intel, SCH},"
|
||||
"{ATI, SB450},"
|
||||
@ -535,6 +536,7 @@ enum {
|
||||
#define AZX_DCAPS_BUFSIZE (1 << 21) /* no buffer size alignment */
|
||||
#define AZX_DCAPS_ALIGN_BUFSIZE (1 << 22) /* buffer size alignment */
|
||||
#define AZX_DCAPS_4K_BDLE_BOUNDARY (1 << 23) /* BDLE in 4k boundary */
|
||||
#define AZX_DCAPS_POSFIX_COMBO (1 << 24) /* Use COMBO as default */
|
||||
|
||||
/* quirks for ATI SB / AMD Hudson */
|
||||
#define AZX_DCAPS_PRESET_ATI_SB \
|
||||
@ -2403,9 +2405,10 @@ static void azx_power_notify(struct hda_bus *bus)
|
||||
* power management
|
||||
*/
|
||||
|
||||
static int azx_suspend(struct pci_dev *pci, pm_message_t state)
|
||||
static int azx_suspend(struct device *dev)
|
||||
{
|
||||
struct snd_card *card = pci_get_drvdata(pci);
|
||||
struct pci_dev *pci = to_pci_dev(dev);
|
||||
struct snd_card *card = dev_get_drvdata(dev);
|
||||
struct azx *chip = card->private_data;
|
||||
struct azx_pcm *p;
|
||||
|
||||
@ -2424,13 +2427,14 @@ static int azx_suspend(struct pci_dev *pci, pm_message_t state)
|
||||
pci_disable_msi(chip->pci);
|
||||
pci_disable_device(pci);
|
||||
pci_save_state(pci);
|
||||
pci_set_power_state(pci, pci_choose_state(pci, state));
|
||||
pci_set_power_state(pci, PCI_D3hot);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int azx_resume(struct pci_dev *pci)
|
||||
static int azx_resume(struct device *dev)
|
||||
{
|
||||
struct snd_card *card = pci_get_drvdata(pci);
|
||||
struct pci_dev *pci = to_pci_dev(dev);
|
||||
struct snd_card *card = dev_get_drvdata(dev);
|
||||
struct azx *chip = card->private_data;
|
||||
|
||||
pci_set_power_state(pci, PCI_D0);
|
||||
@ -2455,6 +2459,12 @@ static int azx_resume(struct pci_dev *pci)
|
||||
snd_power_change_state(card, SNDRV_CTL_POWER_D0);
|
||||
return 0;
|
||||
}
|
||||
static SIMPLE_DEV_PM_OPS(azx_pm, azx_suspend, azx_resume);
|
||||
#define AZX_PM_OPS &azx_pm
|
||||
#else
|
||||
#define azx_suspend(dev)
|
||||
#define azx_resume(dev)
|
||||
#define AZX_PM_OPS NULL
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
|
||||
@ -2521,13 +2531,13 @@ static void azx_vs_set_state(struct pci_dev *pci,
|
||||
disabled ? "Disabling" : "Enabling",
|
||||
pci_name(chip->pci));
|
||||
if (disabled) {
|
||||
azx_suspend(pci, PMSG_FREEZE);
|
||||
azx_suspend(&pci->dev);
|
||||
chip->disabled = true;
|
||||
snd_hda_lock_devices(chip->bus);
|
||||
} else {
|
||||
snd_hda_unlock_devices(chip->bus);
|
||||
chip->disabled = false;
|
||||
azx_resume(pci);
|
||||
azx_resume(&pci->dev);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2731,6 +2741,10 @@ static int __devinit check_position_fix(struct azx *chip, int fix)
|
||||
snd_printd(SFX "Using LPIB position fix\n");
|
||||
return POS_FIX_LPIB;
|
||||
}
|
||||
if (chip->driver_caps & AZX_DCAPS_POSFIX_COMBO) {
|
||||
snd_printd(SFX "Using COMBO position fix\n");
|
||||
return POS_FIX_COMBO;
|
||||
}
|
||||
return POS_FIX_AUTO;
|
||||
}
|
||||
|
||||
@ -3243,7 +3257,7 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = {
|
||||
/* CPT */
|
||||
{ PCI_DEVICE(0x8086, 0x1c20),
|
||||
.driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
|
||||
AZX_DCAPS_BUFSIZE },
|
||||
AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_COMBO },
|
||||
/* PBG */
|
||||
{ PCI_DEVICE(0x8086, 0x1d20),
|
||||
.driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
|
||||
@ -3251,11 +3265,15 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = {
|
||||
/* Panther Point */
|
||||
{ PCI_DEVICE(0x8086, 0x1e20),
|
||||
.driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
|
||||
AZX_DCAPS_BUFSIZE},
|
||||
AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_COMBO },
|
||||
/* Lynx Point */
|
||||
{ PCI_DEVICE(0x8086, 0x8c20),
|
||||
.driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
|
||||
AZX_DCAPS_BUFSIZE},
|
||||
AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_COMBO },
|
||||
/* Haswell */
|
||||
{ PCI_DEVICE(0x8086, 0x0c0c),
|
||||
.driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP |
|
||||
AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_COMBO },
|
||||
/* SCH */
|
||||
{ PCI_DEVICE(0x8086, 0x811b),
|
||||
.driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP |
|
||||
@ -3341,6 +3359,10 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = {
|
||||
/* VIA VT8251/VT8237A */
|
||||
{ PCI_DEVICE(0x1106, 0x3288),
|
||||
.driver_data = AZX_DRIVER_VIA | AZX_DCAPS_POSFIX_VIA },
|
||||
/* 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 },
|
||||
/* SIS966 */
|
||||
{ PCI_DEVICE(0x1039, 0x7502), .driver_data = AZX_DRIVER_SIS },
|
||||
/* ULI M5461 */
|
||||
@ -3398,10 +3420,9 @@ static struct pci_driver azx_driver = {
|
||||
.id_table = azx_ids,
|
||||
.probe = azx_probe,
|
||||
.remove = __devexit_p(azx_remove),
|
||||
#ifdef CONFIG_PM
|
||||
.suspend = azx_suspend,
|
||||
.resume = azx_resume,
|
||||
#endif
|
||||
.driver = {
|
||||
.pm = AZX_PM_OPS,
|
||||
},
|
||||
};
|
||||
|
||||
module_pci_driver(azx_driver);
|
||||
|
@ -127,10 +127,15 @@ void snd_hda_jack_tbl_clear(struct hda_codec *codec)
|
||||
static void jack_detect_update(struct hda_codec *codec,
|
||||
struct hda_jack_tbl *jack)
|
||||
{
|
||||
if (jack->jack_dirty || !jack->jack_detect) {
|
||||
if (!jack->jack_dirty)
|
||||
return;
|
||||
|
||||
if (jack->phantom_jack)
|
||||
jack->pin_sense = AC_PINSENSE_PRESENCE;
|
||||
else
|
||||
jack->pin_sense = read_pin_sense(codec, jack->nid);
|
||||
jack->jack_dirty = 0;
|
||||
}
|
||||
|
||||
jack->jack_dirty = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -264,8 +269,8 @@ static void hda_free_jack_priv(struct snd_jack *jack)
|
||||
* This assigns a jack-detection kctl to the given pin. The kcontrol
|
||||
* will have the given name and index.
|
||||
*/
|
||||
int snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid,
|
||||
const char *name, int idx)
|
||||
static int __snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid,
|
||||
const char *name, int idx, bool phantom_jack)
|
||||
{
|
||||
struct hda_jack_tbl *jack;
|
||||
struct snd_kcontrol *kctl;
|
||||
@ -283,47 +288,81 @@ int snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid,
|
||||
if (err < 0)
|
||||
return err;
|
||||
jack->kctl = kctl;
|
||||
jack->phantom_jack = !!phantom_jack;
|
||||
|
||||
state = snd_hda_jack_detect(codec, nid);
|
||||
snd_kctl_jack_report(codec->bus->card, kctl, state);
|
||||
#ifdef CONFIG_SND_HDA_INPUT_JACK
|
||||
jack->type = get_input_jack_type(codec, nid);
|
||||
err = snd_jack_new(codec->bus->card, name, jack->type, &jack->jack);
|
||||
if (err < 0)
|
||||
return err;
|
||||
jack->jack->private_data = jack;
|
||||
jack->jack->private_free = hda_free_jack_priv;
|
||||
snd_jack_report(jack->jack, state ? jack->type : 0);
|
||||
if (!phantom_jack) {
|
||||
jack->type = get_input_jack_type(codec, nid);
|
||||
err = snd_jack_new(codec->bus->card, name, jack->type,
|
||||
&jack->jack);
|
||||
if (err < 0)
|
||||
return err;
|
||||
jack->jack->private_data = jack;
|
||||
jack->jack->private_free = hda_free_jack_priv;
|
||||
snd_jack_report(jack->jack, state ? jack->type : 0);
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid,
|
||||
const char *name, int idx)
|
||||
{
|
||||
return __snd_hda_jack_add_kctl(codec, nid, name, idx, false);
|
||||
}
|
||||
EXPORT_SYMBOL_HDA(snd_hda_jack_add_kctl);
|
||||
|
||||
/* get the unique index number for the given kctl name */
|
||||
static int get_unique_index(struct hda_codec *codec, const char *name, int idx)
|
||||
{
|
||||
struct hda_jack_tbl *jack;
|
||||
int i, len = strlen(name);
|
||||
again:
|
||||
jack = codec->jacktbl.list;
|
||||
for (i = 0; i < codec->jacktbl.used; i++, jack++) {
|
||||
/* jack->kctl.id contains "XXX Jack" name string with index */
|
||||
if (jack->kctl &&
|
||||
!strncmp(name, jack->kctl->id.name, len) &&
|
||||
!strcmp(" Jack", jack->kctl->id.name + len) &&
|
||||
jack->kctl->id.index == idx) {
|
||||
idx++;
|
||||
goto again;
|
||||
}
|
||||
}
|
||||
return idx;
|
||||
}
|
||||
|
||||
static int add_jack_kctl(struct hda_codec *codec, hda_nid_t nid,
|
||||
const struct auto_pin_cfg *cfg,
|
||||
char *lastname, int *lastidx)
|
||||
const struct auto_pin_cfg *cfg)
|
||||
{
|
||||
unsigned int def_conf, conn;
|
||||
char name[44];
|
||||
int idx, err;
|
||||
bool phantom_jack;
|
||||
|
||||
if (!nid)
|
||||
return 0;
|
||||
if (!is_jack_detectable(codec, nid))
|
||||
return 0;
|
||||
def_conf = snd_hda_codec_get_pincfg(codec, nid);
|
||||
conn = get_defcfg_connect(def_conf);
|
||||
if (conn != AC_JACK_PORT_COMPLEX)
|
||||
if (conn == AC_JACK_PORT_NONE)
|
||||
return 0;
|
||||
phantom_jack = (conn != AC_JACK_PORT_COMPLEX) ||
|
||||
!is_jack_detectable(codec, nid);
|
||||
|
||||
snd_hda_get_pin_label(codec, nid, cfg, name, sizeof(name), &idx);
|
||||
if (!strcmp(name, lastname) && idx == *lastidx)
|
||||
idx++;
|
||||
strncpy(lastname, name, 44);
|
||||
*lastidx = idx;
|
||||
err = snd_hda_jack_add_kctl(codec, nid, name, idx);
|
||||
if (phantom_jack)
|
||||
/* Example final name: "Internal Mic Phantom Jack" */
|
||||
strncat(name, " Phantom", sizeof(name) - strlen(name) - 1);
|
||||
idx = get_unique_index(codec, name, idx);
|
||||
err = __snd_hda_jack_add_kctl(codec, nid, name, idx, phantom_jack);
|
||||
if (err < 0)
|
||||
return err;
|
||||
return snd_hda_jack_detect_enable(codec, nid, 0);
|
||||
|
||||
if (!phantom_jack)
|
||||
return snd_hda_jack_detect_enable(codec, nid, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -333,42 +372,41 @@ int snd_hda_jack_add_kctls(struct hda_codec *codec,
|
||||
const struct auto_pin_cfg *cfg)
|
||||
{
|
||||
const hda_nid_t *p;
|
||||
int i, err, lastidx = 0;
|
||||
char lastname[44] = "";
|
||||
int i, err;
|
||||
|
||||
for (i = 0, p = cfg->line_out_pins; i < cfg->line_outs; i++, p++) {
|
||||
err = add_jack_kctl(codec, *p, cfg, lastname, &lastidx);
|
||||
err = add_jack_kctl(codec, *p, cfg);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
for (i = 0, p = cfg->hp_pins; i < cfg->hp_outs; i++, p++) {
|
||||
if (*p == *cfg->line_out_pins) /* might be duplicated */
|
||||
break;
|
||||
err = add_jack_kctl(codec, *p, cfg, lastname, &lastidx);
|
||||
err = add_jack_kctl(codec, *p, cfg);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
for (i = 0, p = cfg->speaker_pins; i < cfg->speaker_outs; i++, p++) {
|
||||
if (*p == *cfg->line_out_pins) /* might be duplicated */
|
||||
break;
|
||||
err = add_jack_kctl(codec, *p, cfg, lastname, &lastidx);
|
||||
err = add_jack_kctl(codec, *p, cfg);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
for (i = 0; i < cfg->num_inputs; i++) {
|
||||
err = add_jack_kctl(codec, cfg->inputs[i].pin, cfg, lastname, &lastidx);
|
||||
err = add_jack_kctl(codec, cfg->inputs[i].pin, cfg);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
for (i = 0, p = cfg->dig_out_pins; i < cfg->dig_outs; i++, p++) {
|
||||
err = add_jack_kctl(codec, *p, cfg, lastname, &lastidx);
|
||||
err = add_jack_kctl(codec, *p, cfg);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
err = add_jack_kctl(codec, cfg->dig_in_pin, cfg, lastname, &lastidx);
|
||||
err = add_jack_kctl(codec, cfg->dig_in_pin, cfg);
|
||||
if (err < 0)
|
||||
return err;
|
||||
err = add_jack_kctl(codec, cfg->mono_out_pin, cfg, lastname, &lastidx);
|
||||
err = add_jack_kctl(codec, cfg->mono_out_pin, cfg);
|
||||
if (err < 0)
|
||||
return err;
|
||||
return 0;
|
||||
|
@ -23,6 +23,7 @@ struct hda_jack_tbl {
|
||||
unsigned int pin_sense; /* cached pin-sense value */
|
||||
unsigned int jack_detect:1; /* capable of jack-detection? */
|
||||
unsigned int jack_dirty:1; /* needs to update? */
|
||||
unsigned int phantom_jack:1; /* a fixed, always present port? */
|
||||
struct snd_kcontrol *kctl; /* assigned kctl for jack-detection */
|
||||
#ifdef CONFIG_SND_HDA_INPUT_JACK
|
||||
int type;
|
||||
|
@ -89,7 +89,7 @@
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \
|
||||
.subdevice = HDA_SUBDEV_AMP_FLAG, \
|
||||
.info = snd_hda_mixer_amp_switch_info, \
|
||||
.get = snd_hda_mixer_amp_switch_get, \
|
||||
.get = snd_hda_mixer_amp_switch_get_beep, \
|
||||
.put = snd_hda_mixer_amp_switch_put_beep, \
|
||||
.private_value = HDA_COMPOSE_AMP_VAL(nid, channel, xindex, direction) }
|
||||
#else
|
||||
@ -121,6 +121,8 @@ int snd_hda_mixer_amp_switch_get(struct snd_kcontrol *kcontrol,
|
||||
int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
#ifdef CONFIG_SND_HDA_INPUT_BEEP
|
||||
int snd_hda_mixer_amp_switch_get_beep(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
int snd_hda_mixer_amp_switch_put_beep(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
#endif
|
||||
|
@ -426,10 +426,10 @@ static void print_digital_conv(struct snd_info_buffer *buffer,
|
||||
|
||||
static const char *get_pwr_state(u32 state)
|
||||
{
|
||||
static const char * const buf[4] = {
|
||||
"D0", "D1", "D2", "D3"
|
||||
static const char * const buf[] = {
|
||||
"D0", "D1", "D2", "D3", "D3cold"
|
||||
};
|
||||
if (state < 4)
|
||||
if (state < ARRAY_SIZE(buf))
|
||||
return buf[state];
|
||||
return "UNKNOWN";
|
||||
}
|
||||
@ -451,14 +451,21 @@ static void print_power_state(struct snd_info_buffer *buffer,
|
||||
int sup = snd_hda_param_read(codec, nid, AC_PAR_POWER_STATE);
|
||||
int pwr = snd_hda_codec_read(codec, nid, 0,
|
||||
AC_VERB_GET_POWER_STATE, 0);
|
||||
if (sup)
|
||||
if (sup != -1)
|
||||
snd_iprintf(buffer, " Power states: %s\n",
|
||||
bits_names(sup, names, ARRAY_SIZE(names)));
|
||||
|
||||
snd_iprintf(buffer, " Power: setting=%s, actual=%s\n",
|
||||
snd_iprintf(buffer, " Power: setting=%s, actual=%s",
|
||||
get_pwr_state(pwr & AC_PWRST_SETTING),
|
||||
get_pwr_state((pwr & AC_PWRST_ACTUAL) >>
|
||||
AC_PWRST_ACTUAL_SHIFT));
|
||||
if (pwr & AC_PWRST_ERROR)
|
||||
snd_iprintf(buffer, ", Error");
|
||||
if (pwr & AC_PWRST_CLK_STOP_OK)
|
||||
snd_iprintf(buffer, ", Clock-stop-OK");
|
||||
if (pwr & AC_PWRST_SETTING_RESET)
|
||||
snd_iprintf(buffer, ", Setting-reset");
|
||||
snd_iprintf(buffer, "\n");
|
||||
}
|
||||
|
||||
static void print_unsol_cap(struct snd_info_buffer *buffer,
|
||||
|
@ -642,7 +642,7 @@ static void ad198x_free(struct hda_codec *codec)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int ad198x_suspend(struct hda_codec *codec, pm_message_t state)
|
||||
static int ad198x_suspend(struct hda_codec *codec)
|
||||
{
|
||||
ad198x_shutup(codec);
|
||||
return 0;
|
||||
|
@ -1892,7 +1892,7 @@ static int cs421x_parse_auto_config(struct hda_codec *codec)
|
||||
Manage PDREF, when transitioning to D3hot
|
||||
(DAC,ADC) -> D3, PDREF=1, AFG->D3
|
||||
*/
|
||||
static int cs421x_suspend(struct hda_codec *codec, pm_message_t state)
|
||||
static int cs421x_suspend(struct hda_codec *codec)
|
||||
{
|
||||
struct cs_spec *spec = codec->spec;
|
||||
unsigned int coef;
|
||||
|
@ -554,7 +554,7 @@ static int conexant_build_controls(struct hda_codec *codec)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SND_HDA_POWER_SAVE
|
||||
static int conexant_suspend(struct hda_codec *codec, pm_message_t state)
|
||||
static int conexant_suspend(struct hda_codec *codec)
|
||||
{
|
||||
snd_hda_shutup_pins(codec);
|
||||
return 0;
|
||||
|
@ -85,7 +85,7 @@ struct hdmi_spec {
|
||||
* Non-generic ATI/NVIDIA specific
|
||||
*/
|
||||
struct hda_multi_out multiout;
|
||||
const struct hda_pcm_stream *pcm_playback;
|
||||
struct hda_pcm_stream pcm_playback;
|
||||
};
|
||||
|
||||
|
||||
@ -787,7 +787,7 @@ static void hdmi_non_intrinsic_event(struct hda_codec *codec, unsigned int res)
|
||||
int cp_ready = !!(res & AC_UNSOL_RES_CP_READY);
|
||||
|
||||
printk(KERN_INFO
|
||||
"HDMI CP event: CODEC=%d PIN=%d SUBTAG=0x%x CP_STATE=%d CP_READY=%d\n",
|
||||
"HDMI CP event: CODEC=%d TAG=%d SUBTAG=0x%x CP_STATE=%d CP_READY=%d\n",
|
||||
codec->addr,
|
||||
tag,
|
||||
subtag,
|
||||
@ -876,7 +876,6 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo,
|
||||
struct hdmi_spec_per_pin *per_pin;
|
||||
struct hdmi_eld *eld;
|
||||
struct hdmi_spec_per_cvt *per_cvt = NULL;
|
||||
int pinctl;
|
||||
|
||||
/* Validate hinfo */
|
||||
pin_idx = hinfo_to_pin_index(spec, hinfo);
|
||||
@ -912,11 +911,6 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo,
|
||||
snd_hda_codec_write(codec, per_pin->pin_nid, 0,
|
||||
AC_VERB_SET_CONNECT_SEL,
|
||||
mux_idx);
|
||||
pinctl = snd_hda_codec_read(codec, per_pin->pin_nid, 0,
|
||||
AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
|
||||
snd_hda_codec_write(codec, per_pin->pin_nid, 0,
|
||||
AC_VERB_SET_PIN_WIDGET_CONTROL,
|
||||
pinctl | PIN_OUT);
|
||||
snd_hda_spdif_ctls_assign(codec, pin_idx, per_cvt->cvt_nid);
|
||||
|
||||
/* Initially set the converter's capabilities */
|
||||
@ -1153,11 +1147,17 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
|
||||
struct hdmi_spec *spec = codec->spec;
|
||||
int pin_idx = hinfo_to_pin_index(spec, hinfo);
|
||||
hda_nid_t pin_nid = spec->pins[pin_idx].pin_nid;
|
||||
int pinctl;
|
||||
|
||||
hdmi_set_channel_count(codec, cvt_nid, substream->runtime->channels);
|
||||
|
||||
hdmi_setup_audio_infoframe(codec, pin_idx, substream);
|
||||
|
||||
pinctl = snd_hda_codec_read(codec, pin_nid, 0,
|
||||
AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
|
||||
snd_hda_codec_write(codec, pin_nid, 0,
|
||||
AC_VERB_SET_PIN_WIDGET_CONTROL, pinctl | PIN_OUT);
|
||||
|
||||
return hdmi_setup_stream(codec, cvt_nid, pin_nid, stream_tag, format);
|
||||
}
|
||||
|
||||
@ -1277,6 +1277,22 @@ static int generic_hdmi_build_controls(struct hda_codec *codec)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int generic_hdmi_init_per_pins(struct hda_codec *codec)
|
||||
{
|
||||
struct hdmi_spec *spec = codec->spec;
|
||||
int pin_idx;
|
||||
|
||||
for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
|
||||
struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx];
|
||||
struct hdmi_eld *eld = &per_pin->sink_eld;
|
||||
|
||||
per_pin->codec = codec;
|
||||
INIT_DELAYED_WORK(&per_pin->work, hdmi_repoll_eld);
|
||||
snd_hda_eld_proc_new(codec, eld, pin_idx);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int generic_hdmi_init(struct hda_codec *codec)
|
||||
{
|
||||
struct hdmi_spec *spec = codec->spec;
|
||||
@ -1285,14 +1301,9 @@ static int generic_hdmi_init(struct hda_codec *codec)
|
||||
for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
|
||||
struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx];
|
||||
hda_nid_t pin_nid = per_pin->pin_nid;
|
||||
struct hdmi_eld *eld = &per_pin->sink_eld;
|
||||
|
||||
hdmi_init_pin(codec, pin_nid);
|
||||
snd_hda_jack_detect_enable(codec, pin_nid, pin_nid);
|
||||
|
||||
per_pin->codec = codec;
|
||||
INIT_DELAYED_WORK(&per_pin->work, hdmi_repoll_eld);
|
||||
snd_hda_eld_proc_new(codec, eld, pin_idx);
|
||||
}
|
||||
snd_hda_jack_report_sync(codec);
|
||||
return 0;
|
||||
@ -1338,6 +1349,7 @@ static int patch_generic_hdmi(struct hda_codec *codec)
|
||||
return -EINVAL;
|
||||
}
|
||||
codec->patch_ops = generic_hdmi_patch_ops;
|
||||
generic_hdmi_init_per_pins(codec);
|
||||
|
||||
init_channel_allocations();
|
||||
|
||||
@ -1352,45 +1364,65 @@ static int simple_playback_build_pcms(struct hda_codec *codec)
|
||||
{
|
||||
struct hdmi_spec *spec = codec->spec;
|
||||
struct hda_pcm *info = spec->pcm_rec;
|
||||
int i;
|
||||
unsigned int chans;
|
||||
struct hda_pcm_stream *pstr;
|
||||
|
||||
codec->num_pcms = spec->num_cvts;
|
||||
codec->num_pcms = 1;
|
||||
codec->pcm_info = info;
|
||||
|
||||
for (i = 0; i < codec->num_pcms; i++, info++) {
|
||||
unsigned int chans;
|
||||
struct hda_pcm_stream *pstr;
|
||||
chans = get_wcaps(codec, spec->cvts[0].cvt_nid);
|
||||
chans = get_wcaps_channels(chans);
|
||||
|
||||
chans = get_wcaps(codec, spec->cvts[i].cvt_nid);
|
||||
chans = get_wcaps_channels(chans);
|
||||
|
||||
info->name = get_hdmi_pcm_name(i);
|
||||
info->pcm_type = HDA_PCM_TYPE_HDMI;
|
||||
pstr = &info->stream[SNDRV_PCM_STREAM_PLAYBACK];
|
||||
snd_BUG_ON(!spec->pcm_playback);
|
||||
*pstr = *spec->pcm_playback;
|
||||
pstr->nid = spec->cvts[i].cvt_nid;
|
||||
if (pstr->channels_max <= 2 && chans && chans <= 16)
|
||||
pstr->channels_max = chans;
|
||||
}
|
||||
info->name = get_hdmi_pcm_name(0);
|
||||
info->pcm_type = HDA_PCM_TYPE_HDMI;
|
||||
pstr = &info->stream[SNDRV_PCM_STREAM_PLAYBACK];
|
||||
*pstr = spec->pcm_playback;
|
||||
pstr->nid = spec->cvts[0].cvt_nid;
|
||||
if (pstr->channels_max <= 2 && chans && chans <= 16)
|
||||
pstr->channels_max = chans;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* unsolicited event for jack sensing */
|
||||
static void simple_hdmi_unsol_event(struct hda_codec *codec,
|
||||
unsigned int res)
|
||||
{
|
||||
snd_hda_jack_set_dirty_all(codec);
|
||||
snd_hda_jack_report_sync(codec);
|
||||
}
|
||||
|
||||
/* generic_hdmi_build_jack can be used for simple_hdmi, too,
|
||||
* as long as spec->pins[] is set correctly
|
||||
*/
|
||||
#define simple_hdmi_build_jack generic_hdmi_build_jack
|
||||
|
||||
static int simple_playback_build_controls(struct hda_codec *codec)
|
||||
{
|
||||
struct hdmi_spec *spec = codec->spec;
|
||||
int err;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < codec->num_pcms; i++) {
|
||||
err = snd_hda_create_spdif_out_ctls(codec,
|
||||
spec->cvts[i].cvt_nid,
|
||||
spec->cvts[i].cvt_nid);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
err = snd_hda_create_spdif_out_ctls(codec,
|
||||
spec->cvts[0].cvt_nid,
|
||||
spec->cvts[0].cvt_nid);
|
||||
if (err < 0)
|
||||
return err;
|
||||
return simple_hdmi_build_jack(codec, 0);
|
||||
}
|
||||
|
||||
static int simple_playback_init(struct hda_codec *codec)
|
||||
{
|
||||
struct hdmi_spec *spec = codec->spec;
|
||||
hda_nid_t pin = spec->pins[0].pin_nid;
|
||||
|
||||
snd_hda_codec_write(codec, pin, 0,
|
||||
AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
|
||||
/* some codecs require to unmute the pin */
|
||||
if (get_wcaps(codec, pin) & AC_WCAP_OUT_AMP)
|
||||
snd_hda_codec_write(codec, pin, 0, AC_VERB_SET_AMP_GAIN_MUTE,
|
||||
AMP_OUT_UNMUTE);
|
||||
snd_hda_jack_detect_enable(codec, pin, pin);
|
||||
snd_hda_jack_report_sync(codec);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1418,7 +1450,15 @@ static const hda_nid_t nvhdmi_con_nids_7x[4] = {
|
||||
0x6, 0x8, 0xa, 0xc,
|
||||
};
|
||||
|
||||
static const struct hda_verb nvhdmi_basic_init_7x[] = {
|
||||
static const struct hda_verb nvhdmi_basic_init_7x_2ch[] = {
|
||||
/* set audio protect on */
|
||||
{ 0x1, Nv_VERB_SET_Audio_Protection_On, 0x1},
|
||||
/* enable digital output on pin widget */
|
||||
{ 0x5, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x5 },
|
||||
{} /* terminator */
|
||||
};
|
||||
|
||||
static const struct hda_verb nvhdmi_basic_init_7x_8ch[] = {
|
||||
/* set audio protect on */
|
||||
{ 0x1, Nv_VERB_SET_Audio_Protection_On, 0x1},
|
||||
/* enable digital output on pin widget */
|
||||
@ -1446,9 +1486,15 @@ static const struct hda_verb nvhdmi_basic_init_7x[] = {
|
||||
(SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE)
|
||||
#endif
|
||||
|
||||
static int nvhdmi_7x_init(struct hda_codec *codec)
|
||||
static int nvhdmi_7x_init_2ch(struct hda_codec *codec)
|
||||
{
|
||||
snd_hda_sequence_write(codec, nvhdmi_basic_init_7x);
|
||||
snd_hda_sequence_write(codec, nvhdmi_basic_init_7x_2ch);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nvhdmi_7x_init_8ch(struct hda_codec *codec)
|
||||
{
|
||||
snd_hda_sequence_write(codec, nvhdmi_basic_init_7x_8ch);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1524,6 +1570,50 @@ static int simple_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
|
||||
stream_tag, format, substream);
|
||||
}
|
||||
|
||||
static const struct hda_pcm_stream simple_pcm_playback = {
|
||||
.substreams = 1,
|
||||
.channels_min = 2,
|
||||
.channels_max = 2,
|
||||
.ops = {
|
||||
.open = simple_playback_pcm_open,
|
||||
.close = simple_playback_pcm_close,
|
||||
.prepare = simple_playback_pcm_prepare
|
||||
},
|
||||
};
|
||||
|
||||
static const struct hda_codec_ops simple_hdmi_patch_ops = {
|
||||
.build_controls = simple_playback_build_controls,
|
||||
.build_pcms = simple_playback_build_pcms,
|
||||
.init = simple_playback_init,
|
||||
.free = simple_playback_free,
|
||||
.unsol_event = simple_hdmi_unsol_event,
|
||||
};
|
||||
|
||||
static int patch_simple_hdmi(struct hda_codec *codec,
|
||||
hda_nid_t cvt_nid, hda_nid_t pin_nid)
|
||||
{
|
||||
struct hdmi_spec *spec;
|
||||
|
||||
spec = kzalloc(sizeof(*spec), GFP_KERNEL);
|
||||
if (!spec)
|
||||
return -ENOMEM;
|
||||
|
||||
codec->spec = spec;
|
||||
|
||||
spec->multiout.num_dacs = 0; /* no analog */
|
||||
spec->multiout.max_channels = 2;
|
||||
spec->multiout.dig_out_nid = cvt_nid;
|
||||
spec->num_cvts = 1;
|
||||
spec->num_pins = 1;
|
||||
spec->cvts[0].cvt_nid = cvt_nid;
|
||||
spec->pins[0].pin_nid = pin_nid;
|
||||
spec->pcm_playback = simple_pcm_playback;
|
||||
|
||||
codec->patch_ops = simple_hdmi_patch_ops;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void nvhdmi_8ch_7x_set_info_frame_parameters(struct hda_codec *codec,
|
||||
int channels)
|
||||
{
|
||||
@ -1696,54 +1786,20 @@ static const struct hda_pcm_stream nvhdmi_pcm_playback_8ch_7x = {
|
||||
},
|
||||
};
|
||||
|
||||
static const struct hda_pcm_stream nvhdmi_pcm_playback_2ch = {
|
||||
.substreams = 1,
|
||||
.channels_min = 2,
|
||||
.channels_max = 2,
|
||||
.nid = nvhdmi_master_con_nid_7x,
|
||||
.rates = SUPPORTED_RATES,
|
||||
.maxbps = SUPPORTED_MAXBPS,
|
||||
.formats = SUPPORTED_FORMATS,
|
||||
.ops = {
|
||||
.open = simple_playback_pcm_open,
|
||||
.close = simple_playback_pcm_close,
|
||||
.prepare = simple_playback_pcm_prepare
|
||||
},
|
||||
};
|
||||
|
||||
static const struct hda_codec_ops nvhdmi_patch_ops_8ch_7x = {
|
||||
.build_controls = simple_playback_build_controls,
|
||||
.build_pcms = simple_playback_build_pcms,
|
||||
.init = nvhdmi_7x_init,
|
||||
.free = simple_playback_free,
|
||||
};
|
||||
|
||||
static const struct hda_codec_ops nvhdmi_patch_ops_2ch = {
|
||||
.build_controls = simple_playback_build_controls,
|
||||
.build_pcms = simple_playback_build_pcms,
|
||||
.init = nvhdmi_7x_init,
|
||||
.free = simple_playback_free,
|
||||
};
|
||||
|
||||
static int patch_nvhdmi_2ch(struct hda_codec *codec)
|
||||
{
|
||||
struct hdmi_spec *spec;
|
||||
int err = patch_simple_hdmi(codec, nvhdmi_master_con_nid_7x,
|
||||
nvhdmi_master_pin_nid_7x);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
spec = kzalloc(sizeof(*spec), GFP_KERNEL);
|
||||
if (spec == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
codec->spec = spec;
|
||||
|
||||
spec->multiout.num_dacs = 0; /* no analog */
|
||||
spec->multiout.max_channels = 2;
|
||||
spec->multiout.dig_out_nid = nvhdmi_master_con_nid_7x;
|
||||
spec->num_cvts = 1;
|
||||
spec->cvts[0].cvt_nid = nvhdmi_master_con_nid_7x;
|
||||
spec->pcm_playback = &nvhdmi_pcm_playback_2ch;
|
||||
|
||||
codec->patch_ops = nvhdmi_patch_ops_2ch;
|
||||
|
||||
codec->patch_ops.init = nvhdmi_7x_init_2ch;
|
||||
/* override the PCM rates, etc, as the codec doesn't give full list */
|
||||
spec = codec->spec;
|
||||
spec->pcm_playback.rates = SUPPORTED_RATES;
|
||||
spec->pcm_playback.maxbps = SUPPORTED_MAXBPS;
|
||||
spec->pcm_playback.formats = SUPPORTED_FORMATS;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1751,13 +1807,12 @@ static int patch_nvhdmi_8ch_7x(struct hda_codec *codec)
|
||||
{
|
||||
struct hdmi_spec *spec;
|
||||
int err = patch_nvhdmi_2ch(codec);
|
||||
|
||||
if (err < 0)
|
||||
return err;
|
||||
spec = codec->spec;
|
||||
spec->multiout.max_channels = 8;
|
||||
spec->pcm_playback = &nvhdmi_pcm_playback_8ch_7x;
|
||||
codec->patch_ops = nvhdmi_patch_ops_8ch_7x;
|
||||
spec->pcm_playback = nvhdmi_pcm_playback_8ch_7x;
|
||||
codec->patch_ops.init = nvhdmi_7x_init_8ch;
|
||||
|
||||
/* Initialize the audio infoframe channel mask and checksum to something
|
||||
* valid */
|
||||
@ -1801,68 +1856,25 @@ static int atihdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct hda_pcm_stream atihdmi_pcm_digital_playback = {
|
||||
.substreams = 1,
|
||||
.channels_min = 2,
|
||||
.channels_max = 2,
|
||||
.nid = ATIHDMI_CVT_NID,
|
||||
.ops = {
|
||||
.open = simple_playback_pcm_open,
|
||||
.close = simple_playback_pcm_close,
|
||||
.prepare = atihdmi_playback_pcm_prepare
|
||||
},
|
||||
};
|
||||
|
||||
static const struct hda_verb atihdmi_basic_init[] = {
|
||||
/* enable digital output on pin widget */
|
||||
{ 0x03, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
|
||||
{} /* terminator */
|
||||
};
|
||||
|
||||
static int atihdmi_init(struct hda_codec *codec)
|
||||
{
|
||||
struct hdmi_spec *spec = codec->spec;
|
||||
|
||||
snd_hda_sequence_write(codec, atihdmi_basic_init);
|
||||
/* SI codec requires to unmute the pin */
|
||||
if (get_wcaps(codec, spec->pins[0].pin_nid) & AC_WCAP_OUT_AMP)
|
||||
snd_hda_codec_write(codec, spec->pins[0].pin_nid, 0,
|
||||
AC_VERB_SET_AMP_GAIN_MUTE,
|
||||
AMP_OUT_UNMUTE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct hda_codec_ops atihdmi_patch_ops = {
|
||||
.build_controls = simple_playback_build_controls,
|
||||
.build_pcms = simple_playback_build_pcms,
|
||||
.init = atihdmi_init,
|
||||
.free = simple_playback_free,
|
||||
};
|
||||
|
||||
|
||||
static int patch_atihdmi(struct hda_codec *codec)
|
||||
{
|
||||
struct hdmi_spec *spec;
|
||||
|
||||
spec = kzalloc(sizeof(*spec), GFP_KERNEL);
|
||||
if (spec == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
codec->spec = spec;
|
||||
|
||||
spec->multiout.num_dacs = 0; /* no analog */
|
||||
spec->multiout.max_channels = 2;
|
||||
spec->multiout.dig_out_nid = ATIHDMI_CVT_NID;
|
||||
spec->num_cvts = 1;
|
||||
spec->cvts[0].cvt_nid = ATIHDMI_CVT_NID;
|
||||
spec->pins[0].pin_nid = ATIHDMI_PIN_NID;
|
||||
spec->pcm_playback = &atihdmi_pcm_digital_playback;
|
||||
|
||||
codec->patch_ops = atihdmi_patch_ops;
|
||||
|
||||
int err = patch_simple_hdmi(codec, ATIHDMI_CVT_NID, ATIHDMI_PIN_NID);
|
||||
if (err < 0)
|
||||
return err;
|
||||
spec = codec->spec;
|
||||
spec->pcm_playback.ops.prepare = atihdmi_playback_pcm_prepare;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* VIA HDMI Implementation */
|
||||
#define VIAHDMI_CVT_NID 0x02 /* audio converter1 */
|
||||
#define VIAHDMI_PIN_NID 0x03 /* HDMI output pin1 */
|
||||
|
||||
static int patch_via_hdmi(struct hda_codec *codec)
|
||||
{
|
||||
return patch_simple_hdmi(codec, VIAHDMI_CVT_NID, VIAHDMI_PIN_NID);
|
||||
}
|
||||
|
||||
/*
|
||||
* patch entries
|
||||
@ -1902,8 +1914,13 @@ static const struct hda_codec_preset snd_hda_preset_hdmi[] = {
|
||||
{ .id = 0x10de0042, .name = "GPU 42 HDMI/DP", .patch = patch_generic_hdmi },
|
||||
{ .id = 0x10de0043, .name = "GPU 43 HDMI/DP", .patch = patch_generic_hdmi },
|
||||
{ .id = 0x10de0044, .name = "GPU 44 HDMI/DP", .patch = patch_generic_hdmi },
|
||||
{ .id = 0x10de0051, .name = "GPU 51 HDMI/DP", .patch = patch_generic_hdmi },
|
||||
{ .id = 0x10de0067, .name = "MCP67 HDMI", .patch = patch_nvhdmi_2ch },
|
||||
{ .id = 0x10de8001, .name = "MCP73 HDMI", .patch = patch_nvhdmi_2ch },
|
||||
{ .id = 0x11069f80, .name = "VX900 HDMI/DP", .patch = patch_via_hdmi },
|
||||
{ .id = 0x11069f81, .name = "VX900 HDMI/DP", .patch = patch_via_hdmi },
|
||||
{ .id = 0x11069f84, .name = "VX11 HDMI/DP", .patch = patch_generic_hdmi },
|
||||
{ .id = 0x11069f85, .name = "VX11 HDMI/DP", .patch = patch_generic_hdmi },
|
||||
{ .id = 0x80860054, .name = "IbexPeak HDMI", .patch = patch_generic_hdmi },
|
||||
{ .id = 0x80862801, .name = "Bearlake HDMI", .patch = patch_generic_hdmi },
|
||||
{ .id = 0x80862802, .name = "Cantiga HDMI", .patch = patch_generic_hdmi },
|
||||
@ -1911,6 +1928,7 @@ static const struct hda_codec_preset snd_hda_preset_hdmi[] = {
|
||||
{ .id = 0x80862804, .name = "IbexPeak HDMI", .patch = patch_generic_hdmi },
|
||||
{ .id = 0x80862805, .name = "CougarPoint HDMI", .patch = patch_generic_hdmi },
|
||||
{ .id = 0x80862806, .name = "PantherPoint HDMI", .patch = patch_generic_hdmi },
|
||||
{ .id = 0x80862807, .name = "Haswell HDMI", .patch = patch_generic_hdmi },
|
||||
{ .id = 0x80862880, .name = "CedarTrail HDMI", .patch = patch_generic_hdmi },
|
||||
{ .id = 0x808629fb, .name = "Crestline HDMI", .patch = patch_generic_hdmi },
|
||||
{} /* terminator */
|
||||
@ -1948,8 +1966,13 @@ MODULE_ALIAS("snd-hda-codec-id:10de0041");
|
||||
MODULE_ALIAS("snd-hda-codec-id:10de0042");
|
||||
MODULE_ALIAS("snd-hda-codec-id:10de0043");
|
||||
MODULE_ALIAS("snd-hda-codec-id:10de0044");
|
||||
MODULE_ALIAS("snd-hda-codec-id:10de0051");
|
||||
MODULE_ALIAS("snd-hda-codec-id:10de0067");
|
||||
MODULE_ALIAS("snd-hda-codec-id:10de8001");
|
||||
MODULE_ALIAS("snd-hda-codec-id:11069f80");
|
||||
MODULE_ALIAS("snd-hda-codec-id:11069f81");
|
||||
MODULE_ALIAS("snd-hda-codec-id:11069f84");
|
||||
MODULE_ALIAS("snd-hda-codec-id:11069f85");
|
||||
MODULE_ALIAS("snd-hda-codec-id:17e80047");
|
||||
MODULE_ALIAS("snd-hda-codec-id:80860054");
|
||||
MODULE_ALIAS("snd-hda-codec-id:80862801");
|
||||
@ -1958,6 +1981,7 @@ MODULE_ALIAS("snd-hda-codec-id:80862803");
|
||||
MODULE_ALIAS("snd-hda-codec-id:80862804");
|
||||
MODULE_ALIAS("snd-hda-codec-id:80862805");
|
||||
MODULE_ALIAS("snd-hda-codec-id:80862806");
|
||||
MODULE_ALIAS("snd-hda-codec-id:80862807");
|
||||
MODULE_ALIAS("snd-hda-codec-id:80862880");
|
||||
MODULE_ALIAS("snd-hda-codec-id:808629fb");
|
||||
|
||||
|
@ -170,10 +170,10 @@ struct alc_spec {
|
||||
hda_nid_t imux_pins[HDA_MAX_NUM_INPUTS];
|
||||
unsigned int dyn_adc_idx[HDA_MAX_NUM_INPUTS];
|
||||
int int_mic_idx, ext_mic_idx, dock_mic_idx; /* for auto-mic */
|
||||
hda_nid_t inv_dmic_pin;
|
||||
|
||||
/* hooks */
|
||||
void (*init_hook)(struct hda_codec *codec);
|
||||
void (*unsol_event)(struct hda_codec *codec, unsigned int res);
|
||||
#ifdef CONFIG_SND_HDA_POWER_SAVE
|
||||
void (*power_hook)(struct hda_codec *codec);
|
||||
#endif
|
||||
@ -201,6 +201,8 @@ struct alc_spec {
|
||||
unsigned int vol_in_capsrc:1; /* use capsrc volume (ADC has no vol) */
|
||||
unsigned int parse_flags; /* passed to snd_hda_parse_pin_defcfg() */
|
||||
unsigned int shared_mic_hp:1; /* HP/Mic-in sharing */
|
||||
unsigned int inv_dmic_fixup:1; /* has inverted digital-mic workaround */
|
||||
unsigned int inv_dmic_muted:1; /* R-ch of inv d-mic is muted? */
|
||||
|
||||
/* auto-mute control */
|
||||
int automute_mode;
|
||||
@ -298,6 +300,39 @@ static inline hda_nid_t get_capsrc(struct alc_spec *spec, int idx)
|
||||
}
|
||||
|
||||
static void call_update_outputs(struct hda_codec *codec);
|
||||
static void alc_inv_dmic_sync(struct hda_codec *codec, bool force);
|
||||
|
||||
/* for shared I/O, change the pin-control accordingly */
|
||||
static void update_shared_mic_hp(struct hda_codec *codec, bool set_as_mic)
|
||||
{
|
||||
struct alc_spec *spec = codec->spec;
|
||||
unsigned int val;
|
||||
hda_nid_t pin = spec->autocfg.inputs[1].pin;
|
||||
/* NOTE: this assumes that there are only two inputs, the
|
||||
* first is the real internal mic and the second is HP/mic jack.
|
||||
*/
|
||||
|
||||
val = snd_hda_get_default_vref(codec, pin);
|
||||
|
||||
/* This pin does not have vref caps - let's enable vref on pin 0x18
|
||||
instead, as suggested by Realtek */
|
||||
if (val == AC_PINCTL_VREF_HIZ) {
|
||||
const hda_nid_t vref_pin = 0x18;
|
||||
/* Sanity check pin 0x18 */
|
||||
if (get_wcaps_type(get_wcaps(codec, vref_pin)) == AC_WID_PIN &&
|
||||
get_defcfg_connect(snd_hda_codec_get_pincfg(codec, vref_pin)) == AC_JACK_PORT_NONE) {
|
||||
unsigned int vref_val = snd_hda_get_default_vref(codec, vref_pin);
|
||||
if (vref_val != AC_PINCTL_VREF_HIZ)
|
||||
snd_hda_set_pin_ctl(codec, vref_pin, PIN_IN | (set_as_mic ? vref_val : 0));
|
||||
}
|
||||
}
|
||||
|
||||
val = set_as_mic ? val | PIN_IN : PIN_HP;
|
||||
snd_hda_set_pin_ctl(codec, pin, val);
|
||||
|
||||
spec->automute_speaker = !set_as_mic;
|
||||
call_update_outputs(codec);
|
||||
}
|
||||
|
||||
/* select the given imux item; either unmute exclusively or select the route */
|
||||
static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx,
|
||||
@ -325,21 +360,8 @@ static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx,
|
||||
return 0;
|
||||
spec->cur_mux[adc_idx] = idx;
|
||||
|
||||
/* for shared I/O, change the pin-control accordingly */
|
||||
if (spec->shared_mic_hp) {
|
||||
unsigned int val;
|
||||
hda_nid_t pin = spec->autocfg.inputs[1].pin;
|
||||
/* NOTE: this assumes that there are only two inputs, the
|
||||
* first is the real internal mic and the second is HP jack.
|
||||
*/
|
||||
if (spec->cur_mux[adc_idx])
|
||||
val = snd_hda_get_default_vref(codec, pin) | PIN_IN;
|
||||
else
|
||||
val = PIN_HP;
|
||||
snd_hda_set_pin_ctl(codec, pin, val);
|
||||
spec->automute_speaker = !spec->cur_mux[adc_idx];
|
||||
call_update_outputs(codec);
|
||||
}
|
||||
if (spec->shared_mic_hp)
|
||||
update_shared_mic_hp(codec, spec->cur_mux[adc_idx]);
|
||||
|
||||
if (spec->dyn_adc_switch) {
|
||||
alc_dyn_adc_pcm_resetup(codec, idx);
|
||||
@ -368,6 +390,7 @@ static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx,
|
||||
AC_VERB_SET_CONNECT_SEL,
|
||||
imux->items[idx].index);
|
||||
}
|
||||
alc_inv_dmic_sync(codec, true);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -664,7 +687,7 @@ static void alc_update_knob_master(struct hda_codec *codec, hda_nid_t nid)
|
||||
}
|
||||
|
||||
/* unsolicited event for HP jack sensing */
|
||||
static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
|
||||
static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
|
||||
{
|
||||
int action;
|
||||
|
||||
@ -1000,11 +1023,9 @@ static void alc_init_automute(struct hda_codec *codec)
|
||||
spec->automute_lo = spec->automute_lo_possible;
|
||||
spec->automute_speaker = spec->automute_speaker_possible;
|
||||
|
||||
if (spec->automute_speaker_possible || spec->automute_lo_possible) {
|
||||
if (spec->automute_speaker_possible || spec->automute_lo_possible)
|
||||
/* create a control for automute mode */
|
||||
alc_add_automute_mode_enum(codec);
|
||||
spec->unsol_event = alc_sku_unsol_event;
|
||||
}
|
||||
}
|
||||
|
||||
/* return the position of NID in the list, or -1 if not found */
|
||||
@ -1167,7 +1188,6 @@ static void alc_init_auto_mic(struct hda_codec *codec)
|
||||
|
||||
snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x/0x%x\n",
|
||||
ext, fixed, dock);
|
||||
spec->unsol_event = alc_sku_unsol_event;
|
||||
}
|
||||
|
||||
/* check the availabilities of auto-mute and auto-mic switches */
|
||||
@ -1556,14 +1576,14 @@ typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
|
||||
|
||||
static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol,
|
||||
getput_call_t func, bool check_adc_switch)
|
||||
getput_call_t func, bool is_put)
|
||||
{
|
||||
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
|
||||
struct alc_spec *spec = codec->spec;
|
||||
int i, err = 0;
|
||||
|
||||
mutex_lock(&codec->control_mutex);
|
||||
if (check_adc_switch && spec->dyn_adc_switch) {
|
||||
if (is_put && spec->dyn_adc_switch) {
|
||||
for (i = 0; i < spec->num_adc_nids; i++) {
|
||||
kcontrol->private_value =
|
||||
HDA_COMPOSE_AMP_VAL(spec->adc_nids[i],
|
||||
@ -1584,6 +1604,8 @@ static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
|
||||
3, 0, HDA_INPUT);
|
||||
err = func(kcontrol, ucontrol);
|
||||
}
|
||||
if (err >= 0 && is_put)
|
||||
alc_inv_dmic_sync(codec, false);
|
||||
error:
|
||||
mutex_unlock(&codec->control_mutex);
|
||||
return err;
|
||||
@ -1675,6 +1697,116 @@ DEFINE_CAPMIX_NOSRC(1);
|
||||
DEFINE_CAPMIX_NOSRC(2);
|
||||
DEFINE_CAPMIX_NOSRC(3);
|
||||
|
||||
/*
|
||||
* Inverted digital-mic handling
|
||||
*
|
||||
* First off, it's a bit tricky. The "Inverted Internal Mic Capture Switch"
|
||||
* gives the additional mute only to the right channel of the digital mic
|
||||
* capture stream. This is a workaround for avoiding the almost silence
|
||||
* by summing the stereo stream from some (known to be ForteMedia)
|
||||
* digital mic unit.
|
||||
*
|
||||
* The logic is to call alc_inv_dmic_sync() after each action (possibly)
|
||||
* modifying ADC amp. When the mute flag is set, it mutes the R-channel
|
||||
* without caching so that the cache can still keep the original value.
|
||||
* The cached value is then restored when the flag is set off or any other
|
||||
* than d-mic is used as the current input source.
|
||||
*/
|
||||
static void alc_inv_dmic_sync(struct hda_codec *codec, bool force)
|
||||
{
|
||||
struct alc_spec *spec = codec->spec;
|
||||
int i;
|
||||
|
||||
if (!spec->inv_dmic_fixup)
|
||||
return;
|
||||
if (!spec->inv_dmic_muted && !force)
|
||||
return;
|
||||
for (i = 0; i < spec->num_adc_nids; i++) {
|
||||
int src = spec->dyn_adc_switch ? 0 : i;
|
||||
bool dmic_fixup = false;
|
||||
hda_nid_t nid;
|
||||
int parm, dir, v;
|
||||
|
||||
if (spec->inv_dmic_muted &&
|
||||
spec->imux_pins[spec->cur_mux[src]] == spec->inv_dmic_pin)
|
||||
dmic_fixup = true;
|
||||
if (!dmic_fixup && !force)
|
||||
continue;
|
||||
if (spec->vol_in_capsrc) {
|
||||
nid = spec->capsrc_nids[i];
|
||||
parm = AC_AMP_SET_RIGHT | AC_AMP_SET_OUTPUT;
|
||||
dir = HDA_OUTPUT;
|
||||
} else {
|
||||
nid = spec->adc_nids[i];
|
||||
parm = AC_AMP_SET_RIGHT | AC_AMP_SET_INPUT;
|
||||
dir = HDA_INPUT;
|
||||
}
|
||||
/* we care only right channel */
|
||||
v = snd_hda_codec_amp_read(codec, nid, 1, dir, 0);
|
||||
if (v & 0x80) /* if already muted, we don't need to touch */
|
||||
continue;
|
||||
if (dmic_fixup) /* add mute for d-mic */
|
||||
v |= 0x80;
|
||||
snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
|
||||
parm | v);
|
||||
}
|
||||
}
|
||||
|
||||
static int alc_inv_dmic_sw_get(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
|
||||
struct alc_spec *spec = codec->spec;
|
||||
|
||||
ucontrol->value.integer.value[0] = !spec->inv_dmic_muted;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int alc_inv_dmic_sw_put(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
|
||||
struct alc_spec *spec = codec->spec;
|
||||
unsigned int val = !ucontrol->value.integer.value[0];
|
||||
|
||||
if (val == spec->inv_dmic_muted)
|
||||
return 0;
|
||||
spec->inv_dmic_muted = val;
|
||||
alc_inv_dmic_sync(codec, true);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct snd_kcontrol_new alc_inv_dmic_sw = {
|
||||
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
|
||||
.info = snd_ctl_boolean_mono_info,
|
||||
.get = alc_inv_dmic_sw_get,
|
||||
.put = alc_inv_dmic_sw_put,
|
||||
};
|
||||
|
||||
static int alc_add_inv_dmic_mixer(struct hda_codec *codec, hda_nid_t nid)
|
||||
{
|
||||
struct alc_spec *spec = codec->spec;
|
||||
struct snd_kcontrol_new *knew = alc_kcontrol_new(spec);
|
||||
if (!knew)
|
||||
return -ENOMEM;
|
||||
*knew = alc_inv_dmic_sw;
|
||||
knew->name = kstrdup("Inverted Internal Mic Capture Switch", GFP_KERNEL);
|
||||
if (!knew->name)
|
||||
return -ENOMEM;
|
||||
spec->inv_dmic_fixup = 1;
|
||||
spec->inv_dmic_muted = 0;
|
||||
spec->inv_dmic_pin = nid;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* typically the digital mic is put at node 0x12 */
|
||||
static void alc_fixup_inv_dmic_0x12(struct hda_codec *codec,
|
||||
const struct alc_fixup *fix, int action)
|
||||
{
|
||||
if (action == ALC_FIXUP_ACT_PROBE)
|
||||
alc_add_inv_dmic_mixer(codec, 0x12);
|
||||
}
|
||||
|
||||
/*
|
||||
* virtual master controls
|
||||
*/
|
||||
@ -1865,13 +1997,31 @@ static int __alc_build_controls(struct hda_codec *codec)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int alc_build_controls(struct hda_codec *codec)
|
||||
static int alc_build_jacks(struct hda_codec *codec)
|
||||
{
|
||||
struct alc_spec *spec = codec->spec;
|
||||
|
||||
if (spec->shared_mic_hp) {
|
||||
int err;
|
||||
int nid = spec->autocfg.inputs[1].pin;
|
||||
err = snd_hda_jack_add_kctl(codec, nid, "Headphone Mic", 0);
|
||||
if (err < 0)
|
||||
return err;
|
||||
err = snd_hda_jack_detect_enable(codec, nid, 0);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
|
||||
return snd_hda_jack_add_kctls(codec, &spec->autocfg);
|
||||
}
|
||||
|
||||
static int alc_build_controls(struct hda_codec *codec)
|
||||
{
|
||||
int err = __alc_build_controls(codec);
|
||||
if (err < 0)
|
||||
return err;
|
||||
err = snd_hda_jack_add_kctls(codec, &spec->autocfg);
|
||||
|
||||
err = alc_build_jacks(codec);
|
||||
if (err < 0)
|
||||
return err;
|
||||
alc_apply_fixup(codec, ALC_FIXUP_ACT_BUILD);
|
||||
@ -1908,14 +2058,6 @@ static int alc_init(struct hda_codec *codec)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
|
||||
{
|
||||
struct alc_spec *spec = codec->spec;
|
||||
|
||||
if (spec->unsol_event)
|
||||
spec->unsol_event(codec, res);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SND_HDA_POWER_SAVE
|
||||
static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
|
||||
{
|
||||
@ -2300,7 +2442,7 @@ static void alc_power_eapd(struct hda_codec *codec)
|
||||
alc_auto_setup_eapd(codec, false);
|
||||
}
|
||||
|
||||
static int alc_suspend(struct hda_codec *codec, pm_message_t state)
|
||||
static int alc_suspend(struct hda_codec *codec)
|
||||
{
|
||||
struct alc_spec *spec = codec->spec;
|
||||
alc_shutup(codec);
|
||||
@ -2317,6 +2459,7 @@ static int alc_resume(struct hda_codec *codec)
|
||||
codec->patch_ops.init(codec);
|
||||
snd_hda_codec_resume_amp(codec);
|
||||
snd_hda_codec_resume_cache(codec);
|
||||
alc_inv_dmic_sync(codec, true);
|
||||
hda_call_check_power_status(codec, 0x01);
|
||||
return 0;
|
||||
}
|
||||
@ -4116,14 +4259,12 @@ static void set_capture_mixer(struct hda_codec *codec)
|
||||
*/
|
||||
static void alc_auto_init_std(struct hda_codec *codec)
|
||||
{
|
||||
struct alc_spec *spec = codec->spec;
|
||||
alc_auto_init_multi_out(codec);
|
||||
alc_auto_init_extra_out(codec);
|
||||
alc_auto_init_analog_input(codec);
|
||||
alc_auto_init_input_src(codec);
|
||||
alc_auto_init_digital(codec);
|
||||
if (spec->unsol_event)
|
||||
alc_inithook(codec);
|
||||
alc_inithook(codec);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -4724,7 +4865,6 @@ static void alc260_fixup_gpio1_toggle(struct hda_codec *codec,
|
||||
spec->automute_speaker = 1;
|
||||
spec->autocfg.hp_pins[0] = 0x0f; /* copy it for automute */
|
||||
snd_hda_jack_detect_enable(codec, 0x0f, ALC_HP_EVENT);
|
||||
spec->unsol_event = alc_sku_unsol_event;
|
||||
snd_hda_gen_add_verbs(&spec->gen, alc_gpio1_init_verbs);
|
||||
}
|
||||
}
|
||||
@ -4909,6 +5049,7 @@ enum {
|
||||
ALC889_FIXUP_DAC_ROUTE,
|
||||
ALC889_FIXUP_MBP_VREF,
|
||||
ALC889_FIXUP_IMAC91_VREF,
|
||||
ALC882_FIXUP_INV_DMIC,
|
||||
};
|
||||
|
||||
static void alc889_fixup_coef(struct hda_codec *codec,
|
||||
@ -5212,6 +5353,10 @@ static const struct alc_fixup alc882_fixups[] = {
|
||||
.chained = true,
|
||||
.chain_id = ALC882_FIXUP_GPIO1,
|
||||
},
|
||||
[ALC882_FIXUP_INV_DMIC] = {
|
||||
.type = ALC_FIXUP_FUNC,
|
||||
.v.func = alc_fixup_inv_dmic_0x12,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct snd_pci_quirk alc882_fixup_tbl[] = {
|
||||
@ -5286,6 +5431,7 @@ static const struct alc_model_fixup alc882_fixup_models[] = {
|
||||
{.id = ALC882_FIXUP_ACER_ASPIRE_4930G, .name = "acer-aspire-4930g"},
|
||||
{.id = ALC882_FIXUP_ACER_ASPIRE_8930G, .name = "acer-aspire-8930g"},
|
||||
{.id = ALC883_FIXUP_ACER_EAPD, .name = "acer-aspire"},
|
||||
{.id = ALC882_FIXUP_INV_DMIC, .name = "inv-dmic"},
|
||||
{}
|
||||
};
|
||||
|
||||
@ -5373,6 +5519,7 @@ enum {
|
||||
ALC262_FIXUP_LENOVO_3000,
|
||||
ALC262_FIXUP_BENQ,
|
||||
ALC262_FIXUP_BENQ_T31,
|
||||
ALC262_FIXUP_INV_DMIC,
|
||||
};
|
||||
|
||||
static const struct alc_fixup alc262_fixups[] = {
|
||||
@ -5424,6 +5571,10 @@ static const struct alc_fixup alc262_fixups[] = {
|
||||
{}
|
||||
}
|
||||
},
|
||||
[ALC262_FIXUP_INV_DMIC] = {
|
||||
.type = ALC_FIXUP_FUNC,
|
||||
.v.func = alc_fixup_inv_dmic_0x12,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct snd_pci_quirk alc262_fixup_tbl[] = {
|
||||
@ -5438,6 +5589,10 @@ static const struct snd_pci_quirk alc262_fixup_tbl[] = {
|
||||
{}
|
||||
};
|
||||
|
||||
static const struct alc_model_fixup alc262_fixup_models[] = {
|
||||
{.id = ALC262_FIXUP_INV_DMIC, .name = "inv-dmic"},
|
||||
{}
|
||||
};
|
||||
|
||||
/*
|
||||
*/
|
||||
@ -5466,7 +5621,8 @@ static int patch_alc262(struct hda_codec *codec)
|
||||
#endif
|
||||
alc_fix_pll_init(codec, 0x20, 0x0a, 10);
|
||||
|
||||
alc_pick_fixup(codec, NULL, alc262_fixup_tbl, alc262_fixups);
|
||||
alc_pick_fixup(codec, alc262_fixup_models, alc262_fixup_tbl,
|
||||
alc262_fixups);
|
||||
alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
|
||||
|
||||
alc_auto_parse_customize_define(codec);
|
||||
@ -5522,6 +5678,22 @@ static const struct hda_verb alc268_beep_init_verbs[] = {
|
||||
{ }
|
||||
};
|
||||
|
||||
enum {
|
||||
ALC268_FIXUP_INV_DMIC,
|
||||
};
|
||||
|
||||
static const struct alc_fixup alc268_fixups[] = {
|
||||
[ALC268_FIXUP_INV_DMIC] = {
|
||||
.type = ALC_FIXUP_FUNC,
|
||||
.v.func = alc_fixup_inv_dmic_0x12,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct alc_model_fixup alc268_fixup_models[] = {
|
||||
{.id = ALC268_FIXUP_INV_DMIC, .name = "inv-dmic"},
|
||||
{}
|
||||
};
|
||||
|
||||
/*
|
||||
* BIOS auto configuration
|
||||
*/
|
||||
@ -5553,6 +5725,9 @@ static int patch_alc268(struct hda_codec *codec)
|
||||
|
||||
spec = codec->spec;
|
||||
|
||||
alc_pick_fixup(codec, alc268_fixup_models, NULL, alc268_fixups);
|
||||
alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
|
||||
|
||||
/* automatic parse from the BIOS config */
|
||||
err = alc268_parse_auto_config(codec);
|
||||
if (err < 0)
|
||||
@ -5582,6 +5757,8 @@ static int patch_alc268(struct hda_codec *codec)
|
||||
codec->patch_ops = alc_patch_ops;
|
||||
spec->shutup = alc_eapd_shutup;
|
||||
|
||||
alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
@ -5704,6 +5881,15 @@ static int alc269_resume(struct hda_codec *codec)
|
||||
}
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
static void alc269_fixup_pincfg_no_hp_to_lineout(struct hda_codec *codec,
|
||||
const struct alc_fixup *fix, int action)
|
||||
{
|
||||
struct alc_spec *spec = codec->spec;
|
||||
|
||||
if (action == ALC_FIXUP_ACT_PRE_PROBE)
|
||||
spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
|
||||
}
|
||||
|
||||
static void alc269_fixup_hweq(struct hda_codec *codec,
|
||||
const struct alc_fixup *fix, int action)
|
||||
{
|
||||
@ -5810,6 +5996,7 @@ static void alc269_fixup_mic2_mute(struct hda_codec *codec,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
enum {
|
||||
ALC269_FIXUP_SONY_VAIO,
|
||||
ALC275_FIXUP_SONY_VAIO_GPIO2,
|
||||
@ -5828,6 +6015,9 @@ enum {
|
||||
ALC269VB_FIXUP_AMIC,
|
||||
ALC269VB_FIXUP_DMIC,
|
||||
ALC269_FIXUP_MIC2_MUTE_LED,
|
||||
ALC269_FIXUP_INV_DMIC,
|
||||
ALC269_FIXUP_LENOVO_DOCK,
|
||||
ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT,
|
||||
};
|
||||
|
||||
static const struct alc_fixup alc269_fixups[] = {
|
||||
@ -5952,12 +6142,33 @@ static const struct alc_fixup alc269_fixups[] = {
|
||||
.type = ALC_FIXUP_FUNC,
|
||||
.v.func = alc269_fixup_mic2_mute,
|
||||
},
|
||||
[ALC269_FIXUP_INV_DMIC] = {
|
||||
.type = ALC_FIXUP_FUNC,
|
||||
.v.func = alc_fixup_inv_dmic_0x12,
|
||||
},
|
||||
[ALC269_FIXUP_LENOVO_DOCK] = {
|
||||
.type = ALC_FIXUP_PINS,
|
||||
.v.pins = (const struct alc_pincfg[]) {
|
||||
{ 0x19, 0x23a11040 }, /* dock mic */
|
||||
{ 0x1b, 0x2121103f }, /* dock headphone */
|
||||
{ }
|
||||
},
|
||||
.chained = true,
|
||||
.chain_id = ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT
|
||||
},
|
||||
[ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT] = {
|
||||
.type = ALC_FIXUP_FUNC,
|
||||
.v.func = alc269_fixup_pincfg_no_hp_to_lineout,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct snd_pci_quirk alc269_fixup_tbl[] = {
|
||||
SND_PCI_QUIRK(0x1025, 0x029b, "Acer 1810TZ", ALC269_FIXUP_INV_DMIC),
|
||||
SND_PCI_QUIRK(0x1025, 0x0349, "Acer AOD260", ALC269_FIXUP_INV_DMIC),
|
||||
SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_MIC2_MUTE_LED),
|
||||
SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_DMIC),
|
||||
SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
|
||||
SND_PCI_QUIRK(0x1043, 0x1b13, "Asus U41SV", ALC269_FIXUP_INV_DMIC),
|
||||
SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC),
|
||||
SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC),
|
||||
SND_PCI_QUIRK(0x1043, 0x834a, "ASUS S101", ALC269_FIXUP_STEREO_DMIC),
|
||||
@ -5975,6 +6186,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
|
||||
SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
|
||||
SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE),
|
||||
SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE),
|
||||
SND_PCI_QUIRK(0x17aa, 0x2203, "Thinkpad X230 Tablet", ALC269_FIXUP_LENOVO_DOCK),
|
||||
SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_QUANTA_MUTE),
|
||||
SND_PCI_QUIRK(0x17aa, 0x3bf8, "Lenovo Ideapd", ALC269_FIXUP_PCM_44K),
|
||||
SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
|
||||
@ -6033,6 +6245,10 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
|
||||
static const struct alc_model_fixup alc269_fixup_models[] = {
|
||||
{.id = ALC269_FIXUP_AMIC, .name = "laptop-amic"},
|
||||
{.id = ALC269_FIXUP_DMIC, .name = "laptop-dmic"},
|
||||
{.id = ALC269_FIXUP_STEREO_DMIC, .name = "alc269-dmic"},
|
||||
{.id = ALC271_FIXUP_DMIC, .name = "alc271-dmic"},
|
||||
{.id = ALC269_FIXUP_INV_DMIC, .name = "inv-dmic"},
|
||||
{.id = ALC269_FIXUP_LENOVO_DOCK, .name = "lenovo-dock"},
|
||||
{}
|
||||
};
|
||||
|
||||
@ -6329,12 +6545,6 @@ static const struct snd_pci_quirk alc861vd_fixup_tbl[] = {
|
||||
{}
|
||||
};
|
||||
|
||||
static const struct hda_verb alc660vd_eapd_verbs[] = {
|
||||
{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
|
||||
{0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
|
||||
{ }
|
||||
};
|
||||
|
||||
/*
|
||||
*/
|
||||
static int patch_alc861vd(struct hda_codec *codec)
|
||||
@ -6356,11 +6566,6 @@ static int patch_alc861vd(struct hda_codec *codec)
|
||||
if (err < 0)
|
||||
goto error;
|
||||
|
||||
if (codec->vendor_id == 0x10ec0660) {
|
||||
/* always turn on EAPD */
|
||||
snd_hda_gen_add_verbs(&spec->gen, alc660vd_eapd_verbs);
|
||||
}
|
||||
|
||||
if (!spec->no_analog) {
|
||||
err = snd_hda_attach_beep_device(codec, 0x23);
|
||||
if (err < 0)
|
||||
@ -6443,6 +6648,7 @@ enum {
|
||||
ALC662_FIXUP_ASUS_MODE8,
|
||||
ALC662_FIXUP_NO_JACK_DETECT,
|
||||
ALC662_FIXUP_ZOTAC_Z68,
|
||||
ALC662_FIXUP_INV_DMIC,
|
||||
};
|
||||
|
||||
static const struct alc_fixup alc662_fixups[] = {
|
||||
@ -6599,12 +6805,17 @@ static const struct alc_fixup alc662_fixups[] = {
|
||||
{ }
|
||||
}
|
||||
},
|
||||
[ALC662_FIXUP_INV_DMIC] = {
|
||||
.type = ALC_FIXUP_FUNC,
|
||||
.v.func = alc_fixup_inv_dmic_0x12,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct snd_pci_quirk alc662_fixup_tbl[] = {
|
||||
SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_FIXUP_ASUS_MODE2),
|
||||
SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE),
|
||||
SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE),
|
||||
SND_PCI_QUIRK(0x1025, 0x0349, "eMachines eM250", ALC662_FIXUP_INV_DMIC),
|
||||
SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
|
||||
SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800),
|
||||
SND_PCI_QUIRK(0x1043, 0x8469, "ASUS mobo", ALC662_FIXUP_NO_JACK_DETECT),
|
||||
@ -6685,6 +6896,7 @@ static const struct alc_model_fixup alc662_fixup_models[] = {
|
||||
{.id = ALC662_FIXUP_ASUS_MODE6, .name = "asus-mode6"},
|
||||
{.id = ALC662_FIXUP_ASUS_MODE7, .name = "asus-mode7"},
|
||||
{.id = ALC662_FIXUP_ASUS_MODE8, .name = "asus-mode8"},
|
||||
{.id = ALC662_FIXUP_INV_DMIC, .name = "inv-dmic"},
|
||||
{}
|
||||
};
|
||||
|
||||
@ -6831,6 +7043,7 @@ static const struct hda_codec_preset snd_hda_preset_realtek[] = {
|
||||
{ .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 },
|
||||
{ .id = 0x10ec0276, .name = "ALC276", .patch = patch_alc269 },
|
||||
{ .id = 0x10ec0280, .name = "ALC280", .patch = patch_alc269 },
|
||||
{ .id = 0x10ec0282, .name = "ALC282", .patch = patch_alc269 },
|
||||
{ .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
|
||||
.patch = patch_alc861 },
|
||||
{ .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
|
||||
|
@ -4997,7 +4997,7 @@ static int stac92xx_resume(struct hda_codec *codec)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int stac92xx_suspend(struct hda_codec *codec, pm_message_t state)
|
||||
static int stac92xx_suspend(struct hda_codec *codec)
|
||||
{
|
||||
stac92xx_shutup(codec);
|
||||
return 0;
|
||||
|
@ -1748,7 +1748,7 @@ static void via_unsol_event(struct hda_codec *codec,
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int via_suspend(struct hda_codec *codec, pm_message_t state)
|
||||
static int via_suspend(struct hda_codec *codec)
|
||||
{
|
||||
struct via_spec *spec = codec->spec;
|
||||
vt1708_stop_hp_work(spec);
|
||||
|
@ -2793,9 +2793,10 @@ static void __devexit snd_vt1724_remove(struct pci_dev *pci)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int snd_vt1724_suspend(struct pci_dev *pci, pm_message_t state)
|
||||
static int snd_vt1724_suspend(struct device *dev)
|
||||
{
|
||||
struct snd_card *card = pci_get_drvdata(pci);
|
||||
struct pci_dev *pci = to_pci_dev(dev);
|
||||
struct snd_card *card = dev_get_drvdata(dev);
|
||||
struct snd_ice1712 *ice = card->private_data;
|
||||
|
||||
if (!ice->pm_suspend_enabled)
|
||||
@ -2820,13 +2821,14 @@ static int snd_vt1724_suspend(struct pci_dev *pci, pm_message_t state)
|
||||
|
||||
pci_disable_device(pci);
|
||||
pci_save_state(pci);
|
||||
pci_set_power_state(pci, pci_choose_state(pci, state));
|
||||
pci_set_power_state(pci, PCI_D3hot);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_vt1724_resume(struct pci_dev *pci)
|
||||
static int snd_vt1724_resume(struct device *dev)
|
||||
{
|
||||
struct snd_card *card = pci_get_drvdata(pci);
|
||||
struct pci_dev *pci = to_pci_dev(dev);
|
||||
struct snd_card *card = dev_get_drvdata(dev);
|
||||
struct snd_ice1712 *ice = card->private_data;
|
||||
|
||||
if (!ice->pm_suspend_enabled)
|
||||
@ -2871,17 +2873,21 @@ static int snd_vt1724_resume(struct pci_dev *pci)
|
||||
snd_power_change_state(card, SNDRV_CTL_POWER_D0);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(snd_vt1724_pm, snd_vt1724_suspend, snd_vt1724_resume);
|
||||
#define SND_VT1724_PM_OPS &snd_vt1724_pm
|
||||
#else
|
||||
#define SND_VT1724_PM_OPS NULL
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
static struct pci_driver vt1724_driver = {
|
||||
.name = KBUILD_MODNAME,
|
||||
.id_table = snd_vt1724_ids,
|
||||
.probe = snd_vt1724_probe,
|
||||
.remove = __devexit_p(snd_vt1724_remove),
|
||||
#ifdef CONFIG_PM
|
||||
.suspend = snd_vt1724_suspend,
|
||||
.resume = snd_vt1724_resume,
|
||||
#endif
|
||||
.driver = {
|
||||
.pm = SND_VT1724_PM_OPS,
|
||||
},
|
||||
};
|
||||
|
||||
module_pci_driver(vt1724_driver);
|
||||
|
@ -2624,9 +2624,10 @@ static int snd_intel8x0_free(struct intel8x0 *chip)
|
||||
/*
|
||||
* power management
|
||||
*/
|
||||
static int intel8x0_suspend(struct pci_dev *pci, pm_message_t state)
|
||||
static int intel8x0_suspend(struct device *dev)
|
||||
{
|
||||
struct snd_card *card = pci_get_drvdata(pci);
|
||||
struct pci_dev *pci = to_pci_dev(dev);
|
||||
struct snd_card *card = dev_get_drvdata(dev);
|
||||
struct intel8x0 *chip = card->private_data;
|
||||
int i;
|
||||
|
||||
@ -2658,13 +2659,14 @@ static int intel8x0_suspend(struct pci_dev *pci, pm_message_t state)
|
||||
/* The call below may disable built-in speaker on some laptops
|
||||
* after S2RAM. So, don't touch it.
|
||||
*/
|
||||
/* pci_set_power_state(pci, pci_choose_state(pci, state)); */
|
||||
/* pci_set_power_state(pci, PCI_D3hot); */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int intel8x0_resume(struct pci_dev *pci)
|
||||
static int intel8x0_resume(struct device *dev)
|
||||
{
|
||||
struct snd_card *card = pci_get_drvdata(pci);
|
||||
struct pci_dev *pci = to_pci_dev(dev);
|
||||
struct snd_card *card = dev_get_drvdata(dev);
|
||||
struct intel8x0 *chip = card->private_data;
|
||||
int i;
|
||||
|
||||
@ -2734,6 +2736,11 @@ static int intel8x0_resume(struct pci_dev *pci)
|
||||
snd_power_change_state(card, SNDRV_CTL_POWER_D0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(intel8x0_pm, intel8x0_suspend, intel8x0_resume);
|
||||
#define INTEL8X0_PM_OPS &intel8x0_pm
|
||||
#else
|
||||
#define INTEL8X0_PM_OPS NULL
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
#define INTEL8X0_TESTBUF_SIZE 32768 /* enough large for one shot */
|
||||
@ -3343,10 +3350,9 @@ static struct pci_driver intel8x0_driver = {
|
||||
.id_table = snd_intel8x0_ids,
|
||||
.probe = snd_intel8x0_probe,
|
||||
.remove = __devexit_p(snd_intel8x0_remove),
|
||||
#ifdef CONFIG_PM
|
||||
.suspend = intel8x0_suspend,
|
||||
.resume = intel8x0_resume,
|
||||
#endif
|
||||
.driver = {
|
||||
.pm = INTEL8X0_PM_OPS,
|
||||
},
|
||||
};
|
||||
|
||||
module_pci_driver(intel8x0_driver);
|
||||
|
@ -1012,9 +1012,10 @@ static int snd_intel8x0m_free(struct intel8x0m *chip)
|
||||
/*
|
||||
* power management
|
||||
*/
|
||||
static int intel8x0m_suspend(struct pci_dev *pci, pm_message_t state)
|
||||
static int intel8x0m_suspend(struct device *dev)
|
||||
{
|
||||
struct snd_card *card = pci_get_drvdata(pci);
|
||||
struct pci_dev *pci = to_pci_dev(dev);
|
||||
struct snd_card *card = dev_get_drvdata(dev);
|
||||
struct intel8x0m *chip = card->private_data;
|
||||
int i;
|
||||
|
||||
@ -1028,13 +1029,14 @@ static int intel8x0m_suspend(struct pci_dev *pci, pm_message_t state)
|
||||
}
|
||||
pci_disable_device(pci);
|
||||
pci_save_state(pci);
|
||||
pci_set_power_state(pci, pci_choose_state(pci, state));
|
||||
pci_set_power_state(pci, PCI_D3hot);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int intel8x0m_resume(struct pci_dev *pci)
|
||||
static int intel8x0m_resume(struct device *dev)
|
||||
{
|
||||
struct snd_card *card = pci_get_drvdata(pci);
|
||||
struct pci_dev *pci = to_pci_dev(dev);
|
||||
struct snd_card *card = dev_get_drvdata(dev);
|
||||
struct intel8x0m *chip = card->private_data;
|
||||
|
||||
pci_set_power_state(pci, PCI_D0);
|
||||
@ -1060,6 +1062,11 @@ static int intel8x0m_resume(struct pci_dev *pci)
|
||||
snd_power_change_state(card, SNDRV_CTL_POWER_D0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(intel8x0m_pm, intel8x0m_suspend, intel8x0m_resume);
|
||||
#define INTEL8X0M_PM_OPS &intel8x0m_pm
|
||||
#else
|
||||
#define INTEL8X0M_PM_OPS NULL
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
#ifdef CONFIG_PROC_FS
|
||||
@ -1329,10 +1336,9 @@ static struct pci_driver intel8x0m_driver = {
|
||||
.id_table = snd_intel8x0m_ids,
|
||||
.probe = snd_intel8x0m_probe,
|
||||
.remove = __devexit_p(snd_intel8x0m_remove),
|
||||
#ifdef CONFIG_PM
|
||||
.suspend = intel8x0m_suspend,
|
||||
.resume = intel8x0m_resume,
|
||||
#endif
|
||||
.driver = {
|
||||
.pm = INTEL8X0M_PM_OPS,
|
||||
},
|
||||
};
|
||||
|
||||
module_pci_driver(intel8x0m_driver);
|
||||
|
@ -361,74 +361,6 @@ MODULE_PARM_DESC(amp_gpio, "GPIO pin number for external amp. (default = -1)");
|
||||
#define DSP2HOST_REQ_I2SRATE 0x02
|
||||
#define DSP2HOST_REQ_TIMER 0x04
|
||||
|
||||
/* AC97 registers */
|
||||
/* XXX fix this crap up */
|
||||
/*#define AC97_RESET 0x00*/
|
||||
|
||||
#define AC97_VOL_MUTE_B 0x8000
|
||||
#define AC97_VOL_M 0x1F
|
||||
#define AC97_LEFT_VOL_S 8
|
||||
|
||||
#define AC97_MASTER_VOL 0x02
|
||||
#define AC97_LINE_LEVEL_VOL 0x04
|
||||
#define AC97_MASTER_MONO_VOL 0x06
|
||||
#define AC97_PC_BEEP_VOL 0x0A
|
||||
#define AC97_PC_BEEP_VOL_M 0x0F
|
||||
#define AC97_SROUND_MASTER_VOL 0x38
|
||||
#define AC97_PC_BEEP_VOL_S 1
|
||||
|
||||
/*#define AC97_PHONE_VOL 0x0C
|
||||
#define AC97_MIC_VOL 0x0E*/
|
||||
#define AC97_MIC_20DB_ENABLE 0x40
|
||||
|
||||
/*#define AC97_LINEIN_VOL 0x10
|
||||
#define AC97_CD_VOL 0x12
|
||||
#define AC97_VIDEO_VOL 0x14
|
||||
#define AC97_AUX_VOL 0x16*/
|
||||
#define AC97_PCM_OUT_VOL 0x18
|
||||
/*#define AC97_RECORD_SELECT 0x1A*/
|
||||
#define AC97_RECORD_MIC 0x00
|
||||
#define AC97_RECORD_CD 0x01
|
||||
#define AC97_RECORD_VIDEO 0x02
|
||||
#define AC97_RECORD_AUX 0x03
|
||||
#define AC97_RECORD_MONO_MUX 0x02
|
||||
#define AC97_RECORD_DIGITAL 0x03
|
||||
#define AC97_RECORD_LINE 0x04
|
||||
#define AC97_RECORD_STEREO 0x05
|
||||
#define AC97_RECORD_MONO 0x06
|
||||
#define AC97_RECORD_PHONE 0x07
|
||||
|
||||
/*#define AC97_RECORD_GAIN 0x1C*/
|
||||
#define AC97_RECORD_VOL_M 0x0F
|
||||
|
||||
/*#define AC97_GENERAL_PURPOSE 0x20*/
|
||||
#define AC97_POWER_DOWN_CTRL 0x26
|
||||
#define AC97_ADC_READY 0x0001
|
||||
#define AC97_DAC_READY 0x0002
|
||||
#define AC97_ANALOG_READY 0x0004
|
||||
#define AC97_VREF_ON 0x0008
|
||||
#define AC97_PR0 0x0100
|
||||
#define AC97_PR1 0x0200
|
||||
#define AC97_PR2 0x0400
|
||||
#define AC97_PR3 0x0800
|
||||
#define AC97_PR4 0x1000
|
||||
|
||||
#define AC97_RESERVED1 0x28
|
||||
|
||||
#define AC97_VENDOR_TEST 0x5A
|
||||
|
||||
#define AC97_CLOCK_DELAY 0x5C
|
||||
#define AC97_LINEOUT_MUX_SEL 0x0001
|
||||
#define AC97_MONO_MUX_SEL 0x0002
|
||||
#define AC97_CLOCK_DELAY_SEL 0x1F
|
||||
#define AC97_DAC_CDS_SHIFT 6
|
||||
#define AC97_ADC_CDS_SHIFT 11
|
||||
|
||||
#define AC97_MULTI_CHANNEL_SEL 0x74
|
||||
|
||||
/*#define AC97_VENDOR_ID1 0x7C
|
||||
#define AC97_VENDOR_ID2 0x7E*/
|
||||
|
||||
/*
|
||||
* ASSP control regs
|
||||
*/
|
||||
@ -2459,9 +2391,10 @@ static int snd_m3_free(struct snd_m3 *chip)
|
||||
* APM support
|
||||
*/
|
||||
#ifdef CONFIG_PM
|
||||
static int m3_suspend(struct pci_dev *pci, pm_message_t state)
|
||||
static int m3_suspend(struct device *dev)
|
||||
{
|
||||
struct snd_card *card = pci_get_drvdata(pci);
|
||||
struct pci_dev *pci = to_pci_dev(dev);
|
||||
struct snd_card *card = dev_get_drvdata(dev);
|
||||
struct snd_m3 *chip = card->private_data;
|
||||
int i, dsp_index;
|
||||
|
||||
@ -2489,13 +2422,14 @@ static int m3_suspend(struct pci_dev *pci, pm_message_t state)
|
||||
|
||||
pci_disable_device(pci);
|
||||
pci_save_state(pci);
|
||||
pci_set_power_state(pci, pci_choose_state(pci, state));
|
||||
pci_set_power_state(pci, PCI_D3hot);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int m3_resume(struct pci_dev *pci)
|
||||
static int m3_resume(struct device *dev)
|
||||
{
|
||||
struct snd_card *card = pci_get_drvdata(pci);
|
||||
struct pci_dev *pci = to_pci_dev(dev);
|
||||
struct snd_card *card = dev_get_drvdata(dev);
|
||||
struct snd_m3 *chip = card->private_data;
|
||||
int i, dsp_index;
|
||||
|
||||
@ -2546,6 +2480,11 @@ static int m3_resume(struct pci_dev *pci)
|
||||
chip->in_suspend = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(m3_pm, m3_suspend, m3_resume);
|
||||
#define M3_PM_OPS &m3_pm
|
||||
#else
|
||||
#define M3_PM_OPS NULL
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
#ifdef CONFIG_SND_MAESTRO3_INPUT
|
||||
@ -2842,10 +2781,9 @@ static struct pci_driver m3_driver = {
|
||||
.id_table = snd_m3_ids,
|
||||
.probe = snd_m3_probe,
|
||||
.remove = __devexit_p(snd_m3_remove),
|
||||
#ifdef CONFIG_PM
|
||||
.suspend = m3_suspend,
|
||||
.resume = m3_resume,
|
||||
#endif
|
||||
.driver = {
|
||||
.pm = M3_PM_OPS,
|
||||
},
|
||||
};
|
||||
|
||||
module_pci_driver(m3_driver);
|
||||
|
@ -1382,9 +1382,10 @@ snd_nm256_peek_for_sig(struct nm256 *chip)
|
||||
* APM event handler, so the card is properly reinitialized after a power
|
||||
* event.
|
||||
*/
|
||||
static int nm256_suspend(struct pci_dev *pci, pm_message_t state)
|
||||
static int nm256_suspend(struct device *dev)
|
||||
{
|
||||
struct snd_card *card = pci_get_drvdata(pci);
|
||||
struct pci_dev *pci = to_pci_dev(dev);
|
||||
struct snd_card *card = dev_get_drvdata(dev);
|
||||
struct nm256 *chip = card->private_data;
|
||||
|
||||
snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
|
||||
@ -1393,13 +1394,14 @@ static int nm256_suspend(struct pci_dev *pci, pm_message_t state)
|
||||
chip->coeffs_current = 0;
|
||||
pci_disable_device(pci);
|
||||
pci_save_state(pci);
|
||||
pci_set_power_state(pci, pci_choose_state(pci, state));
|
||||
pci_set_power_state(pci, PCI_D3hot);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nm256_resume(struct pci_dev *pci)
|
||||
static int nm256_resume(struct device *dev)
|
||||
{
|
||||
struct snd_card *card = pci_get_drvdata(pci);
|
||||
struct pci_dev *pci = to_pci_dev(dev);
|
||||
struct snd_card *card = dev_get_drvdata(dev);
|
||||
struct nm256 *chip = card->private_data;
|
||||
int i;
|
||||
|
||||
@ -1434,6 +1436,11 @@ static int nm256_resume(struct pci_dev *pci)
|
||||
chip->in_resume = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(nm256_pm, nm256_suspend, nm256_resume);
|
||||
#define NM256_PM_OPS &nm256_pm
|
||||
#else
|
||||
#define NM256_PM_OPS NULL
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
static int snd_nm256_free(struct nm256 *chip)
|
||||
@ -1747,10 +1754,9 @@ static struct pci_driver nm256_driver = {
|
||||
.id_table = snd_nm256_ids,
|
||||
.probe = snd_nm256_probe,
|
||||
.remove = __devexit_p(snd_nm256_remove),
|
||||
#ifdef CONFIG_PM
|
||||
.suspend = nm256_suspend,
|
||||
.resume = nm256_resume,
|
||||
#endif
|
||||
.driver = {
|
||||
.pm = NM256_PM_OPS,
|
||||
},
|
||||
};
|
||||
|
||||
module_pci_driver(nm256_driver);
|
||||
|
@ -873,8 +873,9 @@ static struct pci_driver oxygen_driver = {
|
||||
.probe = generic_oxygen_probe,
|
||||
.remove = __devexit_p(oxygen_pci_remove),
|
||||
#ifdef CONFIG_PM
|
||||
.suspend = oxygen_pci_suspend,
|
||||
.resume = oxygen_pci_resume,
|
||||
.driver = {
|
||||
.pm = &oxygen_pci_pm,
|
||||
},
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@ -162,8 +162,7 @@ int oxygen_pci_probe(struct pci_dev *pci, int index, char *id,
|
||||
);
|
||||
void oxygen_pci_remove(struct pci_dev *pci);
|
||||
#ifdef CONFIG_PM
|
||||
int oxygen_pci_suspend(struct pci_dev *pci, pm_message_t state);
|
||||
int oxygen_pci_resume(struct pci_dev *pci);
|
||||
extern const struct dev_pm_ops oxygen_pci_pm;
|
||||
#endif
|
||||
void oxygen_pci_shutdown(struct pci_dev *pci);
|
||||
|
||||
|
@ -727,9 +727,10 @@ void oxygen_pci_remove(struct pci_dev *pci)
|
||||
EXPORT_SYMBOL(oxygen_pci_remove);
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
int oxygen_pci_suspend(struct pci_dev *pci, pm_message_t state)
|
||||
static int oxygen_pci_suspend(struct device *dev)
|
||||
{
|
||||
struct snd_card *card = pci_get_drvdata(pci);
|
||||
struct pci_dev *pci = to_pci_dev(dev);
|
||||
struct snd_card *card = dev_get_drvdata(dev);
|
||||
struct oxygen *chip = card->private_data;
|
||||
unsigned int i, saved_interrupt_mask;
|
||||
|
||||
@ -756,10 +757,9 @@ int oxygen_pci_suspend(struct pci_dev *pci, pm_message_t state)
|
||||
|
||||
pci_disable_device(pci);
|
||||
pci_save_state(pci);
|
||||
pci_set_power_state(pci, pci_choose_state(pci, state));
|
||||
pci_set_power_state(pci, PCI_D3hot);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(oxygen_pci_suspend);
|
||||
|
||||
static const u32 registers_to_restore[OXYGEN_IO_SIZE / 32] = {
|
||||
0xffffffff, 0x00ff077f, 0x00011d08, 0x007f00ff,
|
||||
@ -787,9 +787,10 @@ static void oxygen_restore_ac97(struct oxygen *chip, unsigned int codec)
|
||||
chip->saved_ac97_registers[codec][i]);
|
||||
}
|
||||
|
||||
int oxygen_pci_resume(struct pci_dev *pci)
|
||||
static int oxygen_pci_resume(struct device *dev)
|
||||
{
|
||||
struct snd_card *card = pci_get_drvdata(pci);
|
||||
struct pci_dev *pci = to_pci_dev(dev);
|
||||
struct snd_card *card = dev_get_drvdata(dev);
|
||||
struct oxygen *chip = card->private_data;
|
||||
unsigned int i;
|
||||
|
||||
@ -820,7 +821,9 @@ int oxygen_pci_resume(struct pci_dev *pci)
|
||||
snd_power_change_state(card, SNDRV_CTL_POWER_D0);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(oxygen_pci_resume);
|
||||
|
||||
SIMPLE_DEV_PM_OPS(oxygen_pci_pm, oxygen_pci_suspend, oxygen_pci_resume);
|
||||
EXPORT_SYMBOL(oxygen_pci_pm);
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
void oxygen_pci_shutdown(struct pci_dev *pci)
|
||||
|
@ -94,8 +94,9 @@ static struct pci_driver xonar_driver = {
|
||||
.probe = xonar_probe,
|
||||
.remove = __devexit_p(oxygen_pci_remove),
|
||||
#ifdef CONFIG_PM
|
||||
.suspend = oxygen_pci_suspend,
|
||||
.resume = oxygen_pci_resume,
|
||||
.driver = {
|
||||
.pm = &oxygen_pci_pm,
|
||||
},
|
||||
#endif
|
||||
.shutdown = oxygen_pci_shutdown,
|
||||
};
|
||||
|
@ -1368,6 +1368,67 @@ static void pcxhr_proc_gpo_write(struct snd_info_entry *entry,
|
||||
}
|
||||
}
|
||||
|
||||
/* Access to the results of the CMD_GET_TIME_CODE RMH */
|
||||
#define TIME_CODE_VALID_MASK 0x00800000
|
||||
#define TIME_CODE_NEW_MASK 0x00400000
|
||||
#define TIME_CODE_BACK_MASK 0x00200000
|
||||
#define TIME_CODE_WAIT_MASK 0x00100000
|
||||
|
||||
/* Values for the CMD_MANAGE_SIGNAL RMH */
|
||||
#define MANAGE_SIGNAL_TIME_CODE 0x01
|
||||
#define MANAGE_SIGNAL_MIDI 0x02
|
||||
|
||||
/* linear time code read proc*/
|
||||
static void pcxhr_proc_ltc(struct snd_info_entry *entry,
|
||||
struct snd_info_buffer *buffer)
|
||||
{
|
||||
struct snd_pcxhr *chip = entry->private_data;
|
||||
struct pcxhr_mgr *mgr = chip->mgr;
|
||||
struct pcxhr_rmh rmh;
|
||||
unsigned int ltcHrs, ltcMin, ltcSec, ltcFrm;
|
||||
int err;
|
||||
/* commands available when embedded DSP is running */
|
||||
if (!(mgr->dsp_loaded & (1 << PCXHR_FIRMWARE_DSP_MAIN_INDEX))) {
|
||||
snd_iprintf(buffer, "no firmware loaded\n");
|
||||
return;
|
||||
}
|
||||
if (!mgr->capture_ltc) {
|
||||
pcxhr_init_rmh(&rmh, CMD_MANAGE_SIGNAL);
|
||||
rmh.cmd[0] |= MANAGE_SIGNAL_TIME_CODE;
|
||||
err = pcxhr_send_msg(mgr, &rmh);
|
||||
if (err) {
|
||||
snd_iprintf(buffer, "ltc not activated (%d)\n", err);
|
||||
return;
|
||||
}
|
||||
if (mgr->is_hr_stereo)
|
||||
hr222_manage_timecode(mgr, 1);
|
||||
else
|
||||
pcxhr_write_io_num_reg_cont(mgr, REG_CONT_VALSMPTE,
|
||||
REG_CONT_VALSMPTE, NULL);
|
||||
mgr->capture_ltc = 1;
|
||||
}
|
||||
pcxhr_init_rmh(&rmh, CMD_GET_TIME_CODE);
|
||||
err = pcxhr_send_msg(mgr, &rmh);
|
||||
if (err) {
|
||||
snd_iprintf(buffer, "ltc read error (err=%d)\n", err);
|
||||
return ;
|
||||
}
|
||||
ltcHrs = 10*((rmh.stat[0] >> 8) & 0x3) + (rmh.stat[0] & 0xf);
|
||||
ltcMin = 10*((rmh.stat[1] >> 16) & 0x7) + ((rmh.stat[1] >> 8) & 0xf);
|
||||
ltcSec = 10*(rmh.stat[1] & 0x7) + ((rmh.stat[2] >> 16) & 0xf);
|
||||
ltcFrm = 10*((rmh.stat[2] >> 8) & 0x3) + (rmh.stat[2] & 0xf);
|
||||
|
||||
snd_iprintf(buffer, "timecode: %02u:%02u:%02u-%02u\n",
|
||||
ltcHrs, ltcMin, ltcSec, ltcFrm);
|
||||
snd_iprintf(buffer, "raw: 0x%04x%06x%06x\n", rmh.stat[0] & 0x00ffff,
|
||||
rmh.stat[1] & 0xffffff, rmh.stat[2] & 0xffffff);
|
||||
/*snd_iprintf(buffer, "dsp ref time: 0x%06x%06x\n",
|
||||
rmh.stat[3] & 0xffffff, rmh.stat[4] & 0xffffff);*/
|
||||
if (!(rmh.stat[0] & TIME_CODE_VALID_MASK)) {
|
||||
snd_iprintf(buffer, "warning: linear timecode not valid\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void __devinit pcxhr_proc_init(struct snd_pcxhr *chip)
|
||||
{
|
||||
struct snd_info_entry *entry;
|
||||
@ -1383,6 +1444,8 @@ static void __devinit pcxhr_proc_init(struct snd_pcxhr *chip)
|
||||
entry->c.text.write = pcxhr_proc_gpo_write;
|
||||
entry->mode |= S_IWUSR;
|
||||
}
|
||||
if (!snd_card_proc_new(chip->card, "ltc", &entry))
|
||||
snd_info_set_text_ops(entry, chip, pcxhr_proc_ltc);
|
||||
}
|
||||
/* end of proc interface */
|
||||
|
||||
|
@ -103,6 +103,7 @@ struct pcxhr_mgr {
|
||||
unsigned int board_has_mic:1; /* if 1 the board has microphone input */
|
||||
unsigned int board_aes_in_192k:1;/* if 1 the aes input plugs do support 192kHz */
|
||||
unsigned int mono_capture:1; /* if 1 the board does mono capture */
|
||||
unsigned int capture_ltc:1; /* if 1 the board captures LTC input */
|
||||
|
||||
struct snd_dma_buffer hostport;
|
||||
|
||||
|
@ -504,6 +504,8 @@ static struct pcxhr_cmd_info pcxhr_dsp_cmds[] = {
|
||||
[CMD_FORMAT_STREAM_IN] = { 0x870000, 0, RMH_SSIZE_FIXED },
|
||||
[CMD_STREAM_SAMPLE_COUNT] = { 0x902000, 2, RMH_SSIZE_FIXED },
|
||||
[CMD_AUDIO_LEVEL_ADJUST] = { 0xc22000, 0, RMH_SSIZE_FIXED },
|
||||
[CMD_GET_TIME_CODE] = { 0x060000, 5, RMH_SSIZE_FIXED },
|
||||
[CMD_MANAGE_SIGNAL] = { 0x0f0000, 0, RMH_SSIZE_FIXED },
|
||||
};
|
||||
|
||||
#ifdef CONFIG_SND_DEBUG_VERBOSE
|
||||
@ -533,6 +535,8 @@ static char* cmd_names[] = {
|
||||
[CMD_FORMAT_STREAM_IN] = "CMD_FORMAT_STREAM_IN",
|
||||
[CMD_STREAM_SAMPLE_COUNT] = "CMD_STREAM_SAMPLE_COUNT",
|
||||
[CMD_AUDIO_LEVEL_ADJUST] = "CMD_AUDIO_LEVEL_ADJUST",
|
||||
[CMD_GET_TIME_CODE] = "CMD_GET_TIME_CODE",
|
||||
[CMD_MANAGE_SIGNAL] = "CMD_MANAGE_SIGNAL",
|
||||
};
|
||||
#endif
|
||||
|
||||
@ -1133,13 +1137,12 @@ static u_int64_t pcxhr_stream_read_position(struct pcxhr_mgr *mgr,
|
||||
hw_sample_count = ((u_int64_t)rmh.stat[0]) << 24;
|
||||
hw_sample_count += (u_int64_t)rmh.stat[1];
|
||||
|
||||
snd_printdd("stream %c%d : abs samples real(%ld) timer(%ld)\n",
|
||||
snd_printdd("stream %c%d : abs samples real(%llu) timer(%llu)\n",
|
||||
stream->pipe->is_capture ? 'C' : 'P',
|
||||
stream->substream->number,
|
||||
(long unsigned int)hw_sample_count,
|
||||
(long unsigned int)(stream->timer_abs_periods +
|
||||
stream->timer_period_frag +
|
||||
mgr->granularity));
|
||||
hw_sample_count,
|
||||
stream->timer_abs_periods + stream->timer_period_frag +
|
||||
mgr->granularity);
|
||||
return hw_sample_count;
|
||||
}
|
||||
|
||||
@ -1243,10 +1246,18 @@ irqreturn_t pcxhr_interrupt(int irq, void *dev_id)
|
||||
|
||||
if ((dsp_time_diff < 0) &&
|
||||
(mgr->dsp_time_last != PCXHR_DSP_TIME_INVALID)) {
|
||||
snd_printdd("ERROR DSP TIME old(%d) new(%d) -> "
|
||||
"resynchronize all streams\n",
|
||||
/* handle dsp counter wraparound without resync */
|
||||
int tmp_diff = dsp_time_diff + PCXHR_DSP_TIME_MASK + 1;
|
||||
snd_printdd("WARNING DSP timestamp old(%d) new(%d)",
|
||||
mgr->dsp_time_last, dsp_time_new);
|
||||
mgr->dsp_time_err++;
|
||||
if (tmp_diff > 0 && tmp_diff <= (2*mgr->granularity)) {
|
||||
snd_printdd("-> timestamp wraparound OK: "
|
||||
"diff=%d\n", tmp_diff);
|
||||
dsp_time_diff = tmp_diff;
|
||||
} else {
|
||||
snd_printdd("-> resynchronize all streams\n");
|
||||
mgr->dsp_time_err++;
|
||||
}
|
||||
}
|
||||
#ifdef CONFIG_SND_DEBUG_VERBOSE
|
||||
if (dsp_time_diff == 0)
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user