From e7549b926dd3ceec048f5689df90d4ec970c9419 Mon Sep 17 00:00:00 2001 From: Wolfgang Wiedmeyer Date: Fri, 23 Oct 2015 13:30:20 +0200 Subject: more driver stuff from 3.2.72 --- drivers/staging/nvec/nvec_kbd.c | 95 ++++++++++++++++++++++++++++++++--------- 1 file changed, 76 insertions(+), 19 deletions(-) (limited to 'drivers/staging/nvec/nvec_kbd.c') diff --git a/drivers/staging/nvec/nvec_kbd.c b/drivers/staging/nvec/nvec_kbd.c index 9a98507..a4ce5a7 100644 --- a/drivers/staging/nvec/nvec_kbd.c +++ b/drivers/staging/nvec/nvec_kbd.c @@ -1,42 +1,76 @@ +/* + * nvec_kbd: keyboard driver for a NVIDIA compliant embedded controller + * + * Copyright (C) 2011 The AC100 Kernel Team + * + * Authors: Pierre-Hugues Husson + * Marc Dietrich + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + */ + +#include #include #include #include +#include + #include "nvec-keytable.h" #include "nvec.h" -#define ACK_KBD_EVENT {'\x05','\xed','\x01'} +#define ACK_KBD_EVENT {'\x05', '\xed', '\x01'} +static const char led_on[3] = "\x05\xed\x07"; +static const char led_off[3] = "\x05\xed\x00"; static unsigned char keycodes[ARRAY_SIZE(code_tab_102us) - + ARRAY_SIZE(extcode_tab_us102)]; + + ARRAY_SIZE(extcode_tab_us102)]; struct nvec_keys { struct input_dev *input; struct notifier_block notifier; struct nvec_chip *nvec; + bool caps_lock; }; static struct nvec_keys keys_dev; +static void nvec_kbd_toggle_led(void) +{ + keys_dev.caps_lock = !keys_dev.caps_lock; + + if (keys_dev.caps_lock) + nvec_write_async(keys_dev.nvec, led_on, sizeof(led_on)); + else + nvec_write_async(keys_dev.nvec, led_off, sizeof(led_off)); +} + static int nvec_keys_notifier(struct notifier_block *nb, - unsigned long event_type, void *data) + unsigned long event_type, void *data) { int code, state; unsigned char *msg = (unsigned char *)data; if (event_type == NVEC_KB_EVT) { - nvec_size _size = (msg[0] & (3 << 5)) >> 5; + int _size = (msg[0] & (3 << 5)) >> 5; /* power on/off button */ - if(_size == NVEC_VAR_SIZE) + if (_size == NVEC_VAR_SIZE) return NOTIFY_STOP; - if(_size == NVEC_3BYTES) + if (_size == NVEC_3BYTES) msg++; code = msg[1] & 0x7f; state = msg[1] & 0x80; - input_report_key(keys_dev.input, code_tabs[_size][code], !state); + if (code_tabs[_size][code] == KEY_CAPSLOCK && state) + nvec_kbd_toggle_led(); + + input_report_key(keys_dev.input, code_tabs[_size][code], + !state); input_sync(keys_dev.input); return NOTIFY_STOP; @@ -46,18 +80,18 @@ static int nvec_keys_notifier(struct notifier_block *nb, } static int nvec_kbd_event(struct input_dev *dev, unsigned int type, - unsigned int code, int value) + unsigned int code, int value) { unsigned char buf[] = ACK_KBD_EVENT; struct nvec_chip *nvec = keys_dev.nvec; - if(type==EV_REP) + if (type == EV_REP) return 0; - if(type!=EV_LED) + if (type != EV_LED) return -1; - if(code!=LED_CAPSL) + if (code != LED_CAPSL) return -1; buf[2] = !!value; @@ -66,22 +100,23 @@ static int nvec_kbd_event(struct input_dev *dev, unsigned int type, return 0; } -int __init nvec_kbd_init(struct nvec_chip *nvec) +static int __devinit nvec_kbd_probe(struct platform_device *pdev) { + struct nvec_chip *nvec = dev_get_drvdata(pdev->dev.parent); int i, j, err; struct input_dev *idev; j = 0; - for(i = 0; i < ARRAY_SIZE(code_tab_102us); ++i) + for (i = 0; i < ARRAY_SIZE(code_tab_102us); ++i) keycodes[j++] = code_tab_102us[i]; - for(i = 0; i < ARRAY_SIZE(extcode_tab_us102); ++i) - keycodes[j++]=extcode_tab_us102[i]; + for (i = 0; i < ARRAY_SIZE(extcode_tab_us102); ++i) + keycodes[j++] = extcode_tab_us102[i]; idev = input_allocate_device(); - idev->name = "Tegra nvec keyboard"; - idev->phys = "i2c3_slave/nvec"; + idev->name = "nvec keyboard"; + idev->phys = "nvec"; idev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP) | BIT_MASK(EV_LED); idev->ledbit[0] = BIT_MASK(LED_CAPSL); idev->event = nvec_kbd_event; @@ -89,12 +124,12 @@ int __init nvec_kbd_init(struct nvec_chip *nvec) idev->keycodesize = sizeof(unsigned char); idev->keycodemax = ARRAY_SIZE(keycodes); - for( i = 0; i < ARRAY_SIZE(keycodes); ++i) + for (i = 0; i < ARRAY_SIZE(keycodes); ++i) set_bit(keycodes[i], idev->keybit); clear_bit(0, idev->keybit); err = input_register_device(idev); - if(err) + if (err) goto fail; keys_dev.input = idev; @@ -114,9 +149,31 @@ int __init nvec_kbd_init(struct nvec_chip *nvec) or until we have a sync write */ mdelay(1000); + /* Disable caps lock LED */ + nvec_write_async(nvec, led_off, sizeof(led_off)); + return 0; fail: input_free_device(idev); return err; } + +static struct platform_driver nvec_kbd_driver = { + .probe = nvec_kbd_probe, + .driver = { + .name = "nvec-kbd", + .owner = THIS_MODULE, + }, +}; + +static int __init nvec_kbd_init(void) +{ + return platform_driver_register(&nvec_kbd_driver); +} + +module_init(nvec_kbd_init); + +MODULE_AUTHOR("Marc Dietrich "); +MODULE_DESCRIPTION("NVEC keyboard driver"); +MODULE_LICENSE("GPL"); -- cgit v1.1