diff options
Diffstat (limited to 'meta/recipes-kernel/linux/linux-rp-2.6.26/sharpsl-rc-r1.patch')
-rw-r--r-- | meta/recipes-kernel/linux/linux-rp-2.6.26/sharpsl-rc-r1.patch | 602 |
1 files changed, 602 insertions, 0 deletions
diff --git a/meta/recipes-kernel/linux/linux-rp-2.6.26/sharpsl-rc-r1.patch b/meta/recipes-kernel/linux/linux-rp-2.6.26/sharpsl-rc-r1.patch new file mode 100644 index 0000000000..c4b95ad4f8 --- /dev/null +++ b/meta/recipes-kernel/linux/linux-rp-2.6.26/sharpsl-rc-r1.patch | |||
@@ -0,0 +1,602 @@ | |||
1 | This patch adds support for Sharp CE-RH2 on Spitz. | ||
2 | |||
3 | It is not clean enough to be upstreamed: | ||
4 | - It is a bit syslog-noisy. | ||
5 | - Does not support other Zaurus models. | ||
6 | - Maybe split to more parts: | ||
7 | * MAX1111 driver | ||
8 | * linear input device | ||
9 | * virtual keyboard on top of linear input device | ||
10 | |||
11 | --- | ||
12 | arch/arm/mach-pxa/sharpsl.h | 7 | ||
13 | arch/arm/mach-pxa/sharpsl_pm.c | 2 | ||
14 | arch/arm/mach-pxa/spitz.c | 8 | ||
15 | arch/arm/mach-pxa/spitz_pm.c | 7 | ||
16 | drivers/input/keyboard/Kconfig | 11 + | ||
17 | drivers/input/keyboard/Makefile | 1 | ||
18 | drivers/input/keyboard/sharpsl_rc.c | 319 ++++++++++++++++++++++++++++++++++ | ||
19 | drivers/input/keyboard/spitzkbd.c | 27 ++ | ||
20 | include/asm-arm/hardware/sharpsl_pm.h | 7 | ||
21 | include/linux/input.h | 1 | ||
22 | 10 files changed, 382 insertions(+), 8 deletions(-) | ||
23 | |||
24 | --- linux-2.6.26.orig/arch/arm/mach-pxa/sharpsl.h | ||
25 | +++ linux-2.6.26/arch/arm/mach-pxa/sharpsl.h | ||
26 | @@ -35,17 +35,12 @@ void corgi_lcdtg_hw_init(int mode); | ||
27 | /* | ||
28 | * SharpSL Battery/PM Driver | ||
29 | */ | ||
30 | #define READ_GPIO_BIT(x) (GPLR(x) & GPIO_bit(x)) | ||
31 | |||
32 | -/* MAX1111 Channel Definitions */ | ||
33 | -#define MAX1111_BATT_VOLT 4u | ||
34 | -#define MAX1111_BATT_TEMP 2u | ||
35 | -#define MAX1111_ACIN_VOLT 6u | ||
36 | - | ||
37 | extern struct battery_thresh spitz_battery_levels_acin[]; | ||
38 | extern struct battery_thresh spitz_battery_levels_noac[]; | ||
39 | void sharpsl_pm_pxa_init(void); | ||
40 | void sharpsl_pm_pxa_remove(void); | ||
41 | -int sharpsl_pm_pxa_read_max1111(int channel); | ||
42 | + | ||
43 | |||
44 | |||
45 | --- linux-2.6.26.orig/arch/arm/mach-pxa/sharpsl_pm.c | ||
46 | +++ linux-2.6.26/arch/arm/mach-pxa/sharpsl_pm.c | ||
47 | @@ -134,10 +134,12 @@ int sharpsl_pm_pxa_read_max1111(int chan | ||
48 | |||
49 | return corgi_ssp_max1111_get((channel << MAXCTRL_SEL_SH) | MAXCTRL_PD0 | MAXCTRL_PD1 | ||
50 | | MAXCTRL_SGL | MAXCTRL_UNI | MAXCTRL_STR); | ||
51 | } | ||
52 | |||
53 | +EXPORT_SYMBOL(sharpsl_pm_pxa_read_max1111); | ||
54 | + | ||
55 | void sharpsl_pm_pxa_init(void) | ||
56 | { | ||
57 | pxa_gpio_mode(sharpsl_pm.machinfo->gpio_acin | GPIO_IN); | ||
58 | pxa_gpio_mode(sharpsl_pm.machinfo->gpio_batfull | GPIO_IN); | ||
59 | pxa_gpio_mode(sharpsl_pm.machinfo->gpio_batlock | GPIO_IN); | ||
60 | --- linux-2.6.26.orig/arch/arm/mach-pxa/spitz.c | ||
61 | +++ linux-2.6.26/arch/arm/mach-pxa/spitz.c | ||
62 | @@ -259,10 +259,17 @@ static struct platform_device spitzbl_de | ||
63 | static struct platform_device spitzkbd_device = { | ||
64 | .name = "spitz-keyboard", | ||
65 | .id = -1, | ||
66 | }; | ||
67 | |||
68 | +/* | ||
69 | + * Spitz Remote Control Device | ||
70 | + */ | ||
71 | +static struct platform_device sharpsl_rc_device = { | ||
72 | + .name = "sharpsl-remote-control", | ||
73 | + .id = -1, | ||
74 | +}; | ||
75 | |||
76 | /* | ||
77 | * Spitz LEDs | ||
78 | */ | ||
79 | static struct platform_device spitzled_device = { | ||
80 | @@ -520,10 +527,11 @@ static struct pxafb_mach_info spitz_pxaf | ||
81 | |||
82 | static struct platform_device *devices[] __initdata = { | ||
83 | &spitzscoop_device, | ||
84 | &spitzssp_device, | ||
85 | &spitzkbd_device, | ||
86 | + &sharpsl_rc_device, | ||
87 | &spitzts_device, | ||
88 | &spitzbl_device, | ||
89 | &spitzled_device, | ||
90 | }; | ||
91 | |||
92 | --- linux-2.6.26.orig/arch/arm/mach-pxa/spitz_pm.c | ||
93 | +++ linux-2.6.26/arch/arm/mach-pxa/spitz_pm.c | ||
94 | @@ -158,10 +158,17 @@ static int spitz_should_wakeup(unsigned | ||
95 | is_resume |= GPIO_bit(SPITZ_GPIO_SYNC); | ||
96 | |||
97 | if (resume_on_alarm && (PEDR & PWER_RTC)) | ||
98 | is_resume |= PWER_RTC; | ||
99 | |||
100 | + printk("wakeup: PEDR: %x, PKSR: %x, HP_IN: %x, AK_INT: %x\n", PEDR, PKSR, GPIO_bit(SPITZ_GPIO_HP_IN), GPIO_bit(SPITZ_GPIO_AK_INT)); | ||
101 | + | ||
102 | + //remote/headphone interrupt, wakeup | ||
103 | + if (PEDR == 0 && (PKSR & 0xc0d01) != 0) { | ||
104 | + is_resume |= PWER_RTC; | ||
105 | + } | ||
106 | + | ||
107 | dev_dbg(sharpsl_pm.dev, "is_resume: %x\n",is_resume); | ||
108 | return is_resume; | ||
109 | } | ||
110 | |||
111 | static unsigned long spitz_charger_wakeup(void) | ||
112 | --- linux-2.6.26.orig/drivers/input/keyboard/Kconfig | ||
113 | +++ linux-2.6.26/drivers/input/keyboard/Kconfig | ||
114 | @@ -173,10 +173,21 @@ config KEYBOARD_TOSA_USE_EXT_KEYCODES | ||
115 | (>= 127) keycodes. Be aware, that they can't be correctly interpreted | ||
116 | by either console keyboard driver or by Kdrive keybd driver. | ||
117 | |||
118 | Say Y only if you know, what you are doing! | ||
119 | |||
120 | +config SHARPSL_RC | ||
121 | + tristate "Sharp SL-Cxx00 Remote Control" | ||
122 | + depends on PXA_SHARPSL | ||
123 | + default y | ||
124 | + help | ||
125 | + Say Y here to enable the remote on the Sharp Zaurus SL-Cxx00, | ||
126 | + SL-C1000, SL-C3000 and Sl-C3100 series of PDAs. | ||
127 | + | ||
128 | + To compile this driver as a module, choose M here: the | ||
129 | + module will be called sharpsl_rc. | ||
130 | + | ||
131 | config KEYBOARD_AMIGA | ||
132 | tristate "Amiga keyboard" | ||
133 | depends on AMIGA | ||
134 | help | ||
135 | Say Y here if you are running Linux on any AMIGA and have a keyboard | ||
136 | --- linux-2.6.26.orig/drivers/input/keyboard/Makefile | ||
137 | +++ linux-2.6.26/drivers/input/keyboard/Makefile | ||
138 | @@ -24,6 +24,7 @@ obj-$(CONFIG_KEYBOARD_AAED2000) += aaed | ||
139 | obj-$(CONFIG_KEYBOARD_GPIO) += gpio_keys.o | ||
140 | obj-$(CONFIG_KEYBOARD_HP6XX) += jornada680_kbd.o | ||
141 | obj-$(CONFIG_KEYBOARD_HP7XX) += jornada720_kbd.o | ||
142 | obj-$(CONFIG_KEYBOARD_MAPLE) += maple_keyb.o | ||
143 | obj-$(CONFIG_KEYBOARD_BFIN) += bf54x-keys.o | ||
144 | +obj-$(CONFIG_SHARPSL_RC) += sharpsl_rc.o | ||
145 | obj-$(CONFIG_KEYBOARD_SH_KEYSC) += sh_keysc.o | ||
146 | --- /dev/null | ||
147 | +++ linux-2.6.26/drivers/input/keyboard/sharpsl_rc.c | ||
148 | @@ -0,0 +1,319 @@ | ||
149 | +/* | ||
150 | + * Keyboard driver for Sharp Clamshell Models (SL-Cxx00) | ||
151 | + * | ||
152 | + * Copyright (c) 2004-2005 Richard Purdie | ||
153 | + * | ||
154 | + * Based on corgikbd.c and Sharp's RC driver | ||
155 | + * | ||
156 | + * This program is free software; you can redistribute it and/or modify | ||
157 | + * it under the terms of the GNU General Public License version 2 as | ||
158 | + * published by the Free Software Foundation. | ||
159 | + * | ||
160 | + */ | ||
161 | + | ||
162 | +#define DEBUG 1 | ||
163 | +#include <linux/delay.h> | ||
164 | +#include <linux/platform_device.h> | ||
165 | +#include <linux/init.h> | ||
166 | +#include <linux/input.h> | ||
167 | +#include <linux/interrupt.h> | ||
168 | +#include <linux/jiffies.h> | ||
169 | +#include <linux/module.h> | ||
170 | +#include <linux/slab.h> | ||
171 | + | ||
172 | +#include <asm/mach-types.h> | ||
173 | +#include <asm/arch/spitz.h> | ||
174 | +#include <asm/arch/akita.h> | ||
175 | +#include <asm/arch/corgi.h> | ||
176 | + | ||
177 | +#include <asm/arch/hardware.h> | ||
178 | +#include <asm/arch/pxa-regs.h> | ||
179 | +#include <asm/arch/pxa2xx-gpio.h> | ||
180 | +#include <asm/hardware/scoop.h> | ||
181 | +#include <asm/arch/sharpsl.h> | ||
182 | +#include <asm/hardware/sharpsl_pm.h> | ||
183 | + | ||
184 | +#define DPRINTK(fmt, args...) dev_dbg(data->dev, fmt "\n", ##args) | ||
185 | + | ||
186 | +struct remote_control_key { | ||
187 | + unsigned char min; | ||
188 | + unsigned char max; | ||
189 | + unsigned char key; | ||
190 | +}; | ||
191 | + | ||
192 | +static struct remote_control_key remote_keys_spitz[] = { | ||
193 | + /* CE-RH2 values */ | ||
194 | + { 25, 35, KEY_STOPCD}, | ||
195 | + { 55, 65, KEY_PLAYPAUSE}, | ||
196 | + { 85, 95, KEY_NEXTSONG}, | ||
197 | + { 115, 125, KEY_VOLUMEUP}, | ||
198 | + { 145, 155, KEY_PREVIOUSSONG}, | ||
199 | + { 180, 190, KEY_MUTE}, | ||
200 | + { 215, 225, KEY_VOLUMEDOWN}, | ||
201 | +}; | ||
202 | +static struct remote_control_key remote_keys_corgi[] = { | ||
203 | + /* CE-RH1 values */ | ||
204 | + { 27, 35, KEY_STOPCD}, | ||
205 | + { 7, 13, KEY_PLAYPAUSE}, | ||
206 | + { 77, 93, KEY_NEXTSONG}, | ||
207 | + { 115, 132, KEY_VOLUMEUP}, | ||
208 | + { 46, 58, KEY_PREVIOUSSONG}, | ||
209 | + { 170, 186, KEY_VOLUMEDOWN}, | ||
210 | +}; | ||
211 | + | ||
212 | +#define RELEASE_HI 230 | ||
213 | +#define MAX_EARPHONE 6 | ||
214 | +#define RC_POLL_MS 10 | ||
215 | +#define RC_FINISH_MS 500 | ||
216 | +#define WAIT_STATE 3 | ||
217 | +#define NOISE_THRESHOLD 100 | ||
218 | + | ||
219 | +struct sharpsl_rc { | ||
220 | + struct input_dev *input; | ||
221 | + struct device *dev; | ||
222 | + | ||
223 | + spinlock_t lock; | ||
224 | + struct timer_list rctimer; | ||
225 | + struct timer_list rctimer_finish; | ||
226 | + | ||
227 | + unsigned int handling_press; | ||
228 | + unsigned int noise; | ||
229 | + unsigned int state; | ||
230 | + unsigned int last_key; | ||
231 | +}; | ||
232 | + | ||
233 | +static int get_remocon_raw(void) | ||
234 | +{ | ||
235 | + int i, val; | ||
236 | + struct remote_control_key *remote_keys; | ||
237 | + | ||
238 | + if (machine_is_borzoi() || machine_is_spitz() || machine_is_akita()) | ||
239 | + remote_keys = remote_keys_spitz; | ||
240 | + else | ||
241 | + remote_keys = remote_keys_corgi; | ||
242 | + | ||
243 | + val = sharpsl_pm_pxa_read_max1111(MAX1111_REMCOM); | ||
244 | + for (i = 0; i < (machine_is_borzoi() || machine_is_spitz() || machine_is_akita() ? | ||
245 | + ARRAY_SIZE(remote_keys_spitz) : ARRAY_SIZE(remote_keys_corgi)); | ||
246 | + ++i) { | ||
247 | + if (val >= remote_keys[i].min | ||
248 | + && val <= remote_keys[i].max) { | ||
249 | + printk("get_remocon_raw: VAL=%i, KEY=%i\n", val, remote_keys[i].key); | ||
250 | + return remote_keys[i].key; | ||
251 | + } | ||
252 | + } | ||
253 | + return 0; | ||
254 | +} | ||
255 | + | ||
256 | +static irqreturn_t sharpsl_rc_interrupt(int irq, void *dev_id) | ||
257 | +{ | ||
258 | + struct sharpsl_rc *data = dev_id; | ||
259 | + DPRINTK("sharpsl_rc_interrupt %d\n", irq); | ||
260 | + if (!data->handling_press) { | ||
261 | + DPRINTK("handling interrupt"); | ||
262 | + data->handling_press = 1; | ||
263 | + data->noise = 0; | ||
264 | + data->state = 0; | ||
265 | + data->last_key = 0; | ||
266 | + | ||
267 | + if (machine_is_borzoi() || machine_is_spitz()) | ||
268 | + reset_scoop_gpio(platform_scoop_config->devs[1].dev, SPITZ_SCP2_AKIN_PULLUP); | ||
269 | + else if (machine_is_akita()) | ||
270 | + akita_reset_ioexp(&akitaioexp_device.dev, AKITA_IOEXP_AKIN_PULLUP); | ||
271 | + else | ||
272 | + reset_scoop_gpio(platform_scoop_config->devs[0].dev, CORGI_SCP_AKIN_PULLUP); | ||
273 | + mod_timer(&data->rctimer, jiffies + msecs_to_jiffies(RC_POLL_MS)); | ||
274 | + } | ||
275 | + return IRQ_HANDLED; | ||
276 | +} | ||
277 | + | ||
278 | +static void sharpsl_rc_timer_callback(unsigned long dataPtr) | ||
279 | +{ | ||
280 | + struct sharpsl_rc *data = (struct sharpsl_rc *) dataPtr; | ||
281 | + int timer = 1; | ||
282 | + int key = get_remocon_raw(); | ||
283 | + DPRINTK("timer callback, key: %d", key); | ||
284 | + | ||
285 | + //wait for value to stabilize | ||
286 | + if (data->state < WAIT_STATE) { | ||
287 | + if (data->last_key != key) { | ||
288 | + ++data->noise; | ||
289 | + if (data->noise > NOISE_THRESHOLD) { | ||
290 | + DPRINTK("too much noise, bailing"); | ||
291 | + timer = 0; | ||
292 | + } | ||
293 | + data->state = 0; | ||
294 | + } else { | ||
295 | + ++data->state; | ||
296 | + } | ||
297 | + data->last_key = key; | ||
298 | + | ||
299 | + //stable value, send event | ||
300 | + } else if (data->state == WAIT_STATE) { | ||
301 | + data->noise = 0; | ||
302 | + //non-key returned, skip the rest of the states and bail now | ||
303 | + if (data->last_key == 0) { | ||
304 | + DPRINTK("non-key detected %d, noise: %d", data->last_key, data->noise); | ||
305 | + timer = 0; | ||
306 | + //send button press | ||
307 | + } else { | ||
308 | + DPRINTK("key press detected %d, noise %d", data->last_key, data->noise); | ||
309 | + input_report_key(data->input, data->last_key, 1); | ||
310 | + } | ||
311 | + ++data->state; | ||
312 | + | ||
313 | + //wait until key is released | ||
314 | + } else if (data->state < WAIT_STATE * 2) { | ||
315 | + if (key == data->last_key | ||
316 | + && data->noise < NOISE_THRESHOLD) { | ||
317 | + data->state = WAIT_STATE + 1; | ||
318 | + ++data->noise; | ||
319 | + } else { | ||
320 | + ++data->state; | ||
321 | + } | ||
322 | + //key is released, send event | ||
323 | + } else { | ||
324 | + //send button release | ||
325 | + DPRINTK("release key %d", data->last_key); | ||
326 | + input_report_key(data->input, data->last_key, 0); | ||
327 | + timer = 0; | ||
328 | + } | ||
329 | + if (timer) { | ||
330 | + mod_timer(&data->rctimer, jiffies + msecs_to_jiffies(RC_POLL_MS)); | ||
331 | + } else { | ||
332 | + if (machine_is_borzoi() || machine_is_spitz()) | ||
333 | + set_scoop_gpio(platform_scoop_config->devs[1].dev, SPITZ_SCP2_AKIN_PULLUP); | ||
334 | + else if (machine_is_akita()) | ||
335 | + akita_set_ioexp(&akitaioexp_device.dev, AKITA_IOEXP_AKIN_PULLUP); | ||
336 | + else | ||
337 | + set_scoop_gpio(platform_scoop_config->devs[0].dev, CORGI_SCP_AKIN_PULLUP); | ||
338 | + data->handling_press = 0; | ||
339 | + } | ||
340 | +} | ||
341 | + | ||
342 | +static int __init sharpsl_rc_probe(struct platform_device *pdev) | ||
343 | +{ | ||
344 | + struct sharpsl_rc *sharpsl_rc; | ||
345 | + struct input_dev *input_dev; | ||
346 | + int i, ret; | ||
347 | + struct remote_control_key *remote_keys; | ||
348 | + | ||
349 | + dev_dbg(&pdev->dev, "sharpsl_rc_probe\n"); | ||
350 | + | ||
351 | + sharpsl_rc = kzalloc(sizeof(struct sharpsl_rc), GFP_KERNEL); | ||
352 | + input_dev = input_allocate_device(); | ||
353 | + if (!sharpsl_rc || !input_dev) { | ||
354 | + kfree(sharpsl_rc); | ||
355 | + input_free_device(input_dev); | ||
356 | + return -ENOMEM; | ||
357 | + } | ||
358 | + | ||
359 | + platform_set_drvdata(pdev, sharpsl_rc); | ||
360 | + | ||
361 | + sharpsl_rc->dev = &pdev->dev; | ||
362 | + sharpsl_rc->input = input_dev; | ||
363 | + spin_lock_init(&sharpsl_rc->lock); | ||
364 | + | ||
365 | + /* Init Remote Control Timer */ | ||
366 | + init_timer(&sharpsl_rc->rctimer); | ||
367 | + sharpsl_rc->rctimer.function = sharpsl_rc_timer_callback; | ||
368 | + sharpsl_rc->rctimer.data = (unsigned long) sharpsl_rc; | ||
369 | + | ||
370 | + input_dev->name = "Sharp Remote Control CE-RHX"; | ||
371 | + input_dev->phys = "sharpsl_rc/input0"; | ||
372 | + input_dev->id.bustype = BUS_HOST; | ||
373 | + input_dev->id.vendor = 0x0001; | ||
374 | + input_dev->id.product = 0x0001; | ||
375 | + input_dev->id.version = 0x0100; | ||
376 | + input_dev->dev.parent = &pdev->dev; | ||
377 | + | ||
378 | + input_dev->evbit[0] = BIT(EV_KEY); | ||
379 | + | ||
380 | + if (machine_is_borzoi() || machine_is_spitz() || machine_is_akita()) | ||
381 | + remote_keys = remote_keys_spitz; | ||
382 | + else | ||
383 | + remote_keys = remote_keys_corgi; | ||
384 | + for (i = 0; i < (machine_is_borzoi() || machine_is_spitz() || machine_is_akita() ? | ||
385 | + ARRAY_SIZE(remote_keys_spitz) : ARRAY_SIZE(remote_keys_corgi)); | ||
386 | + ++i) | ||
387 | + set_bit(remote_keys[i].key, input_dev->keybit); | ||
388 | + | ||
389 | + ret = input_register_device(sharpsl_rc->input); | ||
390 | + if (ret) { | ||
391 | + dev_dbg(&pdev->dev, "Failed to register Sharp Remote input device\n"); | ||
392 | + kfree(sharpsl_rc); | ||
393 | + input_free_device(input_dev); | ||
394 | + return ret; | ||
395 | + } | ||
396 | + | ||
397 | + if (machine_is_borzoi() || machine_is_spitz() || machine_is_akita()) { | ||
398 | + pxa_gpio_mode(SPITZ_GPIO_AK_INT | GPIO_IN); | ||
399 | + ret = request_irq(SPITZ_IRQ_GPIO_AK_INT, | ||
400 | + sharpsl_rc_interrupt, | ||
401 | + IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_SHARED, | ||
402 | + "sharpsl_rc", | ||
403 | + sharpsl_rc); | ||
404 | + } else { | ||
405 | + pxa_gpio_mode(CORGI_GPIO_AK_INT | GPIO_IN); | ||
406 | + ret = request_irq(CORGI_IRQ_GPIO_AK_INT, | ||
407 | + sharpsl_rc_interrupt, | ||
408 | + IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_SHARED, | ||
409 | + "sharpsl_rc", | ||
410 | + sharpsl_rc); | ||
411 | + } | ||
412 | + if (ret < 0) { | ||
413 | + dev_dbg(&pdev->dev, "Can't get IRQ: %d!\n", i); | ||
414 | + kfree(sharpsl_rc); | ||
415 | + input_free_device(input_dev); | ||
416 | + return ret; | ||
417 | + } | ||
418 | + | ||
419 | + return 0; | ||
420 | +} | ||
421 | + | ||
422 | +static int sharpsl_rc_remove(struct platform_device *pdev) | ||
423 | +{ | ||
424 | + struct sharpsl_rc *sharpsl_rc = platform_get_drvdata(pdev); | ||
425 | + | ||
426 | + dev_dbg(&pdev->dev, "sharpsl_rc_remove\n"); | ||
427 | + | ||
428 | + if (machine_is_borzoi() || machine_is_spitz() || machine_is_akita()) | ||
429 | + free_irq(SPITZ_IRQ_GPIO_AK_INT, sharpsl_rc); | ||
430 | + else | ||
431 | + free_irq(CORGI_IRQ_GPIO_AK_INT, sharpsl_rc); | ||
432 | + del_timer_sync(&sharpsl_rc->rctimer); | ||
433 | + input_unregister_device(sharpsl_rc->input); | ||
434 | + kfree(sharpsl_rc); | ||
435 | + | ||
436 | + return 0; | ||
437 | +} | ||
438 | + | ||
439 | +static struct platform_driver sharpsl_rc_driver = { | ||
440 | + .probe = sharpsl_rc_probe, | ||
441 | + .remove = sharpsl_rc_remove, | ||
442 | + .suspend = NULL, | ||
443 | + .resume = NULL, | ||
444 | + .driver = { | ||
445 | + .name = "sharpsl-remote-control", | ||
446 | + }, | ||
447 | +}; | ||
448 | + | ||
449 | +static int __devinit sharpsl_rc_init(void) | ||
450 | +{ | ||
451 | + printk("sharpsl_rc_init\n"); | ||
452 | + return platform_driver_register(&sharpsl_rc_driver); | ||
453 | +} | ||
454 | + | ||
455 | +static void __exit sharpsl_rc_exit(void) | ||
456 | +{ | ||
457 | + printk("sharpsl_rc_exit\n"); | ||
458 | + platform_driver_unregister(&sharpsl_rc_driver); | ||
459 | +} | ||
460 | + | ||
461 | +module_init(sharpsl_rc_init); | ||
462 | +module_exit(sharpsl_rc_exit); | ||
463 | + | ||
464 | +MODULE_AUTHOR("Justin Patrin <papercrane@reversefold.com>"); | ||
465 | +MODULE_AUTHOR("Richard Purdie <rpurdie@rpsys.net>"); | ||
466 | +MODULE_DESCRIPTION("SharpSL Remote Control Driver"); | ||
467 | +MODULE_LICENSE("GPL"); | ||
468 | --- linux-2.6.26.orig/drivers/input/keyboard/spitzkbd.c | ||
469 | +++ linux-2.6.26/drivers/input/keyboard/spitzkbd.c | ||
470 | @@ -17,10 +17,11 @@ | ||
471 | #include <linux/input.h> | ||
472 | #include <linux/interrupt.h> | ||
473 | #include <linux/jiffies.h> | ||
474 | #include <linux/module.h> | ||
475 | #include <linux/slab.h> | ||
476 | +#include <linux/kmod.h> | ||
477 | |||
478 | #include <asm/arch/spitz.h> | ||
479 | #include <asm/arch/hardware.h> | ||
480 | #include <asm/arch/pxa-regs.h> | ||
481 | #include <asm/arch/pxa2xx-gpio.h> | ||
482 | @@ -278,17 +279,25 @@ static irqreturn_t spitzkbd_hinge_isr(in | ||
483 | |||
484 | #define HINGE_STABLE_COUNT 2 | ||
485 | static int sharpsl_hinge_state; | ||
486 | static int hinge_count; | ||
487 | |||
488 | +void spitzkbd_handle_sharpsl_rc(void *arg) { | ||
489 | + request_module("sharpsl_rc"); | ||
490 | +} | ||
491 | + | ||
492 | +DECLARE_WORK(spitzkbd_work, spitzkbd_handle_sharpsl_rc); | ||
493 | + | ||
494 | static void spitzkbd_hinge_timer(unsigned long data) | ||
495 | { | ||
496 | struct spitzkbd *spitzkbd_data = (struct spitzkbd *) data; | ||
497 | unsigned long state; | ||
498 | unsigned long flags; | ||
499 | + unsigned int headphone, remote; | ||
500 | |||
501 | state = GPLR(SPITZ_GPIO_SWA) & (GPIO_bit(SPITZ_GPIO_SWA)|GPIO_bit(SPITZ_GPIO_SWB)); | ||
502 | + state |= (GPLR(SPITZ_GPIO_HP_IN) & GPIO_bit(SPITZ_GPIO_HP_IN)); | ||
503 | state |= (GPLR(SPITZ_GPIO_AK_INT) & GPIO_bit(SPITZ_GPIO_AK_INT)); | ||
504 | if (state != sharpsl_hinge_state) { | ||
505 | hinge_count = 0; | ||
506 | sharpsl_hinge_state = state; | ||
507 | } else if (hinge_count < HINGE_STABLE_COUNT) { | ||
508 | @@ -298,13 +307,22 @@ static void spitzkbd_hinge_timer(unsigne | ||
509 | if (hinge_count >= HINGE_STABLE_COUNT) { | ||
510 | spin_lock_irqsave(&spitzkbd_data->lock, flags); | ||
511 | |||
512 | input_report_switch(spitzkbd_data->input, SW_LID, ((GPLR(SPITZ_GPIO_SWA) & GPIO_bit(SPITZ_GPIO_SWA)) != 0)); | ||
513 | input_report_switch(spitzkbd_data->input, SW_TABLET_MODE, ((GPLR(SPITZ_GPIO_SWB) & GPIO_bit(SPITZ_GPIO_SWB)) != 0)); | ||
514 | - input_report_switch(spitzkbd_data->input, SW_HEADPHONE_INSERT, ((GPLR(SPITZ_GPIO_AK_INT) & GPIO_bit(SPITZ_GPIO_AK_INT)) != 0)); | ||
515 | + | ||
516 | + headphone = ((GPLR(SPITZ_GPIO_HP_IN) & GPIO_bit(SPITZ_GPIO_HP_IN)) != 0); | ||
517 | + input_report_switch(spitzkbd_data->input, SW_HEADPHONE_INSERT, headphone); | ||
518 | + | ||
519 | + remote = headphone && ((GPLR(SPITZ_GPIO_AK_INT) & GPIO_bit(SPITZ_GPIO_AK_INT)) == 0); | ||
520 | + input_report_switch(spitzkbd_data->input, SW_REMOTE_INSERT, remote); | ||
521 | input_sync(spitzkbd_data->input); | ||
522 | |||
523 | + if (remote) { | ||
524 | + schedule_work(&spitzkbd_work); | ||
525 | + } | ||
526 | + | ||
527 | spin_unlock_irqrestore(&spitzkbd_data->lock, flags); | ||
528 | } else { | ||
529 | mod_timer(&spitzkbd_data->htimer, jiffies + msecs_to_jiffies(HINGE_SCAN_INTERVAL)); | ||
530 | } | ||
531 | } | ||
532 | @@ -394,10 +412,11 @@ static int __init spitzkbd_probe(struct | ||
533 | clear_bit(0, input_dev->keybit); | ||
534 | set_bit(KEY_SUSPEND, input_dev->keybit); | ||
535 | set_bit(SW_LID, input_dev->swbit); | ||
536 | set_bit(SW_TABLET_MODE, input_dev->swbit); | ||
537 | set_bit(SW_HEADPHONE_INSERT, input_dev->swbit); | ||
538 | + set_bit(SW_REMOTE_INSERT, input_dev->swbit); | ||
539 | |||
540 | err = input_register_device(input_dev); | ||
541 | if (err) | ||
542 | goto fail; | ||
543 | |||
544 | @@ -431,13 +450,16 @@ static int __init spitzkbd_probe(struct | ||
545 | IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, | ||
546 | "Spitzkbd SWA", spitzkbd); | ||
547 | request_irq(SPITZ_IRQ_GPIO_SWB, spitzkbd_hinge_isr, | ||
548 | IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, | ||
549 | "Spitzkbd SWB", spitzkbd); | ||
550 | - request_irq(SPITZ_IRQ_GPIO_AK_INT, spitzkbd_hinge_isr, | ||
551 | + request_irq(SPITZ_IRQ_GPIO_HP_IN, spitzkbd_hinge_isr, | ||
552 | IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, | ||
553 | "Spitzkbd HP", spitzkbd); | ||
554 | + request_irq(SPITZ_IRQ_GPIO_AK_INT, spitzkbd_hinge_isr, | ||
555 | + IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_SHARED, | ||
556 | + "Spitzkbd HP Type", spitzkbd); | ||
557 | |||
558 | return 0; | ||
559 | |||
560 | fail: input_free_device(input_dev); | ||
561 | kfree(spitzkbd); | ||
562 | @@ -454,10 +476,11 @@ static int spitzkbd_remove(struct platfo | ||
563 | |||
564 | free_irq(SPITZ_IRQ_GPIO_SYNC, spitzkbd); | ||
565 | free_irq(SPITZ_IRQ_GPIO_ON_KEY, spitzkbd); | ||
566 | free_irq(SPITZ_IRQ_GPIO_SWA, spitzkbd); | ||
567 | free_irq(SPITZ_IRQ_GPIO_SWB, spitzkbd); | ||
568 | + free_irq(SPITZ_IRQ_GPIO_HP_IN, spitzkbd); | ||
569 | free_irq(SPITZ_IRQ_GPIO_AK_INT, spitzkbd); | ||
570 | |||
571 | del_timer_sync(&spitzkbd->htimer); | ||
572 | del_timer_sync(&spitzkbd->timer); | ||
573 | |||
574 | --- linux-2.6.26.orig/include/asm-arm/hardware/sharpsl_pm.h | ||
575 | +++ linux-2.6.26/include/asm-arm/hardware/sharpsl_pm.h | ||
576 | @@ -102,5 +102,12 @@ void sharpsl_battery_kick(void); | ||
577 | void sharpsl_pm_led(int val); | ||
578 | irqreturn_t sharpsl_ac_isr(int irq, void *dev_id); | ||
579 | irqreturn_t sharpsl_chrg_full_isr(int irq, void *dev_id); | ||
580 | irqreturn_t sharpsl_fatal_isr(int irq, void *dev_id); | ||
581 | |||
582 | +/* MAX1111 Channel Definitions */ | ||
583 | +#define MAX1111_REMCOM 0u | ||
584 | +#define MAX1111_BATT_VOLT 4u | ||
585 | +#define MAX1111_BATT_TEMP 2u | ||
586 | +#define MAX1111_ACIN_VOLT 6u | ||
587 | + | ||
588 | +int sharpsl_pm_pxa_read_max1111(int channel); | ||
589 | --- linux-2.6.26.orig/include/linux/input.h | ||
590 | +++ linux-2.6.26/include/linux/input.h | ||
591 | @@ -638,10 +638,11 @@ struct input_absinfo { | ||
592 | #define SW_TABLET_MODE 0x01 /* set = tablet mode */ | ||
593 | #define SW_HEADPHONE_INSERT 0x02 /* set = inserted */ | ||
594 | #define SW_RFKILL_ALL 0x03 /* rfkill master switch, type "any" | ||
595 | set = radio enabled */ | ||
596 | #define SW_RADIO SW_RFKILL_ALL /* deprecated */ | ||
597 | +#define SW_REMOTE_INSERT 0x04 /* set = remote */ | ||
598 | #define SW_MAX 0x0f | ||
599 | #define SW_CNT (SW_MAX+1) | ||
600 | |||
601 | /* | ||
602 | * Misc events | ||