rmi_function.c 9.7 KB

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