blob: 7abd909c7b33d6b6d6b40466e53efa2abfd85cec [file] [log] [blame]
Alexandra Chin669d27c2012-12-24 15:42:30 +08001/*
2 * Synaptics RMI4 touchscreen driver
3 *
4 * Copyright (C) 2012 Synaptics Incorporated
5 *
6 * Copyright (C) 2012 Alexandra Chin <alexandra.chin@tw.synaptics.com>
7 * Copyright (C) 2012 Scott Lin <scott.lin@tw.synaptics.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 */
19
20#include <linux/kernel.h>
21#include <linux/module.h>
22#include <linux/slab.h>
23#include <linux/i2c.h>
24#include <linux/interrupt.h>
25#include <linux/delay.h>
26#include <linux/input.h>
27#include <linux/gpio.h>
28#include <linux/uaccess.h>
29#include <linux/cdev.h>
30#include <linux/input/synaptics_dsx.h>
31#include "synaptics_i2c_rmi4.h"
32
33#define CHAR_DEVICE_NAME "rmi"
34#define DEVICE_CLASS_NAME "rmidev"
35#define DEV_NUMBER 1
36#define REG_ADDR_LIMIT 0xFFFF
37
38static ssize_t rmidev_sysfs_open_store(struct device *dev,
39 struct device_attribute *attr, const char *buf, size_t count);
40
41static ssize_t rmidev_sysfs_release_store(struct device *dev,
42 struct device_attribute *attr, const char *buf, size_t count);
43
44static ssize_t rmidev_sysfs_address_store(struct device *dev,
45 struct device_attribute *attr, const char *buf, size_t count);
46
47static ssize_t rmidev_sysfs_length_store(struct device *dev,
48 struct device_attribute *attr, const char *buf, size_t count);
49
50static ssize_t rmidev_sysfs_data_show(struct device *dev,
51 struct device_attribute *attr, char *buf);
52
53static ssize_t rmidev_sysfs_data_store(struct device *dev,
54 struct device_attribute *attr, const char *buf, size_t count);
55
56struct rmidev_handle {
57 dev_t dev_no;
58 unsigned short address;
59 unsigned int length;
60 struct device dev;
61 struct synaptics_rmi4_data *rmi4_data;
62 struct synaptics_rmi4_exp_fn_ptr *fn_ptr;
63 struct kobject *sysfs_dir;
64 void *data;
65};
66
67struct rmidev_data {
68 int ref_count;
69 struct cdev main_dev;
70 struct class *device_class;
71 struct mutex file_mutex;
72 struct rmidev_handle *rmi_dev;
73};
74
75static struct device_attribute attrs[] = {
Himanshu Aggarwal9db4f5d2013-11-25 21:58:56 +053076 __ATTR(open, S_IWUSR | S_IWGRP,
77 NULL,
Alexandra Chin669d27c2012-12-24 15:42:30 +080078 rmidev_sysfs_open_store),
Himanshu Aggarwal9db4f5d2013-11-25 21:58:56 +053079 __ATTR(release, S_IWUSR | S_IWGRP,
80 NULL,
Alexandra Chin669d27c2012-12-24 15:42:30 +080081 rmidev_sysfs_release_store),
Himanshu Aggarwal9db4f5d2013-11-25 21:58:56 +053082 __ATTR(address, S_IWUSR | S_IWGRP,
83 NULL,
Alexandra Chin669d27c2012-12-24 15:42:30 +080084 rmidev_sysfs_address_store),
Himanshu Aggarwal9db4f5d2013-11-25 21:58:56 +053085 __ATTR(length, S_IWUSR | S_IWGRP,
86 NULL,
Alexandra Chin669d27c2012-12-24 15:42:30 +080087 rmidev_sysfs_length_store),
Himanshu Aggarwal9db4f5d2013-11-25 21:58:56 +053088 __ATTR(data, (S_IWUSR | S_IWGRP),
Alexandra Chin669d27c2012-12-24 15:42:30 +080089 rmidev_sysfs_data_show,
90 rmidev_sysfs_data_store),
91};
92
93static int rmidev_major_num;
94
95static struct class *rmidev_device_class;
96
97static struct rmidev_handle *rmidev;
98
99static struct completion remove_complete;
100
101static ssize_t rmidev_sysfs_open_store(struct device *dev,
102 struct device_attribute *attr, const char *buf, size_t count)
103{
104 unsigned int input;
105
106 if (sscanf(buf, "%u", &input) != 1)
107 return -EINVAL;
108
109 if (input != 1)
110 return -EINVAL;
111
112 rmidev->fn_ptr->enable(rmidev->rmi4_data, false);
113 dev_dbg(&rmidev->rmi4_data->i2c_client->dev,
114 "%s: Attention interrupt disabled\n",
115 __func__);
116
117 return count;
118}
119
120static ssize_t rmidev_sysfs_release_store(struct device *dev,
121 struct device_attribute *attr, const char *buf, size_t count)
122{
123 unsigned int input;
124
125 if (sscanf(buf, "%u", &input) != 1)
126 return -EINVAL;
127
128 if (input != 1)
129 return -EINVAL;
130
131 rmidev->fn_ptr->enable(rmidev->rmi4_data, true);
132 dev_dbg(&rmidev->rmi4_data->i2c_client->dev,
133 "%s: Attention interrupt enabled\n",
134 __func__);
135
136 return count;
137}
138
139static ssize_t rmidev_sysfs_address_store(struct device *dev,
140 struct device_attribute *attr, const char *buf, size_t count)
141{
142 unsigned int input;
143
144 if (sscanf(buf, "%u", &input) != 1)
145 return -EINVAL;
146
147 if (input > REG_ADDR_LIMIT)
148 return -EINVAL;
149
150 rmidev->address = (unsigned short)input;
151
152 return count;
153}
154
155static ssize_t rmidev_sysfs_length_store(struct device *dev,
156 struct device_attribute *attr, const char *buf, size_t count)
157{
158 unsigned int input;
159
160 if (sscanf(buf, "%u", &input) != 1)
161 return -EINVAL;
162
163 if (input > REG_ADDR_LIMIT)
164 return -EINVAL;
165
166 rmidev->length = input;
167
168 return count;
169}
170
171static ssize_t rmidev_sysfs_data_show(struct device *dev,
172 struct device_attribute *attr, char *buf)
173{
174 int retval;
175 unsigned int data_length = rmidev->length;
176
177 if (data_length > (REG_ADDR_LIMIT - rmidev->address))
178 data_length = REG_ADDR_LIMIT - rmidev->address;
179
180 if (data_length) {
181 retval = rmidev->fn_ptr->read(rmidev->rmi4_data,
182 rmidev->address,
183 (unsigned char *)buf,
184 data_length);
185 if (retval < 0) {
186 dev_err(&rmidev->rmi4_data->i2c_client->dev,
187 "%s: Failed to read data\n",
188 __func__);
189 return retval;
190 }
191 } else {
192 return -EINVAL;
193 }
194
195 return data_length;
196}
197
198static ssize_t rmidev_sysfs_data_store(struct device *dev,
199 struct device_attribute *attr, const char *buf, size_t count)
200{
201 int retval;
202 unsigned int data_length = rmidev->length;
203
204 if (data_length > (REG_ADDR_LIMIT - rmidev->address))
205 data_length = REG_ADDR_LIMIT - rmidev->address;
206
207 if (data_length) {
208 retval = rmidev->fn_ptr->write(rmidev->rmi4_data,
209 rmidev->address,
210 (unsigned char *)buf,
211 data_length);
212 if (retval < 0) {
213 dev_err(&rmidev->rmi4_data->i2c_client->dev,
214 "%s: Failed to write data\n",
215 __func__);
216 return retval;
217 }
218 } else {
219 return -EINVAL;
220 }
221
222 return data_length;
223}
224
225/*
226 * rmidev_llseek - used to set up register address
227 *
228 * @filp: file structure for seek
229 * @off: offset
230 * if whence == SEEK_SET,
231 * high 16 bits: page address
232 * low 16 bits: register address
233 * if whence == SEEK_CUR,
234 * offset from current position
235 * if whence == SEEK_END,
236 * offset from end position (0xFFFF)
237 * @whence: SEEK_SET, SEEK_CUR, or SEEK_END
238 */
239static loff_t rmidev_llseek(struct file *filp, loff_t off, int whence)
240{
241 loff_t newpos;
242 struct rmidev_data *dev_data = filp->private_data;
243
244 if (IS_ERR(dev_data)) {
245 pr_err("%s: Pointer of char device data is invalid", __func__);
246 return -EBADF;
247 }
248
249 mutex_lock(&(dev_data->file_mutex));
250
251 switch (whence) {
252 case SEEK_SET:
253 newpos = off;
254 break;
255 case SEEK_CUR:
256 newpos = filp->f_pos + off;
257 break;
258 case SEEK_END:
259 newpos = REG_ADDR_LIMIT + off;
260 break;
261 default:
262 newpos = -EINVAL;
263 goto clean_up;
264 }
265
266 if (newpos < 0 || newpos > REG_ADDR_LIMIT) {
267 dev_err(&rmidev->rmi4_data->i2c_client->dev,
268 "%s: New position 0x%04x is invalid\n",
269 __func__, (unsigned int)newpos);
270 newpos = -EINVAL;
271 goto clean_up;
272 }
273
274 filp->f_pos = newpos;
275
276clean_up:
277 mutex_unlock(&(dev_data->file_mutex));
278
279 return newpos;
280}
281
282/*
283 * rmidev_read: - use to read data from rmi device
284 *
285 * @filp: file structure for read
286 * @buf: user space buffer pointer
287 * @count: number of bytes to read
288 * @f_pos: offset (starting register address)
289 */
290static ssize_t rmidev_read(struct file *filp, char __user *buf,
291 size_t count, loff_t *f_pos)
292{
293 ssize_t retval;
294 unsigned char tmpbuf[count + 1];
295 struct rmidev_data *dev_data = filp->private_data;
296
297 if (IS_ERR(dev_data)) {
298 pr_err("%s: Pointer of char device data is invalid", __func__);
299 return -EBADF;
300 }
301
302 if (count == 0)
303 return 0;
304
305 if (count > (REG_ADDR_LIMIT - *f_pos))
306 count = REG_ADDR_LIMIT - *f_pos;
307
308 mutex_lock(&(dev_data->file_mutex));
309
310 retval = rmidev->fn_ptr->read(rmidev->rmi4_data,
311 *f_pos,
312 tmpbuf,
313 count);
314 if (retval < 0)
315 goto clean_up;
316
317 if (copy_to_user(buf, tmpbuf, count))
318 retval = -EFAULT;
319 else
320 *f_pos += retval;
321
322clean_up:
323 mutex_unlock(&(dev_data->file_mutex));
324
325 return retval;
326}
327
328/*
329 * rmidev_write: - used to write data to rmi device
330 *
331 * @filep: file structure for write
332 * @buf: user space buffer pointer
333 * @count: number of bytes to write
334 * @f_pos: offset (starting register address)
335 */
336static ssize_t rmidev_write(struct file *filp, const char __user *buf,
337 size_t count, loff_t *f_pos)
338{
339 ssize_t retval;
340 unsigned char tmpbuf[count + 1];
341 struct rmidev_data *dev_data = filp->private_data;
342
343 if (IS_ERR(dev_data)) {
344 pr_err("%s: Pointer of char device data is invalid", __func__);
345 return -EBADF;
346 }
347
348 if (count == 0)
349 return 0;
350
351 if (count > (REG_ADDR_LIMIT - *f_pos))
352 count = REG_ADDR_LIMIT - *f_pos;
353
354 if (copy_from_user(tmpbuf, buf, count))
355 return -EFAULT;
356
357 mutex_lock(&(dev_data->file_mutex));
358
359 retval = rmidev->fn_ptr->write(rmidev->rmi4_data,
360 *f_pos,
361 tmpbuf,
362 count);
363 if (retval >= 0)
364 *f_pos += retval;
365
366 mutex_unlock(&(dev_data->file_mutex));
367
368 return retval;
369}
370
371/*
372 * rmidev_open: enable access to rmi device
373 * @inp: inode struture
374 * @filp: file structure
375 */
376static int rmidev_open(struct inode *inp, struct file *filp)
377{
378 int retval = 0;
379 struct rmidev_data *dev_data =
380 container_of(inp->i_cdev, struct rmidev_data, main_dev);
381
382 if (!dev_data)
383 return -EACCES;
384
385 filp->private_data = dev_data;
386
387 mutex_lock(&(dev_data->file_mutex));
388
389 rmidev->fn_ptr->enable(rmidev->rmi4_data, false);
390 dev_dbg(&rmidev->rmi4_data->i2c_client->dev,
391 "%s: Attention interrupt disabled\n",
392 __func__);
393
394 if (dev_data->ref_count < 1)
395 dev_data->ref_count++;
396 else
397 retval = -EACCES;
398
399 mutex_unlock(&(dev_data->file_mutex));
400
401 return retval;
402}
403
404/*
405 * rmidev_release: - release access to rmi device
406 * @inp: inode structure
407 * @filp: file structure
408 */
409static int rmidev_release(struct inode *inp, struct file *filp)
410{
411 struct rmidev_data *dev_data =
412 container_of(inp->i_cdev, struct rmidev_data, main_dev);
413
414 if (!dev_data)
415 return -EACCES;
416
417 mutex_lock(&(dev_data->file_mutex));
418
419 dev_data->ref_count--;
420 if (dev_data->ref_count < 0)
421 dev_data->ref_count = 0;
422
423 rmidev->fn_ptr->enable(rmidev->rmi4_data, true);
424 dev_dbg(&rmidev->rmi4_data->i2c_client->dev,
425 "%s: Attention interrupt enabled\n",
426 __func__);
427
428 mutex_unlock(&(dev_data->file_mutex));
429
430 return 0;
431}
432
433static const struct file_operations rmidev_fops = {
434 .owner = THIS_MODULE,
435 .llseek = rmidev_llseek,
436 .read = rmidev_read,
437 .write = rmidev_write,
438 .open = rmidev_open,
439 .release = rmidev_release,
440};
441
442static void rmidev_device_cleanup(struct rmidev_data *dev_data)
443{
444 dev_t devno;
445
446 if (dev_data) {
447 devno = dev_data->main_dev.dev;
448
449 if (dev_data->device_class)
450 device_destroy(dev_data->device_class, devno);
451
452 cdev_del(&dev_data->main_dev);
453
454 unregister_chrdev_region(devno, 1);
455
456 dev_dbg(&rmidev->rmi4_data->i2c_client->dev,
457 "%s: rmidev device removed\n",
458 __func__);
459 }
460
461 return;
462}
463
464static char *rmi_char_devnode(struct device *dev, mode_t *mode)
465{
466 if (!mode)
467 return NULL;
468
469 *mode = (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
470
471 return kasprintf(GFP_KERNEL, "rmi/%s", dev_name(dev));
472}
473
474static int rmidev_create_device_class(void)
475{
476 rmidev_device_class = class_create(THIS_MODULE, DEVICE_CLASS_NAME);
477
478 if (IS_ERR(rmidev_device_class)) {
479 pr_err("%s: Failed to create /dev/%s\n",
480 __func__, CHAR_DEVICE_NAME);
481 return -ENODEV;
482 }
483
484 rmidev_device_class->devnode = rmi_char_devnode;
485
486 return 0;
487}
488
489static int rmidev_init_device(struct synaptics_rmi4_data *rmi4_data)
490{
491 int retval;
492 dev_t dev_no;
493 unsigned char attr_count;
494 struct rmidev_data *dev_data;
495 struct device *device_ptr;
496
497 rmidev = kzalloc(sizeof(*rmidev), GFP_KERNEL);
498 if (!rmidev) {
499 dev_err(&rmi4_data->i2c_client->dev,
500 "%s: Failed to alloc mem for rmidev\n",
501 __func__);
502 retval = -ENOMEM;
503 goto err_rmidev;
504 }
505
506 rmidev->fn_ptr = kzalloc(sizeof(*(rmidev->fn_ptr)), GFP_KERNEL);
507 if (!rmidev) {
508 dev_err(&rmi4_data->i2c_client->dev,
509 "%s: Failed to alloc mem for fn_ptr\n",
510 __func__);
511 retval = -ENOMEM;
512 goto err_fn_ptr;
513 }
514
515 rmidev->fn_ptr->read = rmi4_data->i2c_read;
516 rmidev->fn_ptr->write = rmi4_data->i2c_write;
517 rmidev->fn_ptr->enable = rmi4_data->irq_enable;
518 rmidev->rmi4_data = rmi4_data;
519
520 retval = rmidev_create_device_class();
521 if (retval < 0) {
522 dev_err(&rmi4_data->i2c_client->dev,
523 "%s: Failed to create device class\n",
524 __func__);
525 goto err_device_class;
526 }
527
528 if (rmidev_major_num) {
529 dev_no = MKDEV(rmidev_major_num, DEV_NUMBER);
530 retval = register_chrdev_region(dev_no, 1, CHAR_DEVICE_NAME);
531 } else {
532 retval = alloc_chrdev_region(&dev_no, 0, 1, CHAR_DEVICE_NAME);
533 if (retval < 0) {
534 dev_err(&rmi4_data->i2c_client->dev,
535 "%s: Failed to allocate char device region\n",
536 __func__);
537 goto err_device_region;
538 }
539
540 rmidev_major_num = MAJOR(dev_no);
541 dev_dbg(&rmi4_data->i2c_client->dev,
542 "%s: Major number of rmidev = %d\n",
543 __func__, rmidev_major_num);
544 }
545
546 dev_data = kzalloc(sizeof(*dev_data), GFP_KERNEL);
547 if (!dev_data) {
548 dev_err(&rmi4_data->i2c_client->dev,
549 "%s: Failed to alloc mem for dev_data\n",
550 __func__);
551 retval = -ENOMEM;
552 goto err_dev_data;
553 }
554
555 mutex_init(&dev_data->file_mutex);
556 dev_data->rmi_dev = rmidev;
557 rmidev->data = dev_data;
558
559 cdev_init(&dev_data->main_dev, &rmidev_fops);
560
561 retval = cdev_add(&dev_data->main_dev, dev_no, 1);
562 if (retval < 0) {
563 dev_err(&rmi4_data->i2c_client->dev,
564 "%s: Failed to add rmi char device\n",
565 __func__);
566 goto err_char_device;
567 }
568
569 dev_set_name(&rmidev->dev, "rmidev%d", MINOR(dev_no));
570 dev_data->device_class = rmidev_device_class;
571
572 device_ptr = device_create(dev_data->device_class, NULL, dev_no,
573 NULL, CHAR_DEVICE_NAME"%d", MINOR(dev_no));
574 if (IS_ERR(device_ptr)) {
575 dev_err(&rmi4_data->i2c_client->dev,
576 "%s: Failed to create rmi char device\n",
577 __func__);
578 retval = -ENODEV;
579 goto err_char_device;
580 }
581
582 retval = gpio_export(rmi4_data->board->irq_gpio, false);
583 if (retval < 0) {
584 dev_err(&rmi4_data->i2c_client->dev,
585 "%s: Failed to export attention gpio\n",
586 __func__);
587 } else {
588 retval = gpio_export_link(&(rmi4_data->input_dev->dev),
589 "attn", rmi4_data->board->irq_gpio);
590 if (retval < 0) {
591 dev_err(&rmi4_data->input_dev->dev,
592 "%s Failed to create gpio symlink\n",
593 __func__);
594 } else {
595 dev_dbg(&rmi4_data->input_dev->dev,
596 "%s: Exported attention gpio %d\n",
597 __func__, rmi4_data->board->irq_gpio);
598 }
599 }
600
601 rmidev->sysfs_dir = kobject_create_and_add("rmidev",
602 &rmi4_data->input_dev->dev.kobj);
603 if (!rmidev->sysfs_dir) {
604 dev_err(&rmi4_data->i2c_client->dev,
605 "%s: Failed to create sysfs directory\n",
606 __func__);
607 goto err_sysfs_dir;
608 }
609
610 for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++) {
611 retval = sysfs_create_file(rmidev->sysfs_dir,
612 &attrs[attr_count].attr);
613 if (retval < 0) {
614 dev_err(&rmi4_data->input_dev->dev,
615 "%s: Failed to create sysfs attributes\n",
616 __func__);
617 retval = -ENODEV;
618 goto err_sysfs_attrs;
619 }
620 }
621
Alexandra Chinc556cf02013-03-19 17:46:05 -0700622 init_completion(&remove_complete);
623
Alexandra Chin669d27c2012-12-24 15:42:30 +0800624 return 0;
625
626err_sysfs_attrs:
627 for (attr_count--; attr_count >= 0; attr_count--) {
628 sysfs_remove_file(&rmi4_data->input_dev->dev.kobj,
629 &attrs[attr_count].attr);
630 }
631
632 kobject_put(rmidev->sysfs_dir);
633
634err_sysfs_dir:
635err_char_device:
636 rmidev_device_cleanup(dev_data);
637 kfree(dev_data);
638
639err_dev_data:
640 unregister_chrdev_region(dev_no, 1);
641
642err_device_region:
643 class_destroy(rmidev_device_class);
644
645err_device_class:
646 kfree(rmidev->fn_ptr);
647
648err_fn_ptr:
649 kfree(rmidev);
650
651err_rmidev:
652 return retval;
653}
654
655static void rmidev_remove_device(struct synaptics_rmi4_data *rmi4_data)
656{
657 unsigned char attr_count;
658 struct rmidev_data *dev_data;
659
660 if (!rmidev)
661 return;
662
663 for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++)
664 sysfs_remove_file(rmidev->sysfs_dir, &attrs[attr_count].attr);
665
666 kobject_put(rmidev->sysfs_dir);
667
668 dev_data = rmidev->data;
669 if (dev_data) {
670 rmidev_device_cleanup(dev_data);
671 kfree(dev_data);
672 }
673
674 unregister_chrdev_region(rmidev->dev_no, 1);
675
676 class_destroy(rmidev_device_class);
677
678 kfree(rmidev->fn_ptr);
679 kfree(rmidev);
680
681 complete(&remove_complete);
682
683 return;
684}
685
686static int __init rmidev_module_init(void)
687{
688 synaptics_rmi4_new_function(RMI_DEV, true,
689 rmidev_init_device,
690 rmidev_remove_device,
691 NULL);
692 return 0;
693}
694
695static void __exit rmidev_module_exit(void)
696{
697 init_completion(&remove_complete);
698 synaptics_rmi4_new_function(RMI_DEV, false,
699 rmidev_init_device,
700 rmidev_remove_device,
701 NULL);
702 wait_for_completion(&remove_complete);
703 return;
704}
705
706module_init(rmidev_module_init);
707module_exit(rmidev_module_exit);
708
709MODULE_AUTHOR("Synaptics, Inc.");
710MODULE_DESCRIPTION("RMI4 RMI_Dev Module");
Alexandra Chinbd1dac22013-02-22 12:33:19 -0800711MODULE_LICENSE("GPL v2");