hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/drivers/input/keyboard/qt2160.c
....@@ -1,21 +1,8 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * qt2160.c - Atmel AT42QT2160 Touch Sense Controller
34 *
45 * Copyright (C) 2009 Raphael Derosso Pereira <raphaelpereira@gmail.com>
5
- *
6
- * This program is free software; you can redistribute it and/or modify
7
- * it under the terms of the GNU General Public License as published by
8
- * the Free Software Foundation; either version 2 of the License, or
9
- * (at your option) any later version.
10
- *
11
- * This program is distributed in the hope that it will be useful,
12
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
- * GNU General Public License for more details.
15
- *
16
- * You should have received a copy of the GNU General Public License
17
- * along with this program; if not, write to the Free Software
18
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
196 */
207
218 #include <linux/kernel.h>
....@@ -58,10 +45,9 @@
5845 struct qt2160_led {
5946 struct qt2160_data *qt2160;
6047 struct led_classdev cdev;
61
- struct work_struct work;
6248 char name[32];
6349 int id;
64
- enum led_brightness new_brightness;
50
+ enum led_brightness brightness;
6551 };
6652 #endif
6753
....@@ -69,12 +55,10 @@
6955 struct i2c_client *client;
7056 struct input_dev *input;
7157 struct delayed_work dwork;
72
- spinlock_t lock; /* Protects canceling/rescheduling of dwork */
7358 unsigned short keycodes[ARRAY_SIZE(qt2160_key2code)];
7459 u16 key_matrix;
7560 #ifdef CONFIG_LEDS_CLASS
7661 struct qt2160_led leds[QT2160_NUM_LEDS_X];
77
- struct mutex led_lock;
7862 #endif
7963 };
8064
....@@ -83,46 +67,39 @@
8367
8468 #ifdef CONFIG_LEDS_CLASS
8569
86
-static void qt2160_led_work(struct work_struct *work)
87
-{
88
- struct qt2160_led *led = container_of(work, struct qt2160_led, work);
89
- struct qt2160_data *qt2160 = led->qt2160;
90
- struct i2c_client *client = qt2160->client;
91
- int value = led->new_brightness;
92
- u32 drive, pwmen;
93
-
94
- mutex_lock(&qt2160->led_lock);
95
-
96
- drive = qt2160_read(client, QT2160_CMD_DRIVE_X);
97
- pwmen = qt2160_read(client, QT2160_CMD_PWMEN_X);
98
- if (value != LED_OFF) {
99
- drive |= (1 << led->id);
100
- pwmen |= (1 << led->id);
101
-
102
- } else {
103
- drive &= ~(1 << led->id);
104
- pwmen &= ~(1 << led->id);
105
- }
106
- qt2160_write(client, QT2160_CMD_DRIVE_X, drive);
107
- qt2160_write(client, QT2160_CMD_PWMEN_X, pwmen);
108
-
109
- /*
110
- * Changing this register will change the brightness
111
- * of every LED in the qt2160. It's a HW limitation.
112
- */
113
- if (value != LED_OFF)
114
- qt2160_write(client, QT2160_CMD_PWM_DUTY, value);
115
-
116
- mutex_unlock(&qt2160->led_lock);
117
-}
118
-
119
-static void qt2160_led_set(struct led_classdev *cdev,
120
- enum led_brightness value)
70
+static int qt2160_led_set(struct led_classdev *cdev,
71
+ enum led_brightness value)
12172 {
12273 struct qt2160_led *led = container_of(cdev, struct qt2160_led, cdev);
74
+ struct qt2160_data *qt2160 = led->qt2160;
75
+ struct i2c_client *client = qt2160->client;
76
+ u32 drive, pwmen;
12377
124
- led->new_brightness = value;
125
- schedule_work(&led->work);
78
+ if (value != led->brightness) {
79
+ drive = qt2160_read(client, QT2160_CMD_DRIVE_X);
80
+ pwmen = qt2160_read(client, QT2160_CMD_PWMEN_X);
81
+ if (value != LED_OFF) {
82
+ drive |= BIT(led->id);
83
+ pwmen |= BIT(led->id);
84
+
85
+ } else {
86
+ drive &= ~BIT(led->id);
87
+ pwmen &= ~BIT(led->id);
88
+ }
89
+ qt2160_write(client, QT2160_CMD_DRIVE_X, drive);
90
+ qt2160_write(client, QT2160_CMD_PWMEN_X, pwmen);
91
+
92
+ /*
93
+ * Changing this register will change the brightness
94
+ * of every LED in the qt2160. It's a HW limitation.
95
+ */
96
+ if (value != LED_OFF)
97
+ qt2160_write(client, QT2160_CMD_PWM_DUTY, value);
98
+
99
+ led->brightness = value;
100
+ }
101
+
102
+ return 0;
126103 }
127104
128105 #endif /* CONFIG_LEDS_CLASS */
....@@ -221,22 +198,15 @@
221198 static irqreturn_t qt2160_irq(int irq, void *_qt2160)
222199 {
223200 struct qt2160_data *qt2160 = _qt2160;
224
- unsigned long flags;
225
-
226
- spin_lock_irqsave(&qt2160->lock, flags);
227201
228202 mod_delayed_work(system_wq, &qt2160->dwork, 0);
229
-
230
- spin_unlock_irqrestore(&qt2160->lock, flags);
231203
232204 return IRQ_HANDLED;
233205 }
234206
235207 static void qt2160_schedule_read(struct qt2160_data *qt2160)
236208 {
237
- spin_lock_irq(&qt2160->lock);
238209 schedule_delayed_work(&qt2160->dwork, QT2160_CYCLE_INTERVAL);
239
- spin_unlock_irq(&qt2160->lock);
240210 }
241211
242212 static void qt2160_worker(struct work_struct *work)
....@@ -293,19 +263,15 @@
293263 int ret;
294264 int i;
295265
296
- mutex_init(&qt2160->led_lock);
297
-
298266 for (i = 0; i < QT2160_NUM_LEDS_X; i++) {
299267 struct qt2160_led *led = &qt2160->leds[i];
300268
301269 snprintf(led->name, sizeof(led->name), "qt2160:x%d", i);
302270 led->cdev.name = led->name;
303
- led->cdev.brightness_set = qt2160_led_set;
271
+ led->cdev.brightness_set_blocking = qt2160_led_set;
304272 led->cdev.brightness = LED_OFF;
305273 led->id = i;
306274 led->qt2160 = qt2160;
307
-
308
- INIT_WORK(&led->work, qt2160_led_work);
309275
310276 ret = led_classdev_register(&client->dev, &led->cdev);
311277 if (ret < 0)
....@@ -324,10 +290,8 @@
324290 {
325291 int i;
326292
327
- for (i = 0; i < QT2160_NUM_LEDS_X; i++) {
293
+ for (i = 0; i < QT2160_NUM_LEDS_X; i++)
328294 led_classdev_unregister(&qt2160->leds[i].cdev);
329
- cancel_work_sync(&qt2160->leds[i].work);
330
- }
331295 }
332296
333297 #else
....@@ -406,7 +370,6 @@
406370 qt2160->client = client;
407371 qt2160->input = input;
408372 INIT_DELAYED_WORK(&qt2160->dwork, qt2160_worker);
409
- spin_lock_init(&qt2160->lock);
410373
411374 input->name = "AT42QT2160 Touch Sense Keyboard";
412375 input->id.bustype = BUS_I2C;