Android 按键驱动

Android 按键驱动

#define USE_SOS 1
#if USE_SOS
#define MAX_BUTTON_CNT 		(9)
static int s3c_Keycode[MAX_BUTTON_CNT] = {KEY_POWER, KEY_MEDIA, KEY_HOME, KEY_VOLUMEDOWN, KEY_VOLUMEUP, KEY_DOWN, KEY_UP, KEY_MENU, KEY_END};
#else
#define MAX_BUTTON_CNT 		(7)
static int s3c_Keycode[MAX_BUTTON_CNT] = {KEY_POWER, KEY_MEDIA, KEY_HOME, KEY_VOLUMEDOWN, KEY_VOLUMEUP, KEY_DOWN, KEY_UP};
#endif
static struct timer_list timer;
static struct input_dev * input;

//static int s3c_Keycode[MAX_BUTTON_CNT] = {KEY_POWER, KEY_MEDIA, KEY_HOME, KEY_MENU, KEY_VOLUMEDOWN, KEY_VOLUMEUP, KEY_DOWN, KEY_UP};
static int s3c_button_history[MAX_BUTTON_CNT] = { 0 };

static void s3cbutton_timer_handler(unsigned long data)
{
	int flag;

	/* power ok */
	flag = gpio_get_value(S5PV210_GPH0(1));
	if(flag != s3c_button_history[0])
	{
		if(flag)
			input_report_key(input, s3c_Keycode[0], 0);
		else
			input_report_key(input, s3c_Keycode[0], 1);
		input_sync(input);
		s3c_button_history[0] = flag;
	}

	/* media */
	flag = gpio_get_value(S5PV210_GPH0(2));
	if(flag != s3c_button_history[1])
	{
		if(flag)
			input_report_key(input, s3c_Keycode[1], 0);
		else
			input_report_key(input, s3c_Keycode[1], 1);
		input_sync(input);
		s3c_button_history[1] = flag;
	}

	/* home */
	flag = gpio_get_value(S5PV210_GPH0(3));
	if(flag != s3c_button_history[2])
	{
		if(flag)
			input_report_key(input, s3c_Keycode[2], 0);
		else
			input_report_key(input, s3c_Keycode[2], 1);
		input_sync(input);
		s3c_button_history[2] = flag;
	}
	/* vol- */
	flag = gpio_get_value(S5PV210_GPH1(0));
	if(flag != s3c_button_history[3])
	{
		if(flag)
			input_report_key(input, s3c_Keycode[3], 0);
		else
			input_report_key(input, s3c_Keycode[3], 1);
		input_sync(input);
		s3c_button_history[3] = flag;
	}

	/* vol+ */
	flag = gpio_get_value(S5PV210_GPH1(1));
	if(flag != s3c_button_history[4])
	{
		if(flag)
			input_report_key(input, s3c_Keycode[4], 0);
		else
			input_report_key(input, s3c_Keycode[4], 1);
		input_sync(input);
		s3c_button_history[4] = flag;
	}
	
	/* up */
	flag = gpio_get_value(S5PV210_GPH1(3));
	if(flag != s3c_button_history[5])
	{
		if(flag)
			input_report_key(input, s3c_Keycode[5], 0);
		else
			input_report_key(input, s3c_Keycode[5], 1);
		input_sync(input);
		s3c_button_history[5] = flag;
	}
	
	/* down */
	flag = gpio_get_value(S5PV210_GPH1(7));
	if(flag != s3c_button_history[6])
	{
		if(flag)
			input_report_key(input, s3c_Keycode[6], 0);
		else
			input_report_key(input, s3c_Keycode[6], 1);
		input_sync(input);
		s3c_button_history[6] = flag;
	}
#if USE_SOS
	/* sos */
	flag = gpio_get_value(S5PV210_GPH0(4));
	if(flag != s3c_button_history[7])
	{
		if(flag)
			input_report_key(input, s3c_Keycode[7], 0);
		else
			input_report_key(input, s3c_Keycode[7], 1);
		input_sync(input);
		s3c_button_history[7] = flag;
	}
	/* end */
	flag = gpio_get_value(S5PV210_GPH1(4));
	if(flag != s3c_button_history[8])
	{
		if(flag)
			input_report_key(input, s3c_Keycode[8], 0);
		else
			input_report_key(input, s3c_Keycode[8], 1);
		input_sync(input);
		s3c_button_history[8] = flag;
	}
#endif

	/* Kernel Timer restart */
	mod_timer(&timer,jiffies + HZ/100);
}

