rmi_f34.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558
  1. /**
  2. *
  3. * Synaptics Register Mapped Interface (RMI4) Function $34 support for sensor
  4. * firmware reflashing.
  5. *
  6. * Copyright (c) 2007 - 2011, Synaptics Incorporated
  7. *
  8. */
  9. /*
  10. * This file is licensed under the GPL2 license.
  11. *
  12. *#############################################################################
  13. * GPL
  14. *
  15. * This program is free software; you can redistribute it and/or modify it
  16. * under the terms of the GNU General Public License version 2 as published
  17. * by the Free Software Foundation.
  18. *
  19. * This program is distributed in the hope that it will be useful, but
  20. * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  21. * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  22. * for more details.
  23. *
  24. *#############################################################################
  25. */
  26. #include <linux/kernel.h>
  27. #include <linux/device.h>
  28. #include <linux/delay.h>
  29. #include <linux/slab.h>
  30. #include <linux/kthread.h>
  31. #include <linux/freezer.h>
  32. #include <linux/input.h>
  33. #include <linux/sysfs.h>
  34. #include <linux/math64.h>
  35. #include <linux/module.h>
  36. #include "rmi_drvr.h"
  37. #include "rmi_bus.h"
  38. #include "rmi_sensor.h"
  39. #include "rmi_function.h"
  40. #include "rmi_f34.h"
  41. /* data specific to fn $34 that needs to be kept around */
  42. struct rmi_fn_34_data {
  43. unsigned char status;
  44. unsigned char cmd;
  45. unsigned short bootloaderid;
  46. unsigned short blocksize;
  47. };
  48. static ssize_t rmi_fn_34_status_show(struct device *dev,
  49. struct device_attribute *attr, char *buf);
  50. static ssize_t rmi_fn_34_status_store(struct device *dev,
  51. struct device_attribute *attr,
  52. const char *buf, size_t count);
  53. static ssize_t rmi_fn_34_cmd_show(struct device *dev,
  54. struct device_attribute *attr, char *buf);
  55. static ssize_t rmi_fn_34_cmd_store(struct device *dev,
  56. struct device_attribute *attr,
  57. const char *buf, size_t count);
  58. static ssize_t rmi_fn_34_data_read(struct file *,
  59. struct kobject *kobj,
  60. struct bin_attribute *attributes,
  61. char *buf, loff_t pos, size_t count);
  62. static ssize_t rmi_fn_34_data_write(struct file *,
  63. struct kobject *kobj,
  64. struct bin_attribute *attributes,
  65. char *buf, loff_t pos, size_t count);
  66. static ssize_t rmi_fn_34_bootloaderid_show(struct device *dev,
  67. struct device_attribute *attr, char *buf);
  68. static ssize_t rmi_fn_34_bootloaderid_store(struct device *dev,
  69. struct device_attribute *attr,
  70. const char *buf, size_t count);
  71. static ssize_t rmi_fn_34_blocksize_show(struct device *dev,
  72. struct device_attribute *attr, char *buf);
  73. static ssize_t rmi_fn_34_blocksize_store(struct device *dev,
  74. struct device_attribute *attr,
  75. const char *buf, size_t count);
  76. /* define the device attributes using DEVICE_ATTR macros */
  77. DEVICE_ATTR(status, 0444, rmi_fn_34_status_show, rmi_fn_34_status_store); /* RO attr */
  78. DEVICE_ATTR(cmd, 0664, rmi_fn_34_cmd_show, rmi_fn_34_cmd_store); /* RW attr */
  79. DEVICE_ATTR(bootloaderid, 0644, rmi_fn_34_bootloaderid_show, rmi_fn_34_bootloaderid_store); /* RW attr */
  80. DEVICE_ATTR(blocksize, 0444, rmi_fn_34_blocksize_show, rmi_fn_34_blocksize_store); /* RO attr */
  81. struct bin_attribute dev_attr_data = {
  82. .attr = {
  83. .name = "data",
  84. .mode = 0644
  85. },
  86. .size = 0,
  87. .read = rmi_fn_34_data_read,
  88. .write = rmi_fn_34_data_write,
  89. };
  90. /* Helper fn to convert from processor specific data to our firmware specific endianness.
  91. * TODO: Should we use ntohs or something like that?
  92. */
  93. void copyEndianAgnostic(unsigned char *dest, unsigned short src)
  94. {
  95. dest[0] = src%0x100;
  96. dest[1] = src/0x100;
  97. }
  98. /*.
  99. * The interrupt handler for Fn $34.
  100. */
  101. void FN_34_inthandler(struct rmi_function_info *rmifninfo,
  102. unsigned int assertedIRQs)
  103. {
  104. unsigned int status;
  105. struct rmi_fn_34_data *fn34data = (struct rmi_fn_34_data *)rmifninfo->fndata;
  106. /* Read the Fn $34 status register to see whether the previous command executed OK */
  107. /* inform user space - through a sysfs param. */
  108. if (rmi_read_multiple(rmifninfo->sensor, rmifninfo->funcDescriptor.dataBaseAddr+3,
  109. (unsigned char *)&status, 1)) {
  110. printk(KERN_ERR "%s : Could not read status from 0x%x\n",
  111. __func__, rmifninfo->funcDescriptor.dataBaseAddr+3);
  112. status = 0xff; /* failure */
  113. }
  114. /* set a sysfs value that the user mode can read - only upper 4 bits are the status */
  115. fn34data->status = status & 0xf0; /* successful is $80, anything else is failure */
  116. }
  117. EXPORT_SYMBOL(FN_34_inthandler);
  118. void FN_34_attention(struct rmi_function_info *rmifninfo)
  119. {
  120. }
  121. EXPORT_SYMBOL(FN_34_attention);
  122. int FN_34_config(struct rmi_function_info *rmifninfo)
  123. {
  124. pr_debug("%s: RMI4 function $34 config\n", __func__);
  125. return 0;
  126. }
  127. EXPORT_SYMBOL(FN_34_config);
  128. int FN_34_init(struct rmi_function_device *function_device)
  129. {
  130. int retval = 0;
  131. unsigned char uData[2];
  132. struct rmi_function_info *rmifninfo = function_device->rfi;
  133. struct rmi_fn_34_data *fn34data;
  134. pr_debug("%s: RMI4 function $34 init\n", __func__);
  135. /* Here we will need to set up sysfs files for Bootloader ID and Block size */
  136. fn34data = kzalloc(sizeof(struct rmi_fn_34_data), GFP_KERNEL);
  137. if (!fn34data) {
  138. printk(KERN_ERR "%s: Error allocating memeory for rmi_fn_34_data.\n", __func__);
  139. return -ENOMEM;
  140. }
  141. rmifninfo->fndata = (void *)fn34data;
  142. /* set up sysfs file for Bootloader ID. */
  143. if (sysfs_create_file(&function_device->dev.kobj, &dev_attr_bootloaderid.attr) < 0) {
  144. printk(KERN_ERR "%s: Failed to create sysfs file for fn 34 bootloaderid.\n", __func__);
  145. return -ENODEV;
  146. }
  147. /* set up sysfs file for Block Size. */
  148. if (sysfs_create_file(&function_device->dev.kobj, &dev_attr_blocksize.attr) < 0) {
  149. printk(KERN_ERR "%s: Failed to create sysfs file for fn 34 blocksize.\n", __func__);
  150. return -ENODEV;
  151. }
  152. /* get the Bootloader ID and Block Size and store in the sysfs attributes. */
  153. retval = rmi_read_multiple(rmifninfo->sensor, rmifninfo->funcDescriptor.queryBaseAddr,
  154. uData, 2);
  155. if (retval) {
  156. printk(KERN_ERR "%s : Could not read bootloaderid from 0x%x\n",
  157. __func__, function_device->function->functionQueryBaseAddr);
  158. return retval;
  159. }
  160. /* need to convert from our firmware storage to processore specific data */
  161. fn34data->bootloaderid = (unsigned int)uData[0] + (unsigned int)uData[1]*0x100;
  162. retval = rmi_read_multiple(rmifninfo->sensor, rmifninfo->funcDescriptor.queryBaseAddr+3,
  163. uData, 2);
  164. if (retval) {
  165. printk(KERN_ERR "%s : Could not read block size from 0x%x\n",
  166. __func__, rmifninfo->funcDescriptor.queryBaseAddr+3);
  167. return retval;
  168. }
  169. /* need to convert from our firmware storage to processor specific data */
  170. fn34data->blocksize = (unsigned int)uData[0] + (unsigned int)uData[1]*0x100;
  171. /* set up sysfs file for status. */
  172. if (sysfs_create_file(&function_device->dev.kobj, &dev_attr_status.attr) < 0) {
  173. printk(KERN_ERR "%s: Failed to create sysfs file for fn 34 status.\n", __func__);
  174. return -ENODEV;
  175. }
  176. /* Also, sysfs will need to have a file set up to distinguish between commands - like
  177. Config write/read, Image write/verify.*/
  178. /* set up sysfs file for command code. */
  179. if (sysfs_create_file(&function_device->dev.kobj, &dev_attr_cmd.attr) < 0) {
  180. printk(KERN_ERR "%s: Failed to create sysfs file for fn 34 cmd.\n", __func__);
  181. return -ENODEV;
  182. }
  183. /* We will also need a sysfs file for the image/config block to write or read.*/
  184. /* set up sysfs bin file for binary data block. Since the image is already in our format
  185. there is no need to convert the data for endianess. */
  186. if (sysfs_create_bin_file(&function_device->dev.kobj, &dev_attr_data) < 0) {
  187. printk(KERN_ERR "%s: Failed to create sysfs file for fn 34 data.\n", __func__);
  188. return -ENODEV;
  189. }
  190. return retval;
  191. }
  192. EXPORT_SYMBOL(FN_34_init);
  193. int FN_34_detect(struct rmi_function_info *rmifninfo,
  194. struct rmi_function_descriptor *fndescr, unsigned int interruptCount)
  195. {
  196. int i;
  197. int InterruptOffset;
  198. int retval = 0;
  199. pr_debug("%s: RMI4 function $34 detect\n", __func__);
  200. if (rmifninfo->sensor == NULL) {
  201. printk(KERN_ERR "%s: NULL sensor passed in!", __func__);
  202. return -EINVAL;
  203. }
  204. /* Store addresses - used elsewhere to read data,
  205. * control, query, etc. */
  206. rmifninfo->funcDescriptor.queryBaseAddr = fndescr->queryBaseAddr;
  207. rmifninfo->funcDescriptor.commandBaseAddr = fndescr->commandBaseAddr;
  208. rmifninfo->funcDescriptor.controlBaseAddr = fndescr->controlBaseAddr;
  209. rmifninfo->funcDescriptor.dataBaseAddr = fndescr->dataBaseAddr;
  210. rmifninfo->funcDescriptor.interruptSrcCnt = fndescr->interruptSrcCnt;
  211. rmifninfo->funcDescriptor.functionNum = fndescr->functionNum;
  212. rmifninfo->numSources = fndescr->interruptSrcCnt;
  213. /* Need to get interrupt info to be used later when handling
  214. interrupts. */
  215. rmifninfo->interruptRegister = interruptCount/8;
  216. /* loop through interrupts for each source and or in a bit
  217. to the interrupt mask for each. */
  218. InterruptOffset = interruptCount % 8;
  219. for (i = InterruptOffset;
  220. i < ((fndescr->interruptSrcCnt & 0x7) + InterruptOffset);
  221. i++) {
  222. rmifninfo->interruptMask |= 1 << i;
  223. }
  224. return retval;
  225. }
  226. EXPORT_SYMBOL(FN_34_detect);
  227. static ssize_t rmi_fn_34_bootloaderid_show(struct device *dev,
  228. struct device_attribute *attr, char *buf)
  229. {
  230. struct rmi_function_device *fn = dev_get_drvdata(dev);
  231. struct rmi_fn_34_data *fn34data = (struct rmi_fn_34_data *)fn->rfi->fndata;
  232. return sprintf(buf, "%u\n", fn34data->bootloaderid);
  233. }
  234. static ssize_t rmi_fn_34_bootloaderid_store(struct device *dev,
  235. struct device_attribute *attr,
  236. const char *buf, size_t count)
  237. {
  238. int error;
  239. unsigned long val;
  240. unsigned char uData[2];
  241. struct rmi_function_device *fn = dev_get_drvdata(dev);
  242. struct rmi_fn_34_data *fn34data = (struct rmi_fn_34_data *)fn->rfi->fndata;
  243. /* need to convert the string data to an actual value */
  244. error = strict_strtoul(buf, 10, &val);
  245. if (error)
  246. return error;
  247. fn34data->bootloaderid = val;
  248. /* Write the Bootloader ID key data back to the first two Block Data registers
  249. (F34_Flash_Data2.0 and F34_Flash_Data2.1).*/
  250. copyEndianAgnostic(uData, (unsigned short)val);
  251. error = rmi_write_multiple(fn->sensor, fn->function->functionDataBaseAddr,
  252. uData, 2);
  253. if (error) {
  254. printk(KERN_ERR "%s : Could not write bootloader id to 0x%x\n",
  255. __func__, fn->function->functionDataBaseAddr);
  256. return error;
  257. }
  258. return count;
  259. }
  260. static ssize_t rmi_fn_34_blocksize_show(struct device *dev,
  261. struct device_attribute *attr, char *buf)
  262. {
  263. struct rmi_function_device *fn = dev_get_drvdata(dev);
  264. struct rmi_fn_34_data *fn34data = (struct rmi_fn_34_data *)fn->rfi->fndata;
  265. return sprintf(buf, "%u\n", fn34data->blocksize);
  266. }
  267. static ssize_t rmi_fn_34_blocksize_store(struct device *dev,
  268. struct device_attribute *attr,
  269. const char *buf, size_t count)
  270. {
  271. /* Block Size is RO so we shouldn't do anything if the
  272. user space writes to the sysfs file. */
  273. return -EPERM;
  274. }
  275. static ssize_t rmi_fn_34_status_show(struct device *dev,
  276. struct device_attribute *attr, char *buf)
  277. {
  278. struct rmi_function_device *fn = dev_get_drvdata(dev);
  279. struct rmi_fn_34_data *fn34data = (struct rmi_fn_34_data *)fn->rfi->fndata;
  280. return sprintf(buf, "%u\n", fn34data->status);
  281. }
  282. static ssize_t rmi_fn_34_status_store(struct device *dev,
  283. struct device_attribute *attr,
  284. const char *buf, size_t count)
  285. {
  286. /* Status is RO so we shouldn't do anything if the user
  287. app writes to the sysfs file. */
  288. return -EPERM;
  289. }
  290. static ssize_t rmi_fn_34_cmd_show(struct device *dev,
  291. struct device_attribute *attr, char *buf)
  292. {
  293. struct rmi_function_device *fn = dev_get_drvdata(dev);
  294. struct rmi_fn_34_data *fn34data = (struct rmi_fn_34_data *)fn->rfi->fndata;
  295. return sprintf(buf, "%u\n", fn34data->cmd);
  296. }
  297. static ssize_t rmi_fn_34_cmd_store(struct device *dev,
  298. struct device_attribute *attr,
  299. const char *buf, size_t count)
  300. {
  301. struct rmi_function_device *fn = dev_get_drvdata(dev);
  302. struct rmi_fn_34_data *fn34data = (struct rmi_fn_34_data *)fn->rfi->fndata;
  303. unsigned long val;
  304. unsigned char cmd;
  305. int error;
  306. /* need to convert the string data to an actual value */
  307. error = strict_strtoul(buf, 10, &val);
  308. if (error)
  309. return error;
  310. fn34data->cmd = val;
  311. /* determine the proper command to issue.
  312. */
  313. switch (val) {
  314. case ENABLE_FLASH_PROG:
  315. /* Issue a Flash Program Enable ($0F) command to the Flash Command
  316. (F34_Flash_Data3, bits 3:0) field.*/
  317. cmd = 0x0F;
  318. error = rmi_write_multiple(fn->sensor, fn->function->functionDataBaseAddr+3,
  319. (unsigned char *)&cmd, 1);
  320. if (error) {
  321. printk(KERN_ERR "%s : Could not write Flash Program Enable cmd to 0x%x\n",
  322. __func__, fn->function->functionDataBaseAddr+3);
  323. return error;
  324. }
  325. break;
  326. case ERASE_ALL:
  327. /* Issue a Erase All ($03) command to the Flash Command
  328. (F34_Flash_Data3, bits 3:0) field.*/
  329. cmd = 0x03;
  330. error = rmi_write_multiple(fn->sensor, fn->function->functionDataBaseAddr+3,
  331. (unsigned char *)&cmd, 1);
  332. if (error) {
  333. printk(KERN_ERR "%s : Could not write Erase All cmd to 0x%x\n",
  334. __func__, fn->function->functionDataBaseAddr+3);
  335. return error;
  336. }
  337. break;
  338. case ERASE_CONFIG:
  339. /* Issue a Erase Configuration ($07) command to the Flash Command
  340. (F34_Flash_Data3, bits 3:0) field.*/
  341. cmd = 0x07;
  342. error = rmi_write_multiple(fn->sensor, fn->function->functionDataBaseAddr+3,
  343. (unsigned char *)&cmd, 1);
  344. if (error) {
  345. printk(KERN_ERR "%s : Could not write Erase Configuration cmd to 0x%x\n",
  346. __func__, fn->function->functionDataBaseAddr+3);
  347. return error;
  348. }
  349. break;
  350. case WRITE_FW_BLOCK:
  351. /* Issue a Write Firmware Block ($02) command to the Flash Command
  352. (F34_Flash_Data3, bits 3:0) field.*/
  353. cmd = 0x02;
  354. error = rmi_write_multiple(fn->sensor, fn->function->functionDataBaseAddr+3,
  355. (unsigned char *)&cmd, 1);
  356. if (error) {
  357. printk(KERN_ERR "%s : Could not write Write Firmware Block cmd to 0x%x\n",
  358. __func__, fn->function->functionDataBaseAddr+3);
  359. return error;
  360. }
  361. break;
  362. case WRITE_CONFIG_BLOCK:
  363. /* Issue a Write Config Block ($06) command to the Flash Command
  364. (F34_Flash_Data3, bits 3:0) field.*/
  365. cmd = 0x06;
  366. error = rmi_write_multiple(fn->sensor, fn->function->functionDataBaseAddr+3,
  367. (unsigned char *)&cmd, 1);
  368. if (error) {
  369. printk(KERN_ERR "%s : Could not write Write Config Block cmd to 0x%x\n",
  370. __func__, fn->function->functionDataBaseAddr+3);
  371. return error;
  372. }
  373. break;
  374. case READ_CONFIG_BLOCK:
  375. /* Issue a Read Config Block ($05) command to the Flash Command
  376. (F34_Flash_Data3, bits 3:0) field.*/
  377. cmd = 0x05;
  378. error = rmi_write_multiple(fn->sensor, fn->function->functionDataBaseAddr+3,
  379. (unsigned char *)&cmd, 1);
  380. if (error) {
  381. printk(KERN_ERR "%s : Could not write Read Config Block cmd to 0x%x\n",
  382. __func__, fn->function->functionDataBaseAddr+3);
  383. return error;
  384. }
  385. break;
  386. case DISABLE_FLASH_PROG:
  387. /* Issue a reset command ($01) - this will reboot the sensor and ATTN will now go to
  388. the Fn $01 instead of the Fn $34 since the sensor will no longer be in Flash mode. */
  389. cmd = 0x01;
  390. /*if ((error = rmi_write_multiple(fn->sensor, fn->sensor->sensorCommandBaseAddr,
  391. (unsigned char *)&cmd, 1))) {
  392. printk(KERN_ERR "%s : Could not write Reset cmd to 0x%x\n",
  393. __func__, fn->sensor->sensorCommandBaseAddr);
  394. return error;
  395. }*/
  396. break;
  397. default:
  398. pr_debug("%s: RMI4 function $34 - unknown command.\n", __func__);
  399. break;
  400. }
  401. return count;
  402. }
  403. static ssize_t rmi_fn_34_data_read(struct file * filp,
  404. struct kobject *kobj,
  405. struct bin_attribute *attributes,
  406. char *buf, loff_t pos, size_t count)
  407. {
  408. struct device *dev = container_of(kobj, struct device, kobj);
  409. struct rmi_function_device *fn = dev_get_drvdata(dev);
  410. int error;
  411. /* TODO: add check for count to verify it's the correct blocksize */
  412. /* read the data from flash into buf. */
  413. /* the app layer will be blocked at reading from the sysfs file. */
  414. /* when we return the count (or error if we fail) the app will resume. */
  415. error = rmi_read_multiple(fn->sensor, fn->function->functionDataBaseAddr+pos,
  416. (unsigned char *)buf, count);
  417. if (error) {
  418. printk(KERN_ERR "%s : Could not read data from 0x%llx\n",
  419. __func__, fn->function->functionDataBaseAddr+pos);
  420. return error;
  421. }
  422. return count;
  423. }
  424. static ssize_t rmi_fn_34_data_write(struct file *filp,
  425. struct kobject *kobj,
  426. struct bin_attribute *attributes,
  427. char *buf, loff_t pos, size_t count)
  428. {
  429. struct device *dev = container_of(kobj, struct device, kobj);
  430. struct rmi_function_device *fn = dev_get_drvdata(dev);
  431. struct rmi_fn_34_data *fn34data = (struct rmi_fn_34_data *)fn->rfi->fndata;
  432. unsigned int blocknum;
  433. int error;
  434. /* write the data from buf to flash. */
  435. /* the app layer will be blocked at writing to the sysfs file. */
  436. /* when we return the count (or error if we fail) the app will resume. */
  437. /* TODO: Add check on count - if non-zero veriy it's the correct blocksize */
  438. /* Verify that the byte offset is always aligned on a block boundary and if not
  439. return an error. We can't just use the mod operator % and do a (pos % fn34data->blocksize) because of a gcc
  440. bug that results in undefined symbols. So we have to compute it the hard
  441. way. Grumble. */
  442. unsigned int remainder;
  443. div_u64_rem(pos, fn34data->blocksize, &remainder);
  444. if (remainder) {
  445. printk(KERN_ERR "%s : Invalid byte offset of %llx leads to invalid block number.\n",
  446. __func__, pos);
  447. return -EINVAL;
  448. }
  449. /* Compute the block number using the byte offset (pos) and the block size.
  450. once again, we can't just do a divide due to a gcc bug. */
  451. blocknum = div_u64(pos, fn34data->blocksize);
  452. /* Write the block number first */
  453. error = rmi_write_multiple(fn->sensor, fn->function->functionDataBaseAddr,
  454. (unsigned char *)&blocknum, 2);
  455. if (error) {
  456. printk(KERN_ERR "%s : Could not write block number to 0x%x\n",
  457. __func__, fn->function->functionDataBaseAddr);
  458. return error;
  459. }
  460. /* Write the data block - only if the count is non-zero */
  461. if (count) {
  462. error = rmi_write_multiple(fn->sensor, fn->function->functionDataBaseAddr+2,
  463. (unsigned char *)buf, count);
  464. if (error) {
  465. printk(KERN_ERR "%s : Could not write block data to 0x%x\n",
  466. __func__, fn->function->functionDataBaseAddr+2);
  467. return error;
  468. }
  469. }
  470. return count;
  471. }