linux 按键功能码,【OK210试用体验】功能篇(3)Linux input子系统之Key按键驱动

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define OK210_KBD "ok210kbd"

#define OK210_KBD_NUM (5)

#define KBD_NONE (0xff)

#define KBD_UP (0)

#define KBD_DOWN (1)

typedef struct _ok210_key{

unsigned int gpio;/*对应gpio口*/

unsigned int irq;/*对应中断*/

int n_key;/*键值*/

}ok210_key;

struct ok210_kbd{

ok210_key keys[OK210_KBD_NUM];

struct timer_list key_timer; /*按键去抖定时器*/

unsigned int key_status; /*按键状态*/

struct input_dev *input;

};

static void ok210_init_kbd_data(struct ok210_kbd *p_kbd)

{

printk("ok210_init_kbd_data p_kbd=%x\n", (unsigned int)p_kbd);

p_kbd->keys[0].gpio = s5pv210_GPH0(3);

p_kbd->keys[1].gpio = S5Pv210_GPH0(4);

p_kbd->keys[2].gpio = S5PV210_GPH0(5);

p_kbd->keys[3].gpio = S5PV210_GPH0(6);

p_kbd->keys[4].gpio = S5PV210_GPH0(7);

p_kbd->keys[0].irq = IRQ_EINT3;

p_kbd->keys[1].irq = IRQ_EINT4;

p_kbd->keys[2].irq = IRQ_EINT5;

p_kbd->keys[3].irq = IRQ_EINT6;

p_kbd->keys[4].irq = IRQ_EINT7;

p_kbd->keys[0].n_key = KEY_0;

p_kbd->keys[1].n_key = KEY_1;

p_kbd->keys[2].n_key = KEY_2;

p_kbd->keys[3].n_key = KEY_3;

p_kbd->keys[4].n_key = KEY_4;

}

struct ok210_kbd *p_ok210_kbd;

struct ok210_kbd *get_kbd(void)

{

return p_ok210_kbd;

}

void set_kbd(struct ok210_kbd *p_kbd)

{

p_ok210_kbd = p_kbd;

}

static irqreturn_t ok210_kbd_handler(int irq, void *p_date)

{

unsigned int n_key = 0;

struct ok210_kbd *p_kbd = p_date;

unsigned int key_state = 0;

int i;

for(i = 0; i < OK210_KBD_NUM; i++)

{

if( irq == p_kbd->keys[i].irq )

{

key_state = gpio_get_value(p_kbd->keys[i].gpio);

n_key = p_kbd->keys[i].n_key;

break;

}

}

printk("ok210_kbd_handler n_key=%d, key_state=%d\n", n_key, key_state);

input_report_key(p_kbd->input, n_key, !key_state);/*1表示按下*/

input_sync(p_kbd->input);

return IRQ_HANDLED;

}

static void kbd_free_irqs(void)

{

int i;

struct ok210_kbd *p_kbd = get_kbd();

for(i = 0; i < OK210_KBD_NUM; i++)

free_irq(p_kbd->keys[i].irq, p_kbd);

}

static int kbd_req_irqs(void)

{

int n_ret;

int i;

struct ok210_kbd *p_kbd = get_kbd();

for(i = 0; i < OK210_KBD_NUM; i++)

{

n_ret = request_irq(p_kbd->keys[i].irq, ok210_kbd_handler, IRQ_TYPE_EDGE_BOTH, OK210_KBD, p_kbd);

if(n_ret)

{

printk("%d: could not register interrupt\n", p_kbd->keys[i].irq);

goto fail;

}

}

return n_ret;

fail:

/*因为上面申请失败的那个没有成功,所以也不要释放*/

for(i--; i >= 0; i--)

{

disable_irq(p_kbd->keys[i].irq);

free_irq(p_kbd->keys[i].irq, p_kbd);

}

return n_ret;

}

static int __devinit ok210_keys_probe(struct platform_device *pdev)

{

int err = -ENOMEM;

struct ok210_kbd *p_ok210_keys = NULL;

struct input_dev *input_dev = NULL;

printk("ok210_keys_probe entry!\n");

p_ok210_keys = kmalloc(sizeof(struct ok210_kbd), GFP_KERNEL);

if( !p_ok210_keys )

{

printk("ok210_keys_probe kmalloc error!\n");

return err;

}

ok210_init_kbd_data(p_ok210_keys);

input_dev = input_allocate_device();

if (!input_dev)

{

printk("ok210_keys_probe input_allocate_device error!\n");

goto fail;

}

p_ok210_keys->input = input_dev;

platform_set_drvdata(pdev, p_ok210_keys);

input_dev->name = pdev->name;

input_dev->phys = OK210_KBD"/input0";

input_dev->id.bustype = BUS_HOST;

input_dev->dev.parent = &pdev->dev;

input_dev->id.vendor = 0x0001;

input_dev->id.product = 0x0001;

input_dev->id.version = 0x0100;

__set_bit(EV_KEY, input_dev->evbit);

__set_bit(KEY_0, input_dev->keybit);

__set_bit(KEY_1, input_dev->keybit);

__set_bit(KEY_2, input_dev->keybit);

__set_bit(KEY_3, input_dev->keybit);

__set_bit(KEY_5, input_dev->keybit);

input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);

err = input_register_device(input_dev);

if( err )

{

printk("ok210_keys_probe input_register_device error!\n");

goto fail_allocate;

}

set_kbd(p_ok210_keys);

err = kbd_req_irqs();

if( err )

{

printk("ok210_keys_probe kbd_req_irqs error!\n");

goto fail_register;

}

return 0;

fail_register:

input_unregister_device(input_dev);

goto fail;

fail_allocate:

input_free_device(input_dev);

fail:

kfree(p_ok210_keys);

return err;

}

static int __devexit ok210_keys_remove(struct platform_device *pdev)

{

struct ok210_kbd *p_ok210_keys = platform_get_drvdata(pdev);

kbd_free_irqs();

input_unregister_device(p_ok210_keys->input);

kfree(p_ok210_keys);

return 0;

}

static void ok210_keys_release(struct device *dev)

{

dev = dev;

}

static struct platform_driver ok210_keys_device_driver = {

.probe = ok210_keys_probe,

.remove = __devexit_p(ok210_keys_remove),

.driver = {

.name = OK210_KBD,

.owner = THIS_MODULE,

}

};

static struct platform_device ok210_device_kbd = {

.name = OK210_KBD,

.id = -1,

.dev = {

.release = ok210_keys_release,

}

};

static int __init ok210_keys_init(void)

{

int n_ret;

printk("ok210_keys_init\n");

n_ret = platform_driver_register(&ok210_keys_device_driver);

if( n_ret )

return n_ret;

n_ret = platform_device_register(&ok210_device_kbd);

if( n_ret )

goto fail;

return n_ret;

fail:

platform_driver_unregister(&ok210_keys_device_driver);

return n_ret;

}

static void __exit ok210_keys_exit(void)

{

printk("ok210_keys_exit\n");

platform_device_unregister(&ok210_device_kbd);

platform_driver_unregister(&ok210_keys_device_driver);

}

module_init(ok210_keys_init);

module_exit(ok210_keys_exit);

MODULE_LICENSE("GPL");

MODULE_AUTHOR("gjianw217@163.com");

MODULE_DESCRIPTION("ok210 keyboard input events driver");

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值