1 //==========================================================================
5 // Keypad driver for the Compaq iPAQ
7 //==========================================================================
8 //####ECOSGPLCOPYRIGHTBEGIN####
9 // -------------------------------------------
10 // This file is part of eCos, the Embedded Configurable Operating System.
11 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
13 // eCos is free software; you can redistribute it and/or modify it under
14 // the terms of the GNU General Public License as published by the Free
15 // Software Foundation; either version 2 or (at your option) any later version.
17 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
18 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 // You should have received a copy of the GNU General Public License along
23 // with eCos; if not, write to the Free Software Foundation, Inc.,
24 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
26 // As a special exception, if other files instantiate templates or use macros
27 // or inline functions from this file, or you compile this file and link it
28 // with other works to produce a work based on this file, this file does not
29 // by itself cause the resulting work to be covered by the GNU General Public
30 // License. However the source code for this file must still be made available
31 // in accordance with section (3) of the GNU General Public License.
33 // This exception does not invalidate any other reasons why a work based on
34 // this file might be covered by the GNU General Public License.
36 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
37 // at http://sources.redhat.com/ecos/ecos-license/
38 // -------------------------------------------
39 //####ECOSGPLCOPYRIGHTEND####
40 //==========================================================================
41 //#####DESCRIPTIONBEGIN####
44 // Contributors: gthomas
47 // Description: Keypad driver for Compaq IPAQ
49 //####DESCRIPTIONEND####
51 //==========================================================================
54 #include <pkgconf/devs_kbd_ipaq.h>
56 #include <cyg/kernel/kapi.h>
57 #include <cyg/hal/hal_io.h>
58 #include <cyg/hal/hal_arch.h>
59 #include <cyg/hal/drv_api.h>
60 #include <cyg/hal/hal_intr.h>
61 #include <cyg/hal/hal_sa11x0.h>
62 #include <cyg/hal/ipaq.h>
63 #include <cyg/infra/cyg_type.h>
64 #include <cyg/infra/cyg_ass.h>
66 #include <cyg/fileio/fileio.h> // For select() functionality
67 static cyg_selinfo kbd_select_info;
68 static cyg_bool kbd_select_active;
70 #include <cyg/io/devtab.h>
71 #include <cyg/hal/atmel_support.h>
73 // Functions in this module
75 static Cyg_ErrNo kbd_read(cyg_io_handle_t handle,
78 static cyg_bool kbd_select(cyg_io_handle_t handle,
81 static Cyg_ErrNo kbd_set_config(cyg_io_handle_t handle,
85 static Cyg_ErrNo kbd_get_config(cyg_io_handle_t handle,
89 static bool kbd_init(struct cyg_devtab_entry *tab);
90 static Cyg_ErrNo kbd_lookup(struct cyg_devtab_entry **tab,
91 struct cyg_devtab_entry *st,
94 CHAR_DEVIO_TABLE(ipaq_kbd_handlers,
95 NULL, // Unsupported write() function
101 CHAR_DEVTAB_ENTRY(ipaq_kbd_device,
102 CYGDAT_DEVS_KBD_IPAQ_NAME,
103 NULL, // Base device name
107 NULL); // Private data pointer
109 #define MAX_EVENTS CYGNUM_DEVS_KBD_IPAQ_EVENT_BUFFER_SIZE
110 static int num_events;
111 static int _event_put, _event_get;
112 static unsigned char _events[MAX_EVENTS];
114 static bool _is_open = false;
117 // Note: this routine is called from the Atmel processing DSR
120 kbd_handler(atmel_pkt *pkt)
122 unsigned char *dp = pkt->data;
125 // diag_printf("KBD = %x\n", dp[1]);
126 if (num_events < MAX_EVENTS) {
128 ev = &_events[_event_put++];
129 if (_event_put == MAX_EVENTS) {
133 if (kbd_select_active) {
134 kbd_select_active = false;
135 cyg_selwakeup(&kbd_select_info);
141 kbd_read(cyg_io_handle_t handle,
147 unsigned char *bp = (unsigned char *)buffer;
149 cyg_scheduler_lock(); // Prevent interaction with DSR code
150 while (tot >= sizeof(*ev)) {
151 if (num_events > 0) {
152 ev = &_events[_event_get++];
153 if (_event_get == MAX_EVENTS) {
156 memcpy(bp, ev, sizeof(*ev));
161 break; // No more events
164 cyg_scheduler_unlock(); // Allow DSRs again
170 kbd_select(cyg_io_handle_t handle,
174 if (which == CYG_FREAD) {
175 cyg_scheduler_lock(); // Prevent interaction with DSR code
176 if (num_events > 0) {
177 cyg_scheduler_unlock(); // Reallow interaction with DSR code
180 if (!kbd_select_active) {
181 kbd_select_active = true;
182 cyg_selrecord(info, &kbd_select_info);
184 cyg_scheduler_unlock(); // Reallow interaction with DSR code
190 kbd_set_config(cyg_io_handle_t handle,
199 kbd_get_config(cyg_io_handle_t handle,
208 kbd_init(struct cyg_devtab_entry *tab)
210 cyg_selinit(&kbd_select_info);
215 kbd_lookup(struct cyg_devtab_entry **tab,
216 struct cyg_devtab_entry *st,
221 atmel_register(ATMEL_CMD_KEYBD, kbd_handler);
222 atmel_interrupt_mode(true);