focaltech_ctl.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404
  1. /*
  2. *
  3. * FocalTech TouchScreen driver.
  4. *
  5. * Copyright (c) 2010-2015, Focaltech Ltd. All rights reserved.
  6. *
  7. * This software is licensed under the terms of the GNU General Public
  8. * License version 2, as published by the Free Software Foundation, and
  9. * may be copied, distributed, and modified under those terms.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. */
  17. /************************************************************************
  18. *
  19. * File Name: focaltech_ctl.c
  20. *
  21. * Author: Xu YongFeng
  22. *
  23. * Created: 2015-01-01
  24. *
  25. * Modify by mshl on 2015-03-20
  26. *
  27. * Abstract: Function for old APK tool
  28. *
  29. ************************************************************************/
  30. /*******************************************************************************
  31. * Included header files
  32. *******************************************************************************/
  33. #include "focaltech_core.h"
  34. extern int apk_debug_flag;
  35. /*******************************************************************************
  36. * Private constant and macro definitions using #define
  37. *******************************************************************************/
  38. /* Ô¤ÉèµÄft_rw_iic_drvµÄÖ÷É豸ºÅ*/
  39. #define FTS_RW_IIC_DRV "ft_rw_iic_drv"
  40. #define FTS_RW_IIC_DRV_MAJOR 210
  41. #define FTS_I2C_RDWR_MAX_QUEUE 36
  42. #define FTS_I2C_SLAVEADDR 11
  43. #define FTS_I2C_RW 12
  44. /*******************************************************************************
  45. * Private enumerations, structures and unions using typedef
  46. *******************************************************************************/
  47. typedef struct fts_rw_i2c
  48. {
  49. u8 *buf;
  50. u8 flag; // 0-write 1-read
  51. __u16 length; // the length of data
  52. }*pfts_rw_i2c;
  53. typedef struct fts_rw_i2c_queue
  54. {
  55. struct fts_rw_i2c __user *i2c_queue;
  56. int queuenum;
  57. }*pfts_rw_i2c_queue;
  58. struct fts_rw_i2c_dev
  59. {
  60. struct cdev cdev;
  61. struct mutex fts_rw_i2c_mutex;
  62. struct i2c_client *client;
  63. };
  64. /*******************************************************************************
  65. * Static variables
  66. *******************************************************************************/
  67. static int fts_rw_iic_drv_major = FTS_RW_IIC_DRV_MAJOR;
  68. static struct class *fts_class;
  69. /*******************************************************************************
  70. * Global variable or extern global variabls/functions
  71. *******************************************************************************/
  72. struct fts_rw_i2c_dev *fts_rw_i2c_dev_tt;
  73. /*******************************************************************************
  74. * Static function prototypes
  75. *******************************************************************************/
  76. /************************************************************************
  77. * Name: fts_rw_iic_drv_myread
  78. * Brief: i2c read
  79. * Input: i2c info, data, length
  80. * Output: get data in buf
  81. * Return: fail <0
  82. ***********************************************************************/
  83. static int fts_rw_iic_drv_myread(struct i2c_client *client, u8 *buf, int length)
  84. {
  85. int ret = 0;
  86. ret = fts_i2c_read(client, NULL, 0, buf, length);
  87. if(ret<0)
  88. {
  89. dev_err(&client->dev, "%s:IIC Read failed\n",__func__);
  90. }
  91. return ret;
  92. }
  93. /************************************************************************
  94. * Name: fts_rw_iic_drv_mywrite
  95. * Brief: i2c write
  96. * Input: i2c info, data, length
  97. * Output: no
  98. * Return: fail <0
  99. ***********************************************************************/
  100. static int fts_rw_iic_drv_mywrite(struct i2c_client *client, u8 *buf, int length)
  101. {
  102. int ret = 0;
  103. ret = fts_i2c_write(client, buf, length);
  104. if(ret<0)
  105. {
  106. dev_err(&client->dev, "%s:IIC Write failed\n",__func__);
  107. }
  108. return ret;
  109. }
  110. /************************************************************************
  111. * Name: fts_rw_iic_drv_RDWR
  112. * Brief: get package to i2c read/write
  113. * Input: i2c info, package
  114. * Output: put data in i2c_rw_msg.buf
  115. * Return: fail <0
  116. ***********************************************************************/
  117. static int fts_rw_iic_drv_RDWR(struct i2c_client *client, unsigned long arg)
  118. {
  119. struct fts_rw_i2c_queue i2c_rw_queue;
  120. struct fts_rw_i2c * i2c_rw_msg;
  121. u8 __user **data_ptrs;
  122. int ret = 0;
  123. int i;
  124. if (!access_ok(VERIFY_READ, (struct fts_rw_i2c_queue *)arg, sizeof(struct fts_rw_i2c_queue)))
  125. return -EFAULT;
  126. if (copy_from_user(&i2c_rw_queue,
  127. (struct fts_rw_i2c_queue *)arg,
  128. sizeof(struct fts_rw_i2c_queue)))
  129. return -EFAULT;
  130. if (i2c_rw_queue.queuenum > FTS_I2C_RDWR_MAX_QUEUE)
  131. return -EINVAL;
  132. i2c_rw_msg = (struct fts_rw_i2c*)
  133. kmalloc(i2c_rw_queue.queuenum *sizeof(struct fts_rw_i2c),
  134. GFP_KERNEL);
  135. if (!i2c_rw_msg)
  136. return -ENOMEM;
  137. if (copy_from_user(i2c_rw_msg, i2c_rw_queue.i2c_queue,
  138. i2c_rw_queue.queuenum*sizeof(struct fts_rw_i2c)))
  139. {
  140. kfree(i2c_rw_msg);
  141. return -EFAULT;
  142. }
  143. data_ptrs = kmalloc(i2c_rw_queue.queuenum * sizeof(u8 __user *), GFP_KERNEL);
  144. if (data_ptrs == NULL)
  145. {
  146. kfree(i2c_rw_msg);
  147. return -ENOMEM;
  148. }
  149. ret = 0;
  150. for (i=0; i< i2c_rw_queue.queuenum; i++)
  151. {
  152. if ((i2c_rw_msg[i].length > 8192)||
  153. (i2c_rw_msg[i].flag & I2C_M_RECV_LEN))
  154. {
  155. ret = -EINVAL;
  156. break;
  157. }
  158. data_ptrs[i] = (u8 __user *)i2c_rw_msg[i].buf;
  159. i2c_rw_msg[i].buf = kmalloc(i2c_rw_msg[i].length, GFP_KERNEL);
  160. if (i2c_rw_msg[i].buf == NULL)
  161. {
  162. ret = -ENOMEM;
  163. break;
  164. }
  165. if (copy_from_user(i2c_rw_msg[i].buf, data_ptrs[i], i2c_rw_msg[i].length))
  166. {
  167. ++i;
  168. ret = -EFAULT;
  169. break;
  170. }
  171. }
  172. if (ret < 0)
  173. {
  174. int j;
  175. for (j=0; j<i; ++j)
  176. kfree(i2c_rw_msg[j].buf);
  177. kfree(data_ptrs);
  178. kfree(i2c_rw_msg);
  179. return ret;
  180. }
  181. for (i=0; i< i2c_rw_queue.queuenum; i++)
  182. {
  183. if (i2c_rw_msg[i].flag)
  184. {
  185. ret = fts_rw_iic_drv_myread(client,
  186. i2c_rw_msg[i].buf, i2c_rw_msg[i].length);
  187. if (ret>=0)
  188. ret = copy_to_user(data_ptrs[i], i2c_rw_msg[i].buf, i2c_rw_msg[i].length);
  189. }
  190. else
  191. {
  192. ret = fts_rw_iic_drv_mywrite(client,
  193. i2c_rw_msg[i].buf, i2c_rw_msg[i].length);
  194. }
  195. }
  196. return ret;
  197. }
  198. /************************************************************************
  199. * Name: fts_rw_iic_drv_open
  200. * Brief: char device open function interface
  201. * Input: node, file point
  202. * Output: no
  203. * Return: 0
  204. ***********************************************************************/
  205. static int fts_rw_iic_drv_open(struct inode *inode, struct file *filp)
  206. {
  207. filp->private_data = fts_rw_i2c_dev_tt;
  208. return 0;
  209. }
  210. /************************************************************************
  211. * Name: fts_rw_iic_drv_release
  212. * Brief: char device close function interface
  213. * Input: node, file point
  214. * Output: no
  215. * Return: 0
  216. ***********************************************************************/
  217. static int fts_rw_iic_drv_release(struct inode *inode, struct file *filp)
  218. {
  219. return 0;
  220. }
  221. /************************************************************************
  222. * Name: fts_rw_iic_drv_ioctl
  223. * Brief: char device I/O control function interface
  224. * Input: file point, command, package
  225. * Output: no
  226. * Return: fail <0
  227. ***********************************************************************/
  228. static long fts_rw_iic_drv_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
  229. {
  230. int ret = 0;
  231. struct fts_rw_i2c_dev *ftsdev = filp->private_data;
  232. ftsdev = filp->private_data;
  233. #if FT_ESD_PROTECT
  234. esd_switch(0);apk_debug_flag = 1;
  235. #endif
  236. mutex_lock(&fts_rw_i2c_dev_tt->fts_rw_i2c_mutex);
  237. switch (cmd)
  238. {
  239. case FTS_I2C_RW:
  240. ret = fts_rw_iic_drv_RDWR(ftsdev->client, arg);
  241. break;
  242. //#if INTEL_EN
  243. //case FTS_RESET_TP:
  244. // fts_reset_tp((int)arg);
  245. // break;
  246. //#endif
  247. default:
  248. ret = -ENOTTY;
  249. break;
  250. }
  251. mutex_unlock(&fts_rw_i2c_dev_tt->fts_rw_i2c_mutex);
  252. #if FT_ESD_PROTECT
  253. esd_switch(1);apk_debug_flag = 0;
  254. #endif
  255. return ret;
  256. }
  257. /*
  258. * char device file operation which will be put to register the char device
  259. */
  260. static const struct file_operations fts_rw_iic_drv_fops = {
  261. .owner = THIS_MODULE,
  262. .open = fts_rw_iic_drv_open,
  263. .release = fts_rw_iic_drv_release,
  264. .unlocked_ioctl = fts_rw_iic_drv_ioctl,
  265. };
  266. /************************************************************************
  267. * Name: fts_rw_iic_drv_setup_cdev
  268. * Brief: setup char device
  269. * Input: device point, index number
  270. * Output: no
  271. * Return: no
  272. ***********************************************************************/
  273. static void fts_rw_iic_drv_setup_cdev(struct fts_rw_i2c_dev *dev, int index)
  274. {
  275. int err, devno = MKDEV(fts_rw_iic_drv_major, index);
  276. cdev_init(&dev->cdev, &fts_rw_iic_drv_fops);
  277. dev->cdev.owner = THIS_MODULE;
  278. dev->cdev.ops = &fts_rw_iic_drv_fops;
  279. err = cdev_add(&dev->cdev, devno, 1);
  280. if (err)
  281. printk(KERN_NOTICE "Error %d adding LED%d", err, index);
  282. }
  283. /************************************************************************
  284. * Name: fts_rw_iic_drv_myinitdev
  285. * Brief: initial char device
  286. * Input: i2c info
  287. * Output: no
  288. * Return: fail <0
  289. ***********************************************************************/
  290. static int fts_rw_iic_drv_myinitdev(struct i2c_client *client)
  291. {
  292. int err = 0;
  293. dev_t devno = MKDEV(fts_rw_iic_drv_major, 0);
  294. if (fts_rw_iic_drv_major)
  295. err = register_chrdev_region(devno, 1, FTS_RW_IIC_DRV);
  296. else
  297. {
  298. err = alloc_chrdev_region(&devno, 0, 1, FTS_RW_IIC_DRV);
  299. fts_rw_iic_drv_major = MAJOR(devno);
  300. }
  301. if (err < 0)
  302. {
  303. dev_err(&client->dev, "%s:ft_rw_iic_drv failed error code=%d---\n",
  304. __func__, err);
  305. return err;
  306. }
  307. fts_rw_i2c_dev_tt = kmalloc(sizeof(struct fts_rw_i2c_dev), GFP_KERNEL);
  308. if (!fts_rw_i2c_dev_tt)
  309. {
  310. err = -ENOMEM;
  311. unregister_chrdev_region(devno, 1);
  312. dev_err(&client->dev, "%s:ft_rw_iic_drv failed\n",
  313. __func__);
  314. return err;
  315. }
  316. fts_rw_i2c_dev_tt->client = client;
  317. mutex_init(&fts_rw_i2c_dev_tt->fts_rw_i2c_mutex);
  318. fts_rw_iic_drv_setup_cdev(fts_rw_i2c_dev_tt, 0);
  319. fts_class = class_create(THIS_MODULE, "fts_class");
  320. if (IS_ERR(fts_class))
  321. {
  322. dev_err(&client->dev, "%s:failed in creating class.\n",
  323. __func__);
  324. return -1;
  325. }
  326. /*create device node*/
  327. device_create(fts_class, NULL, MKDEV(fts_rw_iic_drv_major, 0),
  328. NULL, FTS_RW_IIC_DRV);
  329. return 0;
  330. }
  331. /************************************************************************
  332. * Name: fts_rw_iic_drv_init
  333. * Brief: call initial char device
  334. * Input: i2c info
  335. * Output: no
  336. * Return: fail <0
  337. ***********************************************************************/
  338. int fts_rw_iic_drv_init(struct i2c_client *client)
  339. {
  340. dev_dbg(&client->dev, "[FTS]----ft_rw_iic_drv init ---\n");
  341. return fts_rw_iic_drv_myinitdev(client);
  342. }
  343. /************************************************************************
  344. * Name: fts_rw_iic_drv_exit
  345. * Brief: delete char device
  346. * Input: no
  347. * Output: no
  348. * Return: no
  349. ***********************************************************************/
  350. void fts_rw_iic_drv_exit(void)
  351. {
  352. device_destroy(fts_class, MKDEV(fts_rw_iic_drv_major, 0));
  353. /* delete class created by us */
  354. class_destroy(fts_class);
  355. /* delet the cdev */
  356. cdev_del(&fts_rw_i2c_dev_tt->cdev);
  357. kfree(fts_rw_i2c_dev_tt);
  358. unregister_chrdev_region(MKDEV(fts_rw_iic_drv_major, 0), 1);
  359. }