1 /* $NetBSD: btn_obio.c,v 1.4 2008/03/27 02:40:14 uwe Exp $ */
4 * Copyright (c) 2005 NONAKA Kimihiro
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 #include "pwrsw_obio.h"
31 #include <sys/cdefs.h>
32 __KERNEL_RCSID(0, "$NetBSD: btn_obio.c,v 1.4 2008/03/27 02:40:14 uwe Exp $");
34 #include <sys/types.h>
35 #include <sys/param.h>
36 #include <sys/systm.h>
37 #include <sys/device.h>
38 #include <sys/malloc.h>
39 #include <sys/kernel.h>
41 #include <sys/ioctl.h>
42 #include <sys/callout.h>
44 #include <dev/sysmon/sysmonvar.h>
45 #include <dev/sysmon/sysmon_taskq.h>
47 #include <sh3/devreg.h>
49 #include <machine/button.h>
51 #include <landisk/landisk/landiskreg.h>
52 #include <landisk/dev/obiovar.h>
53 #include <landisk/dev/buttonvar.h>
60 struct btn_obio_softc
{
64 struct callout sc_guard_ch
;
65 struct sysmon_pswitch sc_smpsw
; /* reset */
66 struct btn_event sc_bev
[NBUTTON
];
72 #define BTN_TIMEOUT (hz / 10) /* 100ms */
75 static int btn_obio_probe(device_t
, cfdata_t
, void *);
76 static void btn_obio_attach(device_t
, device_t
, void *);
78 static int btn_intr(void *aux
);
79 static void btn_sysmon_pressed_event(void *arg
);
80 static void btn_pressed_event(void *arg
);
81 static void btn_guard_timeout(void *arg
);
83 static struct btn_obio_softc
*btn_softc
;
89 } btnlist
[NBUTTON
] = {
90 { BTN_SELECT
, BTN_SELECT_BIT
, "select" },
91 { BTN_COPY
, BTN_COPY_BIT
, "copy" },
92 { BTN_REMOVE
, BTN_REMOVE_BIT
, "remove" },
95 CFATTACH_DECL_NEW(btn_obio
, sizeof(struct btn_obio_softc
),
96 btn_obio_probe
, btn_obio_attach
, NULL
, NULL
);
99 btn_obio_probe(device_t parent
, cfdata_t cfp
, void *aux
)
101 struct obio_attach_args
*oa
= aux
;
109 oa
->oa_irq
[0].or_irq
= LANDISK_INTR_BTN
;
115 btn_obio_attach(device_t parent
, device_t self
, void *aux
)
117 struct btn_obio_softc
*sc
;
121 aprint_normal(": USL-5P buttons\n");
123 sc
= device_private(self
);
128 callout_init(&sc
->sc_guard_ch
, 0);
129 callout_setfunc(&sc
->sc_guard_ch
, btn_guard_timeout
, sc
);
131 sc
->sc_ih
= extintr_establish(LANDISK_INTR_BTN
, IPL_TTY
, btn_intr
, sc
);
132 if (sc
->sc_ih
== NULL
) {
133 aprint_error_dev(self
, "unable to establish interrupt");
134 panic("extintr_establish");
137 sc
->sc_smpsw
.smpsw_name
= device_xname(self
);
138 sc
->sc_smpsw
.smpsw_type
= PSWITCH_TYPE_RESET
;
139 if (sysmon_pswitch_register(&sc
->sc_smpsw
) != 0) {
140 aprint_error_dev(self
, "unable to register with sysmon\n");
143 sc
->sc_mask
|= BTN_RESET_BIT
;
145 for (i
= 0; i
< NBUTTON
; i
++) {
146 int idx
= btnlist
[i
].idx
;
147 sc
->sc_bev
[idx
].bev_name
= btnlist
[i
].name
;
148 if (btn_event_register(&sc
->sc_bev
[idx
]) != 0) {
149 aprint_error_dev(self
,
150 "unable to register '%s' button\n",
153 sc
->sc_mask
|= btnlist
[i
].mask
;
161 struct btn_obio_softc
*sc
= (void *)arg
;
162 device_t self
= sc
->sc_dev
;
166 status
= (int8_t)_reg_read_1(LANDISK_BTNSTAT
);
172 if (status
& BTN_ALL_BIT
) {
173 if (status
& BTN_RESET_BIT
) {
174 if (sc
->sc_mask
& BTN_RESET_BIT
) {
175 extintr_disable(sc
->sc_ih
);
177 extintr_disable_by_num(LANDISK_INTR_PWRSW
);
179 sysmon_task_queue_sched(0,
180 btn_sysmon_pressed_event
, sc
);
183 aprint_normal_dev(self
,
184 "reset button pressed\n");
188 for (i
= 0; i
< NBUTTON
; i
++) {
189 uint8_t mask
= btnlist
[i
].mask
;
192 if (sc
->sc_mask
& mask
) {
193 sysmon_task_queue_sched(1,
195 &sc
->sc_bev
[btnlist
[i
].idx
]);
197 aprint_normal_dev(self
,
198 "%s button pressed\n",
204 extintr_disable(sc
->sc_ih
);
205 callout_schedule(&sc
->sc_guard_ch
, BTN_TIMEOUT
);
214 btn_sysmon_pressed_event(void *arg
)
216 struct btn_obio_softc
*sc
= (void *)arg
;
218 sysmon_pswitch_event(&sc
->sc_smpsw
, PSWITCH_EVENT_PRESSED
);
222 btn_pressed_event(void *arg
)
224 struct btn_event
*bev
= (void *)arg
;
226 btn_event_send(bev
, BUTTON_EVENT_PRESSED
);
230 btn_guard_timeout(void *arg
)
232 struct btn_obio_softc
*sc
= arg
;
234 callout_stop(&sc
->sc_guard_ch
);
235 extintr_enable(sc
->sc_ih
);