aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/keyboard/atkbd.c
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2009-09-03 20:22:04 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2009-09-03 23:30:36 -0400
commit1ba36e11b227e32f818aea5b4d84f5cbff71e7db (patch)
treeda3a05fc84ece5c911ea3a586b30f9cef2dec0ef /drivers/input/keyboard/atkbd.c
parent903b9124eae00edf8a9d6491dab60fcda777aabd (diff)
Input: atkbd - allow setting force-release bitmap via sysfs
There are more and more laptop requiring use of force_release quirk for their multimedia and other specialized keys. Adding their DMI data to the kernel is not sustainable; instead we will rely on help from userspace (HAL) to do that for us. This patch creates a new 'force_release' sysfs attribute (that belongs to serio device to which keyboard is attached) which can be used to set up force_release keymap. For example, Dell laptop owners might do: echo 133-139,143,147 > /sys/devices/platform/i8042/serio0/force_release Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers/input/keyboard/atkbd.c')
-rw-r--r--drivers/input/keyboard/atkbd.c43
1 files changed, 37 insertions, 6 deletions
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
index 95fe0452dae4..80835080fee9 100644
--- a/drivers/input/keyboard/atkbd.c
+++ b/drivers/input/keyboard/atkbd.c
@@ -68,7 +68,9 @@ MODULE_PARM_DESC(extra, "Enable extra LEDs and keys on IBM RapidAcces, EzKey and
68 * are loadable via a userland utility. 68 * are loadable via a userland utility.
69 */ 69 */
70 70
71static const unsigned short atkbd_set2_keycode[512] = { 71#define ATKBD_KEYMAP_SIZE 512
72
73static const unsigned short atkbd_set2_keycode[ATKBD_KEYMAP_SIZE] = {
72 74
73#ifdef CONFIG_KEYBOARD_ATKBD_HP_KEYCODES 75#ifdef CONFIG_KEYBOARD_ATKBD_HP_KEYCODES
74 76
@@ -99,7 +101,7 @@ static const unsigned short atkbd_set2_keycode[512] = {
99#endif 101#endif
100}; 102};
101 103
102static const unsigned short atkbd_set3_keycode[512] = { 104static const unsigned short atkbd_set3_keycode[ATKBD_KEYMAP_SIZE] = {
103 105
104 0, 0, 0, 0, 0, 0, 0, 59, 1,138,128,129,130, 15, 41, 60, 106 0, 0, 0, 0, 0, 0, 0, 59, 1,138,128,129,130, 15, 41, 60,
105 131, 29, 42, 86, 58, 16, 2, 61,133, 56, 44, 31, 30, 17, 3, 62, 107 131, 29, 42, 86, 58, 16, 2, 61,133, 56, 44, 31, 30, 17, 3, 62,
@@ -200,8 +202,8 @@ struct atkbd {
200 char phys[32]; 202 char phys[32];
201 203
202 unsigned short id; 204 unsigned short id;
203 unsigned short keycode[512]; 205 unsigned short keycode[ATKBD_KEYMAP_SIZE];
204 DECLARE_BITMAP(force_release_mask, 512); 206 DECLARE_BITMAP(force_release_mask, ATKBD_KEYMAP_SIZE);
205 unsigned char set; 207 unsigned char set;
206 unsigned char translated; 208 unsigned char translated;
207 unsigned char extra; 209 unsigned char extra;
@@ -253,6 +255,7 @@ static struct device_attribute atkbd_attr_##_name = \
253 __ATTR(_name, S_IWUSR | S_IRUGO, atkbd_do_show_##_name, atkbd_do_set_##_name); 255 __ATTR(_name, S_IWUSR | S_IRUGO, atkbd_do_show_##_name, atkbd_do_set_##_name);
254 256
255ATKBD_DEFINE_ATTR(extra); 257ATKBD_DEFINE_ATTR(extra);
258ATKBD_DEFINE_ATTR(force_release);
256ATKBD_DEFINE_ATTR(scroll); 259ATKBD_DEFINE_ATTR(scroll);
257ATKBD_DEFINE_ATTR(set); 260ATKBD_DEFINE_ATTR(set);
258ATKBD_DEFINE_ATTR(softrepeat); 261ATKBD_DEFINE_ATTR(softrepeat);
@@ -272,6 +275,7 @@ ATKBD_DEFINE_RO_ATTR(err_count);
272 275
273static struct attribute *atkbd_attributes[] = { 276static struct attribute *atkbd_attributes[] = {
274 &atkbd_attr_extra.attr, 277 &atkbd_attr_extra.attr,
278 &atkbd_attr_force_release.attr,
275 &atkbd_attr_scroll.attr, 279 &atkbd_attr_scroll.attr,
276 &atkbd_attr_set.attr, 280 &atkbd_attr_set.attr,
277 &atkbd_attr_softrepeat.attr, 281 &atkbd_attr_softrepeat.attr,
@@ -926,7 +930,7 @@ static void atkbd_set_keycode_table(struct atkbd *atkbd)
926 int i, j; 930 int i, j;
927 931
928 memset(atkbd->keycode, 0, sizeof(atkbd->keycode)); 932 memset(atkbd->keycode, 0, sizeof(atkbd->keycode));
929 bitmap_zero(atkbd->force_release_mask, 512); 933 bitmap_zero(atkbd->force_release_mask, ATKBD_KEYMAP_SIZE);
930 934
931 if (atkbd->translated) { 935 if (atkbd->translated) {
932 for (i = 0; i < 128; i++) { 936 for (i = 0; i < 128; i++) {
@@ -1033,7 +1037,7 @@ static void atkbd_set_device_attrs(struct atkbd *atkbd)
1033 input_dev->keycodesize = sizeof(unsigned short); 1037 input_dev->keycodesize = sizeof(unsigned short);
1034 input_dev->keycodemax = ARRAY_SIZE(atkbd_set2_keycode); 1038 input_dev->keycodemax = ARRAY_SIZE(atkbd_set2_keycode);
1035 1039
1036 for (i = 0; i < 512; i++) 1040 for (i = 0; i < ATKBD_KEYMAP_SIZE; i++)
1037 if (atkbd->keycode[i] && atkbd->keycode[i] < ATKBD_SPECIAL) 1041 if (atkbd->keycode[i] && atkbd->keycode[i] < ATKBD_SPECIAL)
1038 __set_bit(atkbd->keycode[i], input_dev->keybit); 1042 __set_bit(atkbd->keycode[i], input_dev->keybit);
1039} 1043}
@@ -1301,6 +1305,33 @@ static ssize_t atkbd_set_extra(struct atkbd *atkbd, const char *buf, size_t coun
1301 return count; 1305 return count;
1302} 1306}
1303 1307
1308static ssize_t atkbd_show_force_release(struct atkbd *atkbd, char *buf)
1309{
1310 size_t len = bitmap_scnlistprintf(buf, PAGE_SIZE - 2,
1311 atkbd->force_release_mask, ATKBD_KEYMAP_SIZE);
1312
1313 buf[len++] = '\n';
1314 buf[len] = '\0';
1315
1316 return len;
1317}
1318
1319static ssize_t atkbd_set_force_release(struct atkbd *atkbd,
1320 const char *buf, size_t count)
1321{
1322 /* 64 bytes on stack should be acceptable */
1323 DECLARE_BITMAP(new_mask, ATKBD_KEYMAP_SIZE);
1324 int err;
1325
1326 err = bitmap_parselist(buf, new_mask, ATKBD_KEYMAP_SIZE);
1327 if (err)
1328 return err;
1329
1330 memcpy(atkbd->force_release_mask, new_mask, sizeof(atkbd->force_release_mask));
1331 return count;
1332}
1333
1334
1304static ssize_t atkbd_show_scroll(struct atkbd *atkbd, char *buf) 1335static ssize_t atkbd_show_scroll(struct atkbd *atkbd, char *buf)
1305{ 1336{
1306 return sprintf(buf, "%d\n", atkbd->scroll ? 1 : 0); 1337 return sprintf(buf, "%d\n", atkbd->scroll ? 1 : 0);