diff options
Diffstat (limited to 'sound')
-rw-r--r-- | sound/Kconfig | 5 | ||||
-rw-r--r-- | sound/core/sound.c | 8 | ||||
-rw-r--r-- | sound/drivers/Kconfig | 15 | ||||
-rw-r--r-- | sound/drivers/pcsp/pcsp.c | 2 | ||||
-rw-r--r-- | sound/drivers/pcsp/pcsp.h | 6 | ||||
-rw-r--r-- | sound/drivers/pcsp/pcsp_lib.c | 58 | ||||
-rw-r--r-- | sound/drivers/pcsp/pcsp_mixer.c | 3 | ||||
-rw-r--r-- | sound/isa/sb/sb_mixer.c | 4 | ||||
-rw-r--r-- | sound/oss/Kconfig | 4 | ||||
-rw-r--r-- | sound/pci/ac97/ac97_patch.c | 48 | ||||
-rw-r--r-- | sound/pci/aw2/aw2-alsa.c | 4 | ||||
-rw-r--r-- | sound/pci/emu10k1/emu10k1_main.c | 15 | ||||
-rw-r--r-- | sound/pci/hda/patch_analog.c | 51 | ||||
-rw-r--r-- | sound/pci/hda/patch_cmedia.c | 1 | ||||
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 54 | ||||
-rw-r--r-- | sound/pci/hda/patch_sigmatel.c | 2 | ||||
-rw-r--r-- | sound/pci/hda/patch_via.c | 20 | ||||
-rw-r--r-- | sound/pci/oxygen/oxygen_mixer.c | 12 | ||||
-rw-r--r-- | sound/usb/caiaq/caiaq-device.c | 4 |
19 files changed, 185 insertions, 131 deletions
diff --git a/sound/Kconfig b/sound/Kconfig index b2a2db47aff5..4247406160e7 100644 --- a/sound/Kconfig +++ b/sound/Kconfig | |||
@@ -28,11 +28,6 @@ config SOUND | |||
28 | and read <file:Documentation/sound/oss/README.modules>; the module | 28 | and read <file:Documentation/sound/oss/README.modules>; the module |
29 | will be called soundcore. | 29 | will be called soundcore. |
30 | 30 | ||
31 | I'm told that even without a sound card, you can make your computer | ||
32 | say more than an occasional beep, by programming the PC speaker. | ||
33 | Kernel patches and supporting utilities to do that are in the pcsp | ||
34 | package, available at <ftp://ftp.infradead.org/pub/pcsp/>. | ||
35 | |||
36 | source "sound/oss/dmasound/Kconfig" | 31 | source "sound/oss/dmasound/Kconfig" |
37 | 32 | ||
38 | if !M68K | 33 | if !M68K |
diff --git a/sound/core/sound.c b/sound/core/sound.c index 812f91b3de5b..6c8ab48c689a 100644 --- a/sound/core/sound.c +++ b/sound/core/sound.c | |||
@@ -259,8 +259,9 @@ int snd_register_device_for_dev(int type, struct snd_card *card, int dev, | |||
259 | return minor; | 259 | return minor; |
260 | } | 260 | } |
261 | snd_minors[minor] = preg; | 261 | snd_minors[minor] = preg; |
262 | preg->dev = device_create(sound_class, device, MKDEV(major, minor), | 262 | preg->dev = device_create_drvdata(sound_class, device, |
263 | "%s", name); | 263 | MKDEV(major, minor), |
264 | private_data, "%s", name); | ||
264 | if (IS_ERR(preg->dev)) { | 265 | if (IS_ERR(preg->dev)) { |
265 | snd_minors[minor] = NULL; | 266 | snd_minors[minor] = NULL; |
266 | mutex_unlock(&sound_mutex); | 267 | mutex_unlock(&sound_mutex); |
@@ -269,9 +270,6 @@ int snd_register_device_for_dev(int type, struct snd_card *card, int dev, | |||
269 | return minor; | 270 | return minor; |
270 | } | 271 | } |
271 | 272 | ||
272 | if (preg->dev) | ||
273 | dev_set_drvdata(preg->dev, private_data); | ||
274 | |||
275 | mutex_unlock(&sound_mutex); | 273 | mutex_unlock(&sound_mutex); |
276 | return 0; | 274 | return 0; |
277 | } | 275 | } |
diff --git a/sound/drivers/Kconfig b/sound/drivers/Kconfig index 379bcb074463..602b58e3b55d 100644 --- a/sound/drivers/Kconfig +++ b/sound/drivers/Kconfig | |||
@@ -5,9 +5,10 @@ menu "Generic devices" | |||
5 | 5 | ||
6 | 6 | ||
7 | config SND_PCSP | 7 | config SND_PCSP |
8 | tristate "PC-Speaker support" | 8 | tristate "PC-Speaker support (READ HELP!)" |
9 | depends on PCSPKR_PLATFORM && X86_PC && HIGH_RES_TIMERS | 9 | depends on PCSPKR_PLATFORM && X86_PC && HIGH_RES_TIMERS |
10 | depends on INPUT | 10 | depends on INPUT |
11 | depends on EXPERIMENTAL | ||
11 | depends on SND | 12 | depends on SND |
12 | select SND_PCM | 13 | select SND_PCM |
13 | help | 14 | help |
@@ -18,11 +19,21 @@ config SND_PCSP | |||
18 | 19 | ||
19 | You can compile this as a module which will be called snd-pcsp. | 20 | You can compile this as a module which will be called snd-pcsp. |
20 | 21 | ||
22 | WARNING: if you already have a soundcard, enabling this | ||
23 | driver may lead to a problem. Namely, it may get loaded | ||
24 | before the other sound driver of yours, making the | ||
25 | pc-speaker a default sound device. Which is likely not | ||
26 | what you want. To make this driver play nicely with other | ||
27 | sound driver, you can add this into your /etc/modprobe.conf: | ||
28 | options snd-pcsp index=2 | ||
29 | |||
21 | You don't need this driver if you only want your pc-speaker to beep. | 30 | You don't need this driver if you only want your pc-speaker to beep. |
22 | You don't need this driver if you have a tablet piezo beeper | 31 | You don't need this driver if you have a tablet piezo beeper |
23 | in your PC instead of the real speaker. | 32 | in your PC instead of the real speaker. |
24 | 33 | ||
25 | It should not hurt to say Y or M here in all other cases. | 34 | Say N if you have a sound card. |
35 | Say M if you don't. | ||
36 | Say Y only if you really know what you do. | ||
26 | 37 | ||
27 | config SND_MPU401_UART | 38 | config SND_MPU401_UART |
28 | tristate | 39 | tristate |
diff --git a/sound/drivers/pcsp/pcsp.c b/sound/drivers/pcsp/pcsp.c index 54a1f9036c66..1899cf0685bc 100644 --- a/sound/drivers/pcsp/pcsp.c +++ b/sound/drivers/pcsp/pcsp.c | |||
@@ -96,7 +96,7 @@ static int __devinit snd_card_pcsp_probe(int devnum, struct device *dev) | |||
96 | return -EINVAL; | 96 | return -EINVAL; |
97 | 97 | ||
98 | hrtimer_init(&pcsp_chip.timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); | 98 | hrtimer_init(&pcsp_chip.timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); |
99 | pcsp_chip.timer.cb_mode = HRTIMER_CB_IRQSAFE; | 99 | pcsp_chip.timer.cb_mode = HRTIMER_CB_SOFTIRQ; |
100 | pcsp_chip.timer.function = pcsp_do_timer; | 100 | pcsp_chip.timer.function = pcsp_do_timer; |
101 | 101 | ||
102 | card = snd_card_new(index, id, THIS_MODULE, 0); | 102 | card = snd_card_new(index, id, THIS_MODULE, 0); |
diff --git a/sound/drivers/pcsp/pcsp.h b/sound/drivers/pcsp/pcsp.h index f07cc1ee1fe7..1d661f795e8c 100644 --- a/sound/drivers/pcsp/pcsp.h +++ b/sound/drivers/pcsp/pcsp.h | |||
@@ -24,7 +24,8 @@ static DEFINE_SPINLOCK(i8253_lock); | |||
24 | /* default timer freq for PC-Speaker: 18643 Hz */ | 24 | /* default timer freq for PC-Speaker: 18643 Hz */ |
25 | #define DIV_18KHZ 64 | 25 | #define DIV_18KHZ 64 |
26 | #define MAX_DIV DIV_18KHZ | 26 | #define MAX_DIV DIV_18KHZ |
27 | #define CUR_DIV() (MAX_DIV >> chip->treble) | 27 | #define CALC_DIV(d) (MAX_DIV >> (d)) |
28 | #define CUR_DIV() CALC_DIV(chip->treble) | ||
28 | #define PCSP_MAX_TREBLE 1 | 29 | #define PCSP_MAX_TREBLE 1 |
29 | 30 | ||
30 | /* unfortunately, with hrtimers 37KHz does not work very well :( */ | 31 | /* unfortunately, with hrtimers 37KHz does not work very well :( */ |
@@ -36,7 +37,8 @@ static DEFINE_SPINLOCK(i8253_lock); | |||
36 | #define PCSP_DEFAULT_SDIV (DIV_18KHZ >> 1) | 37 | #define PCSP_DEFAULT_SDIV (DIV_18KHZ >> 1) |
37 | #define PCSP_DEFAULT_SRATE (PIT_TICK_RATE / PCSP_DEFAULT_SDIV) | 38 | #define PCSP_DEFAULT_SRATE (PIT_TICK_RATE / PCSP_DEFAULT_SDIV) |
38 | #define PCSP_INDEX_INC() (1 << (PCSP_MAX_TREBLE - chip->treble)) | 39 | #define PCSP_INDEX_INC() (1 << (PCSP_MAX_TREBLE - chip->treble)) |
39 | #define PCSP_RATE() (PIT_TICK_RATE / CUR_DIV()) | 40 | #define PCSP_CALC_RATE(i) (PIT_TICK_RATE / CALC_DIV(i)) |
41 | #define PCSP_RATE() PCSP_CALC_RATE(chip->treble) | ||
40 | #define PCSP_MIN_RATE__1 MAX_DIV/PIT_TICK_RATE | 42 | #define PCSP_MIN_RATE__1 MAX_DIV/PIT_TICK_RATE |
41 | #define PCSP_MAX_RATE__1 MIN_DIV/PIT_TICK_RATE | 43 | #define PCSP_MAX_RATE__1 MIN_DIV/PIT_TICK_RATE |
42 | #define PCSP_MAX_PERIOD_NS (1000000000ULL * PCSP_MIN_RATE__1) | 44 | #define PCSP_MAX_PERIOD_NS (1000000000ULL * PCSP_MIN_RATE__1) |
diff --git a/sound/drivers/pcsp/pcsp_lib.c b/sound/drivers/pcsp/pcsp_lib.c index ac6238e93513..e341f3f83b6a 100644 --- a/sound/drivers/pcsp/pcsp_lib.c +++ b/sound/drivers/pcsp/pcsp_lib.c | |||
@@ -9,7 +9,6 @@ | |||
9 | #include <linux/module.h> | 9 | #include <linux/module.h> |
10 | #include <linux/moduleparam.h> | 10 | #include <linux/moduleparam.h> |
11 | #include <sound/pcm.h> | 11 | #include <sound/pcm.h> |
12 | #include <linux/interrupt.h> | ||
13 | #include <asm/io.h> | 12 | #include <asm/io.h> |
14 | #include "pcsp.h" | 13 | #include "pcsp.h" |
15 | 14 | ||
@@ -18,36 +17,12 @@ module_param(nforce_wa, bool, 0444); | |||
18 | MODULE_PARM_DESC(nforce_wa, "Apply NForce chipset workaround " | 17 | MODULE_PARM_DESC(nforce_wa, "Apply NForce chipset workaround " |
19 | "(expect bad sound)"); | 18 | "(expect bad sound)"); |
20 | 19 | ||
21 | static void pcsp_start_timer(unsigned long dummy) | 20 | #define DMIX_WANTS_S16 1 |
22 | { | ||
23 | hrtimer_start(&pcsp_chip.timer, ktime_set(0, 0), HRTIMER_MODE_REL); | ||
24 | } | ||
25 | |||
26 | /* | ||
27 | * We need the hrtimer_start as a tasklet to avoid | ||
28 | * the nasty locking problem. :( | ||
29 | * The problem: | ||
30 | * - The timer handler is called with the cpu_base->lock | ||
31 | * already held by hrtimer code. | ||
32 | * - snd_pcm_period_elapsed() takes the | ||
33 | * substream->self_group.lock. | ||
34 | * So far so good. | ||
35 | * But the snd_pcsp_trigger() is called with the | ||
36 | * substream->self_group.lock held, and it calls | ||
37 | * hrtimer_start(), which takes the cpu_base->lock. | ||
38 | * You see the problem. We have the code pathes | ||
39 | * which take two locks in a reverse order. This | ||
40 | * can deadlock and the lock validator complains. | ||
41 | * The only solution I could find was to move the | ||
42 | * hrtimer_start() into a tasklet. -stsp | ||
43 | */ | ||
44 | static DECLARE_TASKLET(pcsp_start_timer_tasklet, pcsp_start_timer, 0); | ||
45 | 21 | ||
46 | enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle) | 22 | enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle) |
47 | { | 23 | { |
48 | unsigned long flags; | ||
49 | unsigned char timer_cnt, val; | 24 | unsigned char timer_cnt, val; |
50 | int periods_elapsed; | 25 | int fmt_size, periods_elapsed; |
51 | u64 ns; | 26 | u64 ns; |
52 | size_t period_bytes, buffer_bytes; | 27 | size_t period_bytes, buffer_bytes; |
53 | struct snd_pcm_substream *substream; | 28 | struct snd_pcm_substream *substream; |
@@ -64,9 +39,7 @@ enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle) | |||
64 | return HRTIMER_RESTART; | 39 | return HRTIMER_RESTART; |
65 | } | 40 | } |
66 | 41 | ||
67 | /* hrtimer calls us from both hardirq and softirq contexts, | 42 | spin_lock_irq(&chip->substream_lock); |
68 | * so irqsave :( */ | ||
69 | spin_lock_irqsave(&chip->substream_lock, flags); | ||
70 | /* Takashi Iwai says regarding this extra lock: | 43 | /* Takashi Iwai says regarding this extra lock: |
71 | 44 | ||
72 | If the irq handler handles some data on the DMA buffer, it should | 45 | If the irq handler handles some data on the DMA buffer, it should |
@@ -92,8 +65,11 @@ enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle) | |||
92 | goto exit_nr_unlock2; | 65 | goto exit_nr_unlock2; |
93 | 66 | ||
94 | runtime = substream->runtime; | 67 | runtime = substream->runtime; |
95 | /* assume it is u8 mono */ | 68 | fmt_size = snd_pcm_format_physical_width(runtime->format) >> 3; |
96 | val = runtime->dma_area[chip->playback_ptr]; | 69 | /* assume it is mono! */ |
70 | val = runtime->dma_area[chip->playback_ptr + fmt_size - 1]; | ||
71 | if (snd_pcm_format_signed(runtime->format)) | ||
72 | val ^= 0x80; | ||
97 | timer_cnt = val * CUR_DIV() / 256; | 73 | timer_cnt = val * CUR_DIV() / 256; |
98 | 74 | ||
99 | if (timer_cnt && chip->enable) { | 75 | if (timer_cnt && chip->enable) { |
@@ -111,12 +87,14 @@ enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle) | |||
111 | 87 | ||
112 | period_bytes = snd_pcm_lib_period_bytes(substream); | 88 | period_bytes = snd_pcm_lib_period_bytes(substream); |
113 | buffer_bytes = snd_pcm_lib_buffer_bytes(substream); | 89 | buffer_bytes = snd_pcm_lib_buffer_bytes(substream); |
114 | chip->playback_ptr += PCSP_INDEX_INC(); | 90 | chip->playback_ptr += PCSP_INDEX_INC() * fmt_size; |
115 | periods_elapsed = chip->playback_ptr - chip->period_ptr; | 91 | periods_elapsed = chip->playback_ptr - chip->period_ptr; |
116 | if (periods_elapsed < 0) { | 92 | if (periods_elapsed < 0) { |
117 | printk(KERN_WARNING "PCSP: playback_ptr inconsistent " | 93 | #if PCSP_DEBUG |
94 | printk(KERN_INFO "PCSP: buffer_bytes mod period_bytes != 0 ? " | ||
118 | "(%zi %zi %zi)\n", | 95 | "(%zi %zi %zi)\n", |
119 | chip->playback_ptr, period_bytes, buffer_bytes); | 96 | chip->playback_ptr, period_bytes, buffer_bytes); |
97 | #endif | ||
120 | periods_elapsed += buffer_bytes; | 98 | periods_elapsed += buffer_bytes; |
121 | } | 99 | } |
122 | periods_elapsed /= period_bytes; | 100 | periods_elapsed /= period_bytes; |
@@ -132,7 +110,7 @@ enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle) | |||
132 | chip->period_ptr %= buffer_bytes; | 110 | chip->period_ptr %= buffer_bytes; |
133 | } | 111 | } |
134 | 112 | ||
135 | spin_unlock_irqrestore(&chip->substream_lock, flags); | 113 | spin_unlock_irq(&chip->substream_lock); |
136 | 114 | ||
137 | if (!atomic_read(&chip->timer_active)) | 115 | if (!atomic_read(&chip->timer_active)) |
138 | return HRTIMER_NORESTART; | 116 | return HRTIMER_NORESTART; |
@@ -146,7 +124,7 @@ enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle) | |||
146 | exit_nr_unlock2: | 124 | exit_nr_unlock2: |
147 | snd_pcm_stream_unlock(substream); | 125 | snd_pcm_stream_unlock(substream); |
148 | exit_nr_unlock1: | 126 | exit_nr_unlock1: |
149 | spin_unlock_irqrestore(&chip->substream_lock, flags); | 127 | spin_unlock_irq(&chip->substream_lock); |
150 | return HRTIMER_NORESTART; | 128 | return HRTIMER_NORESTART; |
151 | } | 129 | } |
152 | 130 | ||
@@ -167,7 +145,7 @@ static void pcsp_start_playing(struct snd_pcsp *chip) | |||
167 | atomic_set(&chip->timer_active, 1); | 145 | atomic_set(&chip->timer_active, 1); |
168 | chip->thalf = 0; | 146 | chip->thalf = 0; |
169 | 147 | ||
170 | tasklet_schedule(&pcsp_start_timer_tasklet); | 148 | hrtimer_start(&pcsp_chip.timer, ktime_set(0, 0), HRTIMER_MODE_REL); |
171 | } | 149 | } |
172 | 150 | ||
173 | static void pcsp_stop_playing(struct snd_pcsp *chip) | 151 | static void pcsp_stop_playing(struct snd_pcsp *chip) |
@@ -270,7 +248,11 @@ static struct snd_pcm_hardware snd_pcsp_playback = { | |||
270 | .info = (SNDRV_PCM_INFO_INTERLEAVED | | 248 | .info = (SNDRV_PCM_INFO_INTERLEAVED | |
271 | SNDRV_PCM_INFO_HALF_DUPLEX | | 249 | SNDRV_PCM_INFO_HALF_DUPLEX | |
272 | SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID), | 250 | SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID), |
273 | .formats = SNDRV_PCM_FMTBIT_U8, | 251 | .formats = (SNDRV_PCM_FMTBIT_U8 |
252 | #if DMIX_WANTS_S16 | ||
253 | | SNDRV_PCM_FMTBIT_S16_LE | ||
254 | #endif | ||
255 | ), | ||
274 | .rates = SNDRV_PCM_RATE_KNOT, | 256 | .rates = SNDRV_PCM_RATE_KNOT, |
275 | .rate_min = PCSP_DEFAULT_SRATE, | 257 | .rate_min = PCSP_DEFAULT_SRATE, |
276 | .rate_max = PCSP_DEFAULT_SRATE, | 258 | .rate_max = PCSP_DEFAULT_SRATE, |
diff --git a/sound/drivers/pcsp/pcsp_mixer.c b/sound/drivers/pcsp/pcsp_mixer.c index 64a695fef74e..caeb0f57fcca 100644 --- a/sound/drivers/pcsp/pcsp_mixer.c +++ b/sound/drivers/pcsp/pcsp_mixer.c | |||
@@ -50,7 +50,8 @@ static int pcsp_treble_info(struct snd_kcontrol *kcontrol, | |||
50 | uinfo->value.enumerated.items = chip->max_treble + 1; | 50 | uinfo->value.enumerated.items = chip->max_treble + 1; |
51 | if (uinfo->value.enumerated.item > chip->max_treble) | 51 | if (uinfo->value.enumerated.item > chip->max_treble) |
52 | uinfo->value.enumerated.item = chip->max_treble; | 52 | uinfo->value.enumerated.item = chip->max_treble; |
53 | sprintf(uinfo->value.enumerated.name, "%d", PCSP_RATE()); | 53 | sprintf(uinfo->value.enumerated.name, "%d", |
54 | PCSP_CALC_RATE(uinfo->value.enumerated.item)); | ||
54 | return 0; | 55 | return 0; |
55 | } | 56 | } |
56 | 57 | ||
diff --git a/sound/isa/sb/sb_mixer.c b/sound/isa/sb/sb_mixer.c index 91d14224f6b3..73d4572d136b 100644 --- a/sound/isa/sb/sb_mixer.c +++ b/sound/isa/sb/sb_mixer.c | |||
@@ -925,7 +925,7 @@ static unsigned char als4000_saved_regs[] = { | |||
925 | static void save_mixer(struct snd_sb *chip, unsigned char *regs, int num_regs) | 925 | static void save_mixer(struct snd_sb *chip, unsigned char *regs, int num_regs) |
926 | { | 926 | { |
927 | unsigned char *val = chip->saved_regs; | 927 | unsigned char *val = chip->saved_regs; |
928 | snd_assert(num_regs > ARRAY_SIZE(chip->saved_regs), return); | 928 | snd_assert(num_regs <= ARRAY_SIZE(chip->saved_regs), return); |
929 | for (; num_regs; num_regs--) | 929 | for (; num_regs; num_regs--) |
930 | *val++ = snd_sbmixer_read(chip, *regs++); | 930 | *val++ = snd_sbmixer_read(chip, *regs++); |
931 | } | 931 | } |
@@ -933,7 +933,7 @@ static void save_mixer(struct snd_sb *chip, unsigned char *regs, int num_regs) | |||
933 | static void restore_mixer(struct snd_sb *chip, unsigned char *regs, int num_regs) | 933 | static void restore_mixer(struct snd_sb *chip, unsigned char *regs, int num_regs) |
934 | { | 934 | { |
935 | unsigned char *val = chip->saved_regs; | 935 | unsigned char *val = chip->saved_regs; |
936 | snd_assert(num_regs > ARRAY_SIZE(chip->saved_regs), return); | 936 | snd_assert(num_regs <= ARRAY_SIZE(chip->saved_regs), return); |
937 | for (; num_regs; num_regs--) | 937 | for (; num_regs; num_regs--) |
938 | snd_sbmixer_write(chip, *regs++, *val++); | 938 | snd_sbmixer_write(chip, *regs++, *val++); |
939 | } | 939 | } |
diff --git a/sound/oss/Kconfig b/sound/oss/Kconfig index 857008bb7167..3be2dc1025b5 100644 --- a/sound/oss/Kconfig +++ b/sound/oss/Kconfig | |||
@@ -79,7 +79,7 @@ config SOUND_TRIDENT | |||
79 | 79 | ||
80 | config SOUND_MSNDCLAS | 80 | config SOUND_MSNDCLAS |
81 | tristate "Support for Turtle Beach MultiSound Classic, Tahiti, Monterey" | 81 | tristate "Support for Turtle Beach MultiSound Classic, Tahiti, Monterey" |
82 | depends on SOUND_PRIME && (m || !STANDALONE) | 82 | depends on SOUND_PRIME && (m || !STANDALONE) && ISA |
83 | help | 83 | help |
84 | Say M here if you have a Turtle Beach MultiSound Classic, Tahiti or | 84 | Say M here if you have a Turtle Beach MultiSound Classic, Tahiti or |
85 | Monterey (not for the Pinnacle or Fiji). | 85 | Monterey (not for the Pinnacle or Fiji). |
@@ -143,7 +143,7 @@ config MSNDCLAS_IO | |||
143 | 143 | ||
144 | config SOUND_MSNDPIN | 144 | config SOUND_MSNDPIN |
145 | tristate "Support for Turtle Beach MultiSound Pinnacle, Fiji" | 145 | tristate "Support for Turtle Beach MultiSound Pinnacle, Fiji" |
146 | depends on SOUND_PRIME && (m || !STANDALONE) | 146 | depends on SOUND_PRIME && (m || !STANDALONE) && ISA |
147 | help | 147 | help |
148 | Say M here if you have a Turtle Beach MultiSound Pinnacle or Fiji. | 148 | Say M here if you have a Turtle Beach MultiSound Pinnacle or Fiji. |
149 | See <file:Documentation/sound/oss/MultiSound> for important information | 149 | See <file:Documentation/sound/oss/MultiSound> for important information |
diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c index 2da89810ca10..1292dcee072d 100644 --- a/sound/pci/ac97/ac97_patch.c +++ b/sound/pci/ac97/ac97_patch.c | |||
@@ -1971,6 +1971,9 @@ static int snd_ac97_ad1888_lohpsel_get(struct snd_kcontrol *kcontrol, struct snd | |||
1971 | 1971 | ||
1972 | val = ac97->regs[AC97_AD_MISC]; | 1972 | val = ac97->regs[AC97_AD_MISC]; |
1973 | ucontrol->value.integer.value[0] = !(val & AC97_AD198X_LOSEL); | 1973 | ucontrol->value.integer.value[0] = !(val & AC97_AD198X_LOSEL); |
1974 | if (ac97->spec.ad18xx.lo_as_master) | ||
1975 | ucontrol->value.integer.value[0] = | ||
1976 | !ucontrol->value.integer.value[0]; | ||
1974 | return 0; | 1977 | return 0; |
1975 | } | 1978 | } |
1976 | 1979 | ||
@@ -1979,8 +1982,10 @@ static int snd_ac97_ad1888_lohpsel_put(struct snd_kcontrol *kcontrol, struct snd | |||
1979 | struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); | 1982 | struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); |
1980 | unsigned short val; | 1983 | unsigned short val; |
1981 | 1984 | ||
1982 | val = !ucontrol->value.integer.value[0] | 1985 | val = !ucontrol->value.integer.value[0]; |
1983 | ? (AC97_AD198X_LOSEL | AC97_AD198X_HPSEL) : 0; | 1986 | if (ac97->spec.ad18xx.lo_as_master) |
1987 | val = !val; | ||
1988 | val = val ? (AC97_AD198X_LOSEL | AC97_AD198X_HPSEL) : 0; | ||
1984 | return snd_ac97_update_bits(ac97, AC97_AD_MISC, | 1989 | return snd_ac97_update_bits(ac97, AC97_AD_MISC, |
1985 | AC97_AD198X_LOSEL | AC97_AD198X_HPSEL, val); | 1990 | AC97_AD198X_LOSEL | AC97_AD198X_HPSEL, val); |
1986 | } | 1991 | } |
@@ -2031,7 +2036,7 @@ static void ad1888_update_jacks(struct snd_ac97 *ac97) | |||
2031 | { | 2036 | { |
2032 | unsigned short val = 0; | 2037 | unsigned short val = 0; |
2033 | /* clear LODIS if shared jack is to be used for Surround out */ | 2038 | /* clear LODIS if shared jack is to be used for Surround out */ |
2034 | if (is_shared_linein(ac97)) | 2039 | if (!ac97->spec.ad18xx.lo_as_master && is_shared_linein(ac97)) |
2035 | val |= (1 << 12); | 2040 | val |= (1 << 12); |
2036 | /* clear CLDIS if shared jack is to be used for C/LFE out */ | 2041 | /* clear CLDIS if shared jack is to be used for C/LFE out */ |
2037 | if (is_shared_micin(ac97)) | 2042 | if (is_shared_micin(ac97)) |
@@ -2067,9 +2072,13 @@ static const struct snd_kcontrol_new snd_ac97_ad1888_controls[] = { | |||
2067 | 2072 | ||
2068 | static int patch_ad1888_specific(struct snd_ac97 *ac97) | 2073 | static int patch_ad1888_specific(struct snd_ac97 *ac97) |
2069 | { | 2074 | { |
2070 | /* rename 0x04 as "Master" and 0x02 as "Master Surround" */ | 2075 | if (!ac97->spec.ad18xx.lo_as_master) { |
2071 | snd_ac97_rename_vol_ctl(ac97, "Master Playback", "Master Surround Playback"); | 2076 | /* rename 0x04 as "Master" and 0x02 as "Master Surround" */ |
2072 | snd_ac97_rename_vol_ctl(ac97, "Headphone Playback", "Master Playback"); | 2077 | snd_ac97_rename_vol_ctl(ac97, "Master Playback", |
2078 | "Master Surround Playback"); | ||
2079 | snd_ac97_rename_vol_ctl(ac97, "Headphone Playback", | ||
2080 | "Master Playback"); | ||
2081 | } | ||
2073 | return patch_build_controls(ac97, snd_ac97_ad1888_controls, ARRAY_SIZE(snd_ac97_ad1888_controls)); | 2082 | return patch_build_controls(ac97, snd_ac97_ad1888_controls, ARRAY_SIZE(snd_ac97_ad1888_controls)); |
2074 | } | 2083 | } |
2075 | 2084 | ||
@@ -2088,16 +2097,27 @@ static int patch_ad1888(struct snd_ac97 * ac97) | |||
2088 | 2097 | ||
2089 | patch_ad1881(ac97); | 2098 | patch_ad1881(ac97); |
2090 | ac97->build_ops = &patch_ad1888_build_ops; | 2099 | ac97->build_ops = &patch_ad1888_build_ops; |
2091 | /* Switch FRONT/SURROUND LINE-OUT/HP-OUT default connection */ | 2100 | |
2092 | /* it seems that most vendors connect line-out connector to headphone out of AC'97 */ | 2101 | /* |
2102 | * LO can be used as a real line-out on some devices, | ||
2103 | * and we need to revert the front/surround mixer switches | ||
2104 | */ | ||
2105 | if (ac97->subsystem_vendor == 0x1043 && | ||
2106 | ac97->subsystem_device == 0x1193) /* ASUS A9T laptop */ | ||
2107 | ac97->spec.ad18xx.lo_as_master = 1; | ||
2108 | |||
2109 | misc = snd_ac97_read(ac97, AC97_AD_MISC); | ||
2093 | /* AD-compatible mode */ | 2110 | /* AD-compatible mode */ |
2094 | /* Stereo mutes enabled */ | 2111 | /* Stereo mutes enabled */ |
2095 | misc = snd_ac97_read(ac97, AC97_AD_MISC); | 2112 | misc |= AC97_AD198X_MSPLT | AC97_AD198X_AC97NC; |
2096 | snd_ac97_write_cache(ac97, AC97_AD_MISC, misc | | 2113 | if (!ac97->spec.ad18xx.lo_as_master) |
2097 | AC97_AD198X_LOSEL | | 2114 | /* Switch FRONT/SURROUND LINE-OUT/HP-OUT default connection */ |
2098 | AC97_AD198X_HPSEL | | 2115 | /* it seems that most vendors connect line-out connector to |
2099 | AC97_AD198X_MSPLT | | 2116 | * headphone out of AC'97 |
2100 | AC97_AD198X_AC97NC); | 2117 | */ |
2118 | misc |= AC97_AD198X_LOSEL | AC97_AD198X_HPSEL; | ||
2119 | |||
2120 | snd_ac97_write_cache(ac97, AC97_AD_MISC, misc); | ||
2101 | ac97->flags |= AC97_STEREO_MUTES; | 2121 | ac97->flags |= AC97_STEREO_MUTES; |
2102 | return 0; | 2122 | return 0; |
2103 | } | 2123 | } |
diff --git a/sound/pci/aw2/aw2-alsa.c b/sound/pci/aw2/aw2-alsa.c index 56f87cd33c19..3f00ddf450f8 100644 --- a/sound/pci/aw2/aw2-alsa.c +++ b/sound/pci/aw2/aw2-alsa.c | |||
@@ -316,6 +316,8 @@ static int __devinit snd_aw2_create(struct snd_card *card, | |||
316 | return -ENOMEM; | 316 | return -ENOMEM; |
317 | } | 317 | } |
318 | 318 | ||
319 | /* (2) initialization of the chip hardware */ | ||
320 | snd_aw2_saa7146_setup(&chip->saa7146, chip->iobase_virt); | ||
319 | 321 | ||
320 | if (request_irq(pci->irq, snd_aw2_saa7146_interrupt, | 322 | if (request_irq(pci->irq, snd_aw2_saa7146_interrupt, |
321 | IRQF_SHARED, "Audiowerk2", chip)) { | 323 | IRQF_SHARED, "Audiowerk2", chip)) { |
@@ -329,8 +331,6 @@ static int __devinit snd_aw2_create(struct snd_card *card, | |||
329 | } | 331 | } |
330 | chip->irq = pci->irq; | 332 | chip->irq = pci->irq; |
331 | 333 | ||
332 | /* (2) initialization of the chip hardware */ | ||
333 | snd_aw2_saa7146_setup(&chip->saa7146, chip->iobase_virt); | ||
334 | err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops); | 334 | err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops); |
335 | if (err < 0) { | 335 | if (err < 0) { |
336 | free_irq(chip->irq, (void *)chip); | 336 | free_irq(chip->irq, (void *)chip); |
diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c index abde5b901884..548c9cc81af5 100644 --- a/sound/pci/emu10k1/emu10k1_main.c +++ b/sound/pci/emu10k1/emu10k1_main.c | |||
@@ -1818,13 +1818,6 @@ int __devinit snd_emu10k1_create(struct snd_card *card, | |||
1818 | } | 1818 | } |
1819 | emu->port = pci_resource_start(pci, 0); | 1819 | emu->port = pci_resource_start(pci, 0); |
1820 | 1820 | ||
1821 | if (request_irq(pci->irq, snd_emu10k1_interrupt, IRQF_SHARED, | ||
1822 | "EMU10K1", emu)) { | ||
1823 | err = -EBUSY; | ||
1824 | goto error; | ||
1825 | } | ||
1826 | emu->irq = pci->irq; | ||
1827 | |||
1828 | emu->max_cache_pages = max_cache_bytes >> PAGE_SHIFT; | 1821 | emu->max_cache_pages = max_cache_bytes >> PAGE_SHIFT; |
1829 | if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci), | 1822 | if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci), |
1830 | 32 * 1024, &emu->ptb_pages) < 0) { | 1823 | 32 * 1024, &emu->ptb_pages) < 0) { |
@@ -1887,6 +1880,14 @@ int __devinit snd_emu10k1_create(struct snd_card *card, | |||
1887 | emu->fx8010.etram_pages.area = NULL; | 1880 | emu->fx8010.etram_pages.area = NULL; |
1888 | emu->fx8010.etram_pages.bytes = 0; | 1881 | emu->fx8010.etram_pages.bytes = 0; |
1889 | 1882 | ||
1883 | /* irq handler must be registered after I/O ports are activated */ | ||
1884 | if (request_irq(pci->irq, snd_emu10k1_interrupt, IRQF_SHARED, | ||
1885 | "EMU10K1", emu)) { | ||
1886 | err = -EBUSY; | ||
1887 | goto error; | ||
1888 | } | ||
1889 | emu->irq = pci->irq; | ||
1890 | |||
1890 | /* | 1891 | /* |
1891 | * Init to 0x02109204 : | 1892 | * Init to 0x02109204 : |
1892 | * Clock accuracy = 0 (1000ppm) | 1893 | * Clock accuracy = 0 (1000ppm) |
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index e0a605adde42..a99e86d74278 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c | |||
@@ -2858,6 +2858,7 @@ static const char *ad1988_models[AD1988_MODEL_LAST] = { | |||
2858 | static struct snd_pci_quirk ad1988_cfg_tbl[] = { | 2858 | static struct snd_pci_quirk ad1988_cfg_tbl[] = { |
2859 | SND_PCI_QUIRK(0x1043, 0x81ec, "Asus P5B-DLX", AD1988_6STACK_DIG), | 2859 | SND_PCI_QUIRK(0x1043, 0x81ec, "Asus P5B-DLX", AD1988_6STACK_DIG), |
2860 | SND_PCI_QUIRK(0x1043, 0x81f6, "Asus M2N-SLI", AD1988_6STACK_DIG), | 2860 | SND_PCI_QUIRK(0x1043, 0x81f6, "Asus M2N-SLI", AD1988_6STACK_DIG), |
2861 | SND_PCI_QUIRK(0x1043, 0x8277, "Asus P5K-E/WIFI-AP", AD1988_6STACK_DIG), | ||
2861 | {} | 2862 | {} |
2862 | }; | 2863 | }; |
2863 | 2864 | ||
@@ -3643,33 +3644,17 @@ static struct snd_kcontrol_new ad1884a_laptop_mixers[] = { | |||
3643 | { } /* end */ | 3644 | { } /* end */ |
3644 | }; | 3645 | }; |
3645 | 3646 | ||
3646 | static struct hda_input_mux ad1884a_mobile_capture_source = { | ||
3647 | .num_items = 2, | ||
3648 | .items = { | ||
3649 | { "Mic", 0x1 }, /* port-C */ | ||
3650 | { "Mix", 0x3 }, | ||
3651 | }, | ||
3652 | }; | ||
3653 | |||
3654 | static struct snd_kcontrol_new ad1884a_mobile_mixers[] = { | 3647 | static struct snd_kcontrol_new ad1884a_mobile_mixers[] = { |
3655 | HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT), | 3648 | HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT), |
3656 | HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT), | 3649 | HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT), |
3657 | HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT), | 3650 | HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT), |
3658 | HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT), | 3651 | HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT), |
3659 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x01, HDA_INPUT), | ||
3660 | HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x01, HDA_INPUT), | ||
3661 | HDA_CODEC_VOLUME("Beep Playback Volume", 0x20, 0x03, HDA_INPUT), | 3652 | HDA_CODEC_VOLUME("Beep Playback Volume", 0x20, 0x03, HDA_INPUT), |
3662 | HDA_CODEC_MUTE("Beep Playback Switch", 0x20, 0x03, HDA_INPUT), | 3653 | HDA_CODEC_MUTE("Beep Playback Switch", 0x20, 0x03, HDA_INPUT), |
3663 | HDA_CODEC_VOLUME("Mic Boost", 0x15, 0x0, HDA_INPUT), | 3654 | HDA_CODEC_VOLUME("Mic Capture Volume", 0x14, 0x0, HDA_INPUT), |
3655 | HDA_CODEC_VOLUME("Internal Mic Capture Volume", 0x15, 0x0, HDA_INPUT), | ||
3664 | HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT), | 3656 | HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT), |
3665 | HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT), | 3657 | HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT), |
3666 | { | ||
3667 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
3668 | .name = "Capture Source", | ||
3669 | .info = ad198x_mux_enum_info, | ||
3670 | .get = ad198x_mux_enum_get, | ||
3671 | .put = ad198x_mux_enum_put, | ||
3672 | }, | ||
3673 | { } /* end */ | 3658 | { } /* end */ |
3674 | }; | 3659 | }; |
3675 | 3660 | ||
@@ -3686,14 +3671,31 @@ static void ad1884a_hp_automute(struct hda_codec *codec) | |||
3686 | present ? 0x00 : 0x02); | 3671 | present ? 0x00 : 0x02); |
3687 | } | 3672 | } |
3688 | 3673 | ||
3674 | /* switch to external mic if plugged */ | ||
3675 | static void ad1884a_hp_automic(struct hda_codec *codec) | ||
3676 | { | ||
3677 | unsigned int present; | ||
3678 | |||
3679 | present = snd_hda_codec_read(codec, 0x14, 0, | ||
3680 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | ||
3681 | snd_hda_codec_write(codec, 0x0c, 0, AC_VERB_SET_CONNECT_SEL, | ||
3682 | present ? 0 : 1); | ||
3683 | } | ||
3684 | |||
3689 | #define AD1884A_HP_EVENT 0x37 | 3685 | #define AD1884A_HP_EVENT 0x37 |
3686 | #define AD1884A_MIC_EVENT 0x36 | ||
3690 | 3687 | ||
3691 | /* unsolicited event for HP jack sensing */ | 3688 | /* unsolicited event for HP jack sensing */ |
3692 | static void ad1884a_hp_unsol_event(struct hda_codec *codec, unsigned int res) | 3689 | static void ad1884a_hp_unsol_event(struct hda_codec *codec, unsigned int res) |
3693 | { | 3690 | { |
3694 | if ((res >> 26) != AD1884A_HP_EVENT) | 3691 | switch (res >> 26) { |
3695 | return; | 3692 | case AD1884A_HP_EVENT: |
3696 | ad1884a_hp_automute(codec); | 3693 | ad1884a_hp_automute(codec); |
3694 | break; | ||
3695 | case AD1884A_MIC_EVENT: | ||
3696 | ad1884a_hp_automic(codec); | ||
3697 | break; | ||
3698 | } | ||
3697 | } | 3699 | } |
3698 | 3700 | ||
3699 | /* initialize jack-sensing, too */ | 3701 | /* initialize jack-sensing, too */ |
@@ -3701,6 +3703,7 @@ static int ad1884a_hp_init(struct hda_codec *codec) | |||
3701 | { | 3703 | { |
3702 | ad198x_init(codec); | 3704 | ad198x_init(codec); |
3703 | ad1884a_hp_automute(codec); | 3705 | ad1884a_hp_automute(codec); |
3706 | ad1884a_hp_automic(codec); | ||
3704 | return 0; | 3707 | return 0; |
3705 | } | 3708 | } |
3706 | 3709 | ||
@@ -3714,10 +3717,15 @@ static struct hda_verb ad1884a_laptop_verbs[] = { | |||
3714 | /* Port-F pin */ | 3717 | /* Port-F pin */ |
3715 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | 3718 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, |
3716 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | 3719 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, |
3720 | /* Port-C pin - internal mic-in */ | ||
3721 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
3722 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */ | ||
3723 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */ | ||
3717 | /* analog mix */ | 3724 | /* analog mix */ |
3718 | {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, | 3725 | {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, |
3719 | /* unsolicited event for pin-sense */ | 3726 | /* unsolicited event for pin-sense */ |
3720 | {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT}, | 3727 | {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT}, |
3728 | {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_MIC_EVENT}, | ||
3721 | { } /* end */ | 3729 | { } /* end */ |
3722 | }; | 3730 | }; |
3723 | 3731 | ||
@@ -3877,7 +3885,6 @@ static int patch_ad1884a(struct hda_codec *codec) | |||
3877 | spec->mixers[0] = ad1884a_mobile_mixers; | 3885 | spec->mixers[0] = ad1884a_mobile_mixers; |
3878 | spec->init_verbs[spec->num_init_verbs++] = ad1884a_laptop_verbs; | 3886 | spec->init_verbs[spec->num_init_verbs++] = ad1884a_laptop_verbs; |
3879 | spec->multiout.dig_out_nid = 0; | 3887 | spec->multiout.dig_out_nid = 0; |
3880 | spec->input_mux = &ad1884a_mobile_capture_source; | ||
3881 | codec->patch_ops.unsol_event = ad1884a_hp_unsol_event; | 3888 | codec->patch_ops.unsol_event = ad1884a_hp_unsol_event; |
3882 | codec->patch_ops.init = ad1884a_hp_init; | 3889 | codec->patch_ops.init = ad1884a_hp_init; |
3883 | break; | 3890 | break; |
diff --git a/sound/pci/hda/patch_cmedia.c b/sound/pci/hda/patch_cmedia.c index c73ce074a6ea..6ef57fbfb6eb 100644 --- a/sound/pci/hda/patch_cmedia.c +++ b/sound/pci/hda/patch_cmedia.c | |||
@@ -611,6 +611,7 @@ static const char *cmi9880_models[CMI_MODELS] = { | |||
611 | 611 | ||
612 | static struct snd_pci_quirk cmi9880_cfg_tbl[] = { | 612 | static struct snd_pci_quirk cmi9880_cfg_tbl[] = { |
613 | SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", CMI_FULL_DIG), | 613 | SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", CMI_FULL_DIG), |
614 | SND_PCI_QUIRK(0x1854, 0x002b, "LG LS75", CMI_MINIMAL), | ||
614 | SND_PCI_QUIRK(0x1854, 0x0032, "LG", CMI_FULL_DIG), | 615 | SND_PCI_QUIRK(0x1854, 0x0032, "LG", CMI_FULL_DIG), |
615 | {} /* terminator */ | 616 | {} /* terminator */ |
616 | }; | 617 | }; |
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 6d4df45e81e0..b0a2a262ece2 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -853,6 +853,7 @@ do_sku: | |||
853 | case 0x10ec0269: | 853 | case 0x10ec0269: |
854 | case 0x10ec0862: | 854 | case 0x10ec0862: |
855 | case 0x10ec0662: | 855 | case 0x10ec0662: |
856 | case 0x10ec0889: | ||
856 | snd_hda_codec_write(codec, 0x14, 0, | 857 | snd_hda_codec_write(codec, 0x14, 0, |
857 | AC_VERB_SET_EAPD_BTLENABLE, 2); | 858 | AC_VERB_SET_EAPD_BTLENABLE, 2); |
858 | snd_hda_codec_write(codec, 0x15, 0, | 859 | snd_hda_codec_write(codec, 0x15, 0, |
@@ -877,6 +878,7 @@ do_sku: | |||
877 | case 0x10ec0883: | 878 | case 0x10ec0883: |
878 | case 0x10ec0885: | 879 | case 0x10ec0885: |
879 | case 0x10ec0888: | 880 | case 0x10ec0888: |
881 | case 0x10ec0889: | ||
880 | snd_hda_codec_write(codec, 0x20, 0, | 882 | snd_hda_codec_write(codec, 0x20, 0, |
881 | AC_VERB_SET_COEF_INDEX, 7); | 883 | AC_VERB_SET_COEF_INDEX, 7); |
882 | tmp = snd_hda_codec_read(codec, 0x20, 0, | 884 | tmp = snd_hda_codec_read(codec, 0x20, 0, |
@@ -940,7 +942,6 @@ do_sku: | |||
940 | AC_VERB_SET_UNSOLICITED_ENABLE, | 942 | AC_VERB_SET_UNSOLICITED_ENABLE, |
941 | AC_USRSP_EN | ALC880_HP_EVENT); | 943 | AC_USRSP_EN | ALC880_HP_EVENT); |
942 | spec->unsol_event = alc_sku_unsol_event; | 944 | spec->unsol_event = alc_sku_unsol_event; |
943 | spec->init_hook = alc_sku_automute; | ||
944 | } | 945 | } |
945 | 946 | ||
946 | /* | 947 | /* |
@@ -2981,7 +2982,7 @@ static struct snd_pci_quirk alc880_cfg_tbl[] = { | |||
2981 | /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */ | 2982 | /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */ |
2982 | SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG), | 2983 | SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG), |
2983 | SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG), | 2984 | SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG), |
2984 | SND_PCI_QUIRK(0x1043, 0x814e, "ASUS", ALC880_ASUS), | 2985 | SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG), |
2985 | SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG), | 2986 | SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG), |
2986 | SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST), | 2987 | SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST), |
2987 | SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST), | 2988 | SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST), |
@@ -7743,6 +7744,7 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = { | |||
7743 | SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP), | 7744 | SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP), |
7744 | SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG), | 7745 | SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG), |
7745 | SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG), | 7746 | SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG), |
7747 | SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG), | ||
7746 | SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG), | 7748 | SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG), |
7747 | SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC), | 7749 | SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC), |
7748 | SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD), | 7750 | SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD), |
@@ -8640,6 +8642,7 @@ static struct hda_verb alc262_sony_unsol_verbs[] = { | |||
8640 | 8642 | ||
8641 | {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, | 8643 | {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, |
8642 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | 8644 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, |
8645 | {} | ||
8643 | }; | 8646 | }; |
8644 | 8647 | ||
8645 | /* mute/unmute internal speaker according to the hp jack and mute state */ | 8648 | /* mute/unmute internal speaker according to the hp jack and mute state */ |
@@ -8757,35 +8760,39 @@ static struct hda_input_mux alc262_HP_D7000_capture_source = { | |||
8757 | }, | 8760 | }, |
8758 | }; | 8761 | }; |
8759 | 8762 | ||
8760 | /* mute/unmute internal speaker according to the hp jack and mute state */ | 8763 | /* mute/unmute internal speaker according to the hp jacks and mute state */ |
8761 | static void alc262_fujitsu_automute(struct hda_codec *codec, int force) | 8764 | static void alc262_fujitsu_automute(struct hda_codec *codec, int force) |
8762 | { | 8765 | { |
8763 | struct alc_spec *spec = codec->spec; | 8766 | struct alc_spec *spec = codec->spec; |
8764 | unsigned int mute; | 8767 | unsigned int mute; |
8765 | 8768 | ||
8766 | if (force || !spec->sense_updated) { | 8769 | if (force || !spec->sense_updated) { |
8767 | unsigned int present_int_hp, present_dock_hp; | 8770 | unsigned int present; |
8768 | /* need to execute and sync at first */ | 8771 | /* need to execute and sync at first */ |
8769 | snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0); | 8772 | snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0); |
8770 | present_int_hp = snd_hda_codec_read(codec, 0x14, 0, | 8773 | /* check laptop HP jack */ |
8771 | AC_VERB_GET_PIN_SENSE, 0); | 8774 | present = snd_hda_codec_read(codec, 0x14, 0, |
8772 | snd_hda_codec_read(codec, 0x1B, 0, AC_VERB_SET_PIN_SENSE, 0); | 8775 | AC_VERB_GET_PIN_SENSE, 0); |
8773 | present_dock_hp = snd_hda_codec_read(codec, 0x1b, 0, | 8776 | /* need to execute and sync at first */ |
8774 | AC_VERB_GET_PIN_SENSE, 0); | 8777 | snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0); |
8775 | spec->jack_present = (present_int_hp & 0x80000000) != 0; | 8778 | /* check docking HP jack */ |
8776 | spec->jack_present |= (present_dock_hp & 0x80000000) != 0; | 8779 | present |= snd_hda_codec_read(codec, 0x1b, 0, |
8780 | AC_VERB_GET_PIN_SENSE, 0); | ||
8781 | if (present & AC_PINSENSE_PRESENCE) | ||
8782 | spec->jack_present = 1; | ||
8783 | else | ||
8784 | spec->jack_present = 0; | ||
8777 | spec->sense_updated = 1; | 8785 | spec->sense_updated = 1; |
8778 | } | 8786 | } |
8779 | if (spec->jack_present) { | 8787 | /* unmute internal speaker only if both HPs are unplugged and |
8780 | /* mute internal speaker */ | 8788 | * master switch is on |
8781 | snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, | 8789 | */ |
8782 | HDA_AMP_MUTE, HDA_AMP_MUTE); | 8790 | if (spec->jack_present) |
8783 | } else { | 8791 | mute = HDA_AMP_MUTE; |
8784 | /* unmute internal speaker if necessary */ | 8792 | else |
8785 | mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0); | 8793 | mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0); |
8786 | snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, | 8794 | snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, |
8787 | HDA_AMP_MUTE, mute); | 8795 | HDA_AMP_MUTE, mute); |
8788 | } | ||
8789 | } | 8796 | } |
8790 | 8797 | ||
8791 | /* unsolicited event for HP jack sensing */ | 8798 | /* unsolicited event for HP jack sensing */ |
@@ -8797,6 +8804,11 @@ static void alc262_fujitsu_unsol_event(struct hda_codec *codec, | |||
8797 | alc262_fujitsu_automute(codec, 1); | 8804 | alc262_fujitsu_automute(codec, 1); |
8798 | } | 8805 | } |
8799 | 8806 | ||
8807 | static void alc262_fujitsu_init_hook(struct hda_codec *codec) | ||
8808 | { | ||
8809 | alc262_fujitsu_automute(codec, 1); | ||
8810 | } | ||
8811 | |||
8800 | /* bind volumes of both NID 0x0c and 0x0d */ | 8812 | /* bind volumes of both NID 0x0c and 0x0d */ |
8801 | static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = { | 8813 | static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = { |
8802 | .ops = &snd_hda_bind_vol, | 8814 | .ops = &snd_hda_bind_vol, |
@@ -9570,6 +9582,7 @@ static struct alc_config_preset alc262_presets[] = { | |||
9570 | .channel_mode = alc262_modes, | 9582 | .channel_mode = alc262_modes, |
9571 | .input_mux = &alc262_fujitsu_capture_source, | 9583 | .input_mux = &alc262_fujitsu_capture_source, |
9572 | .unsol_event = alc262_fujitsu_unsol_event, | 9584 | .unsol_event = alc262_fujitsu_unsol_event, |
9585 | .init_hook = alc262_fujitsu_init_hook, | ||
9573 | }, | 9586 | }, |
9574 | [ALC262_HP_BPC] = { | 9587 | [ALC262_HP_BPC] = { |
9575 | .mixers = { alc262_HP_BPC_mixer }, | 9588 | .mixers = { alc262_HP_BPC_mixer }, |
@@ -10500,6 +10513,7 @@ static struct snd_pci_quirk alc268_cfg_tbl[] = { | |||
10500 | SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST), | 10513 | SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST), |
10501 | SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA), | 10514 | SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA), |
10502 | SND_PCI_QUIRK(0x1179, 0xff50, "TOSHIBA A305", ALC268_TOSHIBA), | 10515 | SND_PCI_QUIRK(0x1179, 0xff50, "TOSHIBA A305", ALC268_TOSHIBA), |
10516 | SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA), | ||
10503 | SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER), | 10517 | SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER), |
10504 | SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1), | 10518 | SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1), |
10505 | SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO), | 10519 | SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO), |
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 393f7fd2b1be..a4f44a00bae8 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c | |||
@@ -840,7 +840,7 @@ static struct snd_kcontrol_new stac92hd71bxx_mixer[] = { | |||
840 | static struct snd_kcontrol_new stac925x_mixer[] = { | 840 | static struct snd_kcontrol_new stac925x_mixer[] = { |
841 | STAC_INPUT_SOURCE(1), | 841 | STAC_INPUT_SOURCE(1), |
842 | HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_OUTPUT), | 842 | HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_OUTPUT), |
843 | HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_OUTPUT), | 843 | HDA_CODEC_MUTE("Capture Switch", 0x14, 0, HDA_OUTPUT), |
844 | HDA_CODEC_VOLUME("Capture Mux Volume", 0x0f, 0, HDA_OUTPUT), | 844 | HDA_CODEC_VOLUME("Capture Mux Volume", 0x0f, 0, HDA_OUTPUT), |
845 | { } /* end */ | 845 | { } /* end */ |
846 | }; | 846 | }; |
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index 52b1d81a26f7..e7e43524f8c7 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c | |||
@@ -447,6 +447,23 @@ static struct hda_pcm_stream vt1708_pcm_analog_playback = { | |||
447 | }, | 447 | }, |
448 | }; | 448 | }; |
449 | 449 | ||
450 | static struct hda_pcm_stream vt1708_pcm_analog_s16_playback = { | ||
451 | .substreams = 1, | ||
452 | .channels_min = 2, | ||
453 | .channels_max = 8, | ||
454 | .nid = 0x10, /* NID to query formats and rates */ | ||
455 | /* We got noisy outputs on the right channel on VT1708 when | ||
456 | * 24bit samples are used. Until any workaround is found, | ||
457 | * disable the 24bit format, so far. | ||
458 | */ | ||
459 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | ||
460 | .ops = { | ||
461 | .open = via_playback_pcm_open, | ||
462 | .prepare = via_playback_pcm_prepare, | ||
463 | .cleanup = via_playback_pcm_cleanup | ||
464 | }, | ||
465 | }; | ||
466 | |||
450 | static struct hda_pcm_stream vt1708_pcm_analog_capture = { | 467 | static struct hda_pcm_stream vt1708_pcm_analog_capture = { |
451 | .substreams = 2, | 468 | .substreams = 2, |
452 | .channels_min = 2, | 469 | .channels_min = 2, |
@@ -899,6 +916,9 @@ static int patch_vt1708(struct hda_codec *codec) | |||
899 | 916 | ||
900 | spec->stream_name_analog = "VT1708 Analog"; | 917 | spec->stream_name_analog = "VT1708 Analog"; |
901 | spec->stream_analog_playback = &vt1708_pcm_analog_playback; | 918 | spec->stream_analog_playback = &vt1708_pcm_analog_playback; |
919 | /* disable 32bit format on VT1708 */ | ||
920 | if (codec->vendor_id == 0x11061708) | ||
921 | spec->stream_analog_playback = &vt1708_pcm_analog_s16_playback; | ||
902 | spec->stream_analog_capture = &vt1708_pcm_analog_capture; | 922 | spec->stream_analog_capture = &vt1708_pcm_analog_capture; |
903 | 923 | ||
904 | spec->stream_name_digital = "VT1708 Digital"; | 924 | spec->stream_name_digital = "VT1708 Digital"; |
diff --git a/sound/pci/oxygen/oxygen_mixer.c b/sound/pci/oxygen/oxygen_mixer.c index cc0cddadd589..6facac5aed90 100644 --- a/sound/pci/oxygen/oxygen_mixer.c +++ b/sound/pci/oxygen/oxygen_mixer.c | |||
@@ -936,11 +936,13 @@ static int add_controls(struct oxygen *chip, | |||
936 | 936 | ||
937 | for (i = 0; i < count; ++i) { | 937 | for (i = 0; i < count; ++i) { |
938 | template = controls[i]; | 938 | template = controls[i]; |
939 | err = chip->model->control_filter(&template); | 939 | if (chip->model->control_filter) { |
940 | if (err < 0) | 940 | err = chip->model->control_filter(&template); |
941 | return err; | 941 | if (err < 0) |
942 | if (err == 1) | 942 | return err; |
943 | continue; | 943 | if (err == 1) |
944 | continue; | ||
945 | } | ||
944 | if (!strcmp(template.name, "Master Playback Volume") && | 946 | if (!strcmp(template.name, "Master Playback Volume") && |
945 | chip->model->dac_tlv) { | 947 | chip->model->dac_tlv) { |
946 | template.tlv.p = chip->model->dac_tlv; | 948 | template.tlv.p = chip->model->dac_tlv; |
diff --git a/sound/usb/caiaq/caiaq-device.c b/sound/usb/caiaq/caiaq-device.c index e97d8b2ac16a..a972f77bd785 100644 --- a/sound/usb/caiaq/caiaq-device.c +++ b/sound/usb/caiaq/caiaq-device.c | |||
@@ -351,8 +351,8 @@ static struct snd_card* create_card(struct usb_device* usb_dev) | |||
351 | dev = caiaqdev(card); | 351 | dev = caiaqdev(card); |
352 | dev->chip.dev = usb_dev; | 352 | dev->chip.dev = usb_dev; |
353 | dev->chip.card = card; | 353 | dev->chip.card = card; |
354 | dev->chip.usb_id = USB_ID(usb_dev->descriptor.idVendor, | 354 | dev->chip.usb_id = USB_ID(le16_to_cpu(usb_dev->descriptor.idVendor), |
355 | usb_dev->descriptor.idProduct); | 355 | le16_to_cpu(usb_dev->descriptor.idProduct)); |
356 | spin_lock_init(&dev->spinlock); | 356 | spin_lock_init(&dev->spinlock); |
357 | snd_card_set_dev(card, &usb_dev->dev); | 357 | snd_card_set_dev(card, &usb_dev->dev); |
358 | 358 | ||