aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/ams/ams-input.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hwmon/ams/ams-input.c')
-rw-r--r--drivers/hwmon/ams/ams-input.c59
1 files changed, 34 insertions, 25 deletions
diff --git a/drivers/hwmon/ams/ams-input.c b/drivers/hwmon/ams/ams-input.c
index 48dbf7d6a66d..8a712392cd38 100644
--- a/drivers/hwmon/ams/ams-input.c
+++ b/drivers/hwmon/ams/ams-input.c
@@ -27,6 +27,8 @@ static unsigned int invert;
27module_param(invert, bool, S_IWUSR | S_IRUGO); 27module_param(invert, bool, S_IWUSR | S_IRUGO);
28MODULE_PARM_DESC(invert, "Invert input data on X and Y axis"); 28MODULE_PARM_DESC(invert, "Invert input data on X and Y axis");
29 29
30static DEFINE_MUTEX(ams_input_mutex);
31
30static void ams_idev_poll(struct input_polled_dev *dev) 32static void ams_idev_poll(struct input_polled_dev *dev)
31{ 33{
32 struct input_dev *idev = dev->input; 34 struct input_dev *idev = dev->input;
@@ -50,13 +52,11 @@ static void ams_idev_poll(struct input_polled_dev *dev)
50} 52}
51 53
52/* Call with ams_info.lock held! */ 54/* Call with ams_info.lock held! */
53static void ams_input_enable(void) 55static int ams_input_enable(void)
54{ 56{
55 struct input_dev *input; 57 struct input_dev *input;
56 s8 x, y, z; 58 s8 x, y, z;
57 59 int error;
58 if (ams_info.idev)
59 return;
60 60
61 ams_sensors(&x, &y, &z); 61 ams_sensors(&x, &y, &z);
62 ams_info.xcalib = x; 62 ams_info.xcalib = x;
@@ -65,7 +65,7 @@ static void ams_input_enable(void)
65 65
66 ams_info.idev = input_allocate_polled_device(); 66 ams_info.idev = input_allocate_polled_device();
67 if (!ams_info.idev) 67 if (!ams_info.idev)
68 return; 68 return -ENOMEM;
69 69
70 ams_info.idev->poll = ams_idev_poll; 70 ams_info.idev->poll = ams_idev_poll;
71 ams_info.idev->poll_interval = 25; 71 ams_info.idev->poll_interval = 25;
@@ -84,14 +84,18 @@ static void ams_input_enable(void)
84 set_bit(EV_KEY, input->evbit); 84 set_bit(EV_KEY, input->evbit);
85 set_bit(BTN_TOUCH, input->keybit); 85 set_bit(BTN_TOUCH, input->keybit);
86 86
87 if (input_register_polled_device(ams_info.idev)) { 87 error = input_register_polled_device(ams_info.idev);
88 if (error) {
88 input_free_polled_device(ams_info.idev); 89 input_free_polled_device(ams_info.idev);
89 ams_info.idev = NULL; 90 ams_info.idev = NULL;
90 return; 91 return error;
91 } 92 }
93
94 joystick = 1;
95
96 return 0;
92} 97}
93 98
94/* Call with ams_info.lock held! */
95static void ams_input_disable(void) 99static void ams_input_disable(void)
96{ 100{
97 if (ams_info.idev) { 101 if (ams_info.idev) {
@@ -99,6 +103,8 @@ static void ams_input_disable(void)
99 input_free_polled_device(ams_info.idev); 103 input_free_polled_device(ams_info.idev);
100 ams_info.idev = NULL; 104 ams_info.idev = NULL;
101 } 105 }
106
107 joystick = 0;
102} 108}
103 109
104static ssize_t ams_input_show_joystick(struct device *dev, 110static ssize_t ams_input_show_joystick(struct device *dev,
@@ -110,39 +116,42 @@ static ssize_t ams_input_show_joystick(struct device *dev,
110static ssize_t ams_input_store_joystick(struct device *dev, 116static ssize_t ams_input_store_joystick(struct device *dev,
111 struct device_attribute *attr, const char *buf, size_t count) 117 struct device_attribute *attr, const char *buf, size_t count)
112{ 118{
113 if (sscanf(buf, "%d\n", &joystick) != 1) 119 unsigned long enable;
120 int error = 0;
121
122 if (strict_strtoul(buf, 0, &enable) || enable > 1)
114 return -EINVAL; 123 return -EINVAL;
115 124
116 mutex_lock(&ams_info.lock); 125 mutex_lock(&ams_input_mutex);
117 126
118 if (joystick) 127 if (enable != joystick) {
119 ams_input_enable(); 128 if (enable)
120 else 129 error = ams_input_enable();
121 ams_input_disable(); 130 else
131 ams_input_disable();
132 }
122 133
123 mutex_unlock(&ams_info.lock); 134 mutex_unlock(&ams_input_mutex);
124 135
125 return count; 136 return error ? error : count;
126} 137}
127 138
128static DEVICE_ATTR(joystick, S_IRUGO | S_IWUSR, 139static DEVICE_ATTR(joystick, S_IRUGO | S_IWUSR,
129 ams_input_show_joystick, ams_input_store_joystick); 140 ams_input_show_joystick, ams_input_store_joystick);
130 141
131/* Call with ams_info.lock held! */
132int ams_input_init(void) 142int ams_input_init(void)
133{ 143{
134 int result; 144 if (joystick)
135
136 result = device_create_file(&ams_info.of_dev->dev, &dev_attr_joystick);
137
138 if (!result && joystick)
139 ams_input_enable(); 145 ams_input_enable();
140 return result; 146
147 return device_create_file(&ams_info.of_dev->dev, &dev_attr_joystick);
141} 148}
142 149
143/* Call with ams_info.lock held! */
144void ams_input_exit(void) 150void ams_input_exit(void)
145{ 151{
146 ams_input_disable();
147 device_remove_file(&ams_info.of_dev->dev, &dev_attr_joystick); 152 device_remove_file(&ams_info.of_dev->dev, &dev_attr_joystick);
153
154 mutex_lock(&ams_input_mutex);
155 ams_input_disable();
156 mutex_unlock(&ams_input_mutex);
148} 157}