alsps.c 28 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079
  1. #include "inc/alsps.h"
  2. #include "inc/aal_control.h"
  3. struct alsps_context *alsps_context_obj = NULL;
  4. struct platform_device *pltfm_dev;
  5. static struct alsps_init_info *alsps_init_list[MAX_CHOOSE_ALSPS_NUM] = {0};
  6. static bool alsps_misc_dev_init;
  7. int als_data_report(struct input_dev *dev, int value, int status)
  8. {
  9. struct alsps_context *cxt = NULL;
  10. cxt = alsps_context_obj;
  11. /*ALSPS_LOG(" +als_data_report! %d, %d\n", value, status);*/
  12. /* force trigger data update after sensor enable. */
  13. if (cxt->is_get_valid_als_data_after_enable == false) {
  14. input_report_abs(dev, EVENT_TYPE_ALS_VALUE, value+1);
  15. cxt->is_get_valid_als_data_after_enable = true;
  16. }
  17. input_report_abs(dev, EVENT_TYPE_ALS_VALUE, value);
  18. input_report_abs(dev, EVENT_TYPE_ALS_STATUS, status);
  19. input_sync(dev);
  20. return 0;
  21. }
  22. int ps_data_report(struct input_dev *dev, int value, int status)
  23. {
  24. /* ALSPS_LOG("+ps_data_report! %d, %d\n",value,status); */
  25. input_report_rel(dev, EVENT_TYPE_PS_VALUE, (value+1));
  26. input_report_rel(dev, EVENT_TYPE_PS_STATUS, status);
  27. input_sync(dev);
  28. return 0;
  29. }
  30. static void als_work_func(struct work_struct *work)
  31. {
  32. struct alsps_context *cxt = NULL;
  33. int value, status;
  34. int64_t nt;
  35. struct timespec time;
  36. int err;
  37. cxt = alsps_context_obj;
  38. if (NULL == cxt->als_data.get_data) {
  39. ALSPS_ERR("alsps driver not register data path\n");
  40. return;
  41. }
  42. time.tv_sec = time.tv_nsec = 0;
  43. time = get_monotonic_coarse();
  44. nt = time.tv_sec*1000000000LL+time.tv_nsec;
  45. /* add wake lock to make sure data can be read before system suspend */
  46. err = cxt->als_data.get_data(&value, &status);
  47. if (err) {
  48. ALSPS_ERR("get alsps data fails!!\n");
  49. goto als_loop;
  50. } else {
  51. cxt->drv_data.als_data.values[0] = value;
  52. cxt->drv_data.als_data.status = status;
  53. cxt->drv_data.als_data.time = nt;
  54. }
  55. if (true == cxt->is_als_first_data_after_enable) {
  56. cxt->is_als_first_data_after_enable = false;
  57. /* filter -1 value */
  58. if (ALSPS_INVALID_VALUE == cxt->drv_data.als_data.values[0]) {
  59. ALSPS_LOG(" read invalid data\n");
  60. goto als_loop;
  61. }
  62. }
  63. ALSPS_LOG(" als data[%d]\n" , cxt->drv_data.als_data.values[0]);
  64. als_data_report(cxt->idev,
  65. cxt->drv_data.als_data.values[0],
  66. cxt->drv_data.als_data.status);
  67. als_loop:
  68. if (true == cxt->is_als_polling_run)
  69. mod_timer(&cxt->timer_als, jiffies + atomic_read(&cxt->delay_als)/(1000/HZ));
  70. }
  71. static void ps_work_func(struct work_struct *work)
  72. {
  73. struct alsps_context *cxt = NULL;
  74. int value, status;
  75. int64_t nt;
  76. struct timespec time;
  77. int err = 0;
  78. cxt = alsps_context_obj;
  79. if (NULL == cxt->ps_data.get_data) {
  80. ALSPS_ERR("alsps driver not register data path\n");
  81. return;
  82. }
  83. time.tv_sec = time.tv_nsec = 0;
  84. time = get_monotonic_coarse();
  85. nt = time.tv_sec*1000000000LL+time.tv_nsec;
  86. /* add wake lock to make sure data can be read before system suspend */
  87. err = cxt->ps_data.get_data(&value, &status);
  88. if (err) {
  89. ALSPS_ERR("get alsps data fails!!\n");
  90. goto ps_loop;
  91. } else {
  92. cxt->drv_data.ps_data.values[0] = value;
  93. cxt->drv_data.ps_data.status = status;
  94. cxt->drv_data.ps_data.time = nt;
  95. }
  96. if (true == cxt->is_ps_first_data_after_enable) {
  97. cxt->is_ps_first_data_after_enable = false;
  98. /* filter -1 value */
  99. if (ALSPS_INVALID_VALUE == cxt->drv_data.ps_data.values[0]) {
  100. ALSPS_LOG(" read invalid data\n");
  101. goto ps_loop;
  102. }
  103. }
  104. if (cxt->is_get_valid_ps_data_after_enable == false) {
  105. if (ALSPS_INVALID_VALUE != cxt->drv_data.ps_data.values[0])
  106. cxt->is_get_valid_ps_data_after_enable = true;
  107. }
  108. ps_data_report(cxt->idev,
  109. cxt->drv_data.ps_data.values[0],
  110. cxt->drv_data.ps_data.status);
  111. ps_loop:
  112. if (true == cxt->is_ps_polling_run) {
  113. if (cxt->ps_ctl.is_polling_mode || (cxt->is_get_valid_ps_data_after_enable == false))
  114. mod_timer(&cxt->timer_ps, jiffies + atomic_read(&cxt->delay_ps)/(1000/HZ));
  115. }
  116. }
  117. static void als_poll(unsigned long data)
  118. {
  119. struct alsps_context *obj = (struct alsps_context *)data;
  120. if ((obj != NULL) && (obj->is_als_polling_run))
  121. schedule_work(&obj->report_als);
  122. }
  123. static void ps_poll(unsigned long data)
  124. {
  125. struct alsps_context *obj = (struct alsps_context *)data;
  126. if (obj != NULL)
  127. schedule_work(&obj->report_ps);
  128. }
  129. static struct alsps_context *alsps_context_alloc_object(void)
  130. {
  131. struct alsps_context *obj = kzalloc(sizeof(*obj), GFP_KERNEL);
  132. ALSPS_LOG("alsps_context_alloc_object++++\n");
  133. if (!obj) {
  134. ALSPS_ERR("Alloc alsps object error!\n");
  135. return NULL;
  136. }
  137. atomic_set(&obj->delay_als, 200); /*5Hz, set work queue delay time 200ms */
  138. atomic_set(&obj->delay_ps, 200); /* 5Hz, set work queue delay time 200ms */
  139. atomic_set(&obj->wake, 0);
  140. INIT_WORK(&obj->report_als, als_work_func);
  141. INIT_WORK(&obj->report_ps, ps_work_func);
  142. init_timer(&obj->timer_als);
  143. init_timer(&obj->timer_ps);
  144. obj->timer_als.expires = jiffies + atomic_read(&obj->delay_als)/(1000/HZ);
  145. obj->timer_als.function = als_poll;
  146. obj->timer_als.data = (unsigned long)obj;
  147. obj->timer_ps.expires = jiffies + atomic_read(&obj->delay_ps)/(1000/HZ);
  148. obj->timer_ps.function = ps_poll;
  149. obj->timer_ps.data = (unsigned long)obj;
  150. obj->is_als_first_data_after_enable = false;
  151. obj->is_als_polling_run = false;
  152. obj->is_ps_first_data_after_enable = false;
  153. obj->is_ps_polling_run = false;
  154. mutex_init(&obj->alsps_op_mutex);
  155. obj->is_als_batch_enable = false;/* for batch mode init */
  156. obj->is_ps_batch_enable = false;/* for batch mode init */
  157. ALSPS_LOG("alsps_context_alloc_object----\n");
  158. return obj;
  159. }
  160. static int als_real_enable(int enable)
  161. {
  162. int err = 0;
  163. struct alsps_context *cxt = NULL;
  164. cxt = alsps_context_obj;
  165. if (1 == enable) {
  166. if (true == cxt->is_als_active_data || true == cxt->is_als_active_nodata) {
  167. err = cxt->als_ctl.enable_nodata(1);
  168. if (err)
  169. err = cxt->als_ctl.enable_nodata(1);
  170. if (err) {
  171. err = cxt->als_ctl.enable_nodata(1);
  172. if (err)
  173. ALSPS_ERR("alsps enable(%d) err 3 timers = %d\n", enable, err);
  174. }
  175. }
  176. ALSPS_LOG("alsps real enable\n");
  177. }
  178. if (0 == enable) {
  179. if (false == cxt->is_als_active_data && false == cxt->is_als_active_nodata) {
  180. ALSPS_LOG("AAL status is %d\n", aal_use);
  181. if (aal_use == 0) {
  182. err = cxt->als_ctl.enable_nodata(0);
  183. if (err)
  184. ALSPS_ERR("alsps enable(%d) err = %d\n", enable, err);
  185. }
  186. ALSPS_LOG("alsps real disable\n");
  187. }
  188. }
  189. return err;
  190. }
  191. static int als_enable_data(int enable)
  192. {
  193. struct alsps_context *cxt = NULL;
  194. cxt = alsps_context_obj;
  195. if (NULL == cxt->als_ctl.open_report_data) {
  196. ALSPS_ERR("no als control path\n");
  197. return -1;
  198. }
  199. if (1 == enable) {
  200. ALSPS_LOG("ALSPS enable data\n");
  201. cxt->is_als_active_data = true;
  202. cxt->is_als_first_data_after_enable = true;
  203. cxt->als_ctl.open_report_data(1);
  204. als_real_enable(enable);
  205. if (false == cxt->is_als_polling_run && cxt->is_als_batch_enable == false) {
  206. if (false == cxt->als_ctl.is_report_input_direct) {
  207. cxt->is_get_valid_als_data_after_enable = false;
  208. mod_timer(&cxt->timer_als, jiffies + atomic_read(&cxt->delay_als)/(1000/HZ));
  209. cxt->is_als_polling_run = true;
  210. }
  211. }
  212. }
  213. if (0 == enable) {
  214. ALSPS_LOG("ALSPS disable\n");
  215. cxt->is_als_active_data = false;
  216. cxt->als_ctl.open_report_data(0);
  217. if (true == cxt->is_als_polling_run) {
  218. if (false == cxt->als_ctl.is_report_input_direct) {
  219. cxt->is_als_polling_run = false;
  220. smp_mb();/* for memory barrier */
  221. del_timer_sync(&cxt->timer_als);
  222. smp_mb();/* for memory barrier */
  223. cancel_work_sync(&cxt->report_als);
  224. cxt->drv_data.als_data.values[0] = ALSPS_INVALID_VALUE;
  225. }
  226. }
  227. als_real_enable(enable);
  228. }
  229. return 0;
  230. }
  231. static int ps_real_enable(int enable)
  232. {
  233. int err = 0;
  234. struct alsps_context *cxt = NULL;
  235. cxt = alsps_context_obj;
  236. if (1 == enable) {
  237. if (true == cxt->is_ps_active_data || true == cxt->is_ps_active_nodata) {
  238. err = cxt->ps_ctl.enable_nodata(1);
  239. if (err) {
  240. err = cxt->ps_ctl.enable_nodata(1);
  241. if (err) {
  242. err = cxt->ps_ctl.enable_nodata(1);
  243. if (err)
  244. ALSPS_ERR("ps enable(%d) err 3 timers = %d\n", enable, err);
  245. }
  246. }
  247. ALSPS_LOG("ps real enable\n");
  248. }
  249. }
  250. if (0 == enable) {
  251. if (false == cxt->is_ps_active_data && false == cxt->is_ps_active_nodata) {
  252. err = cxt->ps_ctl.enable_nodata(0);
  253. if (err)
  254. ALSPS_ERR("ps enable(%d) err = %d\n", enable, err);
  255. ALSPS_LOG("ps real disable\n");
  256. }
  257. }
  258. return err;
  259. }
  260. static int ps_enable_data(int enable)
  261. {
  262. struct alsps_context *cxt = NULL;
  263. cxt = alsps_context_obj;
  264. if (NULL == cxt->ps_ctl.open_report_data) {
  265. ALSPS_ERR("no ps control path\n");
  266. return -1;
  267. }
  268. if (1 == enable) {
  269. ALSPS_LOG("PS enable data\n");
  270. cxt->is_ps_active_data = true;
  271. cxt->is_ps_first_data_after_enable = true;
  272. cxt->ps_ctl.open_report_data(1);
  273. ps_real_enable(enable);
  274. if (false == cxt->is_ps_polling_run && cxt->is_ps_batch_enable == false) {
  275. if (false == cxt->ps_ctl.is_report_input_direct) {
  276. mod_timer(&cxt->timer_ps, jiffies + atomic_read(&cxt->delay_ps)/(1000/HZ));
  277. cxt->is_ps_polling_run = true;
  278. cxt->is_get_valid_ps_data_after_enable = false;
  279. }
  280. }
  281. }
  282. if (0 == enable) {
  283. ALSPS_LOG("PS disable\n");
  284. cxt->is_ps_active_data = false;
  285. cxt->ps_ctl.open_report_data(0);
  286. if (true == cxt->is_ps_polling_run) {
  287. if (false == cxt->ps_ctl.is_report_input_direct) {
  288. cxt->is_ps_polling_run = false;
  289. smp_mb();/* for memory barrier*/
  290. del_timer_sync(&cxt->timer_ps);
  291. smp_mb();/* for memory barrier*/
  292. cancel_work_sync(&cxt->report_ps);
  293. cxt->drv_data.ps_data.values[0] = ALSPS_INVALID_VALUE;
  294. }
  295. }
  296. ps_real_enable(enable);
  297. }
  298. return 0;
  299. }
  300. static ssize_t als_store_active(struct device *dev, struct device_attribute *attr,
  301. const char *buf, size_t count)
  302. {
  303. struct alsps_context *cxt = NULL;
  304. ALSPS_LOG("als_store_active buf=%s\n", buf);
  305. mutex_lock(&alsps_context_obj->alsps_op_mutex);
  306. cxt = alsps_context_obj;
  307. if (!strncmp(buf, "1", 1))
  308. als_enable_data(1);
  309. else if (!strncmp(buf, "0", 1))
  310. als_enable_data(0);
  311. else
  312. ALSPS_ERR(" alsps_store_active error !!\n");
  313. mutex_unlock(&alsps_context_obj->alsps_op_mutex);
  314. ALSPS_LOG(" alsps_store_active done\n");
  315. return count;
  316. }
  317. /*----------------------------------------------------------------------------*/
  318. static ssize_t als_show_active(struct device *dev,
  319. struct device_attribute *attr, char *buf)
  320. {
  321. struct alsps_context *cxt = NULL;
  322. int div = 0;
  323. cxt = alsps_context_obj;
  324. div = cxt->als_data.vender_div;
  325. ALSPS_LOG("als vender_div value: %d\n", div);
  326. return snprintf(buf, PAGE_SIZE, "%d\n", div);
  327. }
  328. static ssize_t als_store_delay(struct device *dev, struct device_attribute *attr,
  329. const char *buf, size_t count)
  330. {
  331. int delay;
  332. int mdelay = 0;
  333. int ret = 0;
  334. struct alsps_context *cxt = NULL;
  335. mutex_lock(&alsps_context_obj->alsps_op_mutex);
  336. cxt = alsps_context_obj;
  337. if (NULL == cxt->als_ctl.set_delay) {
  338. ALSPS_LOG("als_ctl set_delay NULL\n");
  339. mutex_unlock(&alsps_context_obj->alsps_op_mutex);
  340. return count;
  341. }
  342. ret = kstrtoint(buf, 10, &delay);
  343. if (0 != ret) {
  344. ALSPS_ERR("invalid format!!\n");
  345. mutex_unlock(&alsps_context_obj->alsps_op_mutex);
  346. return count;
  347. }
  348. if (false == cxt->als_ctl.is_report_input_direct) {
  349. mdelay = (int)delay/1000/1000;
  350. atomic_set(&alsps_context_obj->delay_als, mdelay);
  351. }
  352. cxt->als_ctl.set_delay(delay);
  353. ALSPS_LOG(" als_delay %d ns\n", delay);
  354. mutex_unlock(&alsps_context_obj->alsps_op_mutex);
  355. return count;
  356. }
  357. static ssize_t als_show_delay(struct device *dev,
  358. struct device_attribute *attr, char *buf)
  359. {
  360. int len = 0;
  361. ALSPS_LOG(" not support now\n");
  362. return len;
  363. }
  364. static ssize_t als_store_batch(struct device *dev, struct device_attribute *attr,
  365. const char *buf, size_t count)
  366. {
  367. struct alsps_context *cxt = NULL;
  368. ALSPS_LOG("als_store_batch buf=%s\n", buf);
  369. mutex_lock(&alsps_context_obj->alsps_op_mutex);
  370. cxt = alsps_context_obj;
  371. if (cxt->als_ctl.is_support_batch) {
  372. if (!strncmp(buf, "1", 1)) {
  373. cxt->is_als_batch_enable = true;
  374. if (true == cxt->is_als_polling_run) {
  375. cxt->is_als_polling_run = false;
  376. del_timer_sync(&cxt->timer_als);
  377. cancel_work_sync(&cxt->report_als);
  378. cxt->drv_data.als_data.values[0] = ALSPS_INVALID_VALUE;
  379. cxt->drv_data.als_data.values[1] = ALSPS_INVALID_VALUE;
  380. cxt->drv_data.als_data.values[2] = ALSPS_INVALID_VALUE;
  381. }
  382. } else if (!strncmp(buf, "0", 1)) {
  383. cxt->is_als_batch_enable = false;
  384. if (false == cxt->is_als_polling_run) {
  385. if (false == cxt->als_ctl.is_report_input_direct) {
  386. cxt->is_get_valid_als_data_after_enable = false;
  387. mod_timer(&cxt->timer_als, jiffies + atomic_read(&cxt->delay_als)/(1000/HZ));
  388. cxt->is_als_polling_run = true;
  389. }
  390. }
  391. } else
  392. ALSPS_ERR(" als_store_batch error !!\n");
  393. } else
  394. ALSPS_LOG(" als_store_batch not supported\n");
  395. mutex_unlock(&alsps_context_obj->alsps_op_mutex);
  396. ALSPS_LOG(" als_store_batch done: %d\n", cxt->is_als_batch_enable);
  397. return count;
  398. }
  399. static ssize_t als_show_batch(struct device *dev,
  400. struct device_attribute *attr, char *buf)
  401. {
  402. return snprintf(buf, PAGE_SIZE, "%d\n", 0);
  403. }
  404. static ssize_t als_store_flush(struct device *dev, struct device_attribute *attr,
  405. const char *buf, size_t count)
  406. {
  407. return count;
  408. }
  409. static ssize_t als_show_flush(struct device *dev,
  410. struct device_attribute *attr, char *buf)
  411. {
  412. return snprintf(buf, PAGE_SIZE, "%d\n", 0);
  413. }
  414. /* need work around again */
  415. static ssize_t als_show_devnum(struct device *dev,
  416. struct device_attribute *attr, char *buf)
  417. {
  418. unsigned int devnum;
  419. const char *devname = NULL;
  420. int ret;
  421. devname = dev_name(&alsps_context_obj->idev->dev);
  422. ret = sscanf(devname+5, "%d", &devnum);
  423. return snprintf(buf, PAGE_SIZE, "%d\n", devnum);
  424. }
  425. static ssize_t ps_store_active(struct device *dev, struct device_attribute *attr,
  426. const char *buf, size_t count)
  427. {
  428. struct alsps_context *cxt = NULL;
  429. ALSPS_LOG("ps_store_active buf=%s\n", buf);
  430. mutex_lock(&alsps_context_obj->alsps_op_mutex);
  431. cxt = alsps_context_obj;
  432. if (!strncmp(buf, "1", 1))
  433. ps_enable_data(1);
  434. else if (!strncmp(buf, "0", 1))
  435. ps_enable_data(0);
  436. else
  437. ALSPS_ERR(" ps_store_active error !!\n");
  438. mutex_unlock(&alsps_context_obj->alsps_op_mutex);
  439. ALSPS_LOG(" ps_store_active done\n");
  440. return count;
  441. }
  442. /*----------------------------------------------------------------------------*/
  443. static ssize_t ps_show_active(struct device *dev,
  444. struct device_attribute *attr, char *buf)
  445. {
  446. struct alsps_context *cxt = NULL;
  447. int div = 0;
  448. cxt = alsps_context_obj;
  449. div = cxt->ps_data.vender_div;
  450. ALSPS_LOG("ps vender_div value: %d\n", div);
  451. return snprintf(buf, PAGE_SIZE, "%d\n", div);
  452. }
  453. static ssize_t ps_store_delay(struct device *dev, struct device_attribute *attr,
  454. const char *buf, size_t count)
  455. {
  456. int delay;
  457. int mdelay = 0;
  458. int ret = 0;
  459. struct alsps_context *cxt = NULL;
  460. mutex_lock(&alsps_context_obj->alsps_op_mutex);
  461. cxt = alsps_context_obj;
  462. if (NULL == cxt->ps_ctl.set_delay) {
  463. ALSPS_LOG("ps_ctl set_delay NULL\n");
  464. mutex_unlock(&alsps_context_obj->alsps_op_mutex);
  465. return count;
  466. }
  467. ret = kstrtoint(buf, 10, &delay);
  468. if (0 != ret) {
  469. ALSPS_ERR("invalid format!!\n");
  470. mutex_unlock(&alsps_context_obj->alsps_op_mutex);
  471. return count;
  472. }
  473. if (false == cxt->ps_ctl.is_report_input_direct) {
  474. mdelay = (int)delay/1000/1000;
  475. atomic_set(&alsps_context_obj->delay_ps, mdelay);
  476. }
  477. cxt->ps_ctl.set_delay(delay);
  478. ALSPS_LOG(" ps_delay %d ns\n", delay);
  479. mutex_unlock(&alsps_context_obj->alsps_op_mutex);
  480. return count;
  481. }
  482. static ssize_t ps_show_delay(struct device *dev,
  483. struct device_attribute *attr, char *buf)
  484. {
  485. int len = 0;
  486. ALSPS_LOG(" not support now\n");
  487. return len;
  488. }
  489. static ssize_t ps_store_batch(struct device *dev, struct device_attribute *attr,
  490. const char *buf, size_t count)
  491. {
  492. struct alsps_context *cxt = NULL;
  493. ALSPS_LOG("ps_store_batch buf=%s\n", buf);
  494. mutex_lock(&alsps_context_obj->alsps_op_mutex);
  495. cxt = alsps_context_obj;
  496. if (cxt->ps_ctl.is_support_batch) {
  497. if (!strncmp(buf, "1", 1)) {
  498. cxt->is_ps_batch_enable = true;
  499. if (true == cxt->is_ps_polling_run) {
  500. cxt->is_ps_polling_run = false;
  501. del_timer_sync(&cxt->timer_ps);
  502. cancel_work_sync(&cxt->report_ps);
  503. cxt->drv_data.ps_data.values[0] = ALSPS_INVALID_VALUE;
  504. cxt->drv_data.ps_data.values[1] = ALSPS_INVALID_VALUE;
  505. cxt->drv_data.ps_data.values[2] = ALSPS_INVALID_VALUE;
  506. }
  507. } else if (!strncmp(buf, "0", 1)) {
  508. cxt->is_ps_batch_enable = false;
  509. if (false == cxt->is_ps_polling_run) {
  510. if (false == cxt->ps_ctl.is_report_input_direct) {
  511. mod_timer(&cxt->timer_ps, jiffies + atomic_read(&cxt->delay_ps)/(1000/HZ));
  512. cxt->is_ps_polling_run = true;
  513. cxt->is_get_valid_ps_data_after_enable = false;
  514. }
  515. }
  516. } else
  517. ALSPS_ERR(" ps_store_batch error !!\n");
  518. } else
  519. ALSPS_LOG(" ps_store_batch not supported\n");
  520. mutex_unlock(&alsps_context_obj->alsps_op_mutex);
  521. ALSPS_LOG(" ps_store_batch done: %d\n", cxt->is_ps_batch_enable);
  522. return count;
  523. }
  524. static ssize_t ps_show_batch(struct device *dev,
  525. struct device_attribute *attr, char *buf)
  526. {
  527. return snprintf(buf, PAGE_SIZE, "%d\n", 0);
  528. }
  529. static ssize_t ps_store_flush(struct device *dev, struct device_attribute *attr,
  530. const char *buf, size_t count)
  531. {
  532. return count;
  533. }
  534. static ssize_t ps_show_flush(struct device *dev,
  535. struct device_attribute *attr, char *buf)
  536. {
  537. return snprintf(buf, PAGE_SIZE, "%d\n", 0);
  538. }
  539. /* need work around again */
  540. static ssize_t ps_show_devnum(struct device *dev,
  541. struct device_attribute *attr, char *buf)
  542. {
  543. unsigned int devnum;
  544. const char *devname = NULL;
  545. int ret;
  546. devname = dev_name(&alsps_context_obj->idev->dev);
  547. ret = sscanf(devname+5, "%d", &devnum);
  548. return snprintf(buf, PAGE_SIZE, "%d\n", devnum);
  549. }
  550. static int als_ps_remove(struct platform_device *pdev)
  551. {
  552. ALSPS_LOG("als_ps_remove\n");
  553. return 0;
  554. }
  555. static int als_ps_probe(struct platform_device *pdev)
  556. {
  557. ALSPS_LOG("als_ps_probe\n");
  558. pltfm_dev = pdev;
  559. return 0;
  560. }
  561. #ifdef CONFIG_OF
  562. static const struct of_device_id als_ps_of_match[] = {
  563. {.compatible = "mediatek,als_ps",},
  564. {},
  565. };
  566. #endif
  567. static struct platform_driver als_ps_driver = {
  568. .probe = als_ps_probe,
  569. .remove = als_ps_remove,
  570. .driver = {
  571. .name = "als_ps",
  572. #ifdef CONFIG_OF
  573. .of_match_table = als_ps_of_match,
  574. #endif
  575. }
  576. };
  577. static int alsps_real_driver_init(void)
  578. {
  579. int i = 0;
  580. int err = 0;
  581. ALSPS_LOG(" alsps_real_driver_init +\n");
  582. for (i = 0; i < MAX_CHOOSE_ALSPS_NUM; i++) {
  583. ALSPS_LOG("alsps_real_driver_init i=%d\n", i);
  584. if (0 != alsps_init_list[i]) {
  585. ALSPS_LOG(" alsps try to init driver %s\n", alsps_init_list[i]->name);
  586. err = alsps_init_list[i]->init();
  587. if (0 == err) {
  588. ALSPS_LOG(" alsps real driver %s probe ok\n", alsps_init_list[i]->name);
  589. break;
  590. }
  591. }
  592. }
  593. if (i == MAX_CHOOSE_ALSPS_NUM) {
  594. ALSPS_LOG(" alsps_real_driver_init fail\n");
  595. err = -1;
  596. }
  597. return err;
  598. }
  599. int alsps_driver_add(struct alsps_init_info *obj)
  600. {
  601. int err = 0;
  602. int i = 0;
  603. ALSPS_FUN();
  604. if (!obj) {
  605. ALSPS_ERR("ALSPS driver add fail, alsps_init_info is NULL\n");
  606. return -1;
  607. }
  608. for (i = 0; i < MAX_CHOOSE_ALSPS_NUM; i++) {
  609. if ((i == 0) && (NULL == alsps_init_list[0])) {
  610. ALSPS_LOG("register alsps driver for the first time\n");
  611. if (platform_driver_register(&als_ps_driver))
  612. ALSPS_ERR("failed to register alsps driver already exist\n");
  613. }
  614. if (NULL == alsps_init_list[i]) {
  615. obj->platform_diver_addr = &als_ps_driver;
  616. alsps_init_list[i] = obj;
  617. break;
  618. }
  619. }
  620. if (i >= MAX_CHOOSE_ALSPS_NUM) {
  621. ALSPS_ERR("ALSPS driver add err\n");
  622. err = -1;
  623. }
  624. return err;
  625. }
  626. EXPORT_SYMBOL_GPL(alsps_driver_add);
  627. struct platform_device *get_alsps_platformdev(void)
  628. {
  629. return pltfm_dev;
  630. }
  631. int ps_report_interrupt_data(int value)
  632. {
  633. struct alsps_context *cxt = NULL;
  634. /* int err =0; */
  635. cxt = alsps_context_obj;
  636. if (cxt->is_get_valid_ps_data_after_enable == false) {
  637. if (ALSPS_INVALID_VALUE != value) {
  638. cxt->is_get_valid_ps_data_after_enable = true;
  639. smp_mb();/*for memory barriier*/
  640. del_timer_sync(&cxt->timer_ps);
  641. smp_mb();/*for memory barriier*/
  642. cancel_work_sync(&cxt->report_ps);
  643. }
  644. }
  645. if (cxt->is_ps_batch_enable == false)
  646. ps_data_report(cxt->idev, value, 3);
  647. return 0;
  648. }
  649. /*----------------------------------------------------------------------------*/
  650. EXPORT_SYMBOL_GPL(ps_report_interrupt_data);
  651. static int alsps_misc_init(struct alsps_context *cxt)
  652. {
  653. int err = 0;
  654. cxt->mdev.minor = MISC_DYNAMIC_MINOR;
  655. cxt->mdev.name = ALSPS_MISC_DEV_NAME;
  656. err = misc_register(&cxt->mdev);
  657. if (err)
  658. ALSPS_ERR("unable to register alsps misc device!!\n");
  659. return err;
  660. }
  661. static int alsps_input_init(struct alsps_context *cxt)
  662. {
  663. struct input_dev *dev;
  664. int err = 0;
  665. dev = input_allocate_device();
  666. if (NULL == dev)
  667. return -ENOMEM;
  668. dev->name = ALSPS_INPUTDEV_NAME;
  669. set_bit(EV_REL, dev->evbit);
  670. set_bit(EV_SYN, dev->evbit);
  671. input_set_capability(dev, EV_REL, EVENT_TYPE_PS_VALUE);
  672. input_set_capability(dev, EV_REL, EVENT_TYPE_PS_STATUS);
  673. input_set_capability(dev, EV_ABS, EVENT_TYPE_ALS_VALUE);
  674. input_set_capability(dev, EV_ABS, EVENT_TYPE_ALS_STATUS);
  675. input_set_abs_params(dev, EVENT_TYPE_ALS_VALUE, ALSPS_VALUE_MIN, ALSPS_VALUE_MAX, 0, 0);
  676. input_set_abs_params(dev, EVENT_TYPE_ALS_STATUS, ALSPS_STATUS_MIN, ALSPS_STATUS_MAX, 0, 0);
  677. input_set_drvdata(dev, cxt);
  678. err = input_register_device(dev);
  679. if (err < 0) {
  680. input_free_device(dev);
  681. return err;
  682. }
  683. cxt->idev = dev;
  684. return 0;
  685. }
  686. DEVICE_ATTR(alsactive, S_IWUSR | S_IRUGO, als_show_active, als_store_active);
  687. DEVICE_ATTR(alsdelay, S_IWUSR | S_IRUGO, als_show_delay, als_store_delay);
  688. DEVICE_ATTR(alsbatch, S_IWUSR | S_IRUGO, als_show_batch, als_store_batch);
  689. DEVICE_ATTR(alsflush, S_IWUSR | S_IRUGO, als_show_flush, als_store_flush);
  690. DEVICE_ATTR(alsdevnum, S_IWUSR | S_IRUGO, als_show_devnum, NULL);
  691. DEVICE_ATTR(psactive, S_IWUSR | S_IRUGO, ps_show_active, ps_store_active);
  692. DEVICE_ATTR(psdelay, S_IWUSR | S_IRUGO, ps_show_delay, ps_store_delay);
  693. DEVICE_ATTR(psbatch, S_IWUSR | S_IRUGO, ps_show_batch, ps_store_batch);
  694. DEVICE_ATTR(psflush, S_IWUSR | S_IRUGO, ps_show_flush, ps_store_flush);
  695. DEVICE_ATTR(psdevnum, S_IWUSR | S_IRUGO, ps_show_devnum, NULL);
  696. static struct attribute *alsps_attributes[] = {
  697. &dev_attr_alsactive.attr,
  698. &dev_attr_alsdelay.attr,
  699. &dev_attr_alsbatch.attr,
  700. &dev_attr_alsflush.attr,
  701. &dev_attr_alsdevnum.attr,
  702. &dev_attr_psactive.attr,
  703. &dev_attr_psdelay.attr,
  704. &dev_attr_psbatch.attr,
  705. &dev_attr_psflush.attr,
  706. &dev_attr_psdevnum.attr,
  707. NULL
  708. };
  709. static struct attribute_group alsps_attribute_group = {
  710. .attrs = alsps_attributes
  711. };
  712. int als_register_data_path(struct als_data_path *data)
  713. {
  714. struct alsps_context *cxt = NULL;
  715. /* int err =0; */
  716. cxt = alsps_context_obj;
  717. cxt->als_data.get_data = data->get_data;
  718. cxt->als_data.vender_div = data->vender_div;
  719. cxt->als_data.als_get_raw_data = data->als_get_raw_data;
  720. ALSPS_LOG("alsps register data path vender_div: %d\n", cxt->als_data.vender_div);
  721. if (NULL == cxt->als_data.get_data) {
  722. ALSPS_LOG("als register data path fail\n");
  723. return -1;
  724. }
  725. return 0;
  726. }
  727. int ps_register_data_path(struct ps_data_path *data)
  728. {
  729. struct alsps_context *cxt = NULL;
  730. /* int err =0; */
  731. cxt = alsps_context_obj;
  732. cxt->ps_data.get_data = data->get_data;
  733. cxt->ps_data.vender_div = data->vender_div;
  734. cxt->ps_data.ps_get_raw_data = data->ps_get_raw_data;
  735. ALSPS_LOG("alsps register data path vender_div: %d\n", cxt->ps_data.vender_div);
  736. if (NULL == cxt->ps_data.get_data) {
  737. ALSPS_LOG("ps register data path fail\n");
  738. return -1;
  739. }
  740. return 0;
  741. }
  742. int als_register_control_path(struct als_control_path *ctl)
  743. {
  744. struct alsps_context *cxt = NULL;
  745. int err = 0;
  746. cxt = alsps_context_obj;
  747. cxt->als_ctl.set_delay = ctl->set_delay;
  748. cxt->als_ctl.open_report_data = ctl->open_report_data;
  749. cxt->als_ctl.enable_nodata = ctl->enable_nodata;
  750. cxt->als_ctl.is_support_batch = ctl->is_support_batch;
  751. cxt->als_ctl.is_report_input_direct = ctl->is_report_input_direct;
  752. cxt->als_ctl.is_use_common_factory = ctl->is_use_common_factory;
  753. if (NULL == cxt->als_ctl.set_delay || NULL == cxt->als_ctl.open_report_data
  754. || NULL == cxt->als_ctl.enable_nodata) {
  755. ALSPS_LOG("als register control path fail\n");
  756. return -1;
  757. }
  758. if (!alsps_misc_dev_init) {
  759. /* add misc dev for sensor hal control cmd */
  760. err = alsps_misc_init(alsps_context_obj);
  761. if (err) {
  762. ALSPS_ERR("unable to register alsps misc device!!\n");
  763. return -2;
  764. }
  765. err = sysfs_create_group(&alsps_context_obj->mdev.this_device->kobj,
  766. &alsps_attribute_group);
  767. if (err < 0) {
  768. ALSPS_ERR("unable to create alsps attribute file\n");
  769. return -3;
  770. }
  771. kobject_uevent(&alsps_context_obj->mdev.this_device->kobj, KOBJ_ADD);
  772. alsps_misc_dev_init = true;
  773. }
  774. return 0;
  775. }
  776. int ps_register_control_path(struct ps_control_path *ctl)
  777. {
  778. struct alsps_context *cxt = NULL;
  779. int err = 0;
  780. cxt = alsps_context_obj;
  781. cxt->ps_ctl.set_delay = ctl->set_delay;
  782. cxt->ps_ctl.open_report_data = ctl->open_report_data;
  783. cxt->ps_ctl.enable_nodata = ctl->enable_nodata;
  784. cxt->ps_ctl.is_support_batch = ctl->is_support_batch;
  785. cxt->ps_ctl.is_report_input_direct = ctl->is_report_input_direct;
  786. cxt->ps_ctl.ps_calibration = ctl->ps_calibration;
  787. cxt->ps_ctl.ps_threshold_setting = ctl->ps_threshold_setting;
  788. cxt->ps_ctl.is_use_common_factory = ctl->is_use_common_factory;
  789. cxt->ps_ctl.is_polling_mode = ctl->is_polling_mode;
  790. if (NULL == cxt->ps_ctl.set_delay || NULL == cxt->ps_ctl.open_report_data
  791. || NULL == cxt->ps_ctl.enable_nodata) {
  792. ALSPS_LOG("ps register control path fail\n");
  793. return -1;
  794. }
  795. if (!alsps_misc_dev_init) {
  796. /* add misc dev for sensor hal control cmd */
  797. err = alsps_misc_init(alsps_context_obj);
  798. if (err) {
  799. ALSPS_ERR("unable to register alsps misc device!!\n");
  800. return -2;
  801. }
  802. err = sysfs_create_group(&alsps_context_obj->mdev.this_device->kobj,
  803. &alsps_attribute_group);
  804. if (err < 0) {
  805. ALSPS_ERR("unable to create alsps attribute file\n");
  806. return -3;
  807. }
  808. kobject_uevent(&alsps_context_obj->mdev.this_device->kobj, KOBJ_ADD);
  809. alsps_misc_dev_init = true;
  810. }
  811. return 0;
  812. }
  813. /* AAL functions**************************************** */
  814. int alsps_aal_enable(int enable)
  815. {
  816. int ret = 0;
  817. struct alsps_context *cxt = NULL;
  818. if (!alsps_context_obj) {
  819. ALSPS_ERR("null pointer of alsps_context_obj!!\n");
  820. return -1;
  821. }
  822. if (alsps_context_obj->als_ctl.enable_nodata == NULL) {
  823. ALSPS_ERR("alsps context obj not exsit in alsps_aal_enable\n");
  824. return -1;
  825. }
  826. cxt = alsps_context_obj;
  827. if (enable == 1) {
  828. if (alsps_context_obj->is_als_active_data == false)
  829. ret = cxt->als_ctl.enable_nodata(enable);
  830. } else if (enable == 0) {
  831. if (alsps_context_obj->is_als_active_data == false)
  832. ret = cxt->als_ctl.enable_nodata(enable);
  833. }
  834. return ret;
  835. }
  836. int alsps_aal_get_status(void)
  837. {
  838. return 0;
  839. }
  840. int alsps_aal_get_data(void)
  841. {
  842. int ret = 0;
  843. struct alsps_context *cxt = NULL;
  844. int value = 0;
  845. int status = 0;
  846. if (!alsps_context_obj) {
  847. ALSPS_ERR("alsps_context_obj null pointer!!\n");
  848. return -1;
  849. }
  850. if (alsps_context_obj->als_data.get_data == NULL) {
  851. ALSPS_ERR("aal:get_data not exsit\n");
  852. return -1;
  853. }
  854. cxt = alsps_context_obj;
  855. ret = cxt->als_data.get_data(&value, &status);
  856. if (ret < 0)
  857. return -1;
  858. return value;
  859. }
  860. /* *************************************************** */
  861. static int alsps_probe(void)
  862. {
  863. int err;
  864. ALSPS_LOG("+++++++++++++alsps_probe!!\n");
  865. alsps_context_obj = alsps_context_alloc_object();
  866. if (!alsps_context_obj) {
  867. err = -ENOMEM;
  868. ALSPS_ERR("unable to allocate devobj!\n");
  869. goto exit_alloc_data_failed;
  870. }
  871. /* init real alspseleration driver */
  872. err = alsps_real_driver_init();
  873. if (err) {
  874. ALSPS_ERR("alsps real driver init fail\n");
  875. goto real_driver_init_fail;
  876. }
  877. /* init alsps common factory mode misc device */
  878. err = alsps_factory_device_init();
  879. if (err)
  880. ALSPS_ERR("alsps factory device already registed\n");
  881. /* init input dev */
  882. err = alsps_input_init(alsps_context_obj);
  883. if (err) {
  884. ALSPS_ERR("unable to register alsps input device!\n");
  885. goto exit_alloc_input_dev_failed;
  886. }
  887. ALSPS_LOG("----alsps_probe OK !!\n");
  888. return 0;
  889. real_driver_init_fail:
  890. exit_alloc_input_dev_failed:
  891. kfree(alsps_context_obj);
  892. alsps_context_obj = NULL;
  893. exit_alloc_data_failed:
  894. ALSPS_ERR("----alsps_probe fail !!!\n");
  895. return err;
  896. }
  897. static int alsps_remove(void)
  898. {
  899. int err = 0;
  900. ALSPS_FUN(f);
  901. input_unregister_device(alsps_context_obj->idev);
  902. sysfs_remove_group(&alsps_context_obj->idev->dev.kobj,
  903. &alsps_attribute_group);
  904. err = misc_deregister(&alsps_context_obj->mdev);
  905. if (err)
  906. ALSPS_ERR("misc_deregister fail: %d\n", err);
  907. kfree(alsps_context_obj);
  908. return 0;
  909. }
  910. static int __init alsps_init(void)
  911. {
  912. ALSPS_FUN();
  913. if (alsps_probe()) {
  914. ALSPS_ERR("failed to register alsps driver\n");
  915. return -ENODEV;
  916. }
  917. return 0;
  918. }
  919. static void __exit alsps_exit(void)
  920. {
  921. alsps_remove();
  922. platform_driver_unregister(&als_ps_driver);
  923. }
  924. late_initcall(alsps_init);
  925. MODULE_LICENSE("GPL");
  926. MODULE_DESCRIPTION("ALSPS device driver");
  927. MODULE_AUTHOR("Mediatek");