aphost.c 34 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376
  1. /*
  2. * SPI controller driver for the nordic52832 SoCs
  3. *
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License version 2 as
  7. * published by the Free Software Foundation.
  8. *
  9. */
  10. #include "aphost.h"
  11. #define A11B_NRF
  12. #define CMD_DATA_TAG 0xA6
  13. #define CMD_CLR_BOND_TAG 0xA7
  14. #define CMD_REQUEST_TAG (0xA8)
  15. #define CMD_EXTDATA_RLEDTAG 0xB6
  16. //#define INTERFACE_ADD
  17. #define YC_START_HOST _IO('q', 1)
  18. #define YC_STOP_HOST _IO('q', 2)
  19. #define YC_DATA_NOTIFY _IO('q',3)
  20. #define YC_START_VIB _IO('q', 4)
  21. #define YC_STOP_VIB _IO('q', 5)
  22. #define YC_GET_DATA
  23. struct jspinctrl_info {
  24. struct pinctrl *pinctrl;
  25. struct pinctrl_state *active;
  26. struct pinctrl_state *suspend;
  27. };
  28. struct js_spi_client {
  29. struct spi_device *spi_client;
  30. struct task_struct *kthread;
  31. struct mutex js_mutex; /* power mutex*/
  32. struct mutex js_sm_mutex; /*dma alloc and free mutex*/
  33. struct jspinctrl_info pinctrl_info;
  34. int js_lfen_gpio; /*level shift en gpio*/
  35. int js_irq_gpio;
  36. int js_rled_en_gpio;/*A11B used as all rled trig ,but v02a used as left rled */
  37. int js_tst2_gpio; /*just old test gpio ,not used in a11b and v02a*/
  38. int js_dfu_en_gpio; /*dfu enable gpio ,low enable dfu */
  39. int js_v02a_rled_right_en_gpio; /* A11B not used , V02A useed for right rled */
  40. int js_v33en_gpio;
  41. int js_ledl_gpio; /*old test ,not used now*/
  42. int js_ledr_gpio; /*old test ,not used now*/
  43. int js_irq;
  44. atomic_t dataflag;
  45. atomic_t rledchg;
  46. atomic_t userRequest; //request from userspace
  47. atomic_t nordicAcknowledge; //ack from nordic52832 master
  48. unsigned char JoyStickBondState; //1:left JoyStick 2:right JoyStick
  49. bool suspend;
  50. wait_queue_head_t wait_queue;
  51. void *vaddr;
  52. size_t vsize;
  53. struct dma_buf *js_buf;
  54. spinlock_t smem_lock;
  55. struct miscdevice miscdev;
  56. uint64_t tss;
  57. uint64_t ts_offset;
  58. unsigned char txbuffer[255];
  59. unsigned char rxbuffer[255];
  60. uint64_t tsHost; /*linux boottime */
  61. uint64_t tsoffset; /*time offset between two cpu*/
  62. uint64_t tsoffsetmono;/*linux monotime ,need by app */
  63. uint64_t tsSyncPt;
  64. uint64_t tsSyncPtmono;
  65. uint32_t tshmd_tmp;/*get the time from hmd*/
  66. unsigned char SyncPtFlag;
  67. unsigned char powerstate;
  68. bool irqstate;
  69. unsigned char js_lstate;
  70. unsigned char js_rstate;
  71. struct hrtimer hr_timer;
  72. ktime_t ktime;
  73. struct usb_device *udev;
  74. struct usb_host_interface *desc;
  75. struct usb_endpoint_descriptor *endpoint;
  76. struct usb_interface *intf;
  77. struct urb *urb;
  78. unsigned int pipe;
  79. u8 ubuffer[128];
  80. struct work_struct work;
  81. int memfd;
  82. atomic_t urbstate;
  83. };
  84. struct js_spi_client *gspi_client = NULL;
  85. cp_buffer_t *u_packet=NULL;
  86. static char checkoutpoint=0;
  87. void d_packet_set_instance(cp_buffer_t *in )
  88. {
  89. if(gspi_client==NULL){
  90. pr_err("js %s: drv init err", __func__);
  91. }
  92. spin_lock(&gspi_client->smem_lock);
  93. if(in==NULL){
  94. u_packet=NULL;
  95. }
  96. else{
  97. u_packet=in;
  98. u_packet->c_head=-1;
  99. u_packet->p_head=-1;
  100. }
  101. spin_unlock(&gspi_client->smem_lock);
  102. if(in==NULL)
  103. pr_err("js %s: release mem", __func__);
  104. else
  105. pr_err("js %s: alloc mem", __func__);
  106. }
  107. void js_irq_enable(struct js_spi_client *spi_client,bool enable)
  108. {
  109. if(spi_client->irqstate==enable){
  110. pr_err("js irq already =%d ",enable);
  111. return;
  112. }
  113. pr_err("js irq en =%d ",enable);
  114. if(enable){
  115. enable_irq(spi_client->js_irq);
  116. }
  117. else{
  118. disable_irq(spi_client->js_irq);
  119. }
  120. spi_client->irqstate=enable;
  121. }
  122. void js_set_power(int jspower)
  123. {
  124. if(gspi_client)
  125. {
  126. mutex_lock(&gspi_client->js_mutex);
  127. if(gspi_client->powerstate != jspower)
  128. {
  129. if(jspower==0){/*off */
  130. gspi_client->powerstate=0;
  131. js_irq_enable(gspi_client,false);
  132. gpio_set_value(gspi_client->js_dfu_en_gpio,1);
  133. gpio_set_value(gspi_client->js_lfen_gpio,0);
  134. gpio_set_value(gspi_client->js_v33en_gpio,0);
  135. }
  136. else if(jspower==1){ /*normal on*/
  137. gpio_set_value(gspi_client->js_dfu_en_gpio,1);
  138. gpio_set_value(gspi_client->js_v33en_gpio,1);
  139. gpio_set_value(gspi_client->js_lfen_gpio,1);
  140. gspi_client->powerstate=1;
  141. js_irq_enable(gspi_client,true);
  142. }
  143. else if(jspower==2){/*dfu*/
  144. gspi_client->powerstate=2;
  145. js_irq_enable(gspi_client,false);
  146. gpio_set_value(gspi_client->js_dfu_en_gpio,0);
  147. gpio_set_value(gspi_client->js_v33en_gpio,1);
  148. gpio_set_value(gspi_client->js_lfen_gpio,1);
  149. msleep(100);
  150. }
  151. }
  152. mutex_unlock(&gspi_client->js_mutex);
  153. }
  154. }
  155. static ssize_t jspower_show(struct device *dev,struct device_attribute *attr, char *buf)
  156. {
  157. return sprintf(buf, "%d\n",(unsigned int)gspi_client->powerstate);
  158. }
  159. static ssize_t jspower_store(struct device *dev,struct device_attribute *attr, const char *buf, size_t size)
  160. {
  161. int ctl=0;
  162. if(sscanf(buf,"%d",&ctl)==1)
  163. {
  164. printk("[%s]set power:%d\n", __func__, ctl);
  165. if(gspi_client)
  166. {
  167. if(ctl==0){
  168. js_set_power(0);
  169. }
  170. else if(ctl==1){
  171. js_set_power(1);
  172. }
  173. else if(ctl==2){
  174. js_set_power(2);
  175. }
  176. }
  177. }
  178. return size;
  179. }
  180. static ssize_t jsmem_show(struct device *dev,struct device_attribute *attr, char *buf)
  181. {
  182. return sprintf(buf, "%d\n", gspi_client->memfd);
  183. }
  184. static ssize_t jsmem_store(struct device *dev,struct device_attribute *attr, const char *buf, size_t count)
  185. {
  186. int ret;
  187. cp_buffer_t * inbuf;
  188. ret = kstrtoint(buf, 10, &gspi_client->memfd);
  189. if (ret < 0)
  190. return ret;
  191. mutex_lock(&gspi_client->js_sm_mutex);
  192. if (gspi_client->memfd == -1){
  193. if (IS_ERR_OR_NULL(gspi_client->vaddr))
  194. goto __end;
  195. d_packet_set_instance(NULL);
  196. dma_buf_kunmap(gspi_client->js_buf, 0, gspi_client->vaddr);
  197. dma_buf_end_cpu_access(gspi_client->js_buf, DMA_BIDIRECTIONAL);
  198. dma_buf_put(gspi_client->js_buf);
  199. gspi_client->vaddr = NULL;
  200. gspi_client->js_buf = NULL;
  201. }
  202. else
  203. {
  204. gspi_client->js_buf = dma_buf_get(gspi_client->memfd);
  205. if (IS_ERR_OR_NULL(gspi_client->js_buf)) {
  206. ret = -ENOMEM;
  207. pr_err("[%s]dma_buf_get failed for fd: %d\n", __func__, gspi_client->memfd);
  208. goto __end;
  209. }
  210. ret = dma_buf_begin_cpu_access(gspi_client->js_buf, DMA_BIDIRECTIONAL);
  211. if (ret) {
  212. pr_err("[%s]: dma_buf_begin_cpu_access failed\n", __func__);
  213. dma_buf_put(gspi_client->js_buf);
  214. gspi_client->js_buf = NULL;
  215. goto __end;
  216. }
  217. gspi_client->vsize = gspi_client->js_buf->size;
  218. gspi_client->vaddr = dma_buf_kmap(gspi_client->js_buf, 0);
  219. if (IS_ERR_OR_NULL(gspi_client->vaddr)) {
  220. dma_buf_end_cpu_access(gspi_client->js_buf, DMA_BIDIRECTIONAL);
  221. dma_buf_put(gspi_client->js_buf);
  222. gspi_client->js_buf = NULL;
  223. pr_err("[%s]dma_buf_kmap failed for fd: %d\n",__func__, gspi_client->memfd);
  224. goto __end;
  225. }
  226. inbuf=(cp_buffer_t *)gspi_client->vaddr;
  227. d_packet_set_instance(inbuf);
  228. }
  229. __end:
  230. mutex_unlock(&gspi_client->js_sm_mutex);
  231. return count;
  232. }
  233. static ssize_t jsoffset_show(struct device *dev,struct device_attribute *attr, char *buf)
  234. {
  235. return sprintf(buf, "%llu,%llu\n",gspi_client->tsoffset,gspi_client->tsoffsetmono);
  236. }
  237. static ssize_t jsrequest_show(struct device *dev,struct device_attribute *attr, char *buf)
  238. {
  239. unsigned int input = 0;
  240. acknowledge_t nordicAck;
  241. int size = 0;
  242. mutex_lock(&gspi_client->js_mutex);
  243. memset(&nordicAck, 0, sizeof(acknowledge_t));
  244. input = atomic_read(&gspi_client->nordicAcknowledge);
  245. atomic_set(&gspi_client->nordicAcknowledge, 0);
  246. nordicAck.acknowledgeHead.requestType = ((input&0x7f000000) >> 24);
  247. nordicAck.acknowledgeHead.ack = ((input&0x80000000) >> 31);
  248. nordicAck.acknowledgeData[0] = (input&0x000000ff);
  249. nordicAck.acknowledgeData[1] = ((input&0x0000ff00) >> 8);
  250. nordicAck.acknowledgeData[2] = ((input&0x00ff0000) >> 16);
  251. if (nordicAck.acknowledgeHead.ack == 1)
  252. {
  253. switch(nordicAck.acknowledgeHead.requestType)
  254. {
  255. case getMasterNordicVersionRequest:
  256. size = sprintf(buf, "masterNordic fwVersion:%d.%d\n", nordicAck.acknowledgeData[1], nordicAck.acknowledgeData[0]);
  257. break;
  258. case bondJoyStickRequest:
  259. case disconnectJoyStickRequest:
  260. case setVibStateRequest:
  261. case hostEnterDfuStateRequest:
  262. size = sprintf(buf, "requestType:%d ack:%d\n",nordicAck.acknowledgeHead.requestType, nordicAck.acknowledgeHead.ack);
  263. break;
  264. case getJoyStickBondStateRequest:
  265. gspi_client->JoyStickBondState = (nordicAck.acknowledgeData[0]&0x03);
  266. size = sprintf(buf, "left/right joyStick bond state:%d:%d\n", (gspi_client->JoyStickBondState&0x01), ((gspi_client->JoyStickBondState&0x02)>>1));
  267. break;
  268. case getLeftJoyStickProductNameRequest:
  269. size = sprintf(buf, "leftJoyStick productNameID:%d\n", nordicAck.acknowledgeData[0]);
  270. break;
  271. case getRightJoyStickProductNameRequest:
  272. size = sprintf(buf, "rightJoyStick productNameID:%d\n", nordicAck.acknowledgeData[0]);
  273. break;
  274. case getLeftJoyStickFwVersionRequest:
  275. size = sprintf(buf, "leftJoyStick fwVersion:%d.%d\n", nordicAck.acknowledgeData[1], nordicAck.acknowledgeData[0]);
  276. break;
  277. case getRightJoyStickFwVersionRequest:
  278. size = sprintf(buf, "rightJoyStick fwVersion:%d.%d\n", nordicAck.acknowledgeData[1], nordicAck.acknowledgeData[0]);
  279. break;
  280. default:
  281. size = sprintf(buf, "invalid requestType\n");
  282. break;
  283. }
  284. }
  285. else
  286. {
  287. size = sprintf(buf, "no need to ack\n");
  288. }
  289. mutex_unlock(&gspi_client->js_mutex);
  290. return size;
  291. }
  292. static ssize_t jsrequest_store(struct device *dev,struct device_attribute *attr, const char *buf, size_t size)
  293. {
  294. unsigned int input = 0;
  295. request_t request;
  296. int vibState = 0;
  297. mutex_lock(&gspi_client->js_mutex);
  298. if(sscanf(buf, "%x", &input) == 1)
  299. {
  300. memset(&request, 0, sizeof(request_t));
  301. request.requestHead.requestType = ((input&0x7f000000) >> 24);
  302. request.requestData[0] = (input&0x000000ff);
  303. request.requestData[1] = (input&0x0000ff00);
  304. request.requestData[2] = (input&0x00ff0000);
  305. switch(request.requestHead.requestType)
  306. {
  307. case setVibStateRequest:
  308. vibState = ((request.requestData[1] << 8) | request.requestData[0]);
  309. if (vibState >= 0 && vibState <= 0xffff)
  310. {
  311. if(gspi_client) {
  312. atomic_set(&gspi_client->userRequest, input);
  313. atomic_inc(&gspi_client->dataflag);
  314. wake_up_interruptible(&gspi_client->wait_queue);
  315. }
  316. }
  317. else
  318. {
  319. printk("invalid vibState\n");
  320. memset(&gspi_client->userRequest, 0, sizeof(gspi_client->userRequest));
  321. }
  322. break;
  323. case getMasterNordicVersionRequest:
  324. case bondJoyStickRequest:
  325. case disconnectJoyStickRequest:
  326. case getJoyStickBondStateRequest:
  327. case hostEnterDfuStateRequest:
  328. case getLeftJoyStickProductNameRequest:
  329. case getRightJoyStickProductNameRequest:
  330. case getLeftJoyStickFwVersionRequest:
  331. case getRightJoyStickFwVersionRequest:
  332. if(gspi_client)
  333. {
  334. atomic_set(&gspi_client->userRequest, input);
  335. atomic_inc(&gspi_client->dataflag);
  336. wake_up_interruptible(&gspi_client->wait_queue);
  337. }
  338. break;
  339. default:
  340. printk("invalid requestType\n");
  341. memset(&gspi_client->userRequest, 0, sizeof(gspi_client->userRequest));
  342. return size;
  343. }
  344. }
  345. mutex_unlock(&gspi_client->js_mutex);
  346. return size;
  347. }
  348. //static DEVICE_ATTR(jsbond, S_IRUGO|S_IWUSR|S_IWGRP, jsbond_show, jsbond_store);
  349. static DEVICE_ATTR(jsmem, S_IRUGO|S_IWUSR|S_IWGRP, jsmem_show, jsmem_store);
  350. static DEVICE_ATTR(jspower, S_IRUGO|S_IWUSR|S_IWGRP, jspower_show, jspower_store); /*external for power ctl ,avold someone */
  351. static DEVICE_ATTR(jsoffset, S_IRUGO, jsoffset_show, NULL);
  352. static DEVICE_ATTR(jsrequest, S_IRUGO|S_IWUSR|S_IWGRP, jsrequest_show, jsrequest_store);
  353. static int js_spi_txfr(struct spi_device *spi, char *txbuf,char *rxbuf, int num_byte,uint64_t *tts)
  354. {
  355. int ret=0;
  356. struct spi_transfer txfr;
  357. struct spi_message msg;
  358. memset(&txfr, 0, sizeof(txfr));
  359. txfr.tx_buf = txbuf;
  360. txfr.rx_buf = rxbuf;
  361. txfr.len = num_byte;
  362. spi_message_init(&msg);
  363. spi_message_add_tail(&txfr, &msg);
  364. *tts=ktime_to_ns(ktime_get_boottime());
  365. ret=spi_sync(spi, &msg);
  366. if(ret<0)
  367. {
  368. pr_err(" js xfr err=%d \n",ret);
  369. }
  370. return ret;
  371. }
  372. #define XFR_SIZE 188
  373. int js_thread(void *data)
  374. {
  375. int ret;
  376. unsigned char *pbuf;
  377. uint64_t tts;
  378. uint32_t tth[8];
  379. uint64_t tto[8];
  380. int num = 0;
  381. int pksz = 0;
  382. int index = 0;
  383. uint32_t hosttime;
  384. bool skiprport = false;
  385. unsigned int input = 0;
  386. request_t currentRequest;
  387. static request_t lastRequest;
  388. acknowledge_t nordicAck;
  389. uint8_t val = 0;
  390. struct js_spi_client *spi_client=(struct js_spi_client *)data;
  391. struct sched_param param = {
  392. .sched_priority = 88
  393. };
  394. sched_setscheduler(current, SCHED_RR, &param);
  395. //set_current_state(TASK_INTERRUPTIBLE);
  396. pr_err(" js_thread start \n");
  397. do {
  398. skiprport = false;
  399. ret = wait_event_interruptible(spi_client->wait_queue, atomic_read(&spi_client->dataflag) || kthread_should_stop());
  400. if ((ret < 0) || kthread_should_stop()) {
  401. pr_err("%s: exit\n", __func__);
  402. break;
  403. }
  404. atomic_set(&spi_client->dataflag, 0);
  405. if(spi_client->powerstate != 1){
  406. msleep(100);
  407. continue;
  408. }
  409. input = (unsigned int)atomic_read(&gspi_client->userRequest);
  410. val = gpio_get_value(spi_client->js_irq_gpio);
  411. if(val == 0 && input == 0) //Filter out the exception trigger
  412. {
  413. continue;
  414. }
  415. memset(&currentRequest, 0, sizeof(request_t));
  416. currentRequest.requestHead.needAck = ((input&0x80000000) >> 31);
  417. currentRequest.requestHead.requestType = ((input&0x7f000000) >> 24);
  418. currentRequest.requestData[0] = (input&0x000000ff);
  419. currentRequest.requestData[1] = ((input&0x0000ff00) >> 8);
  420. currentRequest.requestData[2] = ((input&0x00ff0000) >> 16);
  421. memset(spi_client->txbuffer, 0, sizeof(spi_client->txbuffer));
  422. memset(spi_client->rxbuffer, 0, sizeof(spi_client->rxbuffer));
  423. spi_client->txbuffer[0] = CMD_REQUEST_TAG;
  424. spi_client->txbuffer[1] = ((currentRequest.requestHead.needAck << 7)|currentRequest.requestHead.requestType);
  425. switch(currentRequest.requestHead.requestType)
  426. {
  427. case setVibStateRequest:
  428. spi_client->txbuffer[2] = currentRequest.requestData[0];
  429. spi_client->txbuffer[3] = currentRequest.requestData[1];
  430. break;
  431. case bondJoyStickRequest:
  432. case disconnectJoyStickRequest:
  433. spi_client->txbuffer[2] = (currentRequest.requestData[0]&0x01);
  434. break;
  435. default:
  436. break;
  437. }
  438. if(spi_client->powerstate == 1)
  439. {
  440. ret = js_spi_txfr(spi_client->spi_client, spi_client->txbuffer, spi_client->rxbuffer, XFR_SIZE, &tts);
  441. if (ret != 0)
  442. continue;
  443. }
  444. else
  445. {
  446. continue;
  447. }
  448. if (spi_client->rxbuffer[4] == 0xff) //Filtering dirty Data
  449. {
  450. continue;
  451. }
  452. if(lastRequest.requestHead.needAck == 1)
  453. {
  454. memset(&nordicAck, 0, sizeof(acknowledge_t));
  455. nordicAck.acknowledgeHead.ack = ((spi_client->rxbuffer[0]&0x80)>>7);
  456. nordicAck.acknowledgeHead.requestType = (spi_client->rxbuffer[0]&0x7f);
  457. nordicAck.acknowledgeData[0] = spi_client->rxbuffer[1];
  458. nordicAck.acknowledgeData[1] = spi_client->rxbuffer[2];
  459. nordicAck.acknowledgeData[2] = spi_client->rxbuffer[3];
  460. if (lastRequest.requestHead.requestType == nordicAck.acknowledgeHead.requestType)
  461. {
  462. unsigned int input = 0;
  463. input = ((spi_client->rxbuffer[0]<<24)|(spi_client->rxbuffer[3]<<16)|(spi_client->rxbuffer[2]<<8)|spi_client->rxbuffer[1]);
  464. atomic_set(&spi_client->nordicAcknowledge, input);
  465. }
  466. memset(&lastRequest, 0, sizeof(lastRequest));
  467. }
  468. if ((gspi_client->JoyStickBondState&0x03) != 0 && input == 0) //left or right joyStick are bound
  469. //if ((gspi_client->JoyStickBondState&0x03) != 0) //left or right joyStick are bound
  470. {
  471. pksz = spi_client->rxbuffer[4];
  472. num = spi_client->rxbuffer[5];
  473. if(num == 0 || pksz != 30)
  474. {
  475. //pr_err("wjx no joystick data\n");
  476. skiprport = true;
  477. }
  478. memcpy(&hosttime, &spi_client->rxbuffer[6], 4);
  479. tts = spi_client->tsHost;
  480. pbuf = &spi_client->rxbuffer[10];
  481. if(!skiprport){
  482. /*add Protection if someone release the memory */
  483. spin_lock(&gspi_client->smem_lock);
  484. for(index = 0; index < num; index++)
  485. {
  486. memcpy(&tth[index], pbuf, 4);
  487. tto[index] = tts-(hosttime-tth[index])*100000;
  488. if((u_packet)&&(spi_client->vaddr))
  489. {
  490. int8_t p_head;
  491. d_packet_t *pdata;
  492. p_head = (u_packet->p_head + 1) % MAX_PACK_SIZE;
  493. pdata = &u_packet->data[p_head];
  494. pdata->ts = tto[index];
  495. pdata->size = pksz - 4;
  496. memcpy((void*)pdata->data, (void*)(pbuf+4), pksz-4);
  497. u_packet->p_head = p_head;
  498. }
  499. pbuf += pksz;
  500. }
  501. spin_unlock(&gspi_client->smem_lock);
  502. }
  503. }
  504. if (currentRequest.requestHead.requestType != 0)
  505. atomic_set(&gspi_client->userRequest, 0);
  506. memcpy(&lastRequest, &currentRequest, sizeof(currentRequest));
  507. } while (1);
  508. return 0;
  509. }
  510. static int js_pinctrl_init(struct js_spi_client *spi_client)
  511. {
  512. int rc = 0;
  513. spi_client->pinctrl_info.pinctrl= devm_pinctrl_get(&spi_client->spi_client->dev);
  514. if (IS_ERR_OR_NULL(spi_client->pinctrl_info.pinctrl)) {
  515. rc = PTR_ERR(spi_client->pinctrl_info.pinctrl);
  516. pr_err("failed pinctrl, rc=%d\n", rc);
  517. goto error;
  518. }
  519. spi_client->pinctrl_info.active = pinctrl_lookup_state(spi_client->pinctrl_info.pinctrl, "js_default");
  520. if (IS_ERR_OR_NULL(spi_client->pinctrl_info.active)) {
  521. rc = PTR_ERR(spi_client->pinctrl_info.active);
  522. pr_err("failed pinctrl active state, rc=%d\n", rc);
  523. goto error;
  524. }
  525. spi_client->pinctrl_info.suspend =pinctrl_lookup_state(spi_client->pinctrl_info.pinctrl, "js_sleep");
  526. if (IS_ERR_OR_NULL(spi_client->pinctrl_info.suspend)) {
  527. rc = PTR_ERR(spi_client->pinctrl_info.suspend);
  528. pr_err("failed pinctrl suspend state, rc=%d\n", rc);
  529. goto error;
  530. }
  531. pr_err("js_pinctrl_init ok \n");
  532. error:
  533. return rc;
  534. }
  535. static int js_parse_gpios(struct js_spi_client *spi_client)
  536. {
  537. int rc = 0;
  538. struct device_node *of_node = spi_client->spi_client->dev.of_node;
  539. spi_client->js_lfen_gpio= of_get_named_gpio(of_node,"js,lfen-gpio", 0);
  540. if (!gpio_is_valid(spi_client->js_lfen_gpio)) {
  541. pr_err("failed get js_lfen_gpio gpio, rc=%d\n", rc);
  542. rc = -EINVAL;
  543. goto error;
  544. }
  545. #ifdef A11B_NRF
  546. spi_client->js_v33en_gpio= of_get_named_gpio(of_node,"js,v33en-gpio", 0);
  547. if (!gpio_is_valid(spi_client->js_v33en_gpio)) {
  548. pr_err("failed get js_v33en_gpio gpio, rc=%d\n", rc);
  549. rc = -EINVAL;
  550. goto error;
  551. }
  552. #endif
  553. spi_client->js_irq_gpio= of_get_named_gpio(of_node,"js,irq-gpio", 0);
  554. if (!gpio_is_valid(spi_client->js_irq_gpio)) {
  555. pr_err("failed get js_irq_gpio gpio, rc=%d\n", rc);
  556. rc = -EINVAL;
  557. goto error;
  558. }
  559. /*not used now*/
  560. spi_client->js_ledl_gpio= of_get_named_gpio(of_node,"js,ledl", 0);
  561. if (!gpio_is_valid(spi_client->js_ledl_gpio)) {
  562. pr_err("failed get js_ledl_gpio gpio, rc=%d\n", rc);
  563. }
  564. spi_client->js_ledr_gpio= of_get_named_gpio(of_node,"js,ledr", 0);
  565. if (!gpio_is_valid(spi_client->js_ledr_gpio)) {
  566. pr_err("failed get js_ledr_gpio gpio, rc=%d\n", rc);
  567. }
  568. spi_client->js_rled_en_gpio= of_get_named_gpio(of_node,"js,tst1", 0);
  569. if (!gpio_is_valid(spi_client->js_rled_en_gpio)) {
  570. pr_err("failed get js_rled_en_gpio gpio, rc=%d\n", rc);
  571. rc = -EINVAL;
  572. goto error;
  573. }
  574. spi_client->js_tst2_gpio= of_get_named_gpio(of_node,"js,tst2", 0);
  575. if (!gpio_is_valid(spi_client->js_tst2_gpio)) {
  576. pr_err("failed get js_tst2_gpio gpio, rc=%d\n", rc);
  577. }
  578. spi_client->js_dfu_en_gpio= of_get_named_gpio(of_node,"js,tst3", 0);
  579. if (!gpio_is_valid(spi_client->js_dfu_en_gpio)) {
  580. pr_err("failed get js_dfu_en_gpio gpio, rc=%d\n", rc);
  581. }
  582. spi_client->js_v02a_rled_right_en_gpio= of_get_named_gpio(of_node,"js,tst4", 0);
  583. if (!gpio_is_valid(spi_client->js_v02a_rled_right_en_gpio)) {
  584. pr_err("failed get js_v02a_rled_right_en_gpio gpio, rc=%d\n", rc);
  585. }
  586. //tst
  587. pr_err("js_parse_gpios ok \n");
  588. error:
  589. return rc;
  590. }
  591. static int js_gpio_request(struct js_spi_client *spi_client)
  592. {
  593. int rc = 0;
  594. if (gpio_is_valid(spi_client->js_lfen_gpio)) {
  595. pr_err("request for js_lfen_gpio =%d ", spi_client->js_lfen_gpio);
  596. rc = gpio_request(spi_client->js_lfen_gpio, "js_lfen_gpio");
  597. if (rc) {
  598. pr_err("request for js_lfen_gpio failed, rc=%d\n", rc);
  599. goto error;
  600. }
  601. }
  602. #ifdef A11B_NRF
  603. if (gpio_is_valid(spi_client->js_v33en_gpio)) {
  604. pr_err("request for js_v33en_gpio =%d ", spi_client->js_v33en_gpio);
  605. rc = gpio_request(spi_client->js_v33en_gpio, "js_v33en_gpio");
  606. if (rc) {
  607. pr_err("request for js_v33en_gpio failed, rc=%d\n", rc);
  608. goto error;
  609. }
  610. }
  611. #endif
  612. if (gpio_is_valid(spi_client->js_irq_gpio)) {
  613. pr_err("request for js_irq_gpio =%d ", spi_client->js_irq_gpio);
  614. rc = gpio_request(spi_client->js_irq_gpio, "js_irq_gpio");
  615. if (rc) {
  616. pr_err("request for js_irq_gpio failed, rc=%d\n", rc);
  617. goto error;
  618. }
  619. }
  620. if (gpio_is_valid(spi_client->js_ledl_gpio)) {
  621. pr_err("request for js_ledl_gpio =%d ", spi_client->js_ledl_gpio);
  622. rc = gpio_request(spi_client->js_ledl_gpio, "js_ledl_gpio");
  623. if (rc) {
  624. pr_err("request for js_ledl_gpio failed, rc=%d\n", rc);
  625. }
  626. else
  627. gpio_direction_output(spi_client->js_ledl_gpio,1);
  628. }
  629. if (gpio_is_valid(spi_client->js_ledr_gpio)) {
  630. pr_err("request for js_ledr_gpio =%d ", spi_client->js_ledr_gpio);
  631. rc = gpio_request(spi_client->js_ledr_gpio, "js_ledr_gpio");
  632. if (rc) {
  633. pr_err("request for js_ledr_gpio failed, rc=%d\n", rc);
  634. }
  635. else
  636. gpio_direction_output(spi_client->js_ledr_gpio,1);
  637. }
  638. if (gpio_is_valid(spi_client->js_rled_en_gpio)) {
  639. pr_err("request for js_rled_en_gpio =%d ", spi_client->js_rled_en_gpio);
  640. rc = gpio_request(spi_client->js_rled_en_gpio, "js_rled_en_gpio");
  641. if (rc) {
  642. pr_err("request for js_rled_en_gpio failed, rc=%d\n", rc);
  643. goto error;
  644. }
  645. gpio_direction_output(spi_client->js_rled_en_gpio,0);
  646. }
  647. if (gpio_is_valid(spi_client->js_tst2_gpio)) {
  648. pr_err("request for js_tst2_gpio =%d ", spi_client->js_tst2_gpio);
  649. rc = gpio_request(spi_client->js_tst2_gpio, "js_tst2_gpio");
  650. if (rc) {
  651. pr_err("request for js_tst2_gpio failed, rc=%d\n", rc);
  652. }
  653. else
  654. gpio_direction_input(spi_client->js_tst2_gpio);
  655. }
  656. if (gpio_is_valid(spi_client->js_dfu_en_gpio)) {
  657. pr_err("request for js_dfu_en_gpio =%d ", spi_client->js_dfu_en_gpio);
  658. rc = gpio_request(spi_client->js_dfu_en_gpio, "js_dfu_en_gpio");
  659. if (rc) {
  660. pr_err("request for js_dfu_en_gpio failed, rc=%d\n", rc);
  661. }
  662. else
  663. gpio_direction_output(spi_client->js_dfu_en_gpio,0);
  664. }
  665. if (gpio_is_valid(spi_client->js_v02a_rled_right_en_gpio)) {
  666. pr_err("request for js_v02a_rled_right_en_gpio =%d ", spi_client->js_v02a_rled_right_en_gpio);
  667. rc = gpio_request(spi_client->js_v02a_rled_right_en_gpio, "js_v02a_rled_right_en_gpio");
  668. if (rc) {
  669. pr_err("request for js_v02a_rled_right_en_gpio failed, rc=%d\n", rc);
  670. }
  671. else
  672. gpio_direction_output(spi_client->js_v02a_rled_right_en_gpio,0);
  673. //gpio_direction_input(spi_client->js_v02a_rled_right_en_gpio);
  674. }
  675. pr_err("js_gpio_request ok \n");
  676. error:
  677. return rc;
  678. }
  679. static irqreturn_t js_irq_handler(int irq, void *dev_id)
  680. {
  681. int val = 0;
  682. struct js_spi_client *spi_client = (struct js_spi_client *)dev_id;
  683. if(spi_client->powerstate==1)
  684. {
  685. val = gpio_get_value(spi_client->js_irq_gpio);
  686. if(val == 1)
  687. {
  688. //disable_irq_nosync(spi_client->js_irq);
  689. spi_client->tsHost=ktime_to_ns(ktime_get_boottime());
  690. atomic_inc(&spi_client->dataflag);
  691. wake_up_interruptible(&spi_client->wait_queue);
  692. }
  693. }
  694. return IRQ_HANDLED;
  695. }
  696. static int js_io_init(struct js_spi_client *spi_client)
  697. {
  698. int ret;
  699. int rc = 0;
  700. rc=pinctrl_select_state(spi_client->pinctrl_info.pinctrl ,spi_client->pinctrl_info.active);
  701. if (rc)
  702. pr_err("js failed to set pin state, rc=%d\n",rc);
  703. gpio_direction_output(spi_client->js_dfu_en_gpio,1);
  704. gpio_direction_output(spi_client->js_v02a_rled_right_en_gpio,0);
  705. gpio_direction_input(spi_client->js_irq_gpio);
  706. gpio_direction_output(spi_client->js_lfen_gpio,0);
  707. #ifdef A11B_NRF
  708. gpio_direction_output(spi_client->js_v33en_gpio,0);
  709. #endif
  710. gpio_direction_output(spi_client->js_lfen_gpio,0);
  711. spi_client->powerstate=0;
  712. spi_client->js_lstate=1;
  713. spi_client->js_rstate=1;
  714. spi_client->js_irq = gpio_to_irq(spi_client->js_irq_gpio);
  715. if (spi_client->js_irq < 0) {
  716. spi_client->js_irq=-1;
  717. pr_err(" js gpio_to_irq err\n");
  718. }
  719. else{
  720. ret = request_irq(spi_client->js_irq, js_irq_handler,IRQF_TRIGGER_RISING, "js", spi_client);//IRQF_TRIGGER_FALLING
  721. disable_irq_nosync(spi_client->js_irq);
  722. if(ret<0)
  723. pr_err("js request_irq err =%d \n",spi_client->js_irq);
  724. else
  725. pr_err("js request_irq =%d\n",spi_client->js_irq);
  726. }
  727. pr_err(" js_io_init ok\n");
  728. return 0;
  729. }
  730. /*
  731. note:
  732. this fuction used for :
  733. 1 notify to JoyStick the trig rled
  734. 2 . sync offset for android user space used to synctime .
  735. */
  736. static void glass_private_ep_callback(struct urb *urb)
  737. {
  738. struct js_spi_client *client;
  739. client = urb->context;
  740. if(urb->status==0) {
  741. if(gspi_client->js_lstate)
  742. gpio_set_value(client->js_rled_en_gpio,1);
  743. if(gspi_client->js_rstate)
  744. gpio_set_value(client->js_v02a_rled_right_en_gpio,1);
  745. if(checkoutpoint==0){
  746. gspi_client->tsSyncPt=ktime_to_ns(ktime_get_boottime());
  747. gspi_client->tsSyncPtmono=ktime_to_ns(ktime_get());
  748. memcpy(&(gspi_client->tshmd_tmp),(void *)(client->ubuffer),4);
  749. gspi_client->SyncPtFlag=1;
  750. }
  751. hrtimer_start( &client->hr_timer, client->ktime, HRTIMER_MODE_REL );
  752. }
  753. else
  754. pr_err("js notify_pri_callback err\n");
  755. schedule_work(&client->work);
  756. }
  757. enum hrtimer_restart timecallback( struct hrtimer *timer )
  758. {
  759. struct js_spi_client *spi_client;
  760. spi_client = container_of(timer, struct js_spi_client ,hr_timer);
  761. gpio_set_value(spi_client->js_rled_en_gpio,0);
  762. gpio_set_value(spi_client->js_v02a_rled_right_en_gpio,0);
  763. return HRTIMER_NORESTART;
  764. }
  765. static int glass_private_chanel_probe(struct usb_interface *intf,const struct usb_device_id *id)
  766. {
  767. int ret =0;
  768. struct js_spi_client *client;
  769. int maxpacket;
  770. if(gspi_client==NULL)
  771. return -ENOMEM;
  772. client =gspi_client;
  773. client->udev = interface_to_usbdev(intf);
  774. client->desc = intf->cur_altsetting;
  775. if (client->desc->desc.bNumEndpoints != 1){
  776. pr_err("js bNumEndpoints err \n");
  777. return -1;
  778. }
  779. client->endpoint= &client->desc->endpoint[0].desc;
  780. if (!usb_endpoint_is_int_in( client->endpoint)){
  781. pr_err("js not ep \n");
  782. return -1;
  783. }
  784. usb_set_intfdata(intf, client);
  785. client->intf = intf;
  786. client->urb = usb_alloc_urb(0, GFP_KERNEL);
  787. if (!client->urb){
  788. return -ENOMEM;
  789. }
  790. client->pipe = usb_rcvintpipe(client->udev, client->endpoint->bEndpointAddress);
  791. maxpacket = usb_maxpacket(client->udev, client->pipe, usb_pipeout(client->pipe));
  792. usb_fill_int_urb(client->urb, client->udev, client->pipe, client->ubuffer, maxpacket,glass_private_ep_callback, client, client->endpoint->bInterval);
  793. atomic_set(&client->urbstate, 1);
  794. ret = usb_submit_urb(client->urb, GFP_KERNEL);
  795. if (ret < 0) {
  796. pr_err("js usb_submit_urb err =%d \n",ret);
  797. usb_free_urb(client->urb);
  798. return ret ;
  799. }
  800. client->tsoffset=0;
  801. client->tsoffsetmono=0;
  802. checkoutpoint=0;
  803. return ret;
  804. }
  805. static void glass_private_chanel_disconnect(struct usb_interface *intf)
  806. {
  807. struct js_spi_client *client;
  808. client = usb_get_intfdata(intf);
  809. client->tsoffset=0;
  810. client->tsoffsetmono=0;
  811. atomic_set(&client->urbstate, 0);
  812. usb_poison_urb(client->urb);
  813. usb_free_urb(client->urb);
  814. checkoutpoint=0;
  815. }
  816. static int glass_private_chanel_ioctl(struct usb_interface *intf, unsigned int code, void *user_data)
  817. {
  818. // todo if need
  819. return -ENOSYS;
  820. }
  821. static const struct usb_device_id yc_id_table[] = {
  822. { .match_flags = USB_DEVICE_ID_MATCH_DEVICE|USB_DEVICE_ID_MATCH_INT_CLASS,
  823. .idVendor = 0x045e,
  824. .idProduct = 0x0659,
  825. .bInterfaceClass = 0xfe},
  826. { }
  827. };
  828. MODULE_DEVICE_TABLE(usb, hub_id_table);
  829. static struct usb_driver pri_driver = {
  830. .name = "yc",
  831. .probe = glass_private_chanel_probe,
  832. .disconnect = glass_private_chanel_disconnect,
  833. .unlocked_ioctl = glass_private_chanel_ioctl,
  834. .id_table = yc_id_table,
  835. };
  836. /*note : used to calculate time offset for app use
  837. move from irq to work for irq perfermance .
  838. */
  839. static void ts_offset_update_event(struct work_struct *pwork)
  840. {
  841. struct js_spi_client *client = container_of(pwork, struct js_spi_client, work);
  842. int check= atomic_read(&client->urbstate);
  843. if(check==0) return;
  844. usb_submit_urb(client->urb, GFP_KERNEL);
  845. if(gspi_client->SyncPtFlag==1){
  846. gspi_client->SyncPtFlag=0;
  847. gspi_client->tsoffset = gspi_client->tsSyncPt-300000 - (uint64_t)(gspi_client->tshmd_tmp)*1000000;
  848. gspi_client->tsoffsetmono = gspi_client->tsSyncPtmono-300000 - (uint64_t)(gspi_client->tshmd_tmp)*1000000;
  849. //pr_err("js: offset:=%llu adr =%llu, hmdts=%d\n",gspi_client->tsoffset,gspi_client->tsSyncPt,gspi_client->tshmd_tmp);
  850. }
  851. checkoutpoint++;
  852. if(checkoutpoint==30)
  853. checkoutpoint=0;
  854. }
  855. static int js_spi_setup(struct spi_device *spi)
  856. {
  857. struct js_spi_client *spi_client;
  858. int rc = 0;
  859. pr_err("js js_spi_setup 1 \n");
  860. if((spi->dev.of_node)==NULL){
  861. pr_err("js failed to check of_node \n");
  862. return -ENOMEM;
  863. }
  864. pr_err("js js_spi_setup 2 \n");
  865. spi_client = kzalloc(sizeof(*spi_client), GFP_KERNEL);
  866. if (!spi_client) {
  867. pr_err("js failed to malloc \n");
  868. return -ENOMEM;
  869. }
  870. pr_err("js js_spi_setup 3 \n");
  871. spi_client->spi_client = spi;
  872. rc=js_parse_gpios(spi_client);
  873. if (rc) {
  874. pr_err("js failed to parse gpio, rc=%d\n", rc);
  875. goto spi_free;
  876. }
  877. rc =js_pinctrl_init(spi_client);
  878. if (rc) {
  879. pr_err("js failed to init pinctrl, rc=%d\n", rc);
  880. goto spi_free;
  881. }
  882. rc = js_gpio_request(spi_client);
  883. if (rc) {
  884. pr_err("js failed to request gpios, rc=%d\n",rc);
  885. goto spi_free;
  886. }
  887. atomic_set(&spi_client->dataflag, 0);
  888. atomic_set(&spi_client->userRequest, 0);
  889. atomic_set(&spi_client->nordicAcknowledge, 0);
  890. mutex_init(&(spi_client->js_mutex));
  891. mutex_init(&(spi_client->js_sm_mutex));
  892. spin_lock_init(&spi_client->smem_lock);
  893. init_waitqueue_head(&spi_client->wait_queue);
  894. dev_set_drvdata(&spi->dev, spi_client);
  895. device_create_file(&spi->dev, &dev_attr_jsmem);
  896. device_create_file(&spi->dev, &dev_attr_jspower);
  897. device_create_file(&spi->dev, &dev_attr_jsoffset);
  898. device_create_file(&spi->dev, &dev_attr_jsrequest);
  899. spi_client->suspend=false;
  900. spi_client->vaddr =NULL;
  901. spi_client->tsoffset=0;
  902. spi_client->tsoffsetmono=0;
  903. gspi_client = spi_client;
  904. spi_client->kthread =kthread_run(js_thread, spi_client, "jsthread");
  905. if (IS_ERR(spi_client->kthread))
  906. pr_err("js kernel_thread failed\r\n" );
  907. js_io_init(spi_client);
  908. spi_client->ktime = ktime_set(0, 200000);
  909. hrtimer_init( &spi_client->hr_timer, CLOCK_BOOTTIME, HRTIMER_MODE_REL);
  910. spi_client->hr_timer.function = timecallback;
  911. INIT_WORK(&spi_client->work, ts_offset_update_event);
  912. atomic_set(&spi_client->urbstate, 0);
  913. usb_register(&pri_driver);
  914. js_set_power(1);
  915. return rc;
  916. spi_free:
  917. kfree(spi_client);
  918. return rc;
  919. }
  920. static int js_spi_suspend(struct device *dev)
  921. {
  922. struct js_spi_client *spi_client;
  923. if (!dev)
  924. return -EINVAL;
  925. spi_client = dev_get_drvdata(dev);
  926. if (!spi_client)
  927. return -EINVAL;
  928. spi_client->suspend=true ;
  929. js_set_power(0);
  930. pr_err("js_spi_suspend\n");
  931. return 0;
  932. }
  933. /* v02a called by external module to trig the joystick rled */
  934. void external_ctl_gpio(u8 mask )
  935. {
  936. if(gspi_client)
  937. {
  938. if (gpio_is_valid(gspi_client->js_rled_en_gpio))
  939. {
  940. if(mask&0x01)
  941. gpio_set_value(gspi_client->js_rled_en_gpio,1);
  942. else
  943. gpio_set_value(gspi_client->js_rled_en_gpio,0);
  944. }
  945. if (gpio_is_valid(gspi_client->js_v02a_rled_right_en_gpio))
  946. {
  947. if(mask&0x02)
  948. gpio_set_value(gspi_client->js_v02a_rled_right_en_gpio,1);
  949. else
  950. gpio_set_value(gspi_client->js_v02a_rled_right_en_gpio,0);
  951. }
  952. }
  953. }
  954. static int js_spi_resume(struct device *dev)
  955. {
  956. struct js_spi_client *spi_client;
  957. if (!dev)
  958. return -EINVAL;
  959. spi_client = dev_get_drvdata(dev);
  960. if (!spi_client)
  961. return -EINVAL;
  962. js_set_power(1);
  963. spi_client->suspend=false;
  964. pr_err("[%s] exit\n", __func__);
  965. return 0;
  966. }
  967. static int js_spi_driver_probe(struct spi_device *spi)
  968. {
  969. int ret;
  970. pr_err("js_spi_driver_probe start");
  971. spi->bits_per_word = 8;
  972. spi->mode = SPI_MODE_0;
  973. spi->max_speed_hz = 8*1000*1000;
  974. ret=spi_setup(spi);
  975. if (ret < 0){
  976. pr_err("js spi_setup failed ret=%d",ret);
  977. return ret;
  978. }
  979. pr_err("js_spi_driver_probe ok");
  980. return js_spi_setup(spi);
  981. }
  982. static int js_spi_driver_remove(struct spi_device *sdev)
  983. {
  984. return 0;
  985. }
  986. static const struct of_device_id js_dt_match[] = {
  987. { .compatible = "yc,js" },
  988. { }
  989. };
  990. static const struct dev_pm_ops js_pm_ops = {
  991. SET_SYSTEM_SLEEP_PM_OPS(js_spi_suspend, js_spi_resume)
  992. };
  993. static struct spi_driver js_spi_driver = {
  994. .driver = {
  995. .name = "yc,js",
  996. .owner = THIS_MODULE,
  997. .of_match_table = js_dt_match,
  998. .pm = &js_pm_ops,
  999. },
  1000. .probe = js_spi_driver_probe,
  1001. .remove = js_spi_driver_remove,
  1002. //.suspend = js_spi_suspend,
  1003. //.resume = js_spi_resume,
  1004. };
  1005. static int __init js_driver_init(void)
  1006. {
  1007. int rc = 0;
  1008. pr_err("js_driver_init");
  1009. rc = spi_register_driver(&js_spi_driver);
  1010. if (rc < 0) {
  1011. pr_err("spi_register_driver failed rc = %d", rc);
  1012. return rc;
  1013. }
  1014. return rc;
  1015. }
  1016. static void __exit js_driver_exit(void)
  1017. {
  1018. spi_unregister_driver(&js_spi_driver);
  1019. }
  1020. module_init(js_driver_init); //late_initcall
  1021. module_exit(js_driver_exit);
  1022. MODULE_DESCRIPTION("joystick nordic52832 driver");
  1023. MODULE_LICENSE("GPL v2");