| Phil Sutter | d9bdffd | 2009-03-04 23:27:15 -0800 | [diff] [blame] | 1 | /* | 
 | 2 |  * Support for the S1 button on Routerboard 532 | 
 | 3 |  * | 
 | 4 |  * Copyright (C) 2009  Phil Sutter <n0-1@freewrt.org> | 
 | 5 |  */ | 
 | 6 |  | 
 | 7 | #include <linux/input-polldev.h> | 
 | 8 | #include <linux/module.h> | 
 | 9 | #include <linux/platform_device.h> | 
 | 10 |  | 
 | 11 | #include <asm/mach-rc32434/gpio.h> | 
 | 12 | #include <asm/mach-rc32434/rb.h> | 
 | 13 |  | 
 | 14 | #define DRV_NAME "rb532-button" | 
 | 15 |  | 
 | 16 | #define RB532_BTN_RATE 100 /* msec */ | 
 | 17 | #define RB532_BTN_KSYM BTN_0 | 
 | 18 |  | 
 | 19 | /* The S1 button state is provided by GPIO pin 1. But as this | 
 | 20 |  * pin is also used for uart input as alternate function, the | 
 | 21 |  * operational modes must be switched first: | 
 | 22 |  * 1) disable uart using set_latch_u5() | 
 | 23 |  * 2) turn off alternate function implicitly through | 
 | 24 |  *    gpio_direction_input() | 
 | 25 |  * 3) read the GPIO's current value | 
 | 26 |  * 4) undo step 2 by enabling alternate function (in this | 
 | 27 |  *    mode the GPIO direction is fixed, so no change needed) | 
 | 28 |  * 5) turn on uart again | 
 | 29 |  * The GPIO value occurs to be inverted, so pin high means | 
 | 30 |  * button is not pressed. | 
 | 31 |  */ | 
 | 32 | static bool rb532_button_pressed(void) | 
 | 33 | { | 
 | 34 | 	int val; | 
 | 35 |  | 
 | 36 | 	set_latch_u5(0, LO_FOFF); | 
 | 37 | 	gpio_direction_input(GPIO_BTN_S1); | 
 | 38 |  | 
 | 39 | 	val = gpio_get_value(GPIO_BTN_S1); | 
 | 40 |  | 
 | 41 | 	rb532_gpio_set_func(GPIO_BTN_S1); | 
 | 42 | 	set_latch_u5(LO_FOFF, 0); | 
 | 43 |  | 
 | 44 | 	return !val; | 
 | 45 | } | 
 | 46 |  | 
 | 47 | static void rb532_button_poll(struct input_polled_dev *poll_dev) | 
 | 48 | { | 
 | 49 | 	input_report_key(poll_dev->input, RB532_BTN_KSYM, | 
 | 50 | 			 rb532_button_pressed()); | 
 | 51 | 	input_sync(poll_dev->input); | 
 | 52 | } | 
 | 53 |  | 
| Bill Pemberton | 5298cc4 | 2012-11-23 21:38:25 -0800 | [diff] [blame] | 54 | static int rb532_button_probe(struct platform_device *pdev) | 
| Phil Sutter | d9bdffd | 2009-03-04 23:27:15 -0800 | [diff] [blame] | 55 | { | 
 | 56 | 	struct input_polled_dev *poll_dev; | 
 | 57 | 	int error; | 
 | 58 |  | 
 | 59 | 	poll_dev = input_allocate_polled_device(); | 
 | 60 | 	if (!poll_dev) | 
 | 61 | 		return -ENOMEM; | 
 | 62 |  | 
 | 63 | 	poll_dev->poll = rb532_button_poll; | 
 | 64 | 	poll_dev->poll_interval = RB532_BTN_RATE; | 
 | 65 |  | 
 | 66 | 	poll_dev->input->name = "rb532 button"; | 
 | 67 | 	poll_dev->input->phys = "rb532/button0"; | 
 | 68 | 	poll_dev->input->id.bustype = BUS_HOST; | 
 | 69 | 	poll_dev->input->dev.parent = &pdev->dev; | 
 | 70 |  | 
 | 71 | 	dev_set_drvdata(&pdev->dev, poll_dev); | 
 | 72 |  | 
 | 73 | 	input_set_capability(poll_dev->input, EV_KEY, RB532_BTN_KSYM); | 
 | 74 |  | 
 | 75 | 	error = input_register_polled_device(poll_dev); | 
 | 76 | 	if (error) { | 
 | 77 | 		input_free_polled_device(poll_dev); | 
 | 78 | 		return error; | 
 | 79 | 	} | 
 | 80 |  | 
 | 81 | 	return 0; | 
 | 82 | } | 
 | 83 |  | 
| Bill Pemberton | e2619cf | 2012-11-23 21:50:47 -0800 | [diff] [blame] | 84 | static int rb532_button_remove(struct platform_device *pdev) | 
| Phil Sutter | d9bdffd | 2009-03-04 23:27:15 -0800 | [diff] [blame] | 85 | { | 
 | 86 | 	struct input_polled_dev *poll_dev = dev_get_drvdata(&pdev->dev); | 
 | 87 |  | 
 | 88 | 	input_unregister_polled_device(poll_dev); | 
 | 89 | 	input_free_polled_device(poll_dev); | 
 | 90 | 	dev_set_drvdata(&pdev->dev, NULL); | 
 | 91 |  | 
 | 92 | 	return 0; | 
 | 93 | } | 
 | 94 |  | 
 | 95 | static struct platform_driver rb532_button_driver = { | 
 | 96 | 	.probe = rb532_button_probe, | 
| Bill Pemberton | 1cb0aa8 | 2012-11-23 21:27:39 -0800 | [diff] [blame] | 97 | 	.remove = rb532_button_remove, | 
| Phil Sutter | d9bdffd | 2009-03-04 23:27:15 -0800 | [diff] [blame] | 98 | 	.driver = { | 
 | 99 | 		.name = DRV_NAME, | 
 | 100 | 		.owner = THIS_MODULE, | 
 | 101 | 	}, | 
 | 102 | }; | 
| JJ Ding | 840a746 | 2011-11-29 11:08:40 -0800 | [diff] [blame] | 103 | module_platform_driver(rb532_button_driver); | 
| Phil Sutter | d9bdffd | 2009-03-04 23:27:15 -0800 | [diff] [blame] | 104 |  | 
 | 105 | MODULE_AUTHOR("Phil Sutter <n0-1@freewrt.org>"); | 
 | 106 | MODULE_LICENSE("GPL"); | 
 | 107 | MODULE_DESCRIPTION("Support for S1 button on Routerboard 532"); | 
 | 108 | MODULE_ALIAS("platform:" DRV_NAME); |