diff options
Diffstat (limited to 'packages/kexecboot/linux-kexecboot-2.6.24/sharpsl-rc-r1.patch')
-rw-r--r-- | packages/kexecboot/linux-kexecboot-2.6.24/sharpsl-rc-r1.patch | 527 |
1 files changed, 527 insertions, 0 deletions
diff --git a/packages/kexecboot/linux-kexecboot-2.6.24/sharpsl-rc-r1.patch b/packages/kexecboot/linux-kexecboot-2.6.24/sharpsl-rc-r1.patch new file mode 100644 index 0000000000..bed41c55d5 --- /dev/null +++ b/packages/kexecboot/linux-kexecboot-2.6.24/sharpsl-rc-r1.patch @@ -0,0 +1,527 @@ +This patch adds support for Sharp CE-RH2 on Spitz. + +It is not clean enough to be upstreamed: +- It is a bit syslog-noisy. +- Does not support other Zaurus models. +- Maybe split to more parts: + * MAX1111 driver + * linear input device + * virtual keyboard on top of linear input device + +Index: linux-2.6.24/arch/arm/mach-pxa/spitz.c +=================================================================== +--- linux-2.6.24.orig/arch/arm/mach-pxa/spitz.c 2008-03-10 17:05:37.000000000 +0000 ++++ linux-2.6.24/arch/arm/mach-pxa/spitz.c 2008-03-10 17:05:55.000000000 +0000 +@@ -259,6 +259,13 @@ + .id = -1, + }; + ++/* ++ * Spitz Remote Control Device ++ */ ++static struct platform_device sharpsl_rc_device = { ++ .name = "sharpsl-remote-control", ++ .id = -1, ++}; + + /* + * Spitz LEDs +@@ -548,6 +555,7 @@ + &spitzscoop_device, + &spitzssp_device, + &spitzkbd_device, ++ &sharpsl_rc_device, + &spitzts_device, + &spitzbl_device, + &spitzled_device, +Index: linux-2.6.24/drivers/input/keyboard/Kconfig +=================================================================== +--- linux-2.6.24.orig/drivers/input/keyboard/Kconfig 2008-03-10 17:05:40.000000000 +0000 ++++ linux-2.6.24/drivers/input/keyboard/Kconfig 2008-03-10 17:05:55.000000000 +0000 +@@ -154,6 +154,17 @@ + To compile this driver as a module, choose M here: the + module will be called spitzkbd. + ++config SHARPSL_RC ++ tristate "Sharp SL-Cxx00 Remote Control" ++ depends on PXA_SHARPSL ++ default y ++ help ++ Say Y here to enable the remote on the Sharp Zaurus SL-Cxx00, ++ SL-C1000, SL-C3000 and Sl-C3100 series of PDAs. ++ ++ To compile this driver as a module, choose M here: the ++ module will be called sharpsl_rc. ++ + config KEYBOARD_AMIGA + tristate "Amiga keyboard" + depends on AMIGA +Index: linux-2.6.24/drivers/input/keyboard/Makefile +=================================================================== +--- linux-2.6.24.orig/drivers/input/keyboard/Makefile 2008-03-10 17:05:40.000000000 +0000 ++++ linux-2.6.24/drivers/input/keyboard/Makefile 2008-03-10 17:06:17.000000000 +0000 +@@ -26,3 +26,5 @@ + obj-$(CONFIG_KEYBOARD_HP7XX) += jornada720_kbd.o + obj-$(CONFIG_KEYBOARD_MAPLE) += maple_keyb.o + obj-$(CONFIG_KEYBOARD_BFIN) += bf54x-keys.o ++obj-$(CONFIG_SHARPSL_RC) += sharpsl_rc.o ++ +Index: linux-2.6.24/drivers/input/keyboard/sharpsl_rc.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-2.6.24/drivers/input/keyboard/sharpsl_rc.c 2008-03-10 17:05:55.000000000 +0000 +@@ -0,0 +1,291 @@ ++/* ++ * Keyboard driver for Sharp Clamshell Models (SL-Cxx00) ++ * ++ * Copyright (c) 2004-2005 Richard Purdie ++ * ++ * Based on corgikbd.c and Sharp's RC driver ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ */ ++ ++#define DEBUG 1 ++#include <linux/delay.h> ++#include <linux/platform_device.h> ++#include <linux/init.h> ++#include <linux/input.h> ++#include <linux/interrupt.h> ++#include <linux/jiffies.h> ++#include <linux/module.h> ++#include <linux/slab.h> ++ ++#ifdef CONFIG_MACH_SPITZ ++#include <asm/arch/spitz.h> ++#endif ++#ifdef CONFIG_MACH_CORGI ++#include <asm/arch/corgi.h> ++#endif ++ ++#include <asm/arch/hardware.h> ++#include <asm/arch/pxa-regs.h> ++#include <asm/hardware/scoop.h> ++#include <asm/arch/sharpsl.h> ++#include <asm/hardware/sharpsl_pm.h> ++ ++#define DPRINTK(fmt, args...) dev_dbg(data->dev, fmt "\n", ##args) ++ ++struct remote_control_key { ++ unsigned char min; ++ unsigned char max; ++ unsigned char key; ++}; ++ ++#ifdef CONFIG_MACH_SPITZ ++#define REMOTE_AKIN_PULLUP SPITZ_SCP2_AKIN_PULLUP ++#define REMOTE_SCOOP_DEVICE spitzscoop2_device ++#define REMOTE_GPIO_INT SPITZ_GPIO_AK_INT ++#define REMOTE_IRQ_INT SPITZ_IRQ_GPIO_AK_INT ++static struct remote_control_key remote_keys[] = { ++ { 25, 35, KEY_STOPCD}, ++ { 55, 65, KEY_PLAYPAUSE}, ++ { 85, 95, KEY_NEXTSONG}, ++ { 115, 125, KEY_VOLUMEUP}, ++ { 145, 155, KEY_PREVIOUSSONG}, ++ { 180, 190, KEY_MUTE}, ++ { 215, 225, KEY_VOLUMEDOWN}, ++}; ++#endif ++#ifdef CONFIG_MACH_CORGI ++#define REMOTE_AKIN_PULLUP CORGI_SCP_AKIN_PULLUP ++#define REMOTE_SCOOP_DEVICE corgiscoop_device ++#define REMOTE_GPIO_INT CORGI_GPIO_AK_INT ++#define REMOTE_IRQ_INT CORGI_IRQ_GPIO_AK_INT ++static struct remote_control_key remote_keys[] = { ++ //These need to be fixed for the CE-RH1's values ++ { 25, 35, KEY_STOPCD}, ++ { 55, 65, KEY_PLAYPAUSE}, ++ { 85, 95, KEY_NEXTSONG}, ++ { 115, 125, KEY_VOLUMEUP}, ++ { 145, 155, KEY_PREVIOUSSONG}, ++ { 180, 190, KEY_MUTE}, ++ { 215, 225, KEY_VOLUMEDOWN}, ++}; ++#endif ++ ++#define RELEASE_HI 230 ++#define MAX_EARPHONE 6 ++#define RC_POLL_MS 10 ++#define RC_FINISH_MS 500 ++#define WAIT_STATE 3 ++#define NOISE_THRESHOLD 100 ++ ++struct sharpsl_rc { ++ struct input_dev *input; ++ struct device *dev; ++ ++ spinlock_t lock; ++ struct timer_list rctimer; ++ struct timer_list rctimer_finish; ++ ++ unsigned int handling_press; ++ unsigned int noise; ++ unsigned int state; ++ unsigned int last_key; ++}; ++ ++static int get_remocon_raw(void) ++{ ++ int i, val; ++ ++ val = sharpsl_pm_pxa_read_max1111(MAX1111_REMCOM); ++ for (i = 0; i < ARRAY_SIZE(remote_keys); ++i) { ++ if (val >= remote_keys[i].min ++ && val <= remote_keys[i].max) { ++ printk("get_remocon_raw: VAL=%i, KEY=%i\n", val, remote_keys[i].key); ++ return remote_keys[i].key; ++ } ++ } ++ return 0; ++} ++ ++static irqreturn_t sharpsl_rc_interrupt(int irq, void *dev_id, struct pt_regs *regs) ++{ ++ struct sharpsl_rc *data = dev_id; ++ DPRINTK("sharpsl_rc_interrupt %d\n", irq); ++ if (!data->handling_press) { ++ DPRINTK("handling interrupt"); ++ data->handling_press = 1; ++ data->noise = 0; ++ data->state = 0; ++ data->last_key = 0; ++ ++ reset_scoop_gpio(&REMOTE_SCOOP_DEVICE.dev, REMOTE_AKIN_PULLUP); ++ ++ mod_timer(&data->rctimer, jiffies + msecs_to_jiffies(RC_POLL_MS)); ++ } ++ return IRQ_HANDLED; ++} ++ ++static void sharpsl_rc_timer_callback(unsigned long dataPtr) ++{ ++ struct sharpsl_rc *data = (struct sharpsl_rc *) dataPtr; ++ int timer = 1; ++ int key = get_remocon_raw(); ++ DPRINTK("timer callback, key: %d", key); ++ ++ //wait for value to stabilize ++ if (data->state < WAIT_STATE) { ++ if (data->last_key != key) { ++ ++data->noise; ++ if (data->noise > NOISE_THRESHOLD) { ++ DPRINTK("too much noise, bailing"); ++ timer = 0; ++ } ++ data->state = 0; ++ } else { ++ ++data->state; ++ } ++ data->last_key = key; ++ ++ //stable value, send event ++ } else if (data->state == WAIT_STATE) { ++ data->noise = 0; ++ //non-key returned, skip the rest of the states and bail now ++ if (data->last_key == 0) { ++ DPRINTK("non-key detected %d, noise: %d", data->last_key, data->noise); ++ timer = 0; ++ //send button press ++ } else { ++ DPRINTK("key press detected %d, noise %d", data->last_key, data->noise); ++ input_report_key(data->input, data->last_key, 1); ++ } ++ ++data->state; ++ ++ //wait until key is released ++ } else if (data->state < WAIT_STATE * 2) { ++ if (key == data->last_key ++ && data->noise < NOISE_THRESHOLD) { ++ data->state = WAIT_STATE + 1; ++ ++data->noise; ++ } else { ++ ++data->state; ++ } ++ //key is released, send event ++ } else { ++ //send button release ++ DPRINTK("release key %d", data->last_key); ++ input_report_key(data->input, data->last_key, 0); ++ timer = 0; ++ } ++ if (timer) { ++ mod_timer(&data->rctimer, jiffies + msecs_to_jiffies(RC_POLL_MS)); ++ } else { ++ set_scoop_gpio(&REMOTE_SCOOP_DEVICE.dev, REMOTE_AKIN_PULLUP); ++ data->handling_press = 0; ++ } ++} ++ ++static int __init sharpsl_rc_probe(struct platform_device *pdev) ++{ ++ struct sharpsl_rc *sharpsl_rc; ++ struct input_dev *input_dev; ++ int i, ret; ++ ++ dev_dbg(&pdev->dev, "sharpsl_rc_probe\n"); ++ ++ sharpsl_rc = kzalloc(sizeof(struct sharpsl_rc), GFP_KERNEL); ++ input_dev = input_allocate_device(); ++ if (!sharpsl_rc || !input_dev) { ++ kfree(sharpsl_rc); ++ input_free_device(input_dev); ++ return -ENOMEM; ++ } ++ ++ platform_set_drvdata(pdev, sharpsl_rc); ++ ++ sharpsl_rc->dev = &pdev->dev; ++ sharpsl_rc->input = input_dev; ++ spin_lock_init(&sharpsl_rc->lock); ++ ++ /* Init Remote Control Timer */ ++ init_timer(&sharpsl_rc->rctimer); ++ sharpsl_rc->rctimer.function = sharpsl_rc_timer_callback; ++ sharpsl_rc->rctimer.data = (unsigned long) sharpsl_rc; ++ ++ input_dev->name = "Sharp Remote Control CE-RHX"; ++ input_dev->phys = "sharpsl_rc/input0"; ++ input_dev->id.bustype = BUS_HOST; ++ input_dev->id.vendor = 0x0001; ++ input_dev->id.product = 0x0001; ++ input_dev->id.version = 0x0100; ++ input_dev->cdev.dev = &pdev->dev; ++ input_dev->private = sharpsl_rc; ++ ++ input_dev->evbit[0] = BIT(EV_KEY); ++ ++ for (i = 0; i <= ARRAY_SIZE(remote_keys); i++) ++ set_bit(remote_keys[i].key, input_dev->keybit); ++ ++ input_register_device(sharpsl_rc->input); ++ ++ pxa_gpio_mode(REMOTE_GPIO_INT | GPIO_IN); ++ ret = request_irq(REMOTE_IRQ_INT, ++ sharpsl_rc_interrupt, ++ IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_SHARED, ++ "sharpsl_rc", ++ sharpsl_rc); ++ if (ret < 0) { ++ dev_dbg(&pdev->dev, "Can't get IRQ: %d!\n", i); ++ kfree(sharpsl_rc); ++ input_free_device(input_dev); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static int sharpsl_rc_remove(struct platform_device *pdev) ++{ ++ struct sharpsl_rc *sharpsl_rc = platform_get_drvdata(pdev); ++ ++ dev_dbg(&pdev->dev, "sharpsl_rc_remove\n"); ++ ++ free_irq(REMOTE_IRQ_INT, sharpsl_rc); ++ del_timer_sync(&sharpsl_rc->rctimer); ++ input_unregister_device(sharpsl_rc->input); ++ kfree(sharpsl_rc); ++ ++ return 0; ++} ++ ++static struct platform_driver sharpsl_rc_driver = { ++ .probe = sharpsl_rc_probe, ++ .remove = sharpsl_rc_remove, ++ .suspend = NULL, ++ .resume = NULL, ++ .driver = { ++ .name = "sharpsl-remote-control", ++ }, ++}; ++ ++static int __devinit sharpsl_rc_init(void) ++{ ++ printk("sharpsl_rc_init\n"); ++ return platform_driver_register(&sharpsl_rc_driver); ++} ++ ++static void __exit sharpsl_rc_exit(void) ++{ ++ printk("sharpsl_rc_exit\n"); ++ platform_driver_unregister(&sharpsl_rc_driver); ++} ++ ++module_init(sharpsl_rc_init); ++module_exit(sharpsl_rc_exit); ++ ++MODULE_AUTHOR("Justin Patrin <papercrane@reversefold.com>"); ++MODULE_AUTHOR("Richard Purdie <rpurdie@rpsys.net>"); ++MODULE_DESCRIPTION("SharpSL Remote Control Driver"); ++MODULE_LICENSE("GPL"); +Index: linux-2.6.24/drivers/input/keyboard/spitzkbd.c +=================================================================== +--- linux-2.6.24.orig/drivers/input/keyboard/spitzkbd.c 2008-01-24 22:58:37.000000000 +0000 ++++ linux-2.6.24/drivers/input/keyboard/spitzkbd.c 2008-03-10 17:05:55.000000000 +0000 +@@ -19,6 +19,7 @@ + #include <linux/jiffies.h> + #include <linux/module.h> + #include <linux/slab.h> ++#include <linux/kmod.h> + + #include <asm/arch/spitz.h> + #include <asm/arch/hardware.h> +@@ -279,13 +280,21 @@ + static int sharpsl_hinge_state; + static int hinge_count; + ++void spitzkbd_handle_sharpsl_rc(void *arg) { ++ request_module("sharpsl_rc"); ++} ++ ++DECLARE_WORK(spitzkbd_work, spitzkbd_handle_sharpsl_rc); ++ + static void spitzkbd_hinge_timer(unsigned long data) + { + struct spitzkbd *spitzkbd_data = (struct spitzkbd *) data; + unsigned long state; + unsigned long flags; ++ unsigned int headphone, remote; + + state = GPLR(SPITZ_GPIO_SWA) & (GPIO_bit(SPITZ_GPIO_SWA)|GPIO_bit(SPITZ_GPIO_SWB)); ++ state |= (GPLR(SPITZ_GPIO_HP_IN) & GPIO_bit(SPITZ_GPIO_HP_IN)); + state |= (GPLR(SPITZ_GPIO_AK_INT) & GPIO_bit(SPITZ_GPIO_AK_INT)); + if (state != sharpsl_hinge_state) { + hinge_count = 0; +@@ -299,9 +308,18 @@ + + input_report_switch(spitzkbd_data->input, SW_LID, ((GPLR(SPITZ_GPIO_SWA) & GPIO_bit(SPITZ_GPIO_SWA)) != 0)); + input_report_switch(spitzkbd_data->input, SW_TABLET_MODE, ((GPLR(SPITZ_GPIO_SWB) & GPIO_bit(SPITZ_GPIO_SWB)) != 0)); +- input_report_switch(spitzkbd_data->input, SW_HEADPHONE_INSERT, ((GPLR(SPITZ_GPIO_AK_INT) & GPIO_bit(SPITZ_GPIO_AK_INT)) != 0)); ++ ++ headphone = ((GPLR(SPITZ_GPIO_HP_IN) & GPIO_bit(SPITZ_GPIO_HP_IN)) != 0); ++ input_report_switch(spitzkbd_data->input, SW_HEADPHONE_INSERT, headphone); ++ ++ remote = headphone && ((GPLR(SPITZ_GPIO_AK_INT) & GPIO_bit(SPITZ_GPIO_AK_INT)) == 0); ++ input_report_switch(spitzkbd_data->input, SW_REMOTE_INSERT, remote); + input_sync(spitzkbd_data->input); + ++ if (remote) { ++ schedule_work(&spitzkbd_work); ++ } ++ + spin_unlock_irqrestore(&spitzkbd_data->lock, flags); + } else { + mod_timer(&spitzkbd_data->htimer, jiffies + msecs_to_jiffies(HINGE_SCAN_INTERVAL)); +@@ -395,6 +413,7 @@ + set_bit(SW_LID, input_dev->swbit); + set_bit(SW_TABLET_MODE, input_dev->swbit); + set_bit(SW_HEADPHONE_INSERT, input_dev->swbit); ++ set_bit(SW_REMOTE_INSERT, input_dev->swbit); + + err = input_register_device(input_dev); + if (err) +@@ -432,9 +451,12 @@ + request_irq(SPITZ_IRQ_GPIO_SWB, spitzkbd_hinge_isr, + IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, + "Spitzkbd SWB", spitzkbd); +- request_irq(SPITZ_IRQ_GPIO_AK_INT, spitzkbd_hinge_isr, ++ request_irq(SPITZ_IRQ_GPIO_HP_IN, spitzkbd_hinge_isr, + IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, + "Spitzkbd HP", spitzkbd); ++ request_irq(SPITZ_IRQ_GPIO_AK_INT, spitzkbd_hinge_isr, ++ IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_SHARED, ++ "Spitzkbd HP Type", spitzkbd); + + return 0; + +@@ -455,6 +477,7 @@ + free_irq(SPITZ_IRQ_GPIO_ON_KEY, spitzkbd); + free_irq(SPITZ_IRQ_GPIO_SWA, spitzkbd); + free_irq(SPITZ_IRQ_GPIO_SWB, spitzkbd); ++ free_irq(SPITZ_IRQ_GPIO_HP_IN, spitzkbd); + free_irq(SPITZ_IRQ_GPIO_AK_INT, spitzkbd); + + del_timer_sync(&spitzkbd->htimer); +Index: linux-2.6.24/arch/arm/mach-pxa/sharpsl.h +=================================================================== +--- linux-2.6.24.orig/arch/arm/mach-pxa/sharpsl.h 2008-03-10 17:05:35.000000000 +0000 ++++ linux-2.6.24/arch/arm/mach-pxa/sharpsl.h 2008-03-10 17:05:55.000000000 +0000 +@@ -37,15 +37,10 @@ + */ + #define READ_GPIO_BIT(x) (GPLR(x) & GPIO_bit(x)) + +-/* MAX1111 Channel Definitions */ +-#define MAX1111_BATT_VOLT 4u +-#define MAX1111_BATT_TEMP 2u +-#define MAX1111_ACIN_VOLT 6u +- + extern struct battery_thresh spitz_battery_levels_acin[]; + extern struct battery_thresh spitz_battery_levels_noac[]; + void sharpsl_pm_pxa_init(void); + void sharpsl_pm_pxa_remove(void); +-int sharpsl_pm_pxa_read_max1111(int channel); ++ + + +Index: linux-2.6.24/arch/arm/mach-pxa/sharpsl_pm.c +=================================================================== +--- linux-2.6.24.orig/arch/arm/mach-pxa/sharpsl_pm.c 2008-01-24 22:58:37.000000000 +0000 ++++ linux-2.6.24/arch/arm/mach-pxa/sharpsl_pm.c 2008-03-10 17:05:55.000000000 +0000 +@@ -135,6 +135,8 @@ + | MAXCTRL_SGL | MAXCTRL_UNI | MAXCTRL_STR); + } + ++EXPORT_SYMBOL(sharpsl_pm_pxa_read_max1111); ++ + void sharpsl_pm_pxa_init(void) + { + pxa_gpio_mode(sharpsl_pm.machinfo->gpio_acin | GPIO_IN); +Index: linux-2.6.24/include/asm-arm/hardware/sharpsl_pm.h +=================================================================== +--- linux-2.6.24.orig/include/asm-arm/hardware/sharpsl_pm.h 2008-01-24 22:58:37.000000000 +0000 ++++ linux-2.6.24/include/asm-arm/hardware/sharpsl_pm.h 2008-03-10 17:05:55.000000000 +0000 +@@ -104,3 +104,10 @@ + irqreturn_t sharpsl_chrg_full_isr(int irq, void *dev_id); + irqreturn_t sharpsl_fatal_isr(int irq, void *dev_id); + ++/* MAX1111 Channel Definitions */ ++#define MAX1111_REMCOM 0u ++#define MAX1111_BATT_VOLT 4u ++#define MAX1111_BATT_TEMP 2u ++#define MAX1111_ACIN_VOLT 6u ++ ++int sharpsl_pm_pxa_read_max1111(int channel); +Index: linux-2.6.24/include/linux/input.h +=================================================================== +--- linux-2.6.24.orig/include/linux/input.h 2008-01-24 22:58:37.000000000 +0000 ++++ linux-2.6.24/include/linux/input.h 2008-03-10 17:05:55.000000000 +0000 +@@ -636,6 +636,7 @@ + #define SW_TABLET_MODE 0x01 /* set = tablet mode */ + #define SW_HEADPHONE_INSERT 0x02 /* set = inserted */ + #define SW_RADIO 0x03 /* set = radio enabled */ ++#define SW_REMOTE_INSERT 0x04 /* set = remote */ + #define SW_MAX 0x0f + #define SW_CNT (SW_MAX+1) + +Index: linux-2.6.24/arch/arm/mach-pxa/spitz_pm.c +=================================================================== +--- linux-2.6.24.orig/arch/arm/mach-pxa/spitz_pm.c 2008-03-10 17:05:40.000000000 +0000 ++++ linux-2.6.24/arch/arm/mach-pxa/spitz_pm.c 2008-03-10 17:05:55.000000000 +0000 +@@ -162,6 +162,13 @@ + if (resume_on_alarm && (PEDR & PWER_RTC)) + is_resume |= PWER_RTC; + ++ 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)); ++ ++ //remote/headphone interrupt, wakeup ++ if (PEDR == 0 && (PKSR & 0xc0d01) != 0) { ++ is_resume |= PWER_RTC; ++ } ++ + dev_dbg(sharpsl_pm.dev, "is_resume: %x\n",is_resume); + return is_resume; + } |