diff options
Diffstat (limited to 'recipes/linux/linux-2.6.26/boc01/012-081222-cy3218-btns.patch')
-rw-r--r-- | recipes/linux/linux-2.6.26/boc01/012-081222-cy3218-btns.patch | 223 |
1 files changed, 223 insertions, 0 deletions
diff --git a/recipes/linux/linux-2.6.26/boc01/012-081222-cy3218-btns.patch b/recipes/linux/linux-2.6.26/boc01/012-081222-cy3218-btns.patch new file mode 100644 index 0000000000..b3cb9b461b --- /dev/null +++ b/recipes/linux/linux-2.6.26/boc01/012-081222-cy3218-btns.patch @@ -0,0 +1,223 @@ +diff -urN linux-2.6.26.orig/drivers/input/misc/cy3218-btns.c linux-2.6.26/drivers/input/misc/cy3218-btns.c +--- linux-2.6.26.orig/drivers/input/misc/cy3218-btns.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.26/drivers/input/misc/cy3218-btns.c 2008-12-22 12:54:47.000000000 +0100 +@@ -0,0 +1,195 @@ ++/* ++ * CAPSENSE Interface driver ++ * ++ * ++ * Copyright (C) 2007, CenoSYS (www.cenosys.com). ++ * ++ * Guillaume Ligneul <guillaume.ligneul@gmail.com> ++ * Jeremy Lainé <jeremy.laine@bolloretelecom.eu> ++ * ++ * This software program is licensed subject to the GNU General Public License ++ * (GPL).Version 2,June 1991, available at http://www.fsf.org/copyleft/gpl.html ++ */ ++ ++#include <linux/init.h> ++#include <linux/input-polldev.h> ++#include <linux/ioport.h> ++#include <linux/module.h> ++#include <linux/i2c.h> ++ ++static int capsense_attach_adapter(struct i2c_adapter *adapter); ++static int capsense_detach_client(struct i2c_client *client); ++ ++#define CAPSENSE_NAME "Capsense" ++/* i2c configuration */ ++#define CAPSENSE_I2C_ADDR 0x25 ++// To debug (may be add in include/linux/i2c-id.h) ++#define I2C_DRIVERID_CAPSENSE 98 ++#define BUTTONS_POLL_INTERVAL 30 /* msec */ ++#define CAP_STATE_GP0 0x88 ++#define CAP_STATE_GP1 0x89 ++#define MASK0 0x10 ++#define MASK1 0x4 ++#define MASK2 0x8 ++#define MASK3 0x1 ++ ++ ++static int poll_interval = BUTTONS_POLL_INTERVAL; ++module_param_named(poll, poll_interval, uint, 0); ++MODULE_PARM_DESC(poll, "poll interval in msec (30=default)"); ++ ++static const unsigned short normal_i2c[] = { ++ CAPSENSE_I2C_ADDR , I2C_CLIENT_END ++}; ++I2C_CLIENT_INSMOD; ++ ++static struct i2c_driver capsense_driver = { ++ .driver = { ++ .name = CAPSENSE_NAME, ++ }, ++ .id = I2C_DRIVERID_CAPSENSE, ++ .attach_adapter = &capsense_attach_adapter, ++ .detach_client = &capsense_detach_client, ++}; ++ ++struct cy3218 { ++ struct input_polled_dev *ipdev; ++ struct i2c_client client; ++ unsigned char key_state; ++}; ++ ++unsigned short keymap[] = { ++ // GP0 ++ KEY_F1, ++ KEY_ENTER, ++ KEY_DOWN, ++ KEY_BACKSPACE, ++ // GP1 ++ KEY_UP, ++}; ++ ++static void handle_buttons(struct input_polled_dev *dev) ++{ ++ struct cy3218 *capsense = dev->private; ++ u8 port_value; ++ u8 new_state = 0; ++ u8 changed; ++ int i; ++ ++ // read status ++ port_value = i2c_smbus_read_byte_data(&capsense->client, CAP_STATE_GP0); ++ if (port_value & MASK0) new_state |= 0x01; ++ if (port_value & MASK1) new_state |= 0x02; ++ if (port_value & MASK2) new_state |= 0x04; ++ if (port_value & MASK3) new_state |= 0x08; ++ ++ port_value = i2c_smbus_read_byte_data(&capsense->client, CAP_STATE_GP1); ++ if (port_value & MASK0) new_state |= 0x10; ++ ++ // update keyboard state ++ changed = capsense->key_state ^ new_state; ++ for (i = 0; i < ARRAY_SIZE(keymap); i++) ++ if (changed & (1 << i)) ++ input_report_key(dev->input, keymap[i], (new_state & (1 << i))); ++ capsense->key_state = new_state; ++ input_sync(dev->input); ++} ++ ++static int ++capsense_probe(struct i2c_adapter *adapter, int addr, int kind) ++{ ++ struct cy3218 *capsense; ++ struct input_polled_dev *ipdev; ++ struct input_dev *input; ++ int rc = 0, err = -ENOMEM, i=0; ++ ++ capsense = kzalloc(sizeof(*capsense), GFP_KERNEL); ++ if (!capsense) ++ goto failout; ++ ++ if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) { ++ goto failout; ++ } ++ ++ ipdev = input_allocate_polled_device(); ++ if (!ipdev) ++ goto failout; ++ ++ capsense->key_state = 0; ++ capsense->ipdev = ipdev; ++ capsense->client.adapter = adapter; ++ capsense->client.addr = addr; ++ capsense->client.driver = &capsense_driver; ++ strlcpy(capsense->client.name, CAPSENSE_NAME, I2C_NAME_SIZE); ++ i2c_set_clientdata(&capsense->client, capsense); ++ ++ rc = i2c_attach_client(&capsense->client); ++ if (rc) ++ goto out_attach; ++ ++ ipdev->poll = handle_buttons; ++ ipdev->private = capsense; ++ ipdev->poll_interval = poll_interval; ++ ++ input = ipdev->input; ++ input->name = "Capsense buttons"; ++ input->phys = "capsense/input0"; ++ input->id.bustype = BUS_I2C; ++ input->dev.parent = &capsense->client.dev; ++ ++ input->keycode = keymap; ++ input->keycodemax = ARRAY_SIZE(keymap); ++ input->keycodesize = sizeof(unsigned short); ++ ++ input_set_capability(input, EV_MSC, MSC_SCAN); ++ set_bit(EV_KEY, ipdev->input->evbit); ++ ++ for (i = 0; i < ARRAY_SIZE(keymap); i++) ++ set_bit(keymap[i], ipdev->input->keybit); ++ ++ rc = input_register_polled_device(ipdev); ++ if(rc) ++ goto out_polled; ++ ++ return 0; ++ ++out_polled: ++ i2c_detach_client(&capsense->client); ++out_attach: ++ input_free_polled_device(ipdev); ++failout: ++ return err; ++} ++ ++static int ++capsense_attach_adapter (struct i2c_adapter *adapter) ++{ ++ return i2c_probe(adapter, &addr_data, capsense_probe); ++} ++ ++static int ++capsense_detach_client(struct i2c_client *client) ++{ ++ struct cy3218 *capsense = i2c_get_clientdata(client); ++ ++ input_unregister_polled_device(capsense->ipdev); ++ i2c_detach_client(&capsense->client); ++ input_free_polled_device(capsense->ipdev); ++ return 0; ++} ++ ++static int __init capsense_buttons_init(void) ++{ ++ return i2c_add_driver(&capsense_driver); ++} ++ ++static void __exit capsense_buttons_exit(void) ++{ ++ i2c_del_driver(&capsense_driver); ++} ++ ++MODULE_AUTHOR("Guillaume Ligneul <guillaume.ligneul@cenosys.com>"); ++MODULE_DESCRIPTION("Capsense CY3218 Input driver"); ++MODULE_LICENSE("GPL"); ++module_init(capsense_buttons_init); ++module_exit(capsense_buttons_exit); +diff -urN linux-2.6.26.orig/drivers/input/misc/Kconfig linux-2.6.26/drivers/input/misc/Kconfig +--- linux-2.6.26.orig/drivers/input/misc/Kconfig 2008-07-13 23:51:29.000000000 +0200 ++++ linux-2.6.26/drivers/input/misc/Kconfig 2008-12-22 07:47:08.000000000 +0100 +@@ -197,4 +197,12 @@ + Say Y here if you want to support the built-in real time clock + of the HP SDC controller. + ++config INPUT_CAPSENSE_BTNS ++ tristate "CAPSENSE CY3218 button interface" ++ select INPUT_POLLDEV ++ help ++ To compile this driver as a module, choose M here: the ++ module will be called cy3218-btns. ++ To change poll interval, invoque poll parameter in msecs. ++ + endif +diff -urN linux-2.6.26.orig/drivers/input/misc/Makefile linux-2.6.26/drivers/input/misc/Makefile +--- linux-2.6.26.orig/drivers/input/misc/Makefile 2008-07-13 23:51:29.000000000 +0200 ++++ linux-2.6.26/drivers/input/misc/Makefile 2008-12-22 07:47:19.000000000 +0100 +@@ -19,3 +19,4 @@ + obj-$(CONFIG_HP_SDC_RTC) += hp_sdc_rtc.o + obj-$(CONFIG_INPUT_UINPUT) += uinput.o + obj-$(CONFIG_INPUT_APANEL) += apanel.o ++obj-$(CONFIG_INPUT_CAPSENSE_BTNS) +=cy3218-btns.o |