Update DEP-5 uri
[debian/omnibook.git] / kbc.c
1 /*
2  * kbc.c -- low level functions to access Keyboard Controller
3  * 
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms of the GNU General Public License as published by the
6  * Free Software Foundation; either version 2, or (at your option) any
7  * later version.
8  * 
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * Written by Soós Péter <sp@osb.hu>, 2002-2004
15  * Modified by Mathieu Bérard <mathieu.berard@crans.org>, 2006
16  */
17
18 #include "omnibook.h"
19
20 #include <linux/types.h>
21 #include <linux/delay.h>
22 #include <linux/sched.h>
23 #include <linux/spinlock.h>
24 #include <linux/ioport.h>
25
26 #include <asm/io.h>
27 #include "hardware.h"
28
29 extern int omnibook_key_polling_enable(void);
30 extern int omnibook_key_polling_disable(void);
31
32 /*
33  * Registers of the keyboard controller
34  */
35
36 #define OMNIBOOK_KBC_DATA               0x60
37 #define OMNIBOOK_KBC_SC                 0x64
38
39 /*
40  * Keyboard controller status register bits
41  */
42
43 #define OMNIBOOK_KBC_STAT_OBF           0x01    /* Output buffer full */
44 #define OMNIBOOK_KBC_STAT_IBF           0x02    /* Input buffer full */
45
46
47 /*
48  * Interrupt control
49  */
50
51 static DEFINE_SPINLOCK(omnibook_kbc_lock);
52
53 /*
54  * Wait for keyboard buffer
55  */
56
57 static int omnibook_kbc_wait(u8 event)
58 {
59         int timeout = OMNIBOOK_TIMEOUT;
60
61         switch (event) {
62         case OMNIBOOK_KBC_STAT_OBF:
63                 while (!(inb(OMNIBOOK_KBC_SC) & event) && timeout--)
64                         mdelay(1);
65                 break;
66         case OMNIBOOK_KBC_STAT_IBF:
67                 while ((inb(OMNIBOOK_KBC_SC) & event) && timeout--)
68                         mdelay(1);
69                 break;
70         default:
71                 return -EINVAL;
72         }
73         if (timeout > 0)
74                 return 0;
75         return -ETIME;
76 }
77
78 /*
79  * Write to the keyboard command register
80  */
81
82 static int omnibook_kbc_write_command(u8 cmd)
83 {
84         int retval;
85
86         spin_lock_irq(&omnibook_kbc_lock);
87         retval = omnibook_kbc_wait(OMNIBOOK_KBC_STAT_IBF);
88         if (retval)
89                 goto end;
90         outb(cmd, OMNIBOOK_KBC_SC);
91         retval = omnibook_kbc_wait(OMNIBOOK_KBC_STAT_IBF);
92       end:
93         spin_unlock_irq(&omnibook_kbc_lock);
94         return retval;
95 }
96
97 /*
98  * Write to the keyboard data register
99  */
100
101 static int omnibook_kbc_write_data(u8 data)
102 {
103         int retval;
104
105         spin_lock_irq(&omnibook_kbc_lock);
106         retval = omnibook_kbc_wait(OMNIBOOK_KBC_STAT_IBF);
107         if (retval)
108                 goto end;
109         outb(data, OMNIBOOK_KBC_DATA);
110         retval = omnibook_kbc_wait(OMNIBOOK_KBC_STAT_IBF);
111       end:
112         spin_unlock_irq(&omnibook_kbc_lock);
113         return retval;
114 }
115
116 /*
117  * Send a command to keyboard controller
118  */
119
120 static int omnibook_kbc_command(const struct omnibook_operation *io_op, u8 data)
121 {
122         int retval;
123
124         if ((retval = omnibook_kbc_write_command(OMNIBOOK_KBC_CONTROL_CMD)))
125                 return retval;
126
127         retval = omnibook_kbc_write_data(data);
128         return retval;
129 }
130
131 /*
132  * Onetouch button hotkey handler
133  */
134 static int omnibook_kbc_hotkeys(const struct omnibook_operation *io_op, unsigned int state)
135 {
136         int retval;
137
138         retval = __omnibook_toggle(io_op, !!(state & HKEY_ONETOUCH));
139         return retval;
140 }
141
142 /*
143  * Backend interface declarations
144  */
145 struct omnibook_backend kbc_backend = {
146         .name = "i8042",
147         .hotkeys_write_cap = HKEY_ONETOUCH,
148         .byte_write = omnibook_kbc_command,
149         .hotkeys_set = omnibook_kbc_hotkeys,
150 };
151
152 /* End of file */