From 9d40ac5867b9aefe0722bc1f110b965ff294d30d Mon Sep 17 00:00:00 2001 From: Kevin Date: Sat, 15 Nov 2014 10:00:36 +0800 Subject: add via modify part source code for wm8880 4.4 kitkat --- ANDROID_3.4.5/drivers/input/keyboard/wmt_kpad.c | 466 ++++++++++++++++++++++++ 1 file changed, 466 insertions(+) create mode 100755 ANDROID_3.4.5/drivers/input/keyboard/wmt_kpad.c (limited to 'ANDROID_3.4.5/drivers/input/keyboard/wmt_kpad.c') diff --git a/ANDROID_3.4.5/drivers/input/keyboard/wmt_kpad.c b/ANDROID_3.4.5/drivers/input/keyboard/wmt_kpad.c new file mode 100755 index 00000000..cf50cf1c --- /dev/null +++ b/ANDROID_3.4.5/drivers/input/keyboard/wmt_kpad.c @@ -0,0 +1,466 @@ +/*++ +linux/drivers/input/keyboard/wmt_kpad.c + +Some descriptions of such software. Copyright (c) 2008 WonderMedia Technologies, Inc. + +This program is free software: you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the Free Software Foundation, +either version 2 of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +PARTICULAR PURPOSE. See the GNU General Public License for more details. +You should have received a copy of the GNU General Public License along with +this program. If not, see . + +WonderMedia Technologies, Inc. +10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C. +--*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +/* Debug macros */ +#if 0 +#define DPRINTK(fmt, args...) printk(KERN_ALERT "[%s]: " fmt, __func__ , ## args) +#else +#define DPRINTK(fmt, args...) +#endif + +//#define USE_HOME +#define wmt_kpad_timeout (HZ/50) + +#define WMT_KPAD_FUNCTION_NUM 7 + + +static unsigned int wmt_kpad_codes[WMT_KPAD_FUNCTION_NUM] = { + [0] = KEY_VOLUMEUP, + [1] = KEY_VOLUMEDOWN, + [2] = KEY_BACK, + [3] = KEY_HOME, + [4] = KEY_MENU, + [5] = KEY_CAMERA, + [6] = KEY_PLAYPAUSE, +}; + + +enum { + KEY_ST_up, + KEY_ST_down, + KEY_ST_debounce, +}; + +static struct input_dev *kpad_dev; + +int key_num = 0; + +struct wmt_key{ + int gpio; + int keycode; + + int status; + int debounce; + struct timer_list timer; +} ; +struct wmt_key gpio_key[5]; + +#ifdef CONFIG_CPU_FREQ +/* + * Well, the debounce time is not very critical while zac2_clk + * rescaling, but we still do it. + */ + +/* kpad_clock_notifier() + * + * When changing the processor core clock frequency, it is necessary + * to adjust the KPMIR register. + * + * Returns: 0 on success, -1 on error + */ +static int kpad_clock_notifier(struct notifier_block *nb, unsigned long event, + void *data) +{ + return 0; +} + +/* + * Notify callback while issusing zac2_clk rescale. + */ +static struct notifier_block kpad_clock_nblock = { + .notifier_call = kpad_clock_notifier, + .priority = 1 +}; +#endif + +static int wmt_kpad_gpio_requst(void) +{ + int i,j,ret; + DPRINTK("Start\n"); + for(i=0; i< key_num; i++){ + ret = gpio_request(gpio_key[i].gpio,"kpad"); + if(ret) + goto exit; + } + + DPRINTK("End\n"); + return ret; +exit: + for(j=0; j < i; j++) + gpio_free(gpio_key[j].gpio); + return ret; +} + +static int wmt_kpad_gpio_init(void) +{ + int i; + for(i=0; igpio) == 0) { /*Active Low*/ + if(gpk->status == KEY_ST_up){ + gpk->debounce = 5; + gpk->status = KEY_ST_debounce; + DPRINTK("vd down to debounce\n"); + } + + if(gpk->status == KEY_ST_debounce){ + if(--gpk->debounce == 0){ + gpk->status = KEY_ST_down; + /* report volume down key down */ + input_report_key(kpad_dev, gpk->keycode, 1); + input_sync(kpad_dev); + DPRINTK("WMT Volume up keep press\n"); + } + } + //DPRINTK("vd level is low,status=%d\n",vu_status); + + } + else {/* Level High */ + if(gpk->status == KEY_ST_down){ + gpk->status = KEY_ST_up; + /*Volume down release*/ + input_report_key(kpad_dev, gpk->keycode, 0); /*row4 key is release*/ + input_sync(kpad_dev); + DPRINTK("WMT_Volume down release key = %d \n", gpk->keycode); + } + + if(gpk->status == KEY_ST_debounce){ + if(--gpk->debounce == 0){ + gpk->status = KEY_ST_up; + } + } + + //DPRINTK("vd level is high,status=%d\n",vu_status); + + } + + mod_timer(&gpk->timer, jiffies + wmt_kpad_timeout); + //DPRINTK("End\n"); + + return; +} + +static int init_key_timer(void) +{ + int i; + for(i=0; inum_resources = 0x%x\n",pdev->num_resources); + if (pdev->num_resources < 0 || pdev->num_resources > 2) { + ret = -ENODEV; + goto kpad_probe_out; + } + + /* Register an input event device. */ + kpad_dev->name = "keypad", + kpad_dev->phys = "keypad", + + /* + * Let kpad to implement key repeat. + */ + + set_bit(EV_KEY, kpad_dev->evbit); + + for (i = 0; i < WMT_KPAD_FUNCTION_NUM; i++) + set_bit(wmt_kpad_codes[i], kpad_dev->keybit); + + kpad_dev->keycode = wmt_kpad_codes; + kpad_dev->keycodesize = sizeof(unsigned int); + kpad_dev->keycodemax = WMT_KPAD_FUNCTION_NUM; + + /* + * For better view of /proc/bus/input/devices + */ + kpad_dev->id.bustype = 0; + kpad_dev->id.vendor = 0; + kpad_dev->id.product = 0; + kpad_dev->id.version = 0; + + input_register_device(kpad_dev); + kpad_open(kpad_dev); + DPRINTK("End2\n"); +kpad_probe_out: + +#ifndef CONFIG_SKIP_DRIVER_MSG + printk(KERN_INFO "WMT keypad driver initialized: %s\n", + (ret == 0) ? "ok" : "failed"); +#endif + DPRINTK("End3\n"); + return ret; +} + +static int wmt_kpad_remove(struct platform_device *pdev) +{ + int ret; + DPRINTK("Start\n"); + kpad_close(kpad_dev); + wmt_kpad_gpio_free(); + DPRINTK("End\n"); +#ifdef CONFIG_CPU_FREQ + ret = cpufreq_unregister_notifier(&kpad_clock_nblock, \ + CPUFREQ_TRANSITION_NOTIFIER); + + if (ret) { + printk(KERN_ERR "Unable to unregister CPU frequency " \ + "change notifier (%d)\n", ret); + } +#endif + return 0; +} + +static int wmt_kpad_suspend(struct platform_device *pdev, pm_message_t state) +{ + DPRINTK("Start\n"); + + switch (state.event) { + case PM_EVENT_SUSPEND: + del_key_timer(); + break; + case PM_EVENT_FREEZE: + case PM_EVENT_PRETHAW: + + default: + break; + } + + DPRINTK("End2\n"); + return 0; +} + +static int wmt_kpad_resume(struct platform_device *pdev) +{ + DPRINTK("Start\n"); + wmt_kpad_gpio_init(); + start_key_timer(); + DPRINTK("End\n"); + return 0; +} + +static void wmt_kpad_release(struct device *dev) +{ + return ; +} + +static struct platform_driver wmt_kpad_driver = { + .driver.name = "wmt-kpad", + .probe = &wmt_kpad_probe, + .remove = &wmt_kpad_remove, + .suspend = &wmt_kpad_suspend, + .resume = &wmt_kpad_resume +}; + +static struct resource wmt_kpad_resources[] = { + [0] = { + .start = IRQ_GPIO, + .end = IRQ_GPIO, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device wmt_kpad_device = { + .name = "wmt-kpad", + .id = 0, + .num_resources = ARRAY_SIZE(wmt_kpad_resources), + .resource = wmt_kpad_resources, + .dev = { + .release = wmt_kpad_release, + } +}; + +extern int wmt_getsyspara(char *varname, unsigned char *varval, int *varlen); + +static int __init kpad_init(void) +{ + int i,ret; + int retval; + unsigned char buf[80]; + int varlen = 80; + char *varname = "wmt.io.kpad"; + char *p=NULL; + int gpio,code; + + DPRINTK(KERN_ALERT "Start\n"); + retval = wmt_getsyspara(varname, buf, &varlen); + if (retval == 0) { + sscanf(buf,"%d:", &key_num); + if (key_num <= 0) + return -ENODEV; + p = buf; + for(i=0; i