static int s3c_button_probe(struct platform_device *pdev)
{
	int i;
	int ret;
	
	/* gph0_1 (power) */
	ret = gpio_request(S5PV210_GPH0(1), "GPH0");
	if(ret)
		printk("button-smdkv210: request gpio GPH0(1) fail");

	/* gph2_0 (media) */
	ret = gpio_request(S5PV210_GPH0(2), "GPH0");
	if(ret)
		printk("button-smdkv210: request gpio GPH0(2) fail");

	/* gph0_3 (home) */
	ret = gpio_request(S5PV210_GPH0(3), "GPH0");
	if(ret)
		printk("button-smdkv210: request gpio GPH0(3) fail");
#if USE_SOS 
	/* gph0_2 (sos) */
	ret = gpio_request(S5PV210_GPH0(4), "GPH0");
	if(ret)
		printk("button-smdkv210: request gpio GPH0(4) fail");
	/* gph0_2 (end) */
	ret = gpio_request(S5PV210_GPH1(4), "GPH1");
	if(ret)
		printk("button-smdkv210: request gpio GPH1(4) fail");
#endif
	/* gph2_1 (vol-) */
	ret = gpio_request(S5PV210_GPH1(0), "GPH1");
	if(ret)
		printk("button-smdkv210: request gpio GPH1(0) fail");

	/* gph2_3 (vol+) */
	ret = gpio_request(S5PV210_GPH1(1), "GPH1");
	if(ret)
		printk("button-smdkv210: request gpio GPH1(1) fail");

	/* gph2_2 (up) */
	ret = gpio_request(S5PV210_GPH1(3), "GPH1");
	if(ret)
		printk("button-smdkv210: request gpio GPH1(3) fail");

	/* gph2_2 (down) */
	ret = gpio_request(S5PV210_GPH1(7), "GPH1");
	if(ret)
		printk("button-smdkv210: request gpio GPH1(7) fail");

	s3c_gpio_setpull(S5PV210_GPH0(1), S3C_GPIO_PULL_UP);
	s3c_gpio_cfgpin(S5PV210_GPH0(1), S3C_GPIO_SFN(0));

	s3c_gpio_setpull(S5PV210_GPH0(2), S3C_GPIO_PULL_UP);
	s3c_gpio_cfgpin(S5PV210_GPH0(2), S3C_GPIO_SFN(0));

	s3c_gpio_setpull(S5PV210_GPH0(3), S3C_GPIO_PULL_UP);
	s3c_gpio_cfgpin(S5PV210_GPH0(3), S3C_GPIO_SFN(0));
#if USE_SOS
	s3c_gpio_setpull(S5PV210_GPH0(4), S3C_GPIO_PULL_UP);
	s3c_gpio_cfgpin(S5PV210_GPH0(4), S3C_GPIO_SFN(0));

	s3c_gpio_setpull(S5PV210_GPH1(4), S3C_GPIO_PULL_UP);
	s3c_gpio_cfgpin(S5PV210_GPH1(4), S3C_GPIO_SFN(0));
#endif
	s3c_gpio_setpull(S5PV210_GPH1(0), S3C_GPIO_PULL_UP);
	s3c_gpio_cfgpin(S5PV210_GPH1(0), S3C_GPIO_SFN(0));

	s3c_gpio_setpull(S5PV210_GPH1(1), S3C_GPIO_PULL_UP);
	s3c_gpio_cfgpin(S5PV210_GPH1(1), S3C_GPIO_SFN(0));

	s3c_gpio_setpull(S5PV210_GPH1(3), S3C_GPIO_PULL_UP);
	s3c_gpio_cfgpin(S5PV210_GPH1(3), S3C_GPIO_SFN(0));

	s3c_gpio_setpull(S5PV210_GPH1(7), S3C_GPIO_PULL_UP);
	s3c_gpio_cfgpin(S5PV210_GPH1(7), S3C_GPIO_SFN(0));

	s3c_button_history[0] = gpio_get_value(S5PV210_GPH0(1));
	s3c_button_history[1] = gpio_get_value(S5PV210_GPH0(2));
	s3c_button_history[2] = gpio_get_value(S5PV210_GPH0(3));
	s3c_button_history[3] = gpio_get_value(S5PV210_GPH1(0));
	s3c_button_history[4] = gpio_get_value(S5PV210_GPH1(1));
	s3c_button_history[5] = gpio_get_value(S5PV210_GPH1(3));
	s3c_button_history[6] = gpio_get_value(S5PV210_GPH1(7));
#if USE_SOS 
	s3c_button_history[7] = gpio_get_value(S5PV210_GPH0(4));
	s3c_button_history[8] = gpio_get_value(S5PV210_GPH1(4));
#endif

	input = input_allocate_device();
	if(!input) 
		return -ENOMEM;

	set_bit(EV_KEY, input->evbit);
	//set_bit(EV_REP, input->evbit);	/* Repeat Key */

	for(i = 0; i < MAX_BUTTON_CNT; i++)
		set_bit(s3c_Keycode[i], input->keybit);

	input->name = "s3c-button";
	input->phys = "s3c-button/input0";

	input->id.bustype = BUS_HOST;
	input->id.vendor = 0x0001;
	input->id.product = 0x0001;
	input->id.version = 0x0100;

	input->keycode = s3c_Keycode;

	if(input_register_device(input) != 0)
	{
		printk("s3c-button input register device fail!!\n");

		input_free_device(input);
		return -ENODEV;
	}

	/* Scan timer init */
	init_timer(&timer);
	timer.function = s3cbutton_timer_handler;

	timer.expires = jiffies + (HZ/100);
	add_timer(&timer);

	printk("s3c button Initialized!!\n");

	return 0;
}

