blob: 4a029f792f4427f7b87c64ac3e7f9b78bea244e2 [file] [log] [blame]
Taniya Das6f0884b2011-09-06 16:24:21 +05301/**
2 * Synaptics Register Mapped Interface (RMI4) - RMI Function Module.
3 * Copyright (C) 2007 - 2011, Synaptics Incorporated
4 *
5 */
6/*
7 * This file is licensed under the GPL2 license.
8 *
9 *#############################################################################
10 * GPL
11 *
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License version 2 as published
14 * by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
18 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 * for more details.
20 *
21 *#############################################################################
22 */
23
24static const char functionname[10] = "fn";
25
26#include <linux/kernel.h>
27#include <linux/device.h>
28#include <linux/hrtimer.h>
29#include <linux/miscdevice.h>
30#include <linux/fs.h>
31#include <linux/delay.h>
32#include <linux/uaccess.h>
33#include <linux/slab.h>
34#include <linux/kthread.h>
35#include <linux/freezer.h>
36#include <linux/input.h>
37#include <linux/interrupt.h>
Steve Mucklef132c6c2012-06-06 18:30:57 -070038#include <linux/module.h>
Taniya Das6f0884b2011-09-06 16:24:21 +053039
40#include "rmi_drvr.h"
41#include "rmi_function.h"
42#include "rmi_bus.h"
43#include "rmi_sensor.h"
44#include "rmi_f01.h"
45#include "rmi_f05.h"
46#include "rmi_f11.h"
47#include "rmi_f19.h"
48#include "rmi_f34.h"
49
50/* Each time a new RMI4 function support is added the developer needs to
51bump the number of supported functions and add the info for
52that RMI4 function to the array along with pointers to the report,
53config, init and detect functions that they coded in rmi_fxx.c
54and rmi_fxx.h - where xx is the RMI4 function number in hex for the new
55RMI4 data source function. The information for the RMI4 functions is
56obtained from the RMI4 specification document.
57 */
58#define rmi4_num_supported_data_src_fns 5
59
60/* supported RMI4 functions list - controls what we
61 * will provide support for - if it's not in the list then
62 * the developer needs to add support functions for it.*/
63static LIST_HEAD(fns_list);
64static DEFINE_MUTEX(fns_mutex);
65
66/* NOTE: Developer - add in any new RMI4 fn data info - function number
67 * and ptrs to report, config, init and detect functions. This data is
68 * used to point to the functions that need to be called to config, init,
69 * detect and report data for the new RMI4 function. Refer to the RMI4
70 * specification for information on RMI4 functions.
71 */
72/* TODO: This will eventually go away, and each function will be an independent
73 * module. */
74static struct rmi_functions_data
75 rmi4_supported_data_src_functions[rmi4_num_supported_data_src_fns] = {
76 /* Fn $11 - 2D sensing */
77 {.functionNumber = 0x11, .inthandlerFn = FN_11_inthandler, .configFn = FN_11_config, .initFn = FN_11_init, .detectFn = FN_11_detect, .attnFn = NULL},
78 /* Fn $01 - device control */
79 {.functionNumber = 0x01, .inthandlerFn = FN_01_inthandler, .configFn = FN_01_config, .initFn = FN_01_init, .detectFn = FN_01_detect, .attnFn = FN_01_attention},
80 /* Fn $05 - analog report */
81 {.functionNumber = 0x05, .inthandlerFn = FN_05_inthandler, .configFn = FN_05_config, .initFn = FN_05_init, .detectFn = FN_05_detect, .attnFn = NULL},
82 /* Fn $19 - buttons */
83 {.functionNumber = 0x19, .inthandlerFn = FN_19_inthandler, .configFn = FN_19_config, .initFn = FN_19_init, .detectFn = FN_19_detect, .attnFn = NULL},
84 /* Fn $34 - firmware reflash */
85 {.functionNumber = 0x34, .inthandlerFn = FN_34_inthandler, .configFn = FN_34_config, .initFn = FN_34_init, .detectFn = FN_34_detect, .attnFn = FN_34_attention},
86};
87
88
89/* This function is here to provide a way for external modules to access the
90 * functions list. It will try to find a matching function base on the passed
91 * in RMI4 function number and return the pointer to the struct rmi_functions
92 * if a match is found or NULL if not found.
93 */
94struct rmi_functions *rmi_find_function(int functionNum)
95{
96 struct rmi_functions *fn;
97 bool found = false;
98
99 list_for_each_entry(fn, &fns_list, link) {
100 if (functionNum == fn->functionNum) {
101 found = true;
102 break;
103 }
104 }
105
106 if (!found)
107 return NULL;
108 else
109 return fn;
110}
111EXPORT_SYMBOL(rmi_find_function);
112
113
114static void rmi_function_config(struct rmi_function_device *function)
115{
116 printk(KERN_DEBUG "%s: rmi_function_config", __func__);
117
118}
119
120#if 0 /* This may not be needed anymore. */
121/**
122 * This is the probe function passed to the RMI4 subsystem that gives us a
123 * chance to recognize an RMI4 function.
124 */
125static int rmi_function_probe(struct rmi_function_driver *function)
126{
127 struct rmi_phys_driver *rpd;
128
129 rpd = function->rpd;
130
131 if (!rpd) {
132 printk(KERN_ERR "%s: Invalid rmi physical driver - null ptr.", __func__);
133 return 0;
134 }
135
136 return 1;
137}
138#endif
139
140/** Just a stub for now.
141 */
142static int rmi_function_suspend(struct device *dev, pm_message_t state)
143{
144 printk(KERN_INFO "%s: function suspend called.", __func__);
145 return 0;
146}
147
148/** Just a stub for now.
149 */
150static int rmi_function_resume(struct device *dev)
151{
152 printk(KERN_INFO "%s: function resume called.", __func__);
153 return 0;
154}
155
156int rmi_function_register_driver(struct rmi_function_driver *drv, int fnNumber)
157{
158 int retval;
159 char *drvrname;
160
161 printk(KERN_INFO "%s: Registering function driver for F%02x.\n", __func__, fnNumber);
162
163 retval = 0;
164
165 /* Create a function device and function driver for this Fn */
166 drvrname = kzalloc(sizeof(functionname) + 4, GFP_KERNEL);
167 if (!drvrname) {
168 printk(KERN_ERR "%s: Error allocating memeory for rmi_function_driver name.\n", __func__);
169 return -ENOMEM;
170 }
171 sprintf(drvrname, "fn%02x", fnNumber);
172
173 drv->drv.name = drvrname;
174 drv->module = drv->drv.owner;
175
176 drv->drv.suspend = rmi_function_suspend;
177 drv->drv.resume = rmi_function_resume;
178
179 /* register the sensor driver */
180 retval = driver_register(&drv->drv);
181 if (retval) {
182 printk(KERN_ERR "%s: Failed driver_register %d\n",
183 __func__, retval);
184 }
185
186 return retval;
187}
188EXPORT_SYMBOL(rmi_function_register_driver);
189
190void rmi_function_unregister_driver(struct rmi_function_driver *drv)
191{
192 printk(KERN_INFO "%s: Unregistering function driver.\n", __func__);
193
194 driver_unregister(&drv->drv);
195}
196EXPORT_SYMBOL(rmi_function_unregister_driver);
197
198int rmi_function_register_device(struct rmi_function_device *function_device, int fnNumber)
199{
200 struct input_dev *input;
201 int retval;
202
203 printk(KERN_INFO "%s: Registering function device for F%02x.\n", __func__, fnNumber);
204
205 retval = 0;
206
207 /* make name - fn11, fn19, etc. */
208 dev_set_name(&function_device->dev, "%sfn%02x", function_device->sensor->drv.name, fnNumber);
209 dev_set_drvdata(&function_device->dev, function_device);
210 retval = device_register(&function_device->dev);
211 if (retval) {
212 printk(KERN_ERR "%s: Failed device_register for function device.\n",
213 __func__);
214 return retval;
215 }
216
217 input = input_allocate_device();
218 if (input == NULL) {
219 printk(KERN_ERR "%s: Failed to allocate memory for a "
220 "new input device.\n",
221 __func__);
222 return -ENOMEM;
223 }
224
225 input->name = dev_name(&function_device->dev);
226 input->phys = "rmi_function";
227 function_device->input = input;
228
229
230 /* init any input specific params for this function */
231 function_device->rmi_funcs->init(function_device);
232
233 retval = input_register_device(input);
234
235 if (retval) {
236 printk(KERN_ERR "%s: Failed input_register_device.\n",
237 __func__);
238 return retval;
239 }
240
241
242 rmi_function_config(function_device);
243
244 return retval;
245}
246EXPORT_SYMBOL(rmi_function_register_device);
247
248void rmi_function_unregister_device(struct rmi_function_device *dev)
249{
250 printk(KERN_INFO "%s: Unregistering function device.n", __func__);
251
252 input_unregister_device(dev->input);
253 device_unregister(&dev->dev);
254}
255EXPORT_SYMBOL(rmi_function_unregister_device);
256
257static int __init rmi_function_init(void)
258{
259 struct rmi_functions_data *rmi4_fn;
260 int i;
261
262 printk(KERN_DEBUG "%s: RMI Function Init\n", __func__);
263
264 /* Initialize global list of RMI4 Functions.
265 We need to add the supported RMI4 funcions so that we will have
266 pointers to the associated functions for init, config, report and
267 detect. See rmi.h for more details. The developer will add a new
268 RMI4 function number in the array in rmi_drvr.h, then add a new file to
269 the build (called rmi_fXX.c where XX is the hex number for
270 the added RMI4 function). The rest should be automatic.
271 */
272
273 /* for each function number defined in rmi.h creat a new rmi_function
274 struct and initialize the pointers to the servicing functions and then
275 add it into the global list for function support.
276 */
277 for (i = 0; i < rmi4_num_supported_data_src_fns; i++) {
278 /* Add new rmi4 function struct to list */
279 struct rmi_functions *fn = kzalloc(sizeof(*fn), GFP_KERNEL);
280 if (!fn) {
281 printk(KERN_ERR "%s: could not allocate memory "
282 "for rmi_function struct for function 0x%x\n",
283 __func__,
284 rmi4_supported_data_src_functions[i].functionNumber);
285 return -ENOMEM;
286 } else {
287
288 rmi4_fn = &rmi4_supported_data_src_functions[i];
289 fn->functionNum = rmi4_fn->functionNumber;
290 /* Fill in ptrs to functions. The functions are
291 linked in from a file called rmi_fxx.c
292 where xx is the hex number of the RMI4 function
293 from the RMI4 spec. Also, the function prototypes
294 need to be added to rmi_fxx.h - also where
295 xx is the hex number of the RMI4 function. So
296 that you don't get compile errors and that new
297 header needs to be included in the rmi_function.h
298 */
299 fn->inthandler = rmi4_fn->inthandlerFn;
300 fn->config = rmi4_fn->configFn;
301 fn->init = rmi4_fn->initFn;
302 fn->detect = rmi4_fn->detectFn;
303 fn->attention = rmi4_fn->attnFn;
304
305 /* Add the new fn to the global list */
306 mutex_lock(&fns_mutex);
307 list_add_tail(&fn->link, &fns_list);
308 mutex_unlock(&fns_mutex);
309 }
310 }
311
312 return 0;
313}
314
315static void __exit rmi_function_exit(void)
316{
317 printk(KERN_DEBUG "%s: RMI Function Exit\n", __func__);
318}
319
320
321module_init(rmi_function_init);
322module_exit(rmi_function_exit);
323
324MODULE_AUTHOR("Synaptics, Inc.");
325MODULE_DESCRIPTION("RMI4 Function Driver");
326MODULE_LICENSE("GPL");