6853 built in fonts are exposing internal data
[unleashed.git] / usr / src / uts / intel / io / pit_beep.c
blob7b95b48861ea007839388d3a0ee12173c07ea112
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
27 * Simple beeper support for PC platform, using standard timer 2 beeper.
30 #include <sys/types.h>
31 #include <sys/conf.h>
32 #include <sys/beep.h>
33 #include <sys/ksynch.h>
34 #include <sys/ddi.h>
35 #include <sys/sunddi.h>
36 #include <sys/modctl.h>
37 #include <sys/pit.h>
38 #include <sys/inttypes.h>
40 #define PIT_BEEP_UNIT(dev) (getminor((dev)))
42 typedef struct pit_beep_state {
43 /* Dip of pit_beep device */
44 dev_info_t *dip;
46 } pit_beep_state_t;
48 #define PIT_BEEP_ON 1
49 #define PIT_BEEP_OFF 0
51 /* Pointer to the state structure */
52 static void *pit_beep_statep;
54 static int pit_beep_attach(dev_info_t *dip, ddi_attach_cmd_t cmd);
55 static int pit_beep_detach(dev_info_t *dip, ddi_detach_cmd_t cmd);
56 static int pit_beep_info(dev_info_t *dip, ddi_info_cmd_t infocmd,
57 void *arg, void **result);
58 static void pit_beep_freq(void *arg, int freq);
59 static void pit_beep_on(void *arg);
60 static void pit_beep_off(void *arg);
62 struct cb_ops pit_beep_cb_ops = {
63 nulldev, /* open */
64 nulldev, /* close */
65 nulldev, /* strategy */
66 nulldev, /* print */
67 nulldev, /* dump */
68 nulldev, /* read */
69 nulldev, /* write */
70 nulldev, /* ioctl */
71 nulldev, /* devmap */
72 nulldev, /* mmap */
73 nulldev, /* segmap */
74 nochpoll, /* poll */
75 ddi_prop_op, /* cb_prop_op */
76 NULL, /* streamtab */
77 D_MP | D_NEW
81 static struct dev_ops pit_beep_ops = {
82 DEVO_REV, /* Devo_rev */
83 0, /* Refcnt */
84 pit_beep_info, /* Info */
85 nulldev, /* Identify */
86 nulldev, /* Probe */
87 pit_beep_attach, /* Attach */
88 pit_beep_detach, /* Detach */
89 nodev, /* Reset */
90 &pit_beep_cb_ops, /* Driver operations */
91 0, /* Bus operations */
92 NULL, /* Power */
93 ddi_quiesce_not_needed, /* quiesce */
97 static struct modldrv modldrv = {
98 &mod_driverops, /* This one is a driver */
99 "Intel Pit_beep Driver", /* Name of the module. */
100 &pit_beep_ops, /* Driver ops */
104 static struct modlinkage modlinkage = {
105 MODREV_1, (void *)&modldrv, NULL
111 _init(void)
113 int error;
115 /* Initialize the soft state structures */
116 if ((error = ddi_soft_state_init(&pit_beep_statep,
117 sizeof (pit_beep_state_t), 1)) != 0) {
119 return (error);
122 /* Install the loadable module */
123 if ((error = mod_install(&modlinkage)) != 0) {
124 ddi_soft_state_fini(&pit_beep_statep);
127 return (error);
132 _info(struct modinfo *modinfop)
134 return (mod_info(&modlinkage, modinfop));
138 _fini(void)
140 int error;
142 error = mod_remove(&modlinkage);
144 if (error == 0) {
145 /* Release per module resources */
146 ddi_soft_state_fini(&pit_beep_statep);
149 return (error);
153 * pit_beep_attach:
155 static int
156 pit_beep_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
158 switch (cmd) {
159 case DDI_ATTACH:
160 break;
161 case DDI_RESUME:
163 return (DDI_SUCCESS);
164 default:
166 return (DDI_FAILURE);
169 pit_beep_off(dip);
171 (void) beep_init((void *)dip, pit_beep_on, pit_beep_off,
172 pit_beep_freq);
174 /* Display information in the banner */
175 ddi_report_dev(dip);
177 return (DDI_SUCCESS);
182 * pit_beep_detach:
184 /* ARGSUSED */
185 static int
186 pit_beep_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
188 switch (cmd) {
189 case DDI_SUSPEND:
192 * If a beep is in progress; fail suspend
194 if (!beep_busy()) {
196 return (DDI_SUCCESS);
197 } else {
199 return (DDI_FAILURE);
201 default:
203 return (DDI_FAILURE);
209 * pit_beep_info:
211 /* ARGSUSED */
212 static int
213 pit_beep_info(dev_info_t *dip, ddi_info_cmd_t infocmd,
214 void *arg, void **result)
216 dev_t dev;
217 pit_beep_state_t *statep;
218 int instance, error;
220 switch (infocmd) {
221 case DDI_INFO_DEVT2DEVINFO:
222 dev = (dev_t)arg;
223 instance = PIT_BEEP_UNIT(dev);
225 if ((statep = ddi_get_soft_state(pit_beep_statep,
226 instance)) == NULL) {
228 return (DDI_FAILURE);
231 *result = (void *)statep->dip;
233 error = DDI_SUCCESS;
234 break;
235 case DDI_INFO_DEVT2INSTANCE:
236 dev = (dev_t)arg;
237 instance = PIT_BEEP_UNIT(dev);
239 *result = (void *)(uintptr_t)instance;
241 error = DDI_SUCCESS;
242 break;
243 default:
244 error = DDI_FAILURE;
248 return (error);
252 /* ARGSUSED */
253 static void
254 pit_beep_freq(void *arg, int freq)
256 int counter;
258 if (freq == 0)
259 counter = 0;
260 else {
261 counter = PIT_HZ / freq;
262 if (counter > UINT16_MAX)
263 counter = UINT16_MAX;
264 else if (counter < 1)
265 counter = 1;
268 outb(PITCTL_PORT, PIT_C2 | PIT_READMODE | PIT_RATEMODE);
269 outb(PITCTR2_PORT, counter & 0xff);
270 outb(PITCTR2_PORT, counter >> 8);
274 /* ARGSUSED */
275 static void
276 pit_beep_on(void *arg)
278 outb(PITAUX_PORT, inb(PITAUX_PORT) | (PITAUX_OUT2 | PITAUX_GATE2));
282 /* ARGSUSED */
283 static void
284 pit_beep_off(void *arg)
286 outb(PITAUX_PORT, inb(PITAUX_PORT) & ~(PITAUX_OUT2 | PITAUX_GATE2));