pcsp.c (942baad211336efefb93a8369478888ab845c450) pcsp.c (3a1e341c5687b4e8fe51ca1c933b1f23ab3304c1)
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * PC-Speaker driver for Linux
4 *
5 * Copyright (C) 1997-2001 David Woodhouse
6 * Copyright (C) 2001-2008 Stas Sergeev
7 */
8

--- 28 unchanged lines hidden (view full) ---

37MODULE_PARM_DESC(enable, "Enable PC-Speaker sound.");
38module_param(nopcm, bool, 0444);
39MODULE_PARM_DESC(nopcm, "Disable PC-Speaker PCM sound. Only beeps remain.");
40
41struct snd_pcsp pcsp_chip;
42
43static int snd_pcsp_create(struct snd_card *card)
44{
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * PC-Speaker driver for Linux
4 *
5 * Copyright (C) 1997-2001 David Woodhouse
6 * Copyright (C) 2001-2008 Stas Sergeev
7 */
8

--- 28 unchanged lines hidden (view full) ---

37MODULE_PARM_DESC(enable, "Enable PC-Speaker sound.");
38module_param(nopcm, bool, 0444);
39MODULE_PARM_DESC(nopcm, "Disable PC-Speaker PCM sound. Only beeps remain.");
40
41struct snd_pcsp pcsp_chip;
42
43static int snd_pcsp_create(struct snd_card *card)
44{
45 static const struct snd_device_ops ops = { };
46 unsigned int resolution = hrtimer_resolution;
45 unsigned int resolution = hrtimer_resolution;
47 int err, div, min_div, order;
46 int div, min_div, order;
48
49 if (!nopcm) {
50 if (resolution > PCSP_MAX_PERIOD_NS) {
51 printk(KERN_ERR "PCSP: Timer resolution is not sufficient "
52 "(%unS)\n", resolution);
53 printk(KERN_ERR "PCSP: Make sure you have HPET and ACPI "
54 "enabled.\n");
55 printk(KERN_ERR "PCSP: Turned into nopcm mode.\n");

--- 22 unchanged lines hidden (view full) ---

78 pcsp_chip.pcspkr = 1;
79
80 spin_lock_init(&pcsp_chip.substream_lock);
81
82 pcsp_chip.card = card;
83 pcsp_chip.port = 0x61;
84 pcsp_chip.irq = -1;
85 pcsp_chip.dma = -1;
47
48 if (!nopcm) {
49 if (resolution > PCSP_MAX_PERIOD_NS) {
50 printk(KERN_ERR "PCSP: Timer resolution is not sufficient "
51 "(%unS)\n", resolution);
52 printk(KERN_ERR "PCSP: Make sure you have HPET and ACPI "
53 "enabled.\n");
54 printk(KERN_ERR "PCSP: Turned into nopcm mode.\n");

--- 22 unchanged lines hidden (view full) ---

77 pcsp_chip.pcspkr = 1;
78
79 spin_lock_init(&pcsp_chip.substream_lock);
80
81 pcsp_chip.card = card;
82 pcsp_chip.port = 0x61;
83 pcsp_chip.irq = -1;
84 pcsp_chip.dma = -1;
85 card->private_data = &pcsp_chip;
86
86
87 /* Register device */
88 err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, &pcsp_chip, &ops);
89 if (err < 0)
90 return err;
91
92 return 0;
93}
94
87 return 0;
88}
89
90static void pcsp_stop_beep(struct snd_pcsp *chip);
91
92static void alsa_card_pcsp_free(struct snd_card *card)
93{
94 pcsp_stop_beep(card->private_data);
95}
96
95static int snd_card_pcsp_probe(int devnum, struct device *dev)
96{
97 struct snd_card *card;
98 int err;
99
100 if (devnum != 0)
101 return -EINVAL;
102
103 hrtimer_init(&pcsp_chip.timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
104 pcsp_chip.timer.function = pcsp_do_timer;
105
97static int snd_card_pcsp_probe(int devnum, struct device *dev)
98{
99 struct snd_card *card;
100 int err;
101
102 if (devnum != 0)
103 return -EINVAL;
104
105 hrtimer_init(&pcsp_chip.timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
106 pcsp_chip.timer.function = pcsp_do_timer;
107
106 err = snd_card_new(dev, index, id, THIS_MODULE, 0, &card);
108 err = snd_devm_card_new(dev, index, id, THIS_MODULE, 0, &card);
107 if (err < 0)
108 return err;
109
110 err = snd_pcsp_create(card);
111 if (err < 0)
109 if (err < 0)
110 return err;
111
112 err = snd_pcsp_create(card);
113 if (err < 0)
112 goto free_card;
114 return err;
113
114 if (!nopcm) {
115 err = snd_pcsp_new_pcm(&pcsp_chip);
116 if (err < 0)
115
116 if (!nopcm) {
117 err = snd_pcsp_new_pcm(&pcsp_chip);
118 if (err < 0)
117 goto free_card;
119 return err;
118 }
119 err = snd_pcsp_new_mixer(&pcsp_chip, nopcm);
120 if (err < 0)
120 }
121 err = snd_pcsp_new_mixer(&pcsp_chip, nopcm);
122 if (err < 0)
121 goto free_card;
123 return err;
122
123 strcpy(card->driver, "PC-Speaker");
124 strcpy(card->shortname, "pcsp");
125 sprintf(card->longname, "Internal PC-Speaker at port 0x%x",
126 pcsp_chip.port);
127
128 err = snd_card_register(card);
129 if (err < 0)
124
125 strcpy(card->driver, "PC-Speaker");
126 strcpy(card->shortname, "pcsp");
127 sprintf(card->longname, "Internal PC-Speaker at port 0x%x",
128 pcsp_chip.port);
129
130 err = snd_card_register(card);
131 if (err < 0)
130 goto free_card;
132 return err;
133 card->private_free = alsa_card_pcsp_free;
131
132 return 0;
134
135 return 0;
133
134free_card:
135 snd_card_free(card);
136 return err;
137}
138
139static int alsa_card_pcsp_init(struct device *dev)
140{
141 int err;
142
143 err = snd_card_pcsp_probe(0, dev);
144 if (err) {

--- 5 unchanged lines hidden (view full) ---

150 if (debug_pagealloc_enabled()) {
151 printk(KERN_WARNING "PCSP: CONFIG_DEBUG_PAGEALLOC is enabled, "
152 "which may make the sound noisy.\n");
153 }
154
155 return 0;
156}
157
136}
137
138static int alsa_card_pcsp_init(struct device *dev)
139{
140 int err;
141
142 err = snd_card_pcsp_probe(0, dev);
143 if (err) {

--- 5 unchanged lines hidden (view full) ---

149 if (debug_pagealloc_enabled()) {
150 printk(KERN_WARNING "PCSP: CONFIG_DEBUG_PAGEALLOC is enabled, "
151 "which may make the sound noisy.\n");
152 }
153
154 return 0;
155}
156
158static void alsa_card_pcsp_exit(struct snd_pcsp *chip)
159{
160 snd_card_free(chip->card);
161}
162
163static int pcsp_probe(struct platform_device *dev)
164{
165 int err;
166
167 err = pcspkr_input_init(&pcsp_chip.input_dev, &dev->dev);
168 if (err < 0)
169 return err;
170
171 err = alsa_card_pcsp_init(&dev->dev);
157static int pcsp_probe(struct platform_device *dev)
158{
159 int err;
160
161 err = pcspkr_input_init(&pcsp_chip.input_dev, &dev->dev);
162 if (err < 0)
163 return err;
164
165 err = alsa_card_pcsp_init(&dev->dev);
172 if (err < 0) {
173 pcspkr_input_remove(pcsp_chip.input_dev);
166 if (err < 0)
174 return err;
167 return err;
175 }
176
177 platform_set_drvdata(dev, &pcsp_chip);
178 return 0;
179}
180
168
169 platform_set_drvdata(dev, &pcsp_chip);
170 return 0;
171}
172
181static int pcsp_remove(struct platform_device *dev)
182{
183 struct snd_pcsp *chip = platform_get_drvdata(dev);
184 pcspkr_input_remove(chip->input_dev);
185 alsa_card_pcsp_exit(chip);
186 return 0;
187}
188
189static void pcsp_stop_beep(struct snd_pcsp *chip)
190{
191 pcsp_sync_stop(chip);
192 pcspkr_stop_sound();
193}
194
195#ifdef CONFIG_PM_SLEEP
196static int pcsp_suspend(struct device *dev)

--- 16 unchanged lines hidden (view full) ---

213}
214
215static struct platform_driver pcsp_platform_driver = {
216 .driver = {
217 .name = "pcspkr",
218 .pm = PCSP_PM_OPS,
219 },
220 .probe = pcsp_probe,
173static void pcsp_stop_beep(struct snd_pcsp *chip)
174{
175 pcsp_sync_stop(chip);
176 pcspkr_stop_sound();
177}
178
179#ifdef CONFIG_PM_SLEEP
180static int pcsp_suspend(struct device *dev)

--- 16 unchanged lines hidden (view full) ---

197}
198
199static struct platform_driver pcsp_platform_driver = {
200 .driver = {
201 .name = "pcspkr",
202 .pm = PCSP_PM_OPS,
203 },
204 .probe = pcsp_probe,
221 .remove = pcsp_remove,
222 .shutdown = pcsp_shutdown,
223};
224
225static int __init pcsp_init(void)
226{
227 if (!enable)
228 return -ENODEV;
229 return platform_driver_register(&pcsp_platform_driver);
230}
231
232static void __exit pcsp_exit(void)
233{
234 platform_driver_unregister(&pcsp_platform_driver);
235}
236
237module_init(pcsp_init);
238module_exit(pcsp_exit);
205 .shutdown = pcsp_shutdown,
206};
207
208static int __init pcsp_init(void)
209{
210 if (!enable)
211 return -ENODEV;
212 return platform_driver_register(&pcsp_platform_driver);
213}
214
215static void __exit pcsp_exit(void)
216{
217 platform_driver_unregister(&pcsp_platform_driver);
218}
219
220module_init(pcsp_init);
221module_exit(pcsp_exit);