~ubuntu-branches/debian/wheezy/linux-2.6/wheezy

« back to all changes in this revision

Viewing changes to drivers/platform/x86/topstar-laptop.c

  • Committer: Bazaar Package Importer
  • Author(s): Ben Hutchings, Ben Hutchings, Aurelien Jarno, Martin Michlmayr
  • Date: 2011-04-06 13:53:30 UTC
  • mfrom: (43.1.5 sid)
  • Revision ID: james.westby@ubuntu.com-20110406135330-wjufxhd0tvn3zx4z
Tags: 2.6.38-3
[ Ben Hutchings ]
* [ppc64] Add to linux-tools package architectures (Closes: #620124)
* [amd64] Save cr4 to mmu_cr4_features at boot time (Closes: #620284)
* appletalk: Fix bugs introduced when removing use of BKL
* ALSA: Fix yet another race in disconnection
* cciss: Fix lost command issue
* ath9k: Fix kernel panic in AR2427
* ses: Avoid kernel panic when lun 0 is not mapped
* PCI/ACPI: Report ASPM support to BIOS if not disabled from command line

[ Aurelien Jarno ]
* rtlwifi: fix build when PCI is not enabled.

[ Martin Michlmayr ]
* rtlwifi: Eliminate udelay calls with too large values (Closes: #620204)

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
#include <linux/kernel.h>
17
17
#include <linux/module.h>
18
18
#include <linux/init.h>
 
19
#include <linux/slab.h>
19
20
#include <linux/acpi.h>
20
21
#include <linux/input.h>
 
22
#include <linux/input/sparse-keymap.h>
21
23
 
22
24
#define ACPI_TOPSTAR_CLASS "topstar"
23
25
 
25
27
        struct input_dev *inputdev;
26
28
};
27
29
 
28
 
struct tps_key_entry {
29
 
        u8 code;
30
 
        u16 keycode;
31
 
};
32
 
 
33
 
static struct tps_key_entry topstar_keymap[] = {
34
 
        { 0x80, KEY_BRIGHTNESSUP },
35
 
        { 0x81, KEY_BRIGHTNESSDOWN },
36
 
        { 0x83, KEY_VOLUMEUP },
37
 
        { 0x84, KEY_VOLUMEDOWN },
38
 
        { 0x85, KEY_MUTE },
39
 
        { 0x86, KEY_SWITCHVIDEOMODE },
40
 
        { 0x87, KEY_F13 }, /* touchpad enable/disable key */
41
 
        { 0x88, KEY_WLAN },
42
 
        { 0x8a, KEY_WWW },
43
 
        { 0x8b, KEY_MAIL },
44
 
        { 0x8c, KEY_MEDIA },
45
 
        { 0x96, KEY_F14 }, /* G key? */
46
 
        { }
47
 
};
48
 
 
49
 
static struct tps_key_entry *tps_get_key_by_scancode(int code)
50
 
{
51
 
        struct tps_key_entry *key;
52
 
 
53
 
        for (key = topstar_keymap; key->code; key++)
54
 
                if (code == key->code)
55
 
                        return key;
56
 
 
57
 
        return NULL;
58
 
}
59
 
 
60
 
static struct tps_key_entry *tps_get_key_by_keycode(int code)
61
 
{
62
 
        struct tps_key_entry *key;
63
 
 
64
 
        for (key = topstar_keymap; key->code; key++)
65
 
                if (code == key->keycode)
66
 
                        return key;
67
 
 
68
 
        return NULL;
69
 
}
 
30
static const struct key_entry topstar_keymap[] = {
 
31
        { KE_KEY, 0x80, { KEY_BRIGHTNESSUP } },
 
32
        { KE_KEY, 0x81, { KEY_BRIGHTNESSDOWN } },
 
33
        { KE_KEY, 0x83, { KEY_VOLUMEUP } },
 
34
        { KE_KEY, 0x84, { KEY_VOLUMEDOWN } },
 
35
        { KE_KEY, 0x85, { KEY_MUTE } },
 
36
        { KE_KEY, 0x86, { KEY_SWITCHVIDEOMODE } },
 
37
        { KE_KEY, 0x87, { KEY_F13 } }, /* touchpad enable/disable key */
 
38
        { KE_KEY, 0x88, { KEY_WLAN } },
 
39
        { KE_KEY, 0x8a, { KEY_WWW } },
 
40
        { KE_KEY, 0x8b, { KEY_MAIL } },
 
41
        { KE_KEY, 0x8c, { KEY_MEDIA } },
 
42
 
 
43
        /* Known non hotkey events don't handled or that we don't care yet */
 
44
        { KE_IGNORE, 0x8e, },
 
45
        { KE_IGNORE, 0x8f, },
 
46
        { KE_IGNORE, 0x90, },
 
47
 
 
48
        /*
 
49
         * 'G key' generate two event codes, convert to only
 
50
         * one event/key code for now, consider replacing by
 
51
         * a switch (3G switch - SW_3G?)
 
52
         */
 
53
        { KE_KEY, 0x96, { KEY_F14 } },
 
54
        { KE_KEY, 0x97, { KEY_F14 } },
 
55
 
 
56
        { KE_END, 0 }
 
57
};
70
58
 
71
59
static void acpi_topstar_notify(struct acpi_device *device, u32 event)
72
60
{
73
 
        struct tps_key_entry *key;
74
61
        static bool dup_evnt[2];
75
62
        bool *dup;
76
63
        struct topstar_hkey *hkey = acpi_driver_data(device);
85
72
                *dup = true;
86
73
        }
87
74
 
88
 
        /*
89
 
         * 'G key' generate two event codes, convert to only
90
 
         * one event/key code for now (3G switch?)
91
 
         */
92
 
        if (event == 0x97)
93
 
                event = 0x96;
94
 
 
95
 
        key = tps_get_key_by_scancode(event);
96
 
        if (key) {
97
 
                input_report_key(hkey->inputdev, key->keycode, 1);
98
 
                input_sync(hkey->inputdev);
99
 
                input_report_key(hkey->inputdev, key->keycode, 0);
100
 
                input_sync(hkey->inputdev);
101
 
                return;
102
 
        }
103
 
 
104
 
        /* Known non hotkey events don't handled or that we don't care yet */
105
 
        if (event == 0x8e || event == 0x8f || event == 0x90)
106
 
                return;
107
 
 
108
 
        pr_info("unknown event = 0x%02x\n", event);
 
75
        if (!sparse_keymap_report_event(hkey->inputdev, event, 1, true))
 
76
                pr_info("unknown event = 0x%02x\n", event);
109
77
}
110
78
 
111
79
static int acpi_topstar_fncx_switch(struct acpi_device *device, bool state)
126
94
        return 0;
127
95
}
128
96
 
