aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
Diffstat (limited to 'sound')
-rw-r--r--sound/Kconfig5
-rw-r--r--sound/core/sound.c8
-rw-r--r--sound/drivers/Kconfig15
-rw-r--r--sound/drivers/pcsp/pcsp.c2
-rw-r--r--sound/drivers/pcsp/pcsp_lib.c58
-rw-r--r--sound/oss/Kconfig4
-rw-r--r--sound/pci/hda/patch_realtek.c48
-rw-r--r--sound/usb/caiaq/caiaq-device.c4
8 files changed, 70 insertions, 74 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
36source "sound/oss/dmasound/Kconfig" 31source "sound/oss/dmasound/Kconfig"
37 32
38if !M68K 33if !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
7config SND_PCSP 7config 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
27config SND_MPU401_UART 38config 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_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);
18MODULE_PARM_DESC(nforce_wa, "Apply NForce chipset workaround " 17MODULE_PARM_DESC(nforce_wa, "Apply NForce chipset workaround "
19 "(expect bad sound)"); 18 "(expect bad sound)");
20 19
21static 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 */
44static DECLARE_TASKLET(pcsp_start_timer_tasklet, pcsp_start_timer, 0);
45 21
46enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle) 22enum 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)
146exit_nr_unlock2: 124exit_nr_unlock2:
147 snd_pcm_stream_unlock(substream); 125 snd_pcm_stream_unlock(substream);
148exit_nr_unlock1: 126exit_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
173static void pcsp_stop_playing(struct snd_pcsp *chip) 151static 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/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
80config SOUND_MSNDCLAS 80config 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
144config SOUND_MSNDPIN 144config 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/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 6d4df45e81e0..864b2f598c38 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -2981,7 +2981,7 @@ static struct snd_pci_quirk alc880_cfg_tbl[] = {
2981 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */ 2981 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
2982 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG), 2982 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
2983 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG), 2983 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
2984 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS", ALC880_ASUS), 2984 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
2985 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG), 2985 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
2986 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST), 2986 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
2987 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST), 2987 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
@@ -8757,35 +8757,39 @@ static struct hda_input_mux alc262_HP_D7000_capture_source = {
8757 }, 8757 },
8758}; 8758};
8759 8759
8760/* mute/unmute internal speaker according to the hp jack and mute state */ 8760/* mute/unmute internal speaker according to the hp jacks and mute state */
8761static void alc262_fujitsu_automute(struct hda_codec *codec, int force) 8761static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
8762{ 8762{
8763 struct alc_spec *spec = codec->spec; 8763 struct alc_spec *spec = codec->spec;
8764 unsigned int mute; 8764 unsigned int mute;
8765 8765
8766 if (force || !spec->sense_updated) { 8766 if (force || !spec->sense_updated) {
8767 unsigned int present_int_hp, present_dock_hp; 8767 unsigned int present;
8768 /* need to execute and sync at first */ 8768 /* need to execute and sync at first */
8769 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0); 8769 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
8770 present_int_hp = snd_hda_codec_read(codec, 0x14, 0, 8770 /* check laptop HP jack */
8771 AC_VERB_GET_PIN_SENSE, 0); 8771 present = snd_hda_codec_read(codec, 0x14, 0,
8772 snd_hda_codec_read(codec, 0x1B, 0, AC_VERB_SET_PIN_SENSE, 0); 8772 AC_VERB_GET_PIN_SENSE, 0);
8773 present_dock_hp = snd_hda_codec_read(codec, 0x1b, 0, 8773 /* need to execute and sync at first */
8774 AC_VERB_GET_PIN_SENSE, 0); 8774 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
8775 spec->jack_present = (present_int_hp & 0x80000000) != 0; 8775 /* check docking HP jack */
8776 spec->jack_present |= (present_dock_hp & 0x80000000) != 0; 8776 present |= snd_hda_codec_read(codec, 0x1b, 0,
8777 AC_VERB_GET_PIN_SENSE, 0);
8778 if (present & AC_PINSENSE_PRESENCE)
8779 spec->jack_present = 1;
8780 else
8781 spec->jack_present = 0;
8777 spec->sense_updated = 1; 8782 spec->sense_updated = 1;
8778 } 8783 }
8779 if (spec->jack_present) { 8784 /* unmute internal speaker only if both HPs are unplugged and
8780 /* mute internal speaker */ 8785 * master switch is on
8781 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 8786 */
8782 HDA_AMP_MUTE, HDA_AMP_MUTE); 8787 if (spec->jack_present)
8783 } else { 8788 mute = HDA_AMP_MUTE;
8784 /* unmute internal speaker if necessary */ 8789 else
8785 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0); 8790 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
8786 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 8791 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8787 HDA_AMP_MUTE, mute); 8792 HDA_AMP_MUTE, mute);
8788 }
8789} 8793}
8790 8794
8791/* unsolicited event for HP jack sensing */ 8795/* unsolicited event for HP jack sensing */
@@ -8797,6 +8801,11 @@ static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
8797 alc262_fujitsu_automute(codec, 1); 8801 alc262_fujitsu_automute(codec, 1);
8798} 8802}
8799 8803
8804static void alc262_fujitsu_init_hook(struct hda_codec *codec)
8805{
8806 alc262_fujitsu_automute(codec, 1);
8807}
8808
8800/* bind volumes of both NID 0x0c and 0x0d */ 8809/* bind volumes of both NID 0x0c and 0x0d */
8801static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = { 8810static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
8802 .ops = &snd_hda_bind_vol, 8811 .ops = &snd_hda_bind_vol,
@@ -9570,6 +9579,7 @@ static struct alc_config_preset alc262_presets[] = {
9570 .channel_mode = alc262_modes, 9579 .channel_mode = alc262_modes,
9571 .input_mux = &alc262_fujitsu_capture_source, 9580 .input_mux = &alc262_fujitsu_capture_source,
9572 .unsol_event = alc262_fujitsu_unsol_event, 9581 .unsol_event = alc262_fujitsu_unsol_event,
9582 .init_hook = alc262_fujitsu_init_hook,
9573 }, 9583 },
9574 [ALC262_HP_BPC] = { 9584 [ALC262_HP_BPC] = {
9575 .mixers = { alc262_HP_BPC_mixer }, 9585 .mixers = { alc262_HP_BPC_mixer },
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