Update DEP-5 uri
[debian/omnibook.git] / hotkeys.c
1 /*
2  * hotkeys.c -- code to handling Hotkey/E-Key/EasyAccess buttons
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 #include "hardware.h"
20
21 /* Predefined convinient on/off states */
22 #define HKEY_ON  HKEY_ONETOUCH|HKEY_MULTIMEDIA|HKEY_FN|HKEY_DOCK|HKEY_FNF5
23 #define HKEY_OFF 0
24
25 /*
26  * Set hotkeys status and update recorded saved state
27  */
28 static int hotkeys_set_save(struct omnibook_operation *io_op, unsigned int state)
29 {
30         int retval;
31
32         if(mutex_lock_interruptible(&io_op->backend->mutex))
33                 return -ERESTARTSYS;
34
35         retval = __backend_hotkeys_set(io_op, state);
36         if (retval < 0)
37                 goto out;
38
39         /* Update saved state */
40         io_op->backend->hotkeys_state = state & io_op->backend->hotkeys_write_cap;
41
42         out:
43         mutex_unlock(&io_op->backend->mutex);
44         return retval;
45 }
46
47 /*
48  * Read hotkeys status, fallback to reading saved state if real probing is not
49  * supported.
50  */
51 static int hotkeys_get_save(struct omnibook_operation *io_op, unsigned int *state)
52 {
53         unsigned int read_state = 0;
54         int retval = 0;
55
56         if(mutex_lock_interruptible(&io_op->backend->mutex))
57                 return -ERESTARTSYS;
58
59         if (io_op->backend->hotkeys_get)
60                 retval = __backend_hotkeys_get(io_op, &read_state);
61         if (retval < 0)
62                 goto out;
63
64         /* Return previously set state for the fields that are write only */
65         *state = (read_state & io_op->backend->hotkeys_read_cap) + 
66                  (io_op->backend->hotkeys_state & ~io_op->backend->hotkeys_read_cap);
67
68         out:
69         mutex_unlock(&io_op->backend->mutex);
70         return 0;
71 }
72
73 /*
74  * Power management handlers
75  */
76
77 /*
78  * Restore previously saved state
79  */
80 static int omnibook_hotkeys_resume(struct omnibook_operation *io_op)
81 {
82         int retval;
83         mutex_lock(&io_op->backend->mutex);
84         retval = __backend_hotkeys_set(io_op, io_op->backend->hotkeys_state);
85         mutex_unlock(&io_op->backend->mutex);
86         return retval;
87 }
88
89 /*
90  * Disable hotkeys upon suspend (FIXME is the disabling required ?)
91  */
92 static int omnibook_hotkeys_suspend(struct omnibook_operation *io_op)
93 {
94         int retval = 0;
95         retval = backend_hotkeys_set(io_op, HKEY_OFF);
96         return retval;
97 }
98
99 static const char pretty_name[][27] = {
100         "Onetouch buttons are",
101         "Multimedia hotkeys are",
102         "Fn hotkeys are",
103         "Stick key is",
104         "Press Fn twice to lock is",
105         "Dock events are",
106         "Fn + F5 hotkey is",
107 };
108
109 static int omnibook_hotkeys_read(char *buffer, struct omnibook_operation *io_op)
110 {
111         int len = 0;
112         int retval;
113         unsigned int read_state = 0; /* buggy gcc 4.1 warning fix */
114         unsigned int shift, mask;
115
116         retval = hotkeys_get_save(io_op, &read_state);
117
118         if (retval < 0)
119                 return retval;
120
121         for (shift = 0; shift <= HKEY_LAST_SHIFT ; shift++) {
122                 mask = 1 << shift;
123                 /* we assume write capability or read capability imply support */
124                 if ((io_op->backend->hotkeys_read_cap | io_op->backend->hotkeys_write_cap) & mask)
125                         len +=
126                             sprintf(buffer + len, "%s %s.\n", pretty_name[shift],
127                                     (read_state & mask) ? "enabled" : "disabled");
128         }
129
130         return len;
131 }
132
133 static int omnibook_hotkeys_write(char *buffer, struct omnibook_operation *io_op)
134 {
135         unsigned int state;
136         char *endp;
137
138         if (strncmp(buffer, "off", 3) == 0)
139                 hotkeys_set_save(io_op, HKEY_OFF);
140         else if (strncmp(buffer, "on", 2) == 0)
141                 hotkeys_set_save(io_op, HKEY_ON);
142         else {
143                 state = simple_strtoul(buffer, &endp, 16);
144                 if (endp == buffer)
145                         return -EINVAL;
146                 else
147                         hotkeys_set_save(io_op, state);
148         }
149         return 0;
150 }
151
152 static int __init omnibook_hotkeys_init(struct omnibook_operation *io_op)
153 {
154         int retval;
155
156         printk(O_INFO "Enabling all hotkeys.\n");
157         retval = hotkeys_set_save(io_op, HKEY_ON);
158         return retval < 0 ? retval : 0;
159 }
160
161 static void __exit omnibook_hotkeys_cleanup(struct omnibook_operation *io_op)
162 {
163         printk(O_INFO "Disabling all hotkeys.\n");
164         hotkeys_set_save(io_op, HKEY_OFF);
165 }
166
167 static struct omnibook_tbl hotkeys_table[] __initdata = {
168         {XE3GF | XE3GC | OB500 | OB510 | OB6000 | OB6100 | XE4500 | AMILOD | TSP10 | TSM30X, 
169         COMMAND(KBC,OMNIBOOK_KBC_CMD_ONETOUCH_ENABLE,OMNIBOOK_KBC_CMD_ONETOUCH_DISABLE)},
170         {TSM70, {CDI,}},
171         {TSM40, {SMI,}},
172         {TSX205, {ACPI,}},
173         {0,}
174 };
175
176 static struct omnibook_feature __declared_feature hotkeys_driver = {
177         .name = "hotkeys",
178         .enabled = 1,
179         .read = omnibook_hotkeys_read,
180         .write = omnibook_hotkeys_write,
181         .init = omnibook_hotkeys_init,
182         .exit = omnibook_hotkeys_cleanup,
183         .suspend = omnibook_hotkeys_suspend,
184         .resume = omnibook_hotkeys_resume,
185         .ectypes =
186             XE3GF | XE3GC | OB500 | OB510 | OB6000 | OB6100 | XE4500 | AMILOD | TSP10 | TSM70 | TSM30X |
187             TSM40 | TSX205,
188         .tbl = hotkeys_table,
189 };
190
191 module_param_named(hotkeys, hotkeys_driver.enabled, int, S_IRUGO);
192 MODULE_PARM_DESC(hotkeys, "Use 0 to disable, 1 to enable hotkeys handling");
193 /* End of file */