~ubuntu-branches/ubuntu/precise/linux-ti-omap/precise

« back to all changes in this revision

Viewing changes to ubuntu/omnibook/polling.c

  • Committer: Bazaar Package Importer
  • Author(s): Stefan Bader, Amit Kucheria
  • Date: 2010-03-23 18:05:12 UTC
  • Revision ID: james.westby@ubuntu.com-20100323180512-iavj906ocnphdubp
Tags: 2.6.33-500.3
[ Amit Kucheria ]

* [Config] Fix the debug package name to end in -dbgsym
* SAUCE: Add the ubuntu/ drivers to omap
* SAUCE: Re-export the symbols for aufs
* [Config] Enable AUFS and COMPCACHE

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * polling.c -- scancode emulation for volume 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
#include <linux/workqueue.h>
 
21
#include <linux/jiffies.h>
 
22
 
 
23
/*
 
24
 * XE3GC type key_polling polling:
 
25
 *
 
26
 * Polling interval for keys (100 ms)
 
27
 */
 
28
 
 
29
#define OMNIBOOK_POLL   msecs_to_jiffies(100)
 
30
 
 
31
/*
 
32
 * workqueue manipulations are mutex protected and thus kept in sync with key_polling_enabled
 
33
 */
 
34
static struct workqueue_struct *omnibook_wq;  
 
35
static int key_polling_enabled;
 
36
static DEFINE_MUTEX(poll_mutex);
 
37
 
 
38
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,19))
 
39
static void omnibook_key_poller(struct work_struct *work);
 
40
DECLARE_DELAYED_WORK(omnibook_poll_work, *omnibook_key_poller);
 
41
#else
 
42
static void omnibook_key_poller(void *data);
 
43
DECLARE_WORK(omnibook_poll_work, *omnibook_key_poller, NULL);
 
44
#endif
 
45
 
 
46
static struct omnibook_feature key_polling_driver;
 
47
static struct input_dev *poll_input_dev;
 
48
 
 
49
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,19))
 
50
        static void omnibook_key_poller(struct work_struct *work)
 
51
#else
 
52
        static void omnibook_key_poller(void *data)
 
53
#endif
 
54
{
 
55
        u8 q0a;
 
56
        int retval;
 
57
 
 
58
        mutex_lock(&key_polling_driver.io_op->backend->mutex);
 
59
        __backend_byte_read(key_polling_driver.io_op, &q0a);
 
60
        __backend_byte_write(key_polling_driver.io_op, 0);
 
61
        mutex_unlock(&key_polling_driver.io_op->backend->mutex);
 
62
 
 
63
#ifdef CONFIG_OMNIBOOK_DEBUG
 
64
        if (unlikely(q0a & XE3GC_SLPB_MASK))
 
65
                dprintk("Sleep button pressed.\n");
 
66
        if (unlikely(q0a & XE3GC_F5_MASK))
 
67
                dprintk("Fn-F5 - LCD/CRT switch pressed.\n");
 
68
        if (unlikely(q0a & XE3GC_CNTR_MASK))
 
69
                dprintk("Fn+F3/Fn+F4 - Contrast up or down pressed.\n");
 
70
        if (unlikely(q0a & XE3GC_BRGT_MASK))
 
71
                dprintk("Fn+F1/Fn+F2 - Brightness up or down pressed.\n");
 
72
#endif
 
73
 
 
74
        /*
 
75
         * Volume button scancode emulaton
 
76
         * It emulates a key press and a release without repeat as other OneTouch buttons do.
 
77
         */
 
78
 
 
79
        if (unlikely(q0a & XE3GC_VOLD_MASK)) {
 
80
                dprintk("Fn-down arrow or Volume down pressed.\n");
 
81
                omnibook_report_key(poll_input_dev, KEY_VOLUMEDOWN);
 
82
        }
 
83
        if (unlikely(q0a & XE3GC_VOLU_MASK)) {
 
84
                dprintk("Fn-up arrow or Volume up pressed.\n");
 
85
                omnibook_report_key(poll_input_dev, KEY_VOLUMEUP);
 
86
        }
 
87
        if (unlikely(q0a & XE3GC_MUTE_MASK)) {
 
88
                dprintk("Fn+F7 - Volume mute pressed.\n");
 
89
                omnibook_report_key(poll_input_dev, KEY_MUTE);
 
90
        }
 
91
 
 
92
        retval = queue_delayed_work(omnibook_wq, &omnibook_poll_work, OMNIBOOK_POLL);
 
93
        if(unlikely(!retval)) /* here non-zero on success */
 
94
                printk(O_ERR "Key_poller failed to rearm.\n");
 
95
}
 
96
 
 
97
static int omnibook_key_polling_enable(void)
 
98
{
 
99
        int retval = 0;
 
100
 
 
101
        if(mutex_lock_interruptible(&poll_mutex))
 
102
                return -ERESTARTSYS;
 
103
 
 
104
        if(key_polling_enabled)
 
105
                goto out;
 
106
 
 
107
        retval = !queue_delayed_work(omnibook_wq, &omnibook_poll_work, OMNIBOOK_POLL);
 
108
        if(retval)
 
109
                printk(O_ERR "Key_poller enabling failed.\n");
 
110
        else {  
 
111
                dprintk("Scancode emulation for volume buttons enabled.\n");
 
112
                key_polling_enabled = 1;
 
113
        }
 
114
 
 
115
        out:
 
116
        mutex_unlock(&poll_mutex);
 
117
        return retval;
 
118
}
 
119
        
 
120
static int omnibook_key_polling_disable(void)
 
