All
I noticed this problem about 6 months ago and wrote a quick and dirty
kernel module to solve the problem then it slipped my mind.
Basically the pc speaker access from userspace is tied to having a valid
tty in the machine. When there is no tty in the computer the pc speaker
wont work. This of course means you need a video card in said machine.
See vt.c it is the only interface to the pc speaker in the entire
kernel. The ioctl and trying to echo magic characters to a tty thus both
interface there.
Anyway I dont think it would be a good idea to put this proc interface
(as proc interface is a quick hack) into the mainstream kernel but I do
think the pc speaker should be available irelevant of video card
presence.
I know this works on intel machines, havent tested it on non intel
machines. Heck I dont even know how the equivalent of the pc speaker
would be accessed on non intel or if there is one.
I distribute this module as part of some programs I wrote for use with
wireless networking equipment, see http://wibble.net/~sjh/wireless for
use in a computer I have in the roof with no video card.
the module code follows my signature.
I sent this note to Alan a few months back instead of lkml, oh well you
get the idea.
I tried sending this a few days ago to lkml, however I have not seen it
show up on the kernelnotes.org archive and thus suspect it was dropped
by vger, I have this itme set my mail server as my isp's mail server
rather than my behind masq internal mail server.
See You
Steve
-- sjh@wibble.net http://wibble.net/~sjh/ Look Up In The Sky Is it a bird? No Is it a plane? No Is it a small blue banana? YES/********************************************************************* * pcspeaker -- kernel module providing a proc interface allowing * * you to use a pc speaker on a machine with no video * * card * * * * Usage: insmod the module * * echo "frequency duration" > /proc/pcspeaker * * duration is measured in milliseconds * * eg. echo "440 1000" > /proc/pcspeaker * * will make the speaker beep at note A for a second * * * * Author: Steven Hanley * * Date: 20/08/99 * * Last Modified: See ChangeLog * *********************************************************************/
#include <linux/module.h> #include <linux/kernel.h> #include <linux/proc_fs.h> #include <asm/string.h> #include <asm/io.h>
EXPORT_NO_SYMBOLS;
/* following two functions taken from linux/drivers/char/vt.c basically it is a broken thing about the kernel that you can not use a pc speaker in the linxu kernel (ioctl or echo to a tty) unless there is working tty (ie a video card in the machine) */
/* * Generates sound of some frequency for some number of clock ticks * * If freq is 0, will turn off sound, else will turn it on for that * time. If msec is 0, will return immediately, else will sleep for * msec time, then turn sound off. * * We also return immediately, which is what was implied within * the X comments - KDMKTONE doesn't put the process to sleep. */
static void kd_nosound(unsigned long ignored) { /* disable counter 2 */ outb(inb_p(0x61)&0xFC, 0x61); return; }
static void kd_mksound(unsigned int hz, unsigned int ticks) { static struct timer_list sound_timer = { NULL, NULL, 0, 0, kd_nosound };
unsigned int count = 0;
if (hz > 20 && hz < 32767) count = 1193180 / hz; cli(); del_timer(&sound_timer); if (count) { /* enable counter 2 */ outb_p(inb_p(0x61)|3, 0x61); /* set command for counter 2, 2 byte write */ outb_p(0xB6, 0x43); /* select desired HZ */ outb_p(count & 0xff, 0x42); outb((count >> 8) & 0xff, 0x42);
if (ticks) { sound_timer.expires = jiffies+ticks; add_timer(&sound_timer); } } else kd_nosound(0); sti(); return; }
static int pcspeaker_write_proc(struct file *file, const char *buffer, unsigned long count, void *data) { char *str, *endptr; int frequency, snd_dur;
if (! ((memchr (buffer, ' ', count)) && (memchr (buffer, '\n', count)))) { return count; }
frequency = (int) simple_strtoul (buffer, &endptr, 0); if (*endptr != ' ') { return count; } str = memchr (buffer, ' ', count) + 1; snd_dur = (int) simple_strtoul (str, &endptr, 0); if (*endptr != '\n') { return count; }
kd_mksound (frequency, (snd_dur * HZ / 1000));
return count; }
static struct proc_dir_entry *proc_entry;
/* this function is called by the kernel when the module is loaded */ int init_module(void) { int ret = 0; proc_entry = create_proc_entry("pcspeaker", S_IFREG | S_IRUGO, &proc_root);
if (!proc_entry) { printk("Failed to register /proc/pcspeaker\n"); return -1; }
proc_entry->write_proc = pcspeaker_write_proc;
return ret; }
/* this function is called by the kernel when the module is removed */ void cleanup_module(void) { proc_unregister(&proc_root,proc_entry->low_ino); }
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/
This archive was generated by hypermail 2b29 : Wed Jun 07 2000 - 21:00:14 EST