diff options
author | Stas Sergeev <stsp@aknet.ru> | 2009-11-01 05:13:19 -0500 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2009-11-01 05:13:19 -0500 |
commit | bcc2c6b7cb320d10c7fcccd87dce87f4384b4332 (patch) | |
tree | 24663a166d0f4d6901eafad9294e7e54647b5442 | |
parent | e87a3dd33eab30b4db539500064a9584867e4f2c (diff) |
ALSA: snd-pcsp: add nopcm mode
Currently, if the high-res timers are unavailable, snd-pcsp does not
initialize. People who choose it over pcspkr, loose their console beeps
in that case and get annoyed.
With this patch, the console beeps remain regardless of the high-res
timers. Additionally, the "nopcm" modparam is added to forcibly
disable the PCM capabilities of the driver.
Signed-off-by: Stas Sergeev <stsp@aknet.ru>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r-- | Documentation/sound/alsa/ALSA-Configuration.txt | 1 | ||||
-rw-r--r-- | sound/drivers/pcsp/pcsp.c | 32 | ||||
-rw-r--r-- | sound/drivers/pcsp/pcsp.h | 2 | ||||
-rw-r--r-- | sound/drivers/pcsp/pcsp_mixer.c | 33 |
4 files changed, 48 insertions, 20 deletions
diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt index 6de56d134abb..780c213c600f 100644 --- a/Documentation/sound/alsa/ALSA-Configuration.txt +++ b/Documentation/sound/alsa/ALSA-Configuration.txt | |||
@@ -1454,6 +1454,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. | |||
1454 | 1454 | ||
1455 | Module for internal PC-Speaker. | 1455 | Module for internal PC-Speaker. |
1456 | 1456 | ||
1457 | nopcm - Disable PC-Speaker PCM sound. Only beeps remain. | ||
1457 | nforce_wa - enable NForce chipset workaround. Expect bad sound. | 1458 | nforce_wa - enable NForce chipset workaround. Expect bad sound. |
1458 | 1459 | ||
1459 | This module supports system beeps, some kind of PCM playback and | 1460 | This module supports system beeps, some kind of PCM playback and |
diff --git a/sound/drivers/pcsp/pcsp.c b/sound/drivers/pcsp/pcsp.c index b60cef257b58..f165c77d6273 100644 --- a/sound/drivers/pcsp/pcsp.c +++ b/sound/drivers/pcsp/pcsp.c | |||
@@ -26,6 +26,7 @@ MODULE_ALIAS("platform:pcspkr"); | |||
26 | static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */ | 26 | static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */ |
27 | static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */ | 27 | static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */ |
28 | static int enable = SNDRV_DEFAULT_ENABLE1; /* Enable this card */ | 28 | static int enable = SNDRV_DEFAULT_ENABLE1; /* Enable this card */ |
29 | static int nopcm; /* Disable PCM capability of the driver */ | ||
29 | 30 | ||
30 | module_param(index, int, 0444); | 31 | module_param(index, int, 0444); |
31 | MODULE_PARM_DESC(index, "Index value for pcsp soundcard."); | 32 | MODULE_PARM_DESC(index, "Index value for pcsp soundcard."); |
@@ -33,6 +34,8 @@ module_param(id, charp, 0444); | |||
33 | MODULE_PARM_DESC(id, "ID string for pcsp soundcard."); | 34 | MODULE_PARM_DESC(id, "ID string for pcsp soundcard."); |
34 | module_param(enable, bool, 0444); | 35 | module_param(enable, bool, 0444); |
35 | MODULE_PARM_DESC(enable, "Enable PC-Speaker sound."); | 36 | MODULE_PARM_DESC(enable, "Enable PC-Speaker sound."); |
37 | module_param(nopcm, bool, 0444); | ||
38 | MODULE_PARM_DESC(nopcm, "Disable PC-Speaker PCM sound. Only beeps remain."); | ||
36 | 39 | ||
37 | struct snd_pcsp pcsp_chip; | 40 | struct snd_pcsp pcsp_chip; |
38 | 41 | ||
@@ -43,13 +46,16 @@ static int __devinit snd_pcsp_create(struct snd_card *card) | |||
43 | int err; | 46 | int err; |
44 | int div, min_div, order; | 47 | int div, min_div, order; |
45 | 48 | ||
46 | hrtimer_get_res(CLOCK_MONOTONIC, &tp); | 49 | if (!nopcm) { |
47 | if (tp.tv_sec || tp.tv_nsec > PCSP_MAX_PERIOD_NS) { | 50 | hrtimer_get_res(CLOCK_MONOTONIC, &tp); |
48 | printk(KERN_ERR "PCSP: Timer resolution is not sufficient " | 51 | if (tp.tv_sec || tp.tv_nsec > PCSP_MAX_PERIOD_NS) { |
49 | "(%linS)\n", tp.tv_nsec); | 52 | printk(KERN_ERR "PCSP: Timer resolution is not sufficient " |
50 | printk(KERN_ERR "PCSP: Make sure you have HPET and ACPI " | 53 | "(%linS)\n", tp.tv_nsec); |
51 | "enabled.\n"); | 54 | printk(KERN_ERR "PCSP: Make sure you have HPET and ACPI " |
52 | return -EIO; | 55 | "enabled.\n"); |
56 | printk(KERN_ERR "PCSP: Turned into nopcm mode.\n"); | ||
57 | nopcm = 1; | ||
58 | } | ||
53 | } | 59 | } |
54 | 60 | ||
55 | if (loops_per_jiffy >= PCSP_MIN_LPJ && tp.tv_nsec <= PCSP_MIN_PERIOD_NS) | 61 | if (loops_per_jiffy >= PCSP_MIN_LPJ && tp.tv_nsec <= PCSP_MIN_PERIOD_NS) |
@@ -107,12 +113,14 @@ static int __devinit snd_card_pcsp_probe(int devnum, struct device *dev) | |||
107 | snd_card_free(card); | 113 | snd_card_free(card); |
108 | return err; | 114 | return err; |
109 | } | 115 | } |
110 | err = snd_pcsp_new_pcm(&pcsp_chip); | 116 | if (!nopcm) { |
111 | if (err < 0) { | 117 | err = snd_pcsp_new_pcm(&pcsp_chip); |
112 | snd_card_free(card); | 118 | if (err < 0) { |
113 | return err; | 119 | snd_card_free(card); |
120 | return err; | ||
121 | } | ||
114 | } | 122 | } |
115 | err = snd_pcsp_new_mixer(&pcsp_chip); | 123 | err = snd_pcsp_new_mixer(&pcsp_chip, nopcm); |
116 | if (err < 0) { | 124 | if (err < 0) { |
117 | snd_card_free(card); | 125 | snd_card_free(card); |
118 | return err; | 126 | return err; |
diff --git a/sound/drivers/pcsp/pcsp.h b/sound/drivers/pcsp/pcsp.h index 174dd2ff0f22..1e123077923d 100644 --- a/sound/drivers/pcsp/pcsp.h +++ b/sound/drivers/pcsp/pcsp.h | |||
@@ -83,6 +83,6 @@ extern enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle); | |||
83 | extern void pcsp_sync_stop(struct snd_pcsp *chip); | 83 | extern void pcsp_sync_stop(struct snd_pcsp *chip); |
84 | 84 | ||
85 | extern int snd_pcsp_new_pcm(struct snd_pcsp *chip); | 85 | extern int snd_pcsp_new_pcm(struct snd_pcsp *chip); |
86 | extern int snd_pcsp_new_mixer(struct snd_pcsp *chip); | 86 | extern int snd_pcsp_new_mixer(struct snd_pcsp *chip, int nopcm); |
87 | 87 | ||
88 | #endif | 88 | #endif |
diff --git a/sound/drivers/pcsp/pcsp_mixer.c b/sound/drivers/pcsp/pcsp_mixer.c index 903bc846763f..02e05552632b 100644 --- a/sound/drivers/pcsp/pcsp_mixer.c +++ b/sound/drivers/pcsp/pcsp_mixer.c | |||
@@ -119,24 +119,43 @@ static int pcsp_pcspkr_put(struct snd_kcontrol *kcontrol, | |||
119 | .put = pcsp_##ctl_type##_put, \ | 119 | .put = pcsp_##ctl_type##_put, \ |
120 | } | 120 | } |
121 | 121 | ||
122 | static struct snd_kcontrol_new __devinitdata snd_pcsp_controls[] = { | 122 | static struct snd_kcontrol_new __devinitdata snd_pcsp_controls_pcm[] = { |
123 | PCSP_MIXER_CONTROL(enable, "Master Playback Switch"), | 123 | PCSP_MIXER_CONTROL(enable, "Master Playback Switch"), |
124 | PCSP_MIXER_CONTROL(treble, "BaseFRQ Playback Volume"), | 124 | PCSP_MIXER_CONTROL(treble, "BaseFRQ Playback Volume"), |
125 | }; | ||
126 | |||
127 | static struct snd_kcontrol_new __devinitdata snd_pcsp_controls_spkr[] = { | ||
125 | PCSP_MIXER_CONTROL(pcspkr, "PC Speaker Playback Switch"), | 128 | PCSP_MIXER_CONTROL(pcspkr, "PC Speaker Playback Switch"), |
126 | }; | 129 | }; |
127 | 130 | ||
128 | int __devinit snd_pcsp_new_mixer(struct snd_pcsp *chip) | 131 | static int __devinit snd_pcsp_ctls_add(struct snd_pcsp *chip, |
132 | struct snd_kcontrol_new *ctls, int num) | ||
129 | { | 133 | { |
130 | struct snd_card *card = chip->card; | ||
131 | int i, err; | 134 | int i, err; |
135 | struct snd_card *card = chip->card; | ||
136 | for (i = 0; i < num; i++) { | ||
137 | err = snd_ctl_add(card, snd_ctl_new1(ctls + i, chip)); | ||
138 | if (err < 0) | ||
139 | return err; | ||
140 | } | ||
141 | return 0; | ||
142 | } | ||
143 | |||
144 | int __devinit snd_pcsp_new_mixer(struct snd_pcsp *chip, int nopcm) | ||
145 | { | ||
146 | int err; | ||
147 | struct snd_card *card = chip->card; | ||
132 | 148 | ||
133 | for (i = 0; i < ARRAY_SIZE(snd_pcsp_controls); i++) { | 149 | if (!nopcm) { |
134 | err = snd_ctl_add(card, | 150 | err = snd_pcsp_ctls_add(chip, snd_pcsp_controls_pcm, |
135 | snd_ctl_new1(snd_pcsp_controls + i, | 151 | ARRAY_SIZE(snd_pcsp_controls_pcm)); |
136 | chip)); | ||
137 | if (err < 0) | 152 | if (err < 0) |
138 | return err; | 153 | return err; |
139 | } | 154 | } |
155 | err = snd_pcsp_ctls_add(chip, snd_pcsp_controls_spkr, | ||
156 | ARRAY_SIZE(snd_pcsp_controls_spkr)); | ||
157 | if (err < 0) | ||
158 | return err; | ||
140 | 159 | ||
141 | strcpy(card->mixername, "PC-Speaker"); | 160 | strcpy(card->mixername, "PC-Speaker"); |
142 | 161 | ||