PageRenderTime 60ms CodeModel.GetById 25ms RepoModel.GetById 1ms app.codeStats 0ms

/ANDROID_2.6.32-DS/ANDROID_2.6.32/drivers/input/touchscreen/rohm/rohm_bu21020.c

https://bitbucket.org/weilonge/vt8500-linux-kernel
C | 850 lines | 589 code | 124 blank | 137 comment | 82 complexity | 8a421147599f2d56bc18c430a8ca3651 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, AGPL-1.0
  1. /* drivers/input/touchscreen/rohm_bu21020.c
  2. * BU21020 touchscreen driver
  3. *
  4. * Copyright (C) 2010 ROHM SEMICONDUCTOR Co. Ltd.
  5. *
  6. * Author: CT Cheng <ct.cheng@rohm.com.tw>
  7. */
  8. #include <linux/kernel.h>
  9. #include <linux/module.h>
  10. #include <linux/input.h>
  11. #include <linux/interrupt.h>
  12. #include <linux/delay.h>
  13. #include <linux/gpio.h>
  14. #include <linux/spi/spi.h>
  15. #include <linux/hrtimer.h>
  16. #include <linux/spi/rohm_bu21020.h>
  17. #include <linux/cdev.h>
  18. #include <linux/fs.h>
  19. #include <linux/poll.h>
  20. //#include "BU21020_firmware.h" /* BU21020 internal firmware */
  21. #include "bu21020.h"
  22. #define ROHM_TS_ABS_X_MIN 0
  23. #define ROHM_TS_ABS_X_MAX 799
  24. #define ROHM_TS_ABS_Y_MIN 0
  25. #define ROHM_TS_ABS_Y_MAX 479
  26. #define BU21020_HZ (10000000)
  27. // Register map
  28. #define BU21020_REG_X1H (0x20)
  29. #define BU21020_REG_X1L (0x21)
  30. #define BU21020_REG_Y1H (0x22)
  31. #define BU21020_REG_Y1L (0x23)
  32. #define BU21020_REG_X2H (0x24)
  33. #define BU21020_REG_X2L (0x25)
  34. #define BU21020_REG_Y2H (0x26)
  35. #define BU21020_REG_Y2L (0x27)
  36. // Command
  37. #define BU21020_CMD_W(addr) (addr) /* single write */
  38. #define BU21020_CMD_R(addr) (addr | 0x80) /* single read */
  39. #undef SW_AVG
  40. /********************************************/
  41. #ifdef SW_AVG
  42. #define BUFF_ARRAY 16
  43. #define DISTANCE_X 6
  44. #define DISTANCE_Y 6
  45. #define AVG_BOUND_X 4
  46. #define AVG_BOUND_Y 4
  47. #define S_DISTANCE_X 6
  48. #define S_DISTANCE_Y 6
  49. #define S_AVG_BOUND_X 4
  50. #define S_AVG_BOUND_Y 4
  51. #define MULTI_SKIP_TIMES 15
  52. #define SKIP_AVG_1 1
  53. #define SKIP_AVG_2 1
  54. struct touch_point
  55. {
  56. unsigned int x;
  57. unsigned int y;
  58. unsigned int buff_x[BUFF_ARRAY];
  59. unsigned int buff_y[BUFF_ARRAY];
  60. unsigned char buff_cnt;
  61. /* Previous coordinate of touch point after moving average calculating */
  62. unsigned int old_avg_x;
  63. unsigned int old_avg_y;
  64. };
  65. struct touch_point tp1, tp2;
  66. #endif
  67. extern int wmt_getsyspara(char *varname, unsigned char *varval, int *varlen);
  68. extern int wmt_setsyspara(char *varname, char *varval);
  69. #define UBOOT_PARA_USED
  70. #define IOCTL_GET_CAL 0x1601
  71. #define IOCTL_SET_CAL 0x1602
  72. #define IOCTL_GET_RAW 0x1603
  73. #define IOCTL_SET_RAW 0x1604
  74. #define IOCTL_SET_RESOLUTION 0x1605
  75. #define IOCTL_DO_FILTER 0x1606
  76. #define IOCTL_SET_FILTER_DISTANCE 0x1607
  77. #define IOCTL_SET_SPI_FREQ 0x1608
  78. #define IOCTL_GET_SPI_FREQ 0x1609
  79. #define IOCTL_SET_DELAY_TIME 0x160A
  80. #define IOCTL_GET_DELAY_TIME 0x160B
  81. #define TS_IOC_MAGIC 't'
  82. #define TS_IOCTL_CAL_START _IO(TS_IOC_MAGIC, 1)
  83. #define TS_IOCTL_CAL_DONE _IOW(TS_IOC_MAGIC, 2, int*)
  84. #define TS_IOCTL_GET_RAWDATA _IOR(TS_IOC_MAGIC, 3, int*)
  85. struct private_wmt_ts_s {
  86. /* module parameters */
  87. char *buf;
  88. /* char dev struct */
  89. struct cdev cdev;
  90. };
  91. static struct workqueue_struct *rohm_wq;
  92. static struct private_wmt_ts_s private_ts;
  93. static int private_wmt_dev_major = 160;
  94. static int private_wmt_dev_minor = 0 ;
  95. struct class *class_wmt_ts;
  96. static pm_message_t ts_pm_state = {
  97. .event = PM_EVENT_ON,
  98. };
  99. struct calibration_parameter g_CalcParam = {
  100. .a1 = 32602,
  101. .b1 = 339,
  102. .c1 = -1973856,
  103. .a2 = -99,
  104. .b2 = 23003,
  105. .c2 = -3520935,
  106. .delta = 37654,
  107. };
  108. struct bu21020
  109. {
  110. struct spi_device *spi;
  111. struct input_dev *idev;
  112. char phys[32];
  113. struct hrtimer timer;
  114. struct work_struct work;
  115. };
  116. /*
  117. * brief : set calibration information from BOOT ROM
  118. */
  119. int set_twoD_calibration_info(void) {
  120. int retval;
  121. char buf[160];
  122. sprintf(buf, "%d %d %d %d %d %d %d",
  123. g_CalcParam.a1,
  124. g_CalcParam.b1,
  125. g_CalcParam.c1,
  126. g_CalcParam.a2,
  127. g_CalcParam.b2,
  128. g_CalcParam.c2,
  129. g_CalcParam.delta
  130. );
  131. #ifdef UBOOT_PARA_USED
  132. retval = wmt_setsyspara("wmt.io.ts.2dcal", buf);
  133. #endif
  134. retval = 0;
  135. return retval;
  136. }
  137. int get_twoD_calibration_info(void) {
  138. int retval;
  139. char *varname = "wmt.io.ts.2dcal";
  140. #ifdef UBOOT_PARA_USED
  141. int varlen = 160;
  142. #endif
  143. unsigned char buf[160];
  144. #ifdef UBOOT_PARA_USED
  145. retval = wmt_getsyspara(varname, buf, &varlen);
  146. #else
  147. retval = 1;
  148. #endif
  149. if (retval != 0) {
  150. printk("Use default Calibration points\n");
  151. return retval;
  152. } else
  153. printk("%s = %s\n",varname, buf);
  154. sscanf(buf, "%d %d %d %d %d %d %d",
  155. &g_CalcParam.a1,
  156. &g_CalcParam.b1,
  157. &g_CalcParam.c1,
  158. &g_CalcParam.a2,
  159. &g_CalcParam.b2,
  160. &g_CalcParam.c2,
  161. &g_CalcParam.delta);
  162. return retval;
  163. }
  164. static inline void SPI_ByteWrite(struct spi_device *spi, u8 address, u8 data)
  165. {
  166. char tx_buf[2];
  167. int ret;
  168. tx_buf[0] = address;
  169. tx_buf[1] = data;
  170. ret = spi_write(spi, tx_buf, 2);
  171. if (ret != 0)
  172. printk("spi write err\n");
  173. /*
  174. else
  175. printk("<1> Write reg(0x%x): 0x%x\n", address, data);
  176. */
  177. }
  178. static inline u8 SPI_ByteRead(struct spi_device *spi, u8 address)
  179. {
  180. u8 result;
  181. result = spi_w8r8(spi, BU21020_CMD_R(address));
  182. return result;
  183. }
  184. #ifdef SW_AVG
  185. //-----------------------------------------------------------------------------
  186. //
  187. //Coord_Avg
  188. //
  189. //-----------------------------------------------------------------------------
  190. static void Coord_Avg (struct touch_point *tp)
  191. {
  192. unsigned long temp_x = 0, temp_y = 0, temp_n = 0;
  193. unsigned int i;
  194. ////////////////////////////////////////
  195. // X1,Y1 Moving Avg
  196. ////////////////////////////////////////
  197. if ((tp->x != 0) && (tp->y != 0)) {
  198. if(tp->buff_cnt >= SKIP_AVG_1) {
  199. if(((abs(tp->buff_x[0] - tp->x) > DISTANCE_X) && (abs(tp->buff_y[0] - tp->y) > DISTANCE_Y)) ||
  200. ((abs(tp->buff_x[0] - tp->x) > S_DISTANCE_X) && (abs(tp->buff_y[0] - tp->y) < S_DISTANCE_Y)) ||
  201. ((abs(tp->buff_x[0] - tp->x) < S_DISTANCE_X) && (abs(tp->buff_y[0] - tp->y) > S_DISTANCE_Y)) ||
  202. (((tp->old_avg_x != 0) && (abs(tp->old_avg_x - tp->x) > AVG_BOUND_X)) &&
  203. ( (tp->old_avg_y != 0) && (abs(tp->old_avg_y - tp->y) > AVG_BOUND_Y))) ||
  204. (((tp->old_avg_x != 0) && (abs(tp->old_avg_x - tp->x) > S_AVG_BOUND_X)) &&
  205. ( (tp->old_avg_y != 0) && (abs(tp->old_avg_y - tp->y) < S_AVG_BOUND_Y)))||
  206. (((tp->old_avg_x != 0) && (abs(tp->old_avg_x - tp->x) < S_AVG_BOUND_X)) &&
  207. ( (tp->old_avg_y != 0) && (abs(tp->old_avg_y - tp->y) > S_AVG_BOUND_Y)))) {
  208. for (i = 0; i < tp->buff_cnt; i++) {
  209. tp->buff_x[tp->buff_cnt - i] = tp->buff_x[tp->buff_cnt - i - 1];
  210. tp->buff_y[tp->buff_cnt - i] = tp->buff_y[tp->buff_cnt - i - 1];
  211. }
  212. tp->buff_x[0] = tp->x;
  213. tp->buff_y[0] = tp->y;
  214. temp_x = 0; temp_y = 0; temp_n = 0;
  215. for (i = 0; i <= tp->buff_cnt; i++) {
  216. temp_x += ((unsigned long) (tp->buff_x[i] * (tp->buff_cnt - i + 1)));
  217. temp_y += ((unsigned long) (tp->buff_y[i] * (tp->buff_cnt - i + 1)));
  218. temp_n += (unsigned long) (tp->buff_cnt - i + 1);
  219. }
  220. tp->x = temp_x / temp_n;
  221. tp->y = temp_y / temp_n;
  222. tp->old_avg_x = tp->x;
  223. tp->old_avg_y = tp->y;
  224. if (tp->buff_cnt < (BUFF_ARRAY-1))
  225. tp->buff_cnt++;
  226. } else {
  227. tp->x = tp->old_avg_x;
  228. tp->y = tp->old_avg_y;
  229. }
  230. } else {
  231. for (i = 0; i < tp->buff_cnt; i++) {
  232. tp->buff_x[tp->buff_cnt - i] = tp->buff_x[tp->buff_cnt - i - 1];
  233. tp->buff_y[tp->buff_cnt - i] = tp->buff_y[tp->buff_cnt - i - 1];
  234. }
  235. tp->buff_x[0] = tp->x;
  236. tp->buff_y[0] = tp->y;
  237. if(tp->buff_cnt < (BUFF_ARRAY-1))
  238. tp->buff_cnt++;
  239. tp->old_avg_x = tp->x;
  240. tp->old_avg_y = tp->y;
  241. tp->x = 0;
  242. tp->y = 0;
  243. }
  244. } else {//End/ of "if((x1 != 0) && (y1 != 0))"
  245. tp->buff_cnt = 0;
  246. if((tp->buff_x[0] != 0) && (tp->buff_y[0] != 0)) {
  247. tp->x = tp->buff_x[0];
  248. tp->y = tp->buff_y[0];
  249. } else {
  250. tp->x = 0;
  251. tp->y = 0;
  252. }
  253. tp->buff_x[0] = 0;
  254. tp->buff_y[0] = 0;
  255. tp->old_avg_x = 0;
  256. tp->old_avg_y = 0;
  257. }
  258. }
  259. #endif
  260. static u16 cal_data[2];
  261. static void twoDconvert(u32 *cal_x, u32 *cal_y )
  262. {
  263. int UncalX;
  264. int UncalY;
  265. int x,y;
  266. UncalX = (int) *cal_x;
  267. UncalY = (int) *cal_y;
  268. x = (g_CalcParam.a1 * UncalX + g_CalcParam.b1 * UncalY +
  269. g_CalcParam.c1) / g_CalcParam.delta;
  270. y = (g_CalcParam.a2 * UncalX + g_CalcParam.b2 * UncalY +
  271. g_CalcParam.c2) / g_CalcParam.delta;
  272. if (x < 0)
  273. x = 0;
  274. if (y < 0)
  275. y = 0;
  276. *cal_x = (u32)x;
  277. *cal_y = (u32)y;
  278. }
  279. static void rohm_ts_work_func(struct work_struct *work)
  280. {
  281. //define ouput data start
  282. unsigned int finger;
  283. unsigned int x1, y1, x2, y2;
  284. struct bu21020 *tsc = container_of(work, struct bu21020, work);
  285. //Get the coordinate of point 1 and point 2
  286. /*
  287. x1 = (SPI_ByteRead(tsc->spi, BU21020_REG_X1H) << 2) | SPI_ByteRead(tsc->spi, BU21020_REG_X1L);
  288. y1 = (SPI_ByteRead(tsc->spi, BU21020_REG_Y1H) << 2) | SPI_ByteRead(tsc->spi, BU21020_REG_Y1L);
  289. x2 = (SPI_ByteRead(tsc->spi, BU21020_REG_X2H) << 2) | SPI_ByteRead(tsc->spi, BU21020_REG_X2L);
  290. y2 = (SPI_ByteRead(tsc->spi, BU21020_REG_Y2H) << 2) | SPI_ByteRead(tsc->spi, BU21020_REG_Y2L);
  291. */
  292. y1 = (SPI_ByteRead(tsc->spi, BU21020_REG_X1H) << 2) | SPI_ByteRead(tsc->spi, BU21020_REG_X1L);
  293. x1 = (SPI_ByteRead(tsc->spi, BU21020_REG_Y1H) << 2) | SPI_ByteRead(tsc->spi, BU21020_REG_Y1L);
  294. y2 = (SPI_ByteRead(tsc->spi, BU21020_REG_X2H) << 2) | SPI_ByteRead(tsc->spi, BU21020_REG_X2L);
  295. x2 = (SPI_ByteRead(tsc->spi, BU21020_REG_Y2H) << 2) | SPI_ByteRead(tsc->spi, BU21020_REG_Y2L);
  296. //printk(" x1 = %3d, y1 = %3d,x2 = %3d, y2 = %3d, \n", x1, y1, x2, y2);
  297. cal_data[0] = x1;
  298. cal_data[1] = y1;
  299. if (x1 != 0 && y1 != 0)
  300. twoDconvert(&x1, &y1);
  301. if (x2 != 0 && y2 != 0)
  302. twoDconvert(&x2, &y2);
  303. /*
  304. printk(" x1 = %3d, y1 = %3d,x2 = %3d, y2 = %3d, \n", x1, y1, x2, y2);
  305. */
  306. SPI_ByteWrite(tsc->spi, 0x3E, 0xFF);
  307. #ifdef SW_AVG
  308. tp1.x = x1;
  309. tp1.y = y1;
  310. Coord_Avg(&tp1);
  311. x1 = tp1.x;
  312. y1 = tp1.y;
  313. tp2.x = x2;
  314. tp2.y = y2;
  315. Coord_Avg(&tp2);
  316. x2 = tp2.x;
  317. y2 = tp2.y;
  318. #endif
  319. if (((y1 > 0) && (x1 > 0)) && ((y2 > 0) && (x2 > 0))) {
  320. finger = 2;
  321. } else if (((y1 > 0) && (x1 > 0)) || ((y2 > 0) && (x2 > 0))) {
  322. finger = 1;
  323. if ((x2 != 0) && (y2 != 0)) {
  324. x1 = x2;
  325. y1 = y2;
  326. x2 = 0;
  327. y2 = 0;
  328. }
  329. } else {
  330. finger = 0;
  331. }
  332. /*
  333. printk(" x1 = %3d, y1 = %3d,x2 = %3d, y2 = %3d, \n", x1, y1, x2, y2);
  334. */
  335. if(finger == 0)
  336. input_report_abs(tsc->idev, ABS_MT_TOUCH_MAJOR, 0);
  337. else
  338. input_report_abs(tsc->idev, ABS_MT_TOUCH_MAJOR, 3);
  339. /*
  340. input_report_abs(tsc->idev, ABS_MT_WIDTH_MAJOR, 0);
  341. */
  342. input_report_abs(tsc->idev, ABS_MT_POSITION_X, x1);
  343. input_report_abs(tsc->idev, ABS_MT_POSITION_Y, y1);
  344. input_mt_sync(tsc->idev);
  345. if (finger == 2) {
  346. input_report_abs(tsc->idev, ABS_MT_TOUCH_MAJOR, 3);
  347. /*
  348. input_report_abs(tsc->idev, ABS_MT_WIDTH_MAJOR, 0);
  349. */
  350. input_report_abs(tsc->idev, ABS_MT_POSITION_X, x2);
  351. input_report_abs(tsc->idev, ABS_MT_POSITION_Y, y2);
  352. input_mt_sync(tsc->idev);
  353. }
  354. input_report_abs(tsc->idev, ABS_PRESSURE, 0); // 0 touch_pressure
  355. input_report_abs(tsc->idev, ABS_TOOL_WIDTH, 0); // 0 touch_width,File system do judge this register
  356. input_report_key(tsc->idev, BTN_TOUCH,finger); // finger num 0, 1, 2
  357. input_report_key(tsc->idev, BTN_2, finger > 1); // finger2 state 0, 0, 1
  358. input_sync(tsc->idev); // up load data
  359. }
  360. static enum hrtimer_restart rohm_ts_timer_func(struct hrtimer *timer)
  361. {
  362. struct bu21020 *tsc = container_of(timer, struct bu21020, timer);
  363. queue_work(rohm_wq, &tsc->work);
  364. hrtimer_start(&tsc->timer, ktime_set(0, 12500000), HRTIMER_MODE_REL);/*report rate 1/12500000=80Hz*/
  365. return HRTIMER_NORESTART;
  366. }
  367. static int __devinit bu21020_ts_init(struct bu21020 *ts,
  368. struct bu21020_platform_data *pdata)
  369. {
  370. struct input_dev *idev;
  371. int r;
  372. idev = input_allocate_device();
  373. if (idev == NULL) {
  374. r = -ENOMEM;
  375. goto err;
  376. }
  377. idev->name = "BU21020 touchscreen";
  378. /*Dean-
  379. snprintf(ts->phys, sizeof(ts->phys), "%s/input-ts",
  380. ts->spi->dev.bus_id);
  381. */
  382. /*Dean+*/
  383. snprintf(ts->phys, sizeof(ts->phys), "input-ts");
  384. idev->phys = ts->phys;
  385. idev->evbit[0] = BIT(EV_ABS) | BIT(EV_KEY);
  386. idev->absbit[0] = BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE);
  387. ts->idev = idev;
  388. ////////////////////////////////////////////////////////////////////////////
  389. input_set_abs_params(idev, ABS_MT_POSITION_X, ROHM_TS_ABS_X_MIN, ROHM_TS_ABS_X_MAX, 0, 0);
  390. input_set_abs_params(idev, ABS_MT_POSITION_Y, ROHM_TS_ABS_Y_MIN, ROHM_TS_ABS_Y_MAX, 0, 0);
  391. input_set_abs_params(idev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);
  392. //input_set_abs_params(idev, ABS_MT_WIDTH_MAJOR, 0, 15, 0, 0);
  393. ////////////////////////////////////////////////////////////////////////////
  394. //input_set_abs_params(idev, ABS_X, ROHM_TS_ABS_X_MIN, ROHM_TS_ABS_X_MAX, 0, 0);
  395. //input_set_abs_params(idev, ABS_Y, ROHM_TS_ABS_Y_MIN, ROHM_TS_ABS_Y_MAX, 0, 0);
  396. input_set_abs_params(idev, ABS_PRESSURE, 0, 1550, 0 , 0); //1550 two point
  397. input_set_abs_params(idev, ABS_TOOL_WIDTH, 0, 15, 0 , 0); //15 two point
  398. //input_set_abs_params(idev, ABS_HAT0X, ROHM_TS_ABS_X_MIN, ROHM_TS_ABS_X_MAX, 0, 0);
  399. //input_set_abs_params(idev, ABS_HAT0Y, ROHM_TS_ABS_Y_MIN, ROHM_TS_ABS_Y_MAX, 0, 0);
  400. //bu21020_start_scan(ts);
  401. r = input_register_device(idev);
  402. if (r < 0) {
  403. dev_err(&ts->spi->dev, "can't register touchscreen device\n");
  404. goto err;
  405. }
  406. return 0;
  407. err:
  408. return r;
  409. }
  410. static int private_wmt_ts_ioctl(
  411. struct inode *inode, /*!<; //[IN] a pointer point to struct inode */
  412. struct file *filp, /*!<; //[IN] a pointer point to struct file */
  413. unsigned int cmd, /*!<; // please add parameters description her*/
  414. unsigned long arg /*!<; // please add parameters description her*/
  415. )
  416. {
  417. int nBuff[7];
  418. int retval = 0;
  419. switch (cmd) {
  420. case TS_IOCTL_CAL_START:
  421. /*
  422. printk("TS_IOCTL_CAL_START\n");
  423. */
  424. break;
  425. case TS_IOCTL_CAL_DONE:
  426. /*
  427. printk("TS_IOCTL_CAL_DONE\n");
  428. */
  429. copy_from_user(nBuff, (unsigned int*)arg, 7*sizeof(int));
  430. g_CalcParam.a1 = nBuff[0];
  431. g_CalcParam.b1 = nBuff[1];
  432. g_CalcParam.c1 = nBuff[2];
  433. g_CalcParam.a2 = nBuff[3];
  434. g_CalcParam.b2 = nBuff[4];
  435. g_CalcParam.c2 = nBuff[5];
  436. g_CalcParam.delta = nBuff[6];
  437. /*
  438. printk("g_CalcParam = %d, %d, %d, %d, %d, %d, %d\n",
  439. g_CalcParam.a1, g_CalcParam.b1, g_CalcParam.c1,
  440. g_CalcParam.a2, g_CalcParam.b2, g_CalcParam.c2, g_CalcParam.delta);
  441. */
  442. set_twoD_calibration_info();
  443. break;
  444. case TS_IOCTL_GET_RAWDATA:
  445. /*
  446. printk("TS_IOCTL_GET_RAWDATA\n");
  447. */
  448. nBuff[0] = cal_data[0];
  449. nBuff[1] = cal_data[1];
  450. copy_to_user((unsigned int*)arg, nBuff, 2*sizeof(int));
  451. /*
  452. printk("x = %d, y = %d\n", nBuff[0], nBuff[1]);
  453. */
  454. break;
  455. default:
  456. retval = -EINVAL;
  457. break;
  458. }
  459. return retval;
  460. }
  461. static int private_wmt_ts_open(
  462. struct inode *inode, /*!<; //[IN] a pointer point to struct inode */
  463. struct file *filp /*!<; //[IN] a pointer point to struct file */
  464. )
  465. {
  466. struct private_wmt_ts_s *dev;
  467. /*
  468. printk("wmt_ts_open\n");
  469. */
  470. dev = container_of(inode->i_cdev, struct private_wmt_ts_s, cdev);
  471. filp->private_data = dev;
  472. return 0;
  473. }
  474. static int private_wmt_ts_release(
  475. struct inode *inode, /*!<; //[IN] a pointer point to struct inode */
  476. struct file *filp /*!<; //[IN] a pointer point to struct file */
  477. )
  478. {
  479. /*
  480. printk("wmt_ts_release\n");
  481. */
  482. return 0;
  483. }
  484. struct file_operations wmt_ts_fops = {
  485. .owner = THIS_MODULE,
  486. .open = private_wmt_ts_open,
  487. .ioctl = private_wmt_ts_ioctl,
  488. .release = private_wmt_ts_release,
  489. };
  490. // Firmware Download
  491. static int init_bu21020_firm(struct spi_device *spi)
  492. {
  493. ////////////////////////////////////////////////////////////////////////
  494. // Download BU21020 Firmware by HOST
  495. ////////////////////////////////////////////////////////////////////////
  496. // Wait 200usec for Reset
  497. int i = 0;
  498. SPI_ByteWrite(spi, 0x40, 0x00);
  499. udelay(200);
  500. SPI_ByteWrite(spi, 0x30, 0x02);
  501. SPI_ByteWrite(spi, 0x40, 0x01);
  502. // Wait 100usec for POWER-ON
  503. udelay(100);
  504. // Beginning address setting of program memory for host download
  505. SPI_ByteWrite(spi, 0x70, 0x00);
  506. SPI_ByteWrite(spi, 0x71, 0x00);
  507. // Download firmware to BU21020
  508. printk("BU21020 firmware download starts!\n");
  509. for(i = 0; i < CODESIZE; i++)
  510. SPI_ByteWrite(spi, 0x72, program[i]);
  511. printk("BU21020 firmware download is completed!\n");
  512. // Clear all Interrupt
  513. SPI_ByteWrite(spi, 0x3E, 0xFF);
  514. return 0;
  515. }
  516. // Initial Setting (For Register Setting)
  517. static int init_bu21020_reg(struct spi_device *spi)
  518. {
  519. ////////////////////////////////////////////////////////////////////////
  520. // Init BU21020
  521. ////////////////////////////////////////////////////////////////////////
  522. SPI_ByteWrite(spi, 0x40, 0x00);
  523. SPI_ByteWrite(spi, 0x30, 0x46);
  524. SPI_ByteWrite(spi, 0x40, 0x01);
  525. // Wait 100usec for Power-on
  526. udelay(100);
  527. SPI_ByteWrite(spi, 0x31, 0xE6);
  528. SPI_ByteWrite(spi, 0x32, 0x62);
  529. SPI_ByteWrite(spi, 0x35, 0xB0);
  530. SPI_ByteWrite(spi, 0x34, 0x78);
  531. /*
  532. SPI_ByteWrite(spi, 0x35, 0xB0);
  533. SPI_ByteWrite(spi, 0x34, 0x78);
  534. */
  535. SPI_ByteWrite(spi, 0x36, 0x08);
  536. SPI_ByteWrite(spi, 0x37, 0x08);
  537. SPI_ByteWrite(spi, 0x3A, 0x0F);
  538. //Change AD timing
  539. SPI_ByteWrite(spi, 0x50, 0x00);
  540. SPI_ByteWrite(spi, 0x52, 0x08);
  541. SPI_ByteWrite(spi, 0x56, 0xFF);
  542. //SPI_ByteWrite(spi, 0x60, 0x04);
  543. SPI_ByteWrite(spi, 0x61, 0x0A);
  544. SPI_ByteWrite(spi, 0x62, 0x0F);
  545. printk("Dean revised1111\n");
  546. SPI_ByteWrite(spi, 0x64, 0x5C);
  547. SPI_ByteWrite(spi, 0x63, 0xD6);
  548. SPI_ByteWrite(spi, 0x65, 0x01);
  549. // CPU power on
  550. SPI_ByteWrite(spi, 0x40, 0x03);
  551. // Clear all Interrupt
  552. SPI_ByteWrite(spi, 0x3E, 0xFF);
  553. return 0;
  554. }
  555. static int __devinit bu21020_probe(struct spi_device *spi)
  556. {
  557. struct bu21020 *tsc;
  558. struct bu21020_platform_data *pdata = spi->dev.platform_data;
  559. int r;
  560. #if 1
  561. unsigned char version = 0;
  562. #endif
  563. #if 0
  564. int i;
  565. #endif
  566. dev_t dev_no;
  567. struct cdev *cdev;
  568. dev_no = MKDEV(private_wmt_dev_major, private_wmt_dev_minor);
  569. cdev = &private_ts.cdev;
  570. cdev_init(cdev,&wmt_ts_fops);
  571. cdev_add(cdev, dev_no, 8);
  572. class_wmt_ts = class_create(THIS_MODULE, "wmtts");
  573. device_create(class_wmt_ts, NULL ,MKDEV(private_wmt_dev_major,private_wmt_dev_minor),
  574. NULL, "wmtts");
  575. printk(KERN_ERR "ROHM BU21020 rohm_ts_probe!\n");
  576. if (!pdata) {
  577. dev_dbg(&spi->dev, "no platform data?\n");
  578. return -ENODEV;
  579. }
  580. tsc = kzalloc(sizeof(*tsc), GFP_KERNEL);
  581. if (tsc == NULL)
  582. return -ENOMEM;
  583. dev_set_drvdata(&spi->dev, tsc);
  584. tsc->spi = spi;
  585. spi->dev.power.power_state = PMSG_ON;
  586. spi->mode = SPI_MODE_3;
  587. spi->bits_per_word = 8;
  588. /* The max speed might've been defined by the board-specific
  589. * struct */
  590. if (!spi->max_speed_hz)
  591. spi->max_speed_hz = BU21020_HZ;
  592. spi_setup(spi);
  593. INIT_WORK(&tsc->work, rohm_ts_work_func);
  594. #if 1
  595. init_bu21020_firm(spi);
  596. init_bu21020_reg(spi);
  597. #endif
  598. #if 0
  599. ////////////////////////////////////////////////////////////////////////
  600. // Init BU21020
  601. ////////////////////////////////////////////////////////////////////////
  602. // Wait 200usec for Reset
  603. /*
  604. SPI_ByteWrite(spi, 0x40, 0x00);
  605. udelay(200);
  606. */
  607. SPI_ByteWrite(spi, 0x40, 0x01);
  608. udelay(200);
  609. SPI_ByteWrite(spi, 0x30, 0x46);
  610. SPI_ByteWrite(spi, 0x31, 0xE6);
  611. SPI_ByteWrite(spi, 0x32, 0x62);
  612. /*
  613. SPI_ByteWrite(spi, 0x35, 0x78);
  614. SPI_ByteWrite(spi, 0x34, 0xB0);
  615. */
  616. SPI_ByteWrite(spi, 0x34, 0x78);
  617. SPI_ByteWrite(spi, 0x35, 0xB0);
  618. SPI_ByteWrite(spi, 0x36, 0x08);
  619. SPI_ByteWrite(spi, 0x37, 0x08);
  620. SPI_ByteWrite(spi, 0x3A, 0x0F);
  621. SPI_ByteWrite(spi, 0x56, 0xFF);
  622. SPI_ByteWrite(spi, 0x61, 0x0A);
  623. SPI_ByteWrite(spi, 0x62, 0x0F);
  624. SPI_ByteWrite(spi, 0x63, 0x5C);
  625. SPI_ByteWrite(spi, 0x64, 0xD6);
  626. /*
  627. SPI_ByteWrite(spi, 0x63, 0xE0);
  628. SPI_ByteWrite(spi, 0x64, 0xE4);
  629. */
  630. SPI_ByteWrite(spi, 0x65, 0x01);
  631. SPI_ByteWrite(spi, 0x40, 0x01);
  632. // Wait 100usec for Power-on
  633. udelay(100);
  634. // Beginning address setting of program memory for host download
  635. SPI_ByteWrite(spi, 0x70, 0x00);
  636. SPI_ByteWrite(spi, 0x71, 0x00);
  637. // Download firmware to BU21020
  638. printk("BU21020 firmware download starts!\n");
  639. for(i = 0; i < CODESIZE; i++)
  640. SPI_ByteWrite(spi, 0x72, program[i]);
  641. printk("BU21020 firmware download is completed!\n");
  642. // Download path setting
  643. SPI_ByteWrite(spi, 0x3E, 0xFF);
  644. //Change AD timing
  645. //SPI_ByteWrite(spi, 0x50, 0x00);
  646. SPI_ByteWrite(spi, 0x52, 0x08);
  647. // CPU power on
  648. SPI_ByteWrite(spi, 0x40, 0x03);
  649. // Clear all Interrupt
  650. SPI_ByteWrite(spi, 0x3E, 0xFF);
  651. #endif
  652. #if 1 /*for debug*/
  653. mdelay(10);
  654. version = SPI_ByteRead(spi, 0x5f);
  655. printk("BU21020 firmware version = %x\n", version);
  656. #endif
  657. // Init end
  658. ////////////////////////////////////////////////////////////////////////
  659. r = bu21020_ts_init(tsc, pdata);
  660. /* Timer init*/
  661. hrtimer_init(&tsc->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
  662. tsc->timer.function = rohm_ts_timer_func;
  663. hrtimer_start(&tsc->timer, ktime_set(1, 0), HRTIMER_MODE_REL);
  664. get_twoD_calibration_info();
  665. if (r)
  666. goto err1;
  667. return 0;
  668. err1:
  669. kfree(tsc);
  670. return r;
  671. }
  672. static int __devexit bu21020_remove(struct spi_device *spi)
  673. {
  674. struct bu21020 *ts = dev_get_drvdata(&spi->dev);
  675. hrtimer_cancel(&ts->timer);
  676. input_unregister_device(ts->idev);
  677. kfree(ts);
  678. return 0;
  679. }
  680. static int bu21020_suspend(struct spi_device *spi, pm_message_t message)
  681. {
  682. struct bu21020 *ts = dev_get_drvdata(&spi->dev);
  683. ts_pm_state.event = message.event;
  684. hrtimer_cancel(&ts->timer);
  685. return 0;
  686. }
  687. static int bu21020_resume(struct spi_device *spi)
  688. {
  689. struct bu21020 *ts = dev_get_drvdata(&spi->dev);
  690. ts_pm_state.event = PM_EVENT_RESUME;
  691. init_bu21020_firm(spi);
  692. init_bu21020_reg(spi);
  693. hrtimer_start(&ts->timer, ktime_set(1, 0), HRTIMER_MODE_REL);
  694. return 0;
  695. }
  696. static struct spi_driver bu21020_driver = {
  697. .driver = {
  698. .name = "bu21020",
  699. .owner = THIS_MODULE,
  700. },
  701. .probe = bu21020_probe,
  702. .remove = __devexit_p(bu21020_remove),
  703. .suspend = bu21020_suspend,
  704. .resume = bu21020_resume
  705. };
  706. static int __init bu21020_init(void)
  707. {
  708. printk(KERN_INFO "BU21020 driver initializing\n");
  709. rohm_wq = create_singlethread_workqueue("rohm_wq");
  710. if (!rohm_wq) {
  711. printk(KERN_ERR "create_singlethread_workqueue ERROR!! \n");
  712. return -ENOMEM;
  713. }
  714. return spi_register_driver(&bu21020_driver);
  715. }
  716. module_init(bu21020_init);
  717. static void __exit bu21020_exit(void)
  718. {
  719. spi_unregister_driver(&bu21020_driver);
  720. if (rohm_wq)
  721. destroy_workqueue(rohm_wq);
  722. }
  723. module_exit(bu21020_exit);
  724. MODULE_AUTHOR("CT Cheng <ct.cheng@rohm.com.tw>");
  725. MODULE_LICENSE("GPL");
  726. MODULE_ALIAS("platform:bu21020");