旋转按钮如图所示:
实现功能为上,下和确定
驱动源码如下:
/* * 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
源码下载地址:点击打开链接