旋转按钮如图所示:
实现功能为上,下和确定
驱动源码如下:
/** Driver for keys on GPIO lines capable of generating interrupts.* * Copyright 2013 Gzsd Tech** 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.*/#include <linux/init.h>#include <linux/interrupt.h>#include <linux/irq.h>#include <linux/ioport.h>#include <linux/delay.h>#include <linux/serial_core.h>#include <linux/io.h>#include <linux/platform_device.h>#include <plat/map-base.h>#include <plat/gpio-cfg.h>#include <mach/regs-gpio.h>#include <mach/regs-irq.h>#include <linux/gpio.h>#include <linux/slab.h>#include <linux/input.h>#include <linux/gzsd_pulley.h>#define LKEY S5PV210_GPH0(4)#define RKEY S5PV210_GPH0(3)#define MKEY S5PV210_GPH0(2)#define POWER IRQ_EINT(1)#define PWIRQSTA S5PV210_GPH0(1)#define MAX_BUTTON_CNT (4)static int s3c_Keycode[MAX_BUTTON_CNT] = {KEY_UP, KEY_DOWN, KEY_ENTER, KEY_POWER};static struct input_dev *input;static int flag_ll = 0;static int flag_lr = 0;static int flag_rl = 0;static int flag_rr = 0;static irqreturn_t pulley_lkey(int irq, void *dev_id){ disable_irq_nosync(irq); flag_ll = gpio_get_value(LKEY); flag_lr = gpio_get_value(RKEY);#if 0 printk("left flag_ll is %d flag_lr is %d\n",flag_ll,flag_lr); input_report_key(input, s3c_Keycode[1], 0); if((flag_ll == flag_lr) && (flag_rl != flag_rr)) { input_report_key(input, s3c_Keycode[0], 1); printk("left around\n"); }#else if((flag_ll == flag_lr) && (flag_rl != flag_rr)) { input_report_key(input, s3c_Keycode[0], 1); mdelay(50); input_report_key(input, s3c_Keycode[0], 0); //printk("left around\n"); }#endif //mdelay(50); enable_irq(irq); return IRQ_HANDLED;}static irqreturn_t pulley_rkey(int irq, void *dev_id){ disable_irq_nosync(irq); flag_rr = gpio_get_value(RKEY); flag_rl = gpio_get_value(LKEY); //printk("right flag_rl is %d flag_rr is %d\n",flag_rl,flag_rr);#if 0 input_report_key(input, s3c_Keycode[0], 0); if((flag_rl == flag_rr) && (flag_ll != flag_lr)) { input_report_key(input, s3c_Keycode[1], 1); printk("right around\n"); }#else if((flag_rl == flag_rr) && (flag_ll != flag_lr)) { input_report_key(input, s3c_Keycode[1], 1); mdelay(50); input_report_key(input, s3c_Keycode[1], 0); //printk("right around\n"); }#endif //mdelay(50); enable_irq(irq); return IRQ_HANDLED;}static irqreturn_t pulley_mkey(int irq, void *dev_id){ int ret; disable_irq_nosync(irq); ret = gpio_get_value(MKEY); if(ret) { input_report_key(input, s3c_Keycode[2], 0); } else { input_report_key(input, s3c_Keycode[2], 1); } enable_irq(irq); return IRQ_HANDLED;}static irqreturn_t syspow_isr(int irq, void *dev_id){ int ret; disable_irq_nosync(irq); ret = gpio_get_value(PWIRQSTA); //printk("%s : line is %d\n",__func__,__LINE__); if(ret) input_report_key(input, s3c_Keycode[3], 0); else input_report_key(input, s3c_Keycode[3], 1); mdelay(100); enable_irq(irq); return IRQ_HANDLED;}static int __devinit gzsd_pulley_probe(struct platform_device *pdev){ struct gzsd_pulley_platform_data *pdata = pdev->dev.platform_data; struct device *dev = &pdev->dev; int err,i; input = input_allocate_device(); if (!input) { dev_err(dev, "failed to allocate state\n"); input_free_device(input); return -1; } set_bit(EV_KEY, input->evbit); for(i = 0; i < MAX_BUTTON_CNT; i++) set_bit(s3c_Keycode[i], input->keybit); input->name = "gzsd-pulley"; input->phys = "gzsd-pulley/input0"; input->id.bustype = BUS_HOST; input->id.vendor = 0x0001; input->id.product = 0x0001; input->id.version = 0x0100; input->keycode = s3c_Keycode; err = input_register_device(input); if (err) { dev_err(dev, "Unable to register input device, error: %d\n", err); input_free_device(input); } if (request_irq(pdata->lkey, pulley_lkey, IRQ_TYPE_EDGE_BOTH,"gzsd-pulley", pdata)) { dev_err(dev, "Unable to request pulley lkey.\n"); input_unregister_device(input); input = NULL; } if (request_irq(pdata->rkey, pulley_rkey, IRQ_TYPE_EDGE_BOTH,"gzsd-pulley", pdata)) { dev_err(dev, "Unable to request pulley rkey.\n"); input_unregister_device(input); input = NULL; } if (request_irq(pdata->mkey, pulley_mkey, IRQ_TYPE_EDGE_BOTH,"gzsd-pulley", pdata)) { dev_err(dev, "Unable to request pulley mkey.\n"); input_unregister_device(input); input = NULL; } if (request_irq(pdata->power, syspow_isr, IRQ_TYPE_EDGE_BOTH,"gzsd-pulley", pdata)) { dev_err(dev, "Unable to request power key.\n"); input_unregister_device(input); input = NULL; } return 0;}static int __devexit gzsd_pulley_remove(struct platform_device *pdev){ struct gzsd_pulley_platform_data *pdata = pdev->dev.platform_data; free_irq(pdata->lkey, pdata); free_irq(pdata->rkey, pdata); free_irq(pdata->mkey, pdata); free_irq(pdata->power, pdata); input_unregister_device(input); return 0;}static struct platform_driver gzsd_pulley_device_driver = { .probe = gzsd_pulley_probe, .remove = __devexit_p(gzsd_pulley_remove), .driver = { .name = "gzsd-pulley", .owner = THIS_MODULE, }};static int __init gzsd_pulley_init(void){ return platform_driver_register(&gzsd_pulley_device_driver);}static void __exit gzsd_pulley_exit(void){ platform_driver_unregister(&gzsd_pulley_device_driver);}module_init(gzsd_pulley_init);module_exit(gzsd_pulley_exit);MODULE_AUTHOR("[email protected] ");MODULE_DESCRIPTION("gzsd pulley key driver");MODULE_LICENSE("GPL");路径为:drivers/input/keyboard/gzsd_pulley.c
内核版本:2.6.35.7
源码下载地址:点击打开链接