Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/drivers/input/misc/rb532_button.c
15109 views
1
/*
2
* Support for the S1 button on Routerboard 532
3
*
4
* Copyright (C) 2009 Phil Sutter <[email protected]>
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
54
static int __devinit rb532_button_probe(struct platform_device *pdev)
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
84
static int __devexit rb532_button_remove(struct platform_device *pdev)
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,
97
.remove = __devexit_p(rb532_button_remove),
98
.driver = {
99
.name = DRV_NAME,
100
.owner = THIS_MODULE,
101
},
102
};
103
104
static int __init rb532_button_init(void)
105
{
106
return platform_driver_register(&rb532_button_driver);
107
}
108
109
static void __exit rb532_button_exit(void)
110
{
111
platform_driver_unregister(&rb532_button_driver);
112
}
113
114
module_init(rb532_button_init);
115
module_exit(rb532_button_exit);
116
117
MODULE_AUTHOR("Phil Sutter <[email protected]>");
118
MODULE_LICENSE("GPL");
119
MODULE_DESCRIPTION("Support for S1 button on Routerboard 532");
120
MODULE_ALIAS("platform:" DRV_NAME);
121
122