rmi_guest.c 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338
  1. /* Synaptics Register Mapped Interface (RMI4) I2C Physical Layer Driver.
  2. * Copyright (c) 2007-2012, Synaptics Incorporated
  3. *
  4. * This software is licensed under the terms of the GNU General Public
  5. * License version 2, as published by the Free Software Foundation, and
  6. * may be copied, distributed, and modified under those terms.
  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. */
  14. #include <linux/kernel.h>
  15. #include <linux/module.h>
  16. #include <asm/unaligned.h>
  17. #include <asm/siginfo.h>
  18. //#include <mach/cpufreq.h>
  19. #include <linux/slab.h>
  20. #include <linux/i2c.h>
  21. #include <linux/interrupt.h>
  22. #include <linux/delay.h>
  23. #include <linux/input.h>
  24. #include <linux/gpio.h>
  25. #include <linux/uaccess.h>
  26. #include <linux/signal.h>
  27. #include <linux/input/synaptics_dsx.h>
  28. #include "synaptics_i2c_rmi.h"
  29. #include "Multiverse/GMvSystem.h"
  30. #define GEUST_PAGES_TO_SERVICE (0x60)
  31. #define HARDCODE_PDT
  32. static ssize_t rmi_guest_sysfs_query_base_addr_show(struct device *dev,
  33. struct device_attribute *attr, char *buf);
  34. static ssize_t rmi_guest_sysfs_control_base_addr_show(struct device *dev,
  35. struct device_attribute *attr, char *buf);
  36. static ssize_t rmi_guest_sysfs_data_base_addr_show(struct device *dev,
  37. struct device_attribute *attr, char *buf);
  38. static ssize_t rmi_guest_sysfs_command_base_addr_show(struct device *dev,
  39. struct device_attribute *attr, char *buf);
  40. struct rmi_guest_handle {
  41. unsigned char intr_mask;
  42. unsigned char intr_reg_num;
  43. unsigned short query_base_addr;
  44. unsigned short control_base_addr;
  45. unsigned short data_base_addr;
  46. unsigned short command_base_addr;
  47. struct synaptics_rmi4_data *rmi4_data;
  48. struct synaptics_rmi4_exp_fn_ptr *fn_ptr;
  49. struct kobject *sysfs_dir;
  50. };
  51. static struct device_attribute attrs[] = {
  52. __ATTR(query_base_addr, S_IRUGO,
  53. rmi_guest_sysfs_query_base_addr_show,
  54. synaptics_rmi4_store_error),
  55. __ATTR(control_base_addr, S_IRUGO,
  56. rmi_guest_sysfs_control_base_addr_show,
  57. synaptics_rmi4_store_error),
  58. __ATTR(data_base_addr, S_IRUGO,
  59. rmi_guest_sysfs_data_base_addr_show,
  60. synaptics_rmi4_store_error),
  61. __ATTR(command_base_addr, S_IRUGO,
  62. rmi_guest_sysfs_command_base_addr_show,
  63. synaptics_rmi4_store_error),
  64. };
  65. static struct rmi_guest_handle *rmiguest;
  66. static ssize_t rmi_guest_sysfs_query_base_addr_show(struct device *dev,
  67. struct device_attribute *attr, char *buf)
  68. {
  69. return snprintf(buf, PAGE_SIZE, "0x%04x\n",
  70. rmiguest->query_base_addr);
  71. }
  72. static ssize_t rmi_guest_sysfs_control_base_addr_show(struct device *dev,
  73. struct device_attribute *attr, char *buf)
  74. {
  75. return snprintf(buf, PAGE_SIZE, "0x%04x\n",
  76. rmiguest->control_base_addr);
  77. }
  78. static ssize_t rmi_guest_sysfs_data_base_addr_show(struct device *dev,
  79. struct device_attribute *attr, char *buf)
  80. {
  81. return snprintf(buf, PAGE_SIZE, "0x%04x\n",
  82. rmiguest->data_base_addr);
  83. }
  84. static ssize_t rmi_guest_sysfs_command_base_addr_show(struct device *dev,
  85. struct device_attribute *attr, char *buf)
  86. {
  87. return snprintf(buf, PAGE_SIZE, "0x%04x\n",
  88. rmiguest->command_base_addr);
  89. }
  90. static int rmi_guest_scan_pdt(void)
  91. {
  92. int retval;
  93. unsigned short ii;
  94. unsigned short addr;
  95. unsigned char page;
  96. unsigned char intr_count = 0;
  97. unsigned char intr_offset;
  98. bool fguest_found = false;
  99. struct synaptics_rmi4_fn_desc rmi_fd;
  100. struct synaptics_rmi4_data *rmi4_data = rmiguest->rmi4_data;
  101. for (page = 0; page <= GEUST_PAGES_TO_SERVICE; page++) {
  102. for (ii = PDT_START; ii > PDT_END; ii -= PDT_ENTRY_SIZE) {
  103. ii |= (page << 8);
  104. retval = rmiguest->fn_ptr->read(rmiguest->rmi4_data,
  105. ii,
  106. (unsigned char *)&rmi_fd,
  107. sizeof(rmi_fd));
  108. if (retval < 0)
  109. return retval;
  110. ii &= ~(MASK_8BIT << 8);
  111. if (!rmi_fd.fn_number)
  112. break;
  113. if (rmi_fd.fn_number == SYNAPTICS_RMI4_F60) {
  114. fguest_found = true;
  115. goto fguest_found;
  116. }
  117. intr_count += (rmi_fd.intr_src_count & MASK_3BIT);
  118. }
  119. }
  120. #ifndef HARDCODE_PDT
  121. if (!fguest_found) {
  122. dev_err(&rmiguest->rmi4_data->i2c_client->dev,
  123. "%s: Failed to find F60\n",
  124. __func__);
  125. return -EINVAL;
  126. }
  127. #endif
  128. fguest_found:
  129. rmiguest->query_base_addr = rmi_fd.query_base_addr | (page << 8);
  130. rmiguest->control_base_addr = rmi_fd.ctrl_base_addr | (page << 8);
  131. rmiguest->data_base_addr = rmi_fd.data_base_addr | (page << 8);
  132. rmiguest->command_base_addr = rmi_fd.cmd_base_addr | (page << 8);
  133. #ifdef HARDCODE_PDT
  134. rmiguest->query_base_addr = 0x0000;
  135. rmiguest->control_base_addr = 0x0000;
  136. rmiguest->data_base_addr = 0x6000;
  137. rmiguest->command_base_addr = 0x0000;
  138. rmi_fd.intr_src_count = 1;
  139. #endif
  140. rmiguest->intr_reg_num = (intr_count + 7) / 8;
  141. if (rmiguest->intr_reg_num != 0)
  142. rmiguest->intr_reg_num -= 1;
  143. rmiguest->intr_mask = 0;
  144. intr_offset = intr_count % 8;
  145. for (ii = intr_offset;
  146. ii < ((rmi_fd.intr_src_count & MASK_3BIT) +
  147. intr_offset);
  148. ii++) {
  149. rmiguest->intr_mask |= 1 << ii;
  150. }
  151. // pr_info("GT interrupt mask = 0x%02x\n", rmiguest->intr_mask);
  152. rmi4_data->intr_mask[0] |= rmiguest->intr_mask;
  153. addr = rmi4_data->f01_ctrl_base_addr + 1;
  154. retval = rmiguest->fn_ptr->write(rmi4_data,
  155. addr,
  156. &(rmi4_data->intr_mask[0]),
  157. sizeof(rmi4_data->intr_mask[0]));
  158. if (retval < 0)
  159. return retval;
  160. return 0;
  161. }
  162. static void rmi_guest_attn(struct synaptics_rmi4_data *rmi4_data,
  163. unsigned char intr_mask)
  164. {
  165. if (!rmiguest)
  166. return;
  167. if (rmiguest->intr_mask & intr_mask)
  168. GMvBraneIsr();
  169. return;
  170. }
  171. static int rmi_guest_init(struct synaptics_rmi4_data *rmi4_data)
  172. {
  173. int retval;
  174. unsigned char attr_count;
  175. int attr_count_num;
  176. rmiguest = kzalloc(sizeof(*rmiguest), GFP_KERNEL);
  177. if (!rmiguest) {
  178. dev_err(&rmi4_data->i2c_client->dev,
  179. "%s: Failed to alloc mem for rmiguest\n",
  180. __func__);
  181. retval = -ENOMEM;
  182. goto err_rmi_guest;
  183. }
  184. rmiguest->fn_ptr = kzalloc(sizeof(*(rmiguest->fn_ptr)), GFP_KERNEL);
  185. if (!rmiguest->fn_ptr) {
  186. dev_err(&rmi4_data->i2c_client->dev,
  187. "%s: Failed to alloc mem for fn_ptr\n",
  188. __func__);
  189. retval = -ENOMEM;
  190. goto err_fn_ptr;
  191. }
  192. rmiguest->fn_ptr->read = rmi4_data->i2c_read;
  193. rmiguest->fn_ptr->write = rmi4_data->i2c_write;
  194. rmiguest->fn_ptr->enable = rmi4_data->irq_enable;
  195. rmiguest->rmi4_data = rmi4_data;
  196. retval = rmi_guest_scan_pdt();
  197. if (retval < 0) {
  198. retval = 0;
  199. goto err_scan_pdt;
  200. }
  201. rmiguest->sysfs_dir = kobject_create_and_add("guest",
  202. &rmi4_data->input_dev->dev.kobj);
  203. if (!rmiguest->sysfs_dir) {
  204. dev_err(&rmi4_data->i2c_client->dev,
  205. "%s: Failed to create sysfs directory\n",
  206. __func__);
  207. retval = -ENODEV;
  208. goto err_sysfs_dir;
  209. }
  210. for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++) {
  211. retval = sysfs_create_file(rmiguest->sysfs_dir,
  212. &attrs[attr_count].attr);
  213. if (retval < 0) {
  214. dev_err(&rmi4_data->input_dev->dev,
  215. "%s: Failed to create sysfs attributes\n",
  216. __func__);
  217. retval = -ENODEV;
  218. goto err_sysfs_attrs;
  219. }
  220. }
  221. return 0;
  222. err_sysfs_attrs:
  223. attr_count_num = (int)attr_count;
  224. for (attr_count_num--; attr_count_num >= 0; attr_count_num--)
  225. sysfs_remove_file(rmiguest->sysfs_dir, &attrs[attr_count_num].attr);
  226. kobject_put(rmiguest->sysfs_dir);
  227. err_sysfs_dir:
  228. err_scan_pdt:
  229. kfree(rmiguest->fn_ptr);
  230. err_fn_ptr:
  231. kfree(rmiguest);
  232. rmiguest = NULL;
  233. err_rmi_guest:
  234. return retval;
  235. }
  236. static void rmi_guest_remove(struct synaptics_rmi4_data *rmi4_data)
  237. {
  238. unsigned char attr_count;
  239. if (!rmiguest)
  240. goto exit;
  241. for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++)
  242. sysfs_remove_file(rmiguest->sysfs_dir, &attrs[attr_count].attr);
  243. kobject_put(rmiguest->sysfs_dir);
  244. kfree(rmiguest->fn_ptr);
  245. kfree(rmiguest);
  246. rmiguest = NULL;
  247. exit:
  248. return;
  249. }
  250. int rmi_guest_module_register(void)
  251. {
  252. int retval;
  253. retval = synaptics_rmi4_new_function(RMI_GUEST,
  254. rmi_guest_init,
  255. rmi_guest_remove,
  256. rmi_guest_attn);
  257. return retval;
  258. }
  259. void GMvGtReadI2cRegister( uint16 u16Addr, void *pvData, sint32 s32Size )
  260. {
  261. if( rmiguest )
  262. {
  263. if( rmiguest->fn_ptr && rmiguest->rmi4_data )
  264. {
  265. if( rmiguest->fn_ptr->read )
  266. rmiguest->fn_ptr->read( rmiguest->rmi4_data, u16Addr, pvData, s32Size );
  267. }
  268. }
  269. }
  270. void GMvGtWriteI2cRegister( uint16 u16Addr, void *pvData, sint32 s32Size )
  271. {
  272. if( rmiguest )
  273. {
  274. if( rmiguest->fn_ptr && rmiguest->rmi4_data )
  275. {
  276. if( rmiguest->fn_ptr->write )
  277. rmiguest->fn_ptr->write( rmiguest->rmi4_data, u16Addr, pvData, s32Size );
  278. }
  279. }
  280. }