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