121
{
 
122
        if(mutex_lock_interruptible(&poll_mutex))
 
123
                return -ERESTARTSYS;
 
124
 
 
125
        if(!key_polling_enabled)
 
126
                goto out;
 
127
 
 
128
        cancel_rearming_delayed_workqueue(omnibook_wq, &omnibook_poll_work);
 
129
        dprintk("Scancode emulation for volume buttons disabled.\n");
 
130
        key_polling_enabled = 0;
 
131
 
 
132
        out:
 
133
        mutex_unlock(&poll_mutex);
 
134
        return 0;
 
135
}
 
136
 
 
137
 
 
138
static int omnibook_key_polling_read(char *buffer, struct omnibook_operation *io_op)
 
139
{
 
140
        int len = 0;
 
141
        
 
142
        if(mutex_lock_interruptible(&poll_mutex))
 
143
                return -ERESTARTSYS;
 
144
 
 
145
        len += sprintf(buffer + len, "Volume buttons polling is %s.\n",
 
146
                (key_polling_enabled) ? "enabled" : "disabled");
 
147
#ifdef CONFIG_OMNIBOOK_DEBUG
 
148
        if(key_polling_enabled) 
 
149
                len += sprintf(buffer + len, "Will poll in %i msec.\n",
 
150
                jiffies_to_msecs(omnibook_poll_work.timer.expires - jiffies));
 
151
#endif
 
152
        mutex_unlock(&poll_mutex);
 
153
        return len;
 
154
}
 
155
 
 
156
static int omnibook_key_polling_write(char *buffer, struct omnibook_operation *io_op)
 
157
{
 
158
        int retval;
 
159
        switch (*buffer) {
 
160
        case '0':
 
161
                retval = omnibook_key_polling_disable();
 
162
                break;
 
163
        case '1':
 
164
                retval = omnibook_key_polling_enable();
 
165
                break;
 
166
        default:
 
167
                retval = -EINVAL;
 
168
        }
 
169
        return retval;
 
170
}
 
171
 
 
172
 
 
173
/*
 
174
 * Stop polling upon suspend an restore it upon resume
 
175
 */
 
176
static int omnibook_key_polling_resume(struct omnibook_operation *io_op)
 
177
{
 
178
        int retval = 0;
 
179
 
 
180
        mutex_lock(&poll_mutex);
 
181
        if(key_polling_enabled)
 
182
                retval = !queue_delayed_work(omnibook_wq, &omnibook_poll_work, OMNIBOOK_POLL);
 
183
        mutex_unlock(&poll_mutex);
 
184
        return retval;  
 
185
}
 
186
 
 
187
static int omnibook_key_polling_suspend(struct omnibook_operation *io_op)
 
188
{
 
189
        mutex_lock(&poll_mutex);
 
190
        if(key_polling_enabled)
 
191
                cancel_rearming_delayed_workqueue(omnibook_wq, &omnibook_poll_work);
 
192
        mutex_unlock(&poll_mutex);
 
193
        return 0;
 
194
}
 
195
 
 
196
static int __init omnibook_key_polling_init(struct omnibook_operation *io_op)
 
197
{
 
198
        int retval = 0; 
 
199
        
 
200
        poll_input_dev = input_allocate_device();
 
201
        if (!poll_input_dev) {
 
202
                retval = -ENOMEM;
 
203
                goto out;
 
204
        }
 
205
 
 
206
        poll_input_dev->name = "Omnibook legacy laptop scancode generator";
 
207
        poll_input_dev->phys = "omnibook/input0";
 
208
        poll_input_dev->id.bustype = BUS_HOST;
 
209
        
 
210
        /* this device has three keys */
 
211
        set_bit(EV_KEY, poll_input_dev->evbit);
 
212
        set_bit(KEY_VOLUMEDOWN, poll_input_dev->keybit);
 
213
        set_bit(KEY_VOLUMEUP, poll_input_dev->keybit);
 
214
        set_bit(KEY_MUTE, poll_input_dev->keybit);
 
215
 
 
216
        retval = input_register_device(poll_input_dev);
 
217
        if (retval) {
 
218
                input_free_device(poll_input_dev);
 
219
                goto out;
 
220
        }
 
221
 
 
222
        omnibook_wq = create_singlethread_workqueue("omnibook");
 
223
        if(!omnibook_wq)
 
224
                retval = -ENOMEM;
 
225
        else
 
226
                retval = omnibook_key_polling_enable();
 
227
 
 
228
out:
 
229
        return retval;
 
230
}
 
231
 
 
232
static void __exit omnibook_key_polling_cleanup(struct omnibook_operation *io_op)
 
233
{
 
234
        omnibook_key_polling_disable(); 
 
235
        destroy_workqueue(omnibook_wq);
 
236
        input_unregister_device(poll_input_dev);
 
237
}
 
238
 
 
239
static struct omnibook_tbl key_polling_table[] __initdata = {
 
240
        {XE3GC, SIMPLE_BYTE(EC, XE3GC_Q0A, 0)},
 
241
        {0,}
 
242
};
 
243
 
 
244
static struct omnibook_feature __declared_feature key_polling_driver = {
 
245
        .name = "key_polling",
 
246
        .enabled = 0, /* dangerous */
 
247
        .read = omnibook_key_polling_read,
 
248
        .write = omnibook_key_polling_write,
 
249
        .init = omnibook_key_polling_init,
 
250
        .exit = omnibook_key_polling_cleanup,
 
251
        .suspend = omnibook_key_polling_suspend,
 
252
        .resume = omnibook_key_polling_resume,
 
253
        .ectypes = XE3GC,
 
254
        .tbl = key_polling_table,
 
255
};
 
256
 
 
257
module_param_named(key_polling, key_polling_driver.enabled, int, S_IRUGO);
 
258
MODULE_PARM_DESC(key_polling, "Use 0 to disable, 1 to enable key polling");
 
259
/* End of file */