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