static int s3c_button_remove(struct platform_device *pdev)
{
	input_unregister_device(input);
	del_timer(&timer);
	
	return  0;
}


#ifdef CONFIG_PM
static int s3c_button_suspend(struct platform_device *pdev, pm_message_t state)
{
	return 0;
}

static int s3c_button_resume(struct platform_device *pdev)
{
	return 0;
}
#else
#define s3c_button_suspend	NULL
#define s3c_button_resume	NULL
#endif

static struct platform_driver s3c_button_device_driver = {
	.probe		= s3c_button_probe,
	.remove		= s3c_button_remove,
	.suspend	= s3c_button_suspend,
	.resume		= s3c_button_resume,
	.driver		= {
		.name	= "s3c-button",
		.owner	= THIS_MODULE,
	}
};


static struct platform_device s3c_device_button = {
	.name	= "s3c-button",
	.id		= -1,
};

static int __init s3c_button_init(void)
{   
	platform_device_register(&s3c_device_button);       

	return platform_driver_register(&s3c_button_device_driver);
}

static void __exit s3c_button_exit(void)
{
	platform_driver_unregister(&s3c_button_device_driver);
	platform_device_unregister(&s3c_device_button);   
}

module_init(s3c_button_init);
module_exit(s3c_button_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("jvaemape");
MODULE_DESCRIPTION("Keyboard driver");
MODULE_ALIAS("platform:s3c-button");


在平台目录下添加button.c文件, 把以上代码粘贴到其中,  在 Makefile文件中添加一下代码

obj-$(CONFIG_MACH_SMDKV210) += button-x210.o


你可能感兴趣的:(android,linux)