patch-2_6_7-vs1_9_1_12
[linux-2.6.git] / drivers / input / misc / 98spkr.c
1 /*
2  *  PC-9800 Speaker beeper driver for Linux
3  *
4  *  Copyright (c) 2002 Osamu Tomita
5  *  Copyright (c) 2002 Vojtech Pavlik
6  *  Copyright (c) 1992 Orest Zborowski
7  *
8  */
9
10 /*
11  * This program is free software; you can redistribute it and/or modify it
12  * under the terms of the GNU General Public License version 2 as published by
13  * the Free Software Foundation
14  */
15
16 #include <linux/kernel.h>
17 #include <linux/module.h>
18 #include <linux/init.h>
19 #include <linux/input.h>
20 #include <asm/8253pit.h>
21 #include <asm/io.h>
22
23 MODULE_AUTHOR("Osamu Tomita <tomita@cinet.co.jp>");
24 MODULE_DESCRIPTION("PC-9800 Speaker beeper driver");
25 MODULE_LICENSE("GPL");
26
27 static char spkr98_name[] = "PC-9801 Speaker";
28 static char spkr98_phys[] = "isa3fdb/input0";
29 static struct input_dev spkr98_dev;
30
31 spinlock_t i8253_beep_lock = SPIN_LOCK_UNLOCKED;
32
33 static int spkr98_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
34 {
35         unsigned int count = 0;
36         unsigned long flags;
37
38         if (type != EV_SND)
39                 return -1;
40
41         switch (code) {
42                 case SND_BELL: if (value) value = 1000;
43                 case SND_TONE: break;
44                 default: return -1;
45         }
46
47         if (value > 20 && value < 32767)
48                 count = PIT_TICK_RATE / value;
49
50         spin_lock_irqsave(&i8253_beep_lock, flags);
51
52         if (count) {
53                 outb(0x76, 0x3fdf);
54                 outb(0, 0x5f);
55                 outb(count & 0xff, 0x3fdb);
56                 outb(0, 0x5f);
57                 outb((count >> 8) & 0xff, 0x3fdb);
58                 /* beep on */
59                 outb(6, 0x37);
60         } else {
61                 /* beep off */
62                 outb(7, 0x37);
63         }
64
65         spin_unlock_irqrestore(&i8253_beep_lock, flags);
66
67         return 0;
68 }
69
70 static int __init spkr98_init(void)
71 {
72         spkr98_dev.evbit[0] = BIT(EV_SND);
73         spkr98_dev.sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE);
74         spkr98_dev.event = spkr98_event;
75
76         spkr98_dev.name = spkr98_name;
77         spkr98_dev.phys = spkr98_phys;
78         spkr98_dev.id.bustype = BUS_ISA;
79         spkr98_dev.id.vendor = 0x001f;
80         spkr98_dev.id.product = 0x0001;
81         spkr98_dev.id.version = 0x0100;
82
83         input_register_device(&spkr98_dev);
84
85         printk(KERN_INFO "input: %s\n", spkr98_name);
86
87         return 0;
88 }
89
90 static void __exit spkr98_exit(void)
91 {
92         input_unregister_device(&spkr98_dev);
93 }
94
95 module_init(spkr98_init);
96 module_exit(spkr98_exit);