129
 
static int topstar_getkeycode(struct input_dev *dev, int scancode, int *keycode)
130
 
{
131
 
        struct tps_key_entry *key = tps_get_key_by_scancode(scancode);
132
 
 
133
 
        if (!key)
134
 
                return -EINVAL;
135
 
 
136
 
        *keycode = key->keycode;
137
 
        return 0;
138
 
}
139
 
 
140
 
static int topstar_setkeycode(struct input_dev *dev, int scancode, int keycode)
141
 
{
142
 
        struct tps_key_entry *key;
143
 
        int old_keycode;
144
 
 
145
 
        if (keycode < 0 || keycode > KEY_MAX)
146
 
                return -EINVAL;
147
 
 
148
 
        key = tps_get_key_by_scancode(scancode);
149
 
 
150
 
        if (!key)
151
 
                return -EINVAL;
152
 
 
153
 
        old_keycode = key->keycode;
154
 
        key->keycode = keycode;
155
 
        set_bit(keycode, dev->keybit);
156
 
        if (!tps_get_key_by_keycode(old_keycode))
157
 
                clear_bit(old_keycode, dev->keybit);
158
 
        return 0;
159
 
}
160
 
 
161
97
static int acpi_topstar_init_hkey(struct topstar_hkey *hkey)
162
98
{
163
 
        struct tps_key_entry *key;
 
99
        struct input_dev *input;
 
100
        int error;
164
101
 
165
 
        hkey->inputdev = input_allocate_device();
166
 
        if (!hkey->inputdev) {
 
102
        input = input_allocate_device();
 
103
        if (!input) {
167
104
                pr_err("Unable to allocate input device\n");
168
 
                return -ENODEV;
169
 
        }
170
 
        hkey->inputdev->name = "Topstar Laptop extra buttons";
171
 
        hkey->inputdev->phys = "topstar/input0";
172
 
        hkey->inputdev->id.bustype = BUS_HOST;
173
 
        hkey->inputdev->getkeycode = topstar_getkeycode;
174
 
        hkey->inputdev->setkeycode = topstar_setkeycode;
175
 
        for (key = topstar_keymap; key->code; key++) {
176
 
                set_bit(EV_KEY, hkey->inputdev->evbit);
177
 
                set_bit(key->keycode, hkey->inputdev->keybit);
178
 
        }
179
 
        if (input_register_device(hkey->inputdev)) {
 
105
                return -ENOMEM;
 
106
        }
 
107
 
 
108
        input->name = "Topstar Laptop extra buttons";
 
109
        input->phys = "topstar/input0";
 
110
        input->id.bustype = BUS_HOST;
 
111
 
 
112
        error = sparse_keymap_setup(input, topstar_keymap, NULL);
 
113
        if (error) {
 
114
                pr_err("Unable to setup input device keymap\n");
 
115
                goto err_free_dev;
 
116
        }
 
117
 
 
118
        error = input_register_device(input);
 
119
        if (error) {
180
120
                pr_err("Unable to register input device\n");
181
 
                input_free_device(hkey->inputdev);
182
 
                return -ENODEV;
 
121
                goto err_free_keymap;
183
122
        }
184
123
 
 
124
        hkey->inputdev = input;
185
125
        return 0;
 
126
 
 
127
 err_free_keymap:
 
128
        sparse_keymap_free(input);
 
129
 err_free_dev:
 
130
        input_free_device(input);
 
131
        return error;
186
132
}
187
133
 
188
134
static int acpi_topstar_add(struct acpi_device *device)
216
162
 
217
163
        acpi_topstar_fncx_switch(device, false);
218
164
 
 
165
        sparse_keymap_free(tps_hkey->inputdev);
219
166
        input_unregister_device(tps_hkey->inputdev);
220
167
        kfree(tps_hkey);
221
168