temp revert rk change
[firefly-linux-kernel-4.4.55.git] / drivers / mfd / cpcap-key.c
1 /*
2  * Copyright (C) 2009 Motorola, Inc.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
16  * 02111-1307, USA
17  */
18
19 #include <linux/module.h>
20 #include <linux/init.h>
21 #include <linux/platform_device.h>
22 #include <linux/input.h>
23 #include <linux/slab.h>
24 #include <linux/spi/cpcap.h>
25 #include <linux/spi/cpcap-regbits.h>
26
27
28
29 struct cpcap_key_data {
30         struct input_dev *input_dev;
31         struct cpcap_device *cpcap;
32 };
33
34 static int cpcap_key_probe(struct platform_device *pdev)
35 {
36         int err;
37         struct cpcap_key_data *key;
38
39         if (pdev->dev.platform_data == NULL) {
40                 dev_err(&pdev->dev, "no platform_data\n");
41                 return -EINVAL;
42         }
43
44         key = kzalloc(sizeof(*key), GFP_KERNEL);
45         if (!key)
46                 return -ENOMEM;
47
48         key->cpcap = pdev->dev.platform_data;
49
50         key->input_dev = input_allocate_device();
51         if (key->input_dev == NULL) {
52                 dev_err(&pdev->dev, "can't allocate input device\n");
53                 err = -ENOMEM;
54                 goto err0;
55         }
56
57         set_bit(EV_KEY, key->input_dev->evbit);
58         set_bit(KEY_MEDIA, key->input_dev->keybit);
59         set_bit(KEY_END, key->input_dev->keybit);
60
61         key->input_dev->name = "cpcap-key";
62
63         err = input_register_device(key->input_dev);
64         if (err < 0) {
65                 dev_err(&pdev->dev, "could not register input device.\n");
66                 goto err1;
67         }
68
69         platform_set_drvdata(pdev, key);
70         cpcap_set_keydata(key->cpcap, key);
71
72         dev_info(&pdev->dev, "CPCAP key device probed\n");
73
74         return 0;
75
76 err1:
77         input_free_device(key->input_dev);
78 err0:
79         kfree(key);
80         return err;
81 }
82
83 static int __exit cpcap_key_remove(struct platform_device *pdev)
84 {
85         struct cpcap_key_data *key = platform_get_drvdata(pdev);
86
87         input_unregister_device(key->input_dev);
88         input_free_device(key->input_dev);
89         kfree(key);
90
91         return 0;
92 }
93
94 void cpcap_broadcast_key_event(struct cpcap_device *cpcap,
95                                unsigned int code, int value)
96 {
97         struct cpcap_key_data *key = cpcap_get_keydata(cpcap);
98
99         if (key && key->input_dev)
100                 input_report_key(key->input_dev, code, value);
101 }
102 EXPORT_SYMBOL(cpcap_broadcast_key_event);
103
104 static struct platform_driver cpcap_key_driver = {
105         .probe          = cpcap_key_probe,
106         .remove         = __exit_p(cpcap_key_remove),
107         .driver         = {
108                 .name   = "cpcap_key",
109                 .owner  = THIS_MODULE,
110         },
111 };
112
113 static int __init cpcap_key_init(void)
114 {
115         return platform_driver_register(&cpcap_key_driver);
116 }
117 module_init(cpcap_key_init);
118
119 static void __exit cpcap_key_exit(void)
120 {
121         platform_driver_unregister(&cpcap_key_driver);
122 }
123 module_exit(cpcap_key_exit);
124
125 MODULE_ALIAS("platform:cpcap_key");
126 MODULE_DESCRIPTION("CPCAP KEY driver");
127 MODULE_AUTHOR("Motorola");
128 MODULE_LICENSE("GPL");