Initial import from FreeBSD RELENG_4:
[dragonfly.git] / sys / bus / pccard / pccard_beep.c
1 /*-
2  * pccard noise interface.
3  * Nate Williams, October 1997.
4  * This file is in the public domain.
5  */
6 /* $FreeBSD: src/sys/pccard/pccard_beep.c,v 1.3.2.3 2001/06/05 19:11:34 imp Exp $ */
7
8 #include <sys/param.h>
9 #include <sys/kernel.h>
10 #include <sys/systm.h>
11
12 #include <machine/clock.h>
13
14 #include <pccard/driver.h>
15
16 static enum beepstate allow_beep = BEEP_OFF;
17 static int melody_type = 0;
18
19 #define MAX_TONE_MODE   3
20 #define MAX_STATE       4 
21
22 struct tone {
23         int pitch;
24         int duration;
25 };
26
27 static struct tone silent_beep[] = {
28         {0, 0}
29 };
30
31 static struct tone success_beep[] = {
32         {1200,   40}, {0, 0}
33 };
34 static struct tone failure_beep[] = {
35         {3200,   40}, {0, 0}
36 };
37 static struct tone insert_remove_beep[] = {
38         {1600,   20}, {0, 0}
39 };
40
41 static struct tone success_melody_beep[] = {
42         {1200,    7}, {1000,    7}, { 800,   15}, {0, 0}
43 };
44 static struct tone failure_melody_beep[] = {
45         {2000,    7}, {2400,    7}, {2800,   15}, {0, 0}
46 };
47 static struct tone insert_melody_beep[] = {
48         {1600,   10}, {1200,    5}, {0, 0}
49 };
50 static struct tone remove_melody_beep[] = {
51         {1200,   10}, {1600,    5}, {0, 0}
52 };
53
54 static struct tone *melody_table[MAX_TONE_MODE][MAX_STATE] = {
55         { /* silent mode */
56                 silent_beep, silent_beep, silent_beep, silent_beep,
57         },
58         { /* simple beep mode */
59                 success_beep, failure_beep,
60                 insert_remove_beep, insert_remove_beep,
61         },
62         { /* melody beep mode */
63                 success_melody_beep, failure_melody_beep,
64                 insert_melody_beep, remove_melody_beep,
65         },
66 };
67
68
69 static void
70 pccard_beep_sub(void *arg)
71 {
72         struct tone *melody;
73         melody = (struct tone *)arg;
74
75         if (melody->pitch != 0) {
76                 sysbeep(melody->pitch, melody->duration);
77                 timeout(pccard_beep_sub, melody + 1, melody->duration);
78         } else 
79                 allow_beep = BEEP_ON;
80 }
81
82 static void
83 pccard_beep_start(void *arg)
84 {
85         struct tone *melody;
86         melody = (struct tone *)arg;
87
88         if (allow_beep == BEEP_ON && melody->pitch != 0) {
89                 allow_beep = BEEP_OFF;
90                 sysbeep(melody->pitch, melody->duration);
91                 timeout(pccard_beep_sub, melody + 1, melody->duration);
92         }
93 }
94
95 void
96 pccard_success_beep(void)
97 {
98         pccard_beep_start(melody_table[melody_type][0]);
99 }
100
101 void
102 pccard_failure_beep(void)
103 {
104         pccard_beep_start(melody_table[melody_type][1]);
105 }
106
107 void
108 pccard_insert_beep(void)
109 {
110         pccard_beep_start(melody_table[melody_type][2]);
111 }
112
113 void
114 pccard_remove_beep(void)
115 {
116         pccard_beep_start(melody_table[melody_type][3]);
117 }
118
119 int
120 pccard_beep_select(int type)
121 {
122         int errcode = 0;
123
124         if (type == 0)  {
125                 allow_beep = BEEP_OFF;
126                 melody_type = 0;
127         } else if (type < 0 || MAX_TONE_MODE - 1 < type) {
128                 errcode = 1;
129         } else {
130                 allow_beep = BEEP_ON;
131                 melody_type = type;
132         }
133         return (errcode);
134 }