]> git.proxmox.com Git - mirror_ubuntu-kernels.git/blob - drivers/input/keyboard/qt2160.c
HID: logitech-dj: fix spelling in printk
[mirror_ubuntu-kernels.git] / drivers / input / keyboard / qt2160.c
1 /*
2 * qt2160.c - Atmel AT42QT2160 Touch Sense Controller
3 *
4 * 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.
19 */
20
21 #include <linux/kernel.h>
22 #include <linux/leds.h>
23 #include <linux/module.h>
24 #include <linux/slab.h>
25 #include <linux/jiffies.h>
26 #include <linux/i2c.h>
27 #include <linux/irq.h>
28 #include <linux/interrupt.h>
29 #include <linux/input.h>
30
31 #define QT2160_VALID_CHIPID 0x11
32
33 #define QT2160_CMD_CHIPID 0
34 #define QT2160_CMD_CODEVER 1
35 #define QT2160_CMD_GSTAT 2
36 #define QT2160_CMD_KEYS3 3
37 #define QT2160_CMD_KEYS4 4
38 #define QT2160_CMD_SLIDE 5
39 #define QT2160_CMD_GPIOS 6
40 #define QT2160_CMD_SUBVER 7
41 #define QT2160_CMD_CALIBRATE 10
42 #define QT2160_CMD_DRIVE_X 70
43 #define QT2160_CMD_PWMEN_X 74
44 #define QT2160_CMD_PWM_DUTY 76
45
46 #define QT2160_NUM_LEDS_X 8
47
48 #define QT2160_CYCLE_INTERVAL (2*HZ)
49
50 static unsigned char qt2160_key2code[] = {
51 KEY_0, KEY_1, KEY_2, KEY_3,
52 KEY_4, KEY_5, KEY_6, KEY_7,
53 KEY_8, KEY_9, KEY_A, KEY_B,
54 KEY_C, KEY_D, KEY_E, KEY_F,
55 };
56
57 #ifdef CONFIG_LEDS_CLASS
58 struct qt2160_led {
59 struct qt2160_data *qt2160;
60 struct led_classdev cdev;
61 char name[32];
62 int id;
63 enum led_brightness brightness;
64 };
65 #endif
66
67 struct qt2160_data {
68 struct i2c_client *client;
69 struct input_dev *input;
70 struct delayed_work dwork;
71 spinlock_t lock; /* Protects canceling/rescheduling of dwork */
72 unsigned short keycodes[ARRAY_SIZE(qt2160_key2code)];
73 u16 key_matrix;
74 #ifdef CONFIG_LEDS_CLASS
75 struct qt2160_led leds[QT2160_NUM_LEDS_X];
76 #endif
77 };
78
79 static int qt2160_read(struct i2c_client *client, u8 reg);
80 static int qt2160_write(struct i2c_client *client, u8 reg, u8 data);
81
82 #ifdef CONFIG_LEDS_CLASS
83
84 static int qt2160_led_set(struct led_classdev *cdev,
85 enum led_brightness value)
86 {
87 struct qt2160_led *led = container_of(cdev, struct qt2160_led, cdev);
88 struct qt2160_data *qt2160 = led->qt2160;
89 struct i2c_client *client = qt2160->client;
90 u32 drive, pwmen;
91
92 if (value != led->brightness) {
93 drive = qt2160_read(client, QT2160_CMD_DRIVE_X);
94 pwmen = qt2160_read(client, QT2160_CMD_PWMEN_X);
95 if (value != LED_OFF) {
96 drive |= BIT(led->id);
97 pwmen |= BIT(led->id);
98
99 } else {
100 drive &= ~BIT(led->id);
101 pwmen &= ~BIT(led->id);
102 }
103 qt2160_write(client, QT2160_CMD_DRIVE_X, drive);
104 qt2160_write(client, QT2160_CMD_PWMEN_X, pwmen);
105
106 /*
107 * Changing this register will change the brightness
108 * of every LED in the qt2160. It's a HW limitation.
109 */
110 if (value != LED_OFF)
111 qt2160_write(client, QT2160_CMD_PWM_DUTY, value);
112
113 led->brightness = value;
114 }
115
116 return 0;
117 }
118
119 #endif /* CONFIG_LEDS_CLASS */
120
121 static int qt2160_read_block(struct i2c_client *client,
122 u8 inireg, u8 *buffer, unsigned int count)
123 {
124 int error, idx = 0;
125
126 /*
127 * Can't use SMBus block data read. Check for I2C functionality to speed
128 * things up whenever possible. Otherwise we will be forced to read
129 * sequentially.
130 */
131 if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
132
133 error = i2c_smbus_write_byte(client, inireg + idx);
134 if (error) {
135 dev_err(&client->dev,
136 "couldn't send request. Returned %d\n", error);
137 return error;
138 }
139
140 error = i2c_master_recv(client, buffer, count);
141 if (error != count) {
142 dev_err(&client->dev,
143 "couldn't read registers. Returned %d bytes\n", error);
144 return error;
145 }
146 } else {
147
148 while (count--) {
149 int data;
150
151 error = i2c_smbus_write_byte(client, inireg + idx);
152 if (error) {
153 dev_err(&client->dev,
154 "couldn't send request. Returned %d\n", error);
155 return error;
156 }
157
158 data = i2c_smbus_read_byte(client);
159 if (data < 0) {
160 dev_err(&client->dev,
161 "couldn't read register. Returned %d\n", data);
162 return data;
163 }
164
165 buffer[idx++] = data;
166 }
167 }
168
169 return 0;
170 }
171
172 static int qt2160_get_key_matrix(struct qt2160_data *qt2160)
173 {
174 struct i2c_client *client = qt2160->client;
175 struct input_dev *input = qt2160->input;
176 u8 regs[6];
177 u16 old_matrix, new_matrix;
178 int ret, i, mask;
179
180 dev_dbg(&client->dev, "requesting keys...\n");
181
182 /*
183 * Read all registers from General Status Register
184 * to GPIOs register
185 */
186 ret = qt2160_read_block(client, QT2160_CMD_GSTAT, regs, 6);
187 if (ret) {
188 dev_err(&client->dev,
189 "could not perform chip read.\n");
190 return ret;
191 }
192
193 old_matrix = qt2160->key_matrix;
194 qt2160->key_matrix = new_matrix = (regs[2] << 8) | regs[1];
195
196 mask = 0x01;
197 for (i = 0; i < 16; ++i, mask <<= 1) {
198 int keyval = new_matrix & mask;
199
200 if ((old_matrix & mask) != keyval) {
201 input_report_key(input, qt2160->keycodes[i], keyval);
202 dev_dbg(&client->dev, "key %d %s\n",
203 i, keyval ? "pressed" : "released");
204 }
205 }
206
207 input_sync(input);
208
209 return 0;
210 }
211
212 static irqreturn_t qt2160_irq(int irq, void *_qt2160)
213 {
214 struct qt2160_data *qt2160 = _qt2160;
215 unsigned long flags;
216
217 spin_lock_irqsave(&qt2160->lock, flags);
218
219 mod_delayed_work(system_wq, &qt2160->dwork, 0);
220
221 spin_unlock_irqrestore(&qt2160->lock, flags);
222
223 return IRQ_HANDLED;
224 }
225
226 static void qt2160_schedule_read(struct qt2160_data *qt2160)
227 {
228 spin_lock_irq(&qt2160->lock);
229 schedule_delayed_work(&qt2160->dwork, QT2160_CYCLE_INTERVAL);
230 spin_unlock_irq(&qt2160->lock);
231 }
232
233 static void qt2160_worker(struct work_struct *work)
234 {
235 struct qt2160_data *qt2160 =
236 container_of(work, struct qt2160_data, dwork.work);
237
238 dev_dbg(&qt2160->client->dev, "worker\n");
239
240 qt2160_get_key_matrix(qt2160);
241
242 /* Avoid device lock up by checking every so often */
243 qt2160_schedule_read(qt2160);
244 }
245
246 static int qt2160_read(struct i2c_client *client, u8 reg)
247 {
248 int ret;
249
250 ret = i2c_smbus_write_byte(client, reg);
251 if (ret) {
252 dev_err(&client->dev,
253 "couldn't send request. Returned %d\n", ret);
254 return ret;
255 }
256
257 ret = i2c_smbus_read_byte(client);
258 if (ret < 0) {
259 dev_err(&client->dev,
260 "couldn't read register. Returned %d\n", ret);
261 return ret;
262 }
263
264 return ret;
265 }
266
267 static int qt2160_write(struct i2c_client *client, u8 reg, u8 data)
268 {
269 int ret;
270
271 ret = i2c_smbus_write_byte_data(client, reg, data);
272 if (ret < 0)
273 dev_err(&client->dev,
274 "couldn't write data. Returned %d\n", ret);
275
276 return ret;
277 }
278
279 #ifdef CONFIG_LEDS_CLASS
280
281 static int qt2160_register_leds(struct qt2160_data *qt2160)
282 {
283 struct i2c_client *client = qt2160->client;
284 int ret;
285 int i;
286
287 for (i = 0; i < QT2160_NUM_LEDS_X; i++) {
288 struct qt2160_led *led = &qt2160->leds[i];
289
290 snprintf(led->name, sizeof(led->name), "qt2160:x%d", i);
291 led->cdev.name = led->name;
292 led->cdev.brightness_set_blocking = qt2160_led_set;
293 led->cdev.brightness = LED_OFF;
294 led->id = i;
295 led->qt2160 = qt2160;
296
297 ret = led_classdev_register(&client->dev, &led->cdev);
298 if (ret < 0)
299 return ret;
300 }
301
302 /* Tur off LEDs */
303 qt2160_write(client, QT2160_CMD_DRIVE_X, 0);
304 qt2160_write(client, QT2160_CMD_PWMEN_X, 0);
305 qt2160_write(client, QT2160_CMD_PWM_DUTY, 0);
306
307 return 0;
308 }
309
310 static void qt2160_unregister_leds(struct qt2160_data *qt2160)
311 {
312 int i;
313
314 for (i = 0; i < QT2160_NUM_LEDS_X; i++)
315 led_classdev_unregister(&qt2160->leds[i].cdev);
316 }
317
318 #else
319
320 static inline int qt2160_register_leds(struct qt2160_data *qt2160)
321 {
322 return 0;
323 }
324
325 static inline void qt2160_unregister_leds(struct qt2160_data *qt2160)
326 {
327 }
328
329 #endif
330
331 static bool qt2160_identify(struct i2c_client *client)
332 {
333 int id, ver, rev;
334
335 /* Read Chid ID to check if chip is valid */
336 id = qt2160_read(client, QT2160_CMD_CHIPID);
337 if (id != QT2160_VALID_CHIPID) {
338 dev_err(&client->dev, "ID %d not supported\n", id);
339 return false;
340 }
341
342 /* Read chip firmware version */
343 ver = qt2160_read(client, QT2160_CMD_CODEVER);
344 if (ver < 0) {
345 dev_err(&client->dev, "could not get firmware version\n");
346 return false;
347 }
348
349 /* Read chip firmware revision */
350 rev = qt2160_read(client, QT2160_CMD_SUBVER);
351 if (rev < 0) {
352 dev_err(&client->dev, "could not get firmware revision\n");
353 return false;
354 }
355
356 dev_info(&client->dev, "AT42QT2160 firmware version %d.%d.%d\n",
357 ver >> 4, ver & 0xf, rev);
358
359 return true;
360 }
361
362 static int qt2160_probe(struct i2c_client *client,
363 const struct i2c_device_id *id)
364 {
365 struct qt2160_data *qt2160;
366 struct input_dev *input;
367 int i;
368 int error;
369
370 /* Check functionality */
371 error = i2c_check_functionality(client->adapter,
372 I2C_FUNC_SMBUS_BYTE);
373 if (!error) {
374 dev_err(&client->dev, "%s adapter not supported\n",
375 dev_driver_string(&client->adapter->dev));
376 return -ENODEV;
377 }
378
379 if (!qt2160_identify(client))
380 return -ENODEV;
381
382 /* Chip is valid and active. Allocate structure */
383 qt2160 = kzalloc(sizeof(struct qt2160_data), GFP_KERNEL);
384 input = input_allocate_device();
385 if (!qt2160 || !input) {
386 dev_err(&client->dev, "insufficient memory\n");
387 error = -ENOMEM;
388 goto err_free_mem;
389 }
390
391 qt2160->client = client;
392 qt2160->input = input;
393 INIT_DELAYED_WORK(&qt2160->dwork, qt2160_worker);
394 spin_lock_init(&qt2160->lock);
395
396 input->name = "AT42QT2160 Touch Sense Keyboard";
397 input->id.bustype = BUS_I2C;
398
399 input->keycode = qt2160->keycodes;
400 input->keycodesize = sizeof(qt2160->keycodes[0]);
401 input->keycodemax = ARRAY_SIZE(qt2160_key2code);
402
403 __set_bit(EV_KEY, input->evbit);
404 __clear_bit(EV_REP, input->evbit);
405 for (i = 0; i < ARRAY_SIZE(qt2160_key2code); i++) {
406 qt2160->keycodes[i] = qt2160_key2code[i];
407 __set_bit(qt2160_key2code[i], input->keybit);
408 }
409 __clear_bit(KEY_RESERVED, input->keybit);
410
411 /* Calibrate device */
412 error = qt2160_write(client, QT2160_CMD_CALIBRATE, 1);
413 if (error) {
414 dev_err(&client->dev, "failed to calibrate device\n");
415 goto err_free_mem;
416 }
417
418 if (client->irq) {
419 error = request_irq(client->irq, qt2160_irq,
420 IRQF_TRIGGER_FALLING, "qt2160", qt2160);
421 if (error) {
422 dev_err(&client->dev,
423 "failed to allocate irq %d\n", client->irq);
424 goto err_free_mem;
425 }
426 }
427
428 error = qt2160_register_leds(qt2160);
429 if (error) {
430 dev_err(&client->dev, "Failed to register leds\n");
431 goto err_free_irq;
432 }
433
434 error = input_register_device(qt2160->input);
435 if (error) {
436 dev_err(&client->dev,
437 "Failed to register input device\n");
438 goto err_unregister_leds;
439 }
440
441 i2c_set_clientdata(client, qt2160);
442 qt2160_schedule_read(qt2160);
443
444 return 0;
445
446 err_unregister_leds:
447 qt2160_unregister_leds(qt2160);
448 err_free_irq:
449 if (client->irq)
450 free_irq(client->irq, qt2160);
451 err_free_mem:
452 input_free_device(input);
453 kfree(qt2160);
454 return error;
455 }
456
457 static int qt2160_remove(struct i2c_client *client)
458 {
459 struct qt2160_data *qt2160 = i2c_get_clientdata(client);
460
461 qt2160_unregister_leds(qt2160);
462
463 /* Release IRQ so no queue will be scheduled */
464 if (client->irq)
465 free_irq(client->irq, qt2160);
466
467 cancel_delayed_work_sync(&qt2160->dwork);
468
469 input_unregister_device(qt2160->input);
470 kfree(qt2160);
471
472 return 0;
473 }
474
475 static const struct i2c_device_id qt2160_idtable[] = {
476 { "qt2160", 0, },
477 { }
478 };
479
480 MODULE_DEVICE_TABLE(i2c, qt2160_idtable);
481
482 static struct i2c_driver qt2160_driver = {
483 .driver = {
484 .name = "qt2160",
485 },
486
487 .id_table = qt2160_idtable,
488 .probe = qt2160_probe,
489 .remove = qt2160_remove,
490 };
491
492 module_i2c_driver(qt2160_driver);
493
494 MODULE_AUTHOR("Raphael Derosso Pereira <raphaelpereira@gmail.com>");
495 MODULE_DESCRIPTION("Driver for AT42QT2160 Touch Sensor");
496 MODULE_LICENSE("GPL");