lsm6dso_accel.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809
  1. /*
  2. * Copyright (C) 2012, Samsung Electronics Co. Ltd. All Rights Reserved.
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation; either version 2 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. */
  15. #include <linux/init.h>
  16. #include <linux/module.h>
  17. #include "adsp.h"
  18. #ifdef CONFIG_SEC_VIB_NOTIFIER
  19. #include <linux/vibrator/sec_vibrator_notifier.h>
  20. #endif
  21. #define VENDOR "STM"
  22. #if IS_ENABLED(CONFIG_LSM6DSV_FACTORY)
  23. #define CHIP_ID "LSM6DSV"
  24. #else
  25. #define CHIP_ID "LSM6DSO"
  26. #endif
  27. #define ACCEL_ST_TRY_CNT 3
  28. #define ACCEL_FACTORY_CAL_CNT 20
  29. #define ACCEL_RAW_DATA_CNT 3
  30. #define MAX_ACCEL_1G 2048
  31. #define STM_LSM6DSO_INT_CHECK_RUNNING 4
  32. #define MAX_MOTOR_STOP_TIMEOUT (8 * NSEC_PER_SEC)
  33. /* Haptic Pattern A vibrate during 7ms.
  34. * touch, touchkey, operation feedback use this.
  35. * Do not call motor_workfunc when duration is 7ms.
  36. */
  37. #define DURATION_SKIP 10
  38. #define MOTOR_OFF 0
  39. #define MOTOR_ON 1
  40. #define CALL_VIB_IDX 65534
  41. #ifdef CONFIG_SEC_VIB_NOTIFIER
  42. struct accel_motor_data {
  43. struct notifier_block motor_nb;
  44. struct hrtimer motor_stop_timer;
  45. struct workqueue_struct *slpi_motor_wq;
  46. struct work_struct work_slpi_motor;
  47. atomic_t motor_state;
  48. int idx;
  49. int timeout;
  50. };
  51. struct accel_motor_data *pdata_motor;
  52. #endif
  53. struct accel_data {
  54. struct work_struct work_accel;
  55. struct workqueue_struct *accel_wq;
  56. struct adsp_data *dev_data;
  57. bool is_complete_cal;
  58. bool lpf_onoff;
  59. bool st_complete;
  60. int32_t raw_data[ACCEL_RAW_DATA_CNT];
  61. int32_t avg_data[ACCEL_RAW_DATA_CNT];
  62. };
  63. static struct accel_data *pdata;
  64. static bool is_ignore_crash_factory = false;
  65. static ssize_t accel_vendor_show(struct device *dev,
  66. struct device_attribute *attr, char *buf)
  67. {
  68. return snprintf(buf, PAGE_SIZE, "%s\n", VENDOR);
  69. }
  70. static ssize_t accel_name_show(struct device *dev,
  71. struct device_attribute *attr, char *buf)
  72. {
  73. return snprintf(buf, PAGE_SIZE, "%s\n", CHIP_ID);
  74. }
  75. static ssize_t sensor_type_show(struct device *dev,
  76. struct device_attribute *attr, char *buf)
  77. {
  78. return snprintf(buf, PAGE_SIZE, "%s\n", "ADSP");
  79. }
  80. int get_accel_cal_data(struct adsp_data *data, int32_t *cal_data)
  81. {
  82. uint8_t cnt = 0;
  83. adsp_unicast(NULL, 0, MSG_ACCEL, 0, MSG_TYPE_GET_CAL_DATA);
  84. while (!(data->ready_flag[MSG_TYPE_GET_CAL_DATA] & 1 << MSG_ACCEL) &&
  85. cnt++ < TIMEOUT_CNT)
  86. usleep_range(500, 550);
  87. data->ready_flag[MSG_TYPE_GET_CAL_DATA] &= ~(1 << MSG_ACCEL);
  88. if (cnt >= TIMEOUT_CNT) {
  89. pr_err("[FACTORY] %s: Timeout!!!\n", __func__);
  90. return 0;
  91. }
  92. if (data->msg_buf[MSG_ACCEL][3] != ACCEL_RAW_DATA_CNT) {
  93. pr_err("[FACTORY] %s: Reading Bytes Num %d!!!\n",
  94. __func__, data->msg_buf[MSG_ACCEL][3]);
  95. return 0;
  96. }
  97. cal_data[0] = data->msg_buf[MSG_ACCEL][0];
  98. cal_data[1] = data->msg_buf[MSG_ACCEL][1];
  99. cal_data[2] = data->msg_buf[MSG_ACCEL][2];
  100. pr_info("[FACTORY] %s: %d, %d, %d, %d\n", __func__,
  101. cal_data[0], cal_data[1], cal_data[2],
  102. data->msg_buf[MSG_ACCEL][3]);
  103. return data->msg_buf[MSG_ACCEL][3];
  104. }
  105. void set_accel_cal_data(struct adsp_data *data)
  106. {
  107. uint8_t cnt = 0;
  108. pr_info("[FACTORY] %s: %d, %d, %d\n", __func__, pdata->avg_data[0],
  109. pdata->avg_data[1], pdata->avg_data[2]);
  110. adsp_unicast(pdata->avg_data, sizeof(pdata->avg_data),
  111. MSG_ACCEL, 0, MSG_TYPE_SET_CAL_DATA);
  112. while (!(data->ready_flag[MSG_TYPE_SET_CAL_DATA] & 1 << MSG_ACCEL) &&
  113. cnt++ < TIMEOUT_CNT)
  114. usleep_range(500, 550);
  115. data->ready_flag[MSG_TYPE_SET_CAL_DATA] &= ~(1 << MSG_ACCEL);
  116. if (cnt >= TIMEOUT_CNT) {
  117. pr_err("[FACTORY] %s: Timeout!!!\n", __func__);
  118. } else if (data->msg_buf[MSG_ACCEL][0] != ACCEL_RAW_DATA_CNT) {
  119. pr_err("[FACTORY] %s: Write Bytes Num %d!!!\n",
  120. __func__, data->msg_buf[MSG_ACCEL][0]);
  121. }
  122. }
  123. static ssize_t accel_calibration_show(struct device *dev,
  124. struct device_attribute *attr, char *buf)
  125. {
  126. struct adsp_data *data = dev_get_drvdata(dev);
  127. int32_t cal_data[ACCEL_RAW_DATA_CNT] = {0, };
  128. int ret = 0;
  129. mutex_lock(&data->accel_factory_mutex);
  130. ret = get_accel_cal_data(data, cal_data);
  131. mutex_unlock(&data->accel_factory_mutex);
  132. if (ret > 0) {
  133. pr_info("[FACTORY] %s: %d, %d, %d\n", __func__,
  134. cal_data[0], cal_data[1], cal_data[2]);
  135. if (cal_data[0] == 0 && cal_data[1] == 0 && cal_data[2] == 0)
  136. return snprintf(buf, PAGE_SIZE, "%d,%d,%d,%d\n",
  137. 0, 0, 0, 0);
  138. else
  139. return snprintf(buf, PAGE_SIZE, "%d,%d,%d,%d\n",
  140. true, cal_data[0], cal_data[1], cal_data[2]);
  141. } else {
  142. pr_err("[FACTORY] %s: get_accel_cal_data fail\n", __func__);
  143. return snprintf(buf, PAGE_SIZE, "%d,%d,%d,%d\n", 0, 0, 0, 0);
  144. }
  145. }
  146. static ssize_t accel_calibration_store(struct device *dev,
  147. struct device_attribute *attr, const char *buf, size_t size)
  148. {
  149. struct adsp_data *data = dev_get_drvdata(dev);
  150. pdata->dev_data = data;
  151. if (sysfs_streq(buf, "0")) {
  152. mutex_lock(&data->accel_factory_mutex);
  153. memset(pdata->avg_data, 0, sizeof(pdata->avg_data));
  154. set_accel_cal_data(data);
  155. mutex_unlock(&data->accel_factory_mutex);
  156. } else {
  157. pdata->is_complete_cal = false;
  158. queue_work(pdata->accel_wq, &pdata->work_accel);
  159. while (pdata->is_complete_cal == false) {
  160. pr_info("[FACTORY] %s: In factory cal\n", __func__);
  161. msleep(20);
  162. }
  163. mutex_lock(&data->accel_factory_mutex);
  164. set_accel_cal_data(data);
  165. mutex_unlock(&data->accel_factory_mutex);
  166. }
  167. return size;
  168. }
  169. static void accel_work_func(struct work_struct *work)
  170. {
  171. struct accel_data *data = container_of((struct work_struct *)work,
  172. struct accel_data, work_accel);
  173. int i;
  174. mutex_lock(&data->dev_data->accel_factory_mutex);
  175. memset(pdata->avg_data, 0, sizeof(pdata->avg_data));
  176. adsp_unicast(pdata->avg_data, sizeof(pdata->avg_data),
  177. MSG_ACCEL, 0, MSG_TYPE_SET_CAL_DATA);
  178. msleep(30); /* for init of bias */
  179. for (i = 0; i < ACCEL_FACTORY_CAL_CNT; i++) {
  180. msleep(20);
  181. get_accel_raw_data(pdata->raw_data);
  182. pdata->avg_data[0] += pdata->raw_data[0];
  183. pdata->avg_data[1] += pdata->raw_data[1];
  184. pdata->avg_data[2] += pdata->raw_data[2];
  185. pr_info("[FACTORY] %s: %d, %d, %d\n", __func__,
  186. pdata->raw_data[0], pdata->raw_data[1],
  187. pdata->raw_data[2]);
  188. }
  189. for (i = 0; i < ACCEL_RAW_DATA_CNT; i++) {
  190. pdata->avg_data[i] /= ACCEL_FACTORY_CAL_CNT;
  191. pr_info("[FACTORY] %s: avg : %d\n",
  192. __func__, pdata->avg_data[i]);
  193. }
  194. if (pdata->avg_data[2] > 0)
  195. pdata->avg_data[2] -= MAX_ACCEL_1G;
  196. else if (pdata->avg_data[2] < 0)
  197. pdata->avg_data[2] += MAX_ACCEL_1G;
  198. mutex_unlock(&data->dev_data->accel_factory_mutex);
  199. pdata->is_complete_cal = true;
  200. }
  201. void accel_cal_work_func(struct work_struct *work)
  202. {
  203. struct adsp_data *data = container_of((struct delayed_work *)work,
  204. struct adsp_data, accel_cal_work);
  205. int ret = 0;
  206. mutex_lock(&data->accel_factory_mutex);
  207. ret = get_accel_cal_data(data, pdata->avg_data);
  208. mutex_unlock(&data->accel_factory_mutex);
  209. if (ret > 0) {
  210. pr_info("[FACTORY] %s: ret(%d) %d, %d, %d\n", __func__, ret,
  211. pdata->avg_data[0],
  212. pdata->avg_data[1],
  213. pdata->avg_data[2]);
  214. mutex_lock(&data->accel_factory_mutex);
  215. set_accel_cal_data(data);
  216. mutex_unlock(&data->accel_factory_mutex);
  217. } else {
  218. pr_err("[FACTORY] %s: get_accel_cal_data fail (%d)\n",
  219. __func__, ret);
  220. }
  221. }
  222. static ssize_t accel_selftest_show(struct device *dev,
  223. struct device_attribute *attr, char *buf)
  224. {
  225. struct adsp_data *data = dev_get_drvdata(dev);
  226. uint8_t cnt = 0;
  227. int retry = 0;
  228. #if IS_ENABLED(CONFIG_SUPPORT_AK09973) || defined(CONFIG_SUPPORT_AK09973)
  229. int msg_buf = LSM6DSO_SELFTEST_TRUE;
  230. adsp_unicast(&msg_buf, sizeof(msg_buf),
  231. MSG_DIGITAL_HALL_ANGLE, 0, MSG_TYPE_OPTION_DEFINE);
  232. #elif IS_ENABLED(CONFIG_SUPPORT_REF_ANGLE_WITHOUT_DIGITAL_HALL) || defined(CONFIG_SUPPORT_REF_ANGLE_WITHOUT_DIGITAL_HALL)
  233. int msg_buf = LSM6DSO_SELFTEST_TRUE;
  234. adsp_unicast(&msg_buf, sizeof(msg_buf),
  235. MSG_REF_ANGLE, 0, MSG_TYPE_OPTION_DEFINE);
  236. #endif
  237. pdata->st_complete = false;
  238. RETRY_ACCEL_SELFTEST:
  239. adsp_unicast(NULL, 0, MSG_ACCEL, 0, MSG_TYPE_ST_SHOW_DATA);
  240. while (!(data->ready_flag[MSG_TYPE_ST_SHOW_DATA] & 1 << MSG_ACCEL) &&
  241. cnt++ < TIMEOUT_CNT)
  242. msleep(26);
  243. data->ready_flag[MSG_TYPE_ST_SHOW_DATA] &= ~(1 << MSG_ACCEL);
  244. if (cnt >= TIMEOUT_CNT) {
  245. pr_err("[FACTORY] %s: Timeout!!!\n", __func__);
  246. data->msg_buf[MSG_ACCEL][1] = -1;
  247. #ifdef CONFIG_SEC_FACTORY
  248. panic("sensor force crash : accel selftest timeout\n");
  249. #endif
  250. }
  251. pr_info("[FACTORY] %s : init = %d, result = %d, XYZ = %d, %d, %d, nXYZ = %d, %d, %d\n",
  252. __func__, data->msg_buf[MSG_ACCEL][0],
  253. data->msg_buf[MSG_ACCEL][1], data->msg_buf[MSG_ACCEL][2],
  254. data->msg_buf[MSG_ACCEL][3], data->msg_buf[MSG_ACCEL][4],
  255. data->msg_buf[MSG_ACCEL][5], data->msg_buf[MSG_ACCEL][6],
  256. data->msg_buf[MSG_ACCEL][7]);
  257. pr_info("[FACTORY] %s : pre/postP/postN [%d, %d, %d/%d, %d, %d/%d, %d, %d], comm_err_cnt %d/%d/%d\n",
  258. __func__, data->msg_buf[MSG_ACCEL][8],
  259. data->msg_buf[MSG_ACCEL][9], data->msg_buf[MSG_ACCEL][10],
  260. data->msg_buf[MSG_ACCEL][11], data->msg_buf[MSG_ACCEL][12],
  261. data->msg_buf[MSG_ACCEL][13], data->msg_buf[MSG_ACCEL][14],
  262. data->msg_buf[MSG_ACCEL][15], data->msg_buf[MSG_ACCEL][16],
  263. data->msg_buf[MSG_ACCEL][17], data->msg_buf[MSG_ACCEL][18],
  264. data->msg_buf[MSG_ACCEL][19]);
  265. if (data->msg_buf[MSG_ACCEL][1] == 1) {
  266. pr_info("[FACTORY] %s : Pass - result = %d, retry = %d\n",
  267. __func__, data->msg_buf[MSG_ACCEL][1], retry);
  268. } else {
  269. data->msg_buf[MSG_ACCEL][1] = -5;
  270. pr_err("[FACTORY] %s : Fail - result = %d, retry = %d\n",
  271. __func__, data->msg_buf[MSG_ACCEL][1], retry);
  272. if (retry < ACCEL_ST_TRY_CNT) {
  273. retry++;
  274. msleep(50);
  275. cnt = 0;
  276. pr_info("[FACTORY] %s: retry\n", __func__);
  277. goto RETRY_ACCEL_SELFTEST;
  278. }
  279. }
  280. pdata->st_complete = true;
  281. #if IS_ENABLED(CONFIG_SUPPORT_AK09973) || defined(CONFIG_SUPPORT_AK09973) ||\
  282. IS_ENABLED(CONFIG_SUPPORT_REF_ANGLE_WITHOUT_DIGITAL_HALL) || defined(CONFIG_SUPPORT_REF_ANGLE_WITHOUT_DIGITAL_HALL)
  283. schedule_delayed_work(&data->lsm6dso_selftest_stop_work, msecs_to_jiffies(300));
  284. #endif
  285. return snprintf(buf, PAGE_SIZE, "%d,%d,%d,%d,%d,%d,%d\n",
  286. data->msg_buf[MSG_ACCEL][1],
  287. (int)abs(data->msg_buf[MSG_ACCEL][2]),
  288. (int)abs(data->msg_buf[MSG_ACCEL][3]),
  289. (int)abs(data->msg_buf[MSG_ACCEL][4]),
  290. (int)abs(data->msg_buf[MSG_ACCEL][5]),
  291. (int)abs(data->msg_buf[MSG_ACCEL][6]),
  292. (int)abs(data->msg_buf[MSG_ACCEL][7]));
  293. }
  294. static ssize_t accel_raw_data_show(struct device *dev,
  295. struct device_attribute *attr, char *buf)
  296. {
  297. struct adsp_data *data = dev_get_drvdata(dev);
  298. int32_t raw_data[ACCEL_RAW_DATA_CNT] = {0, };
  299. static int32_t prev_raw_data[ACCEL_RAW_DATA_CNT] = {0, };
  300. int ret = 0;
  301. #ifdef CONFIG_SEC_FACTORY
  302. static int same_cnt = 0;
  303. #endif
  304. if (pdata->st_complete == false) {
  305. pr_info("[FACTORY] %s: selftest is running\n", __func__);
  306. return snprintf(buf, PAGE_SIZE, "%d,%d,%d\n",
  307. raw_data[0], raw_data[1], raw_data[2]);
  308. }
  309. mutex_lock(&data->accel_factory_mutex);
  310. ret = get_accel_raw_data(raw_data);
  311. mutex_unlock(&data->accel_factory_mutex);
  312. #ifdef CONFIG_SEC_FACTORY
  313. pr_info("[FACTORY] %s: %d, %d, %d\n", __func__,
  314. raw_data[0], raw_data[1], raw_data[2]);
  315. if (prev_raw_data[0] == raw_data[0] &&
  316. prev_raw_data[1] == raw_data[1] &&
  317. prev_raw_data[2] == raw_data[2]) {
  318. same_cnt++;
  319. pr_info("[FACTORY] %s: same_cnt %d\n", __func__, same_cnt);
  320. if (same_cnt >= 20)
  321. panic("sensor force crash : accel raw_data stuck\n");
  322. } else
  323. same_cnt = 0;
  324. #endif
  325. if (!ret) {
  326. memcpy(prev_raw_data, raw_data, sizeof(int32_t) * 3);
  327. } else if (!pdata->lpf_onoff) {
  328. pr_err("[FACTORY] %s: using prev data!!!\n", __func__);
  329. memcpy(raw_data, prev_raw_data, sizeof(int32_t) * 3);
  330. } else {
  331. pr_err("[FACTORY] %s: Timeout!!!\n", __func__);
  332. }
  333. return snprintf(buf, PAGE_SIZE, "%d,%d,%d\n",
  334. raw_data[0], raw_data[1], raw_data[2]);
  335. }
  336. static ssize_t accel_reactive_show(struct device *dev,
  337. struct device_attribute *attr, char *buf)
  338. {
  339. struct adsp_data *data = dev_get_drvdata(dev);
  340. uint8_t cnt = 0;
  341. bool success = false;
  342. int32_t msg_buf = 0;
  343. mutex_lock(&data->accel_factory_mutex);
  344. adsp_unicast(&msg_buf, sizeof(int32_t), MSG_ACCEL,
  345. 0, MSG_TYPE_GET_REGISTER);
  346. while (!(data->ready_flag[MSG_TYPE_GET_REGISTER] & 1 << MSG_ACCEL) &&
  347. cnt++ < TIMEOUT_CNT)
  348. usleep_range(500, 550);
  349. data->ready_flag[MSG_TYPE_GET_REGISTER] &= ~(1 << MSG_ACCEL);
  350. mutex_unlock(&data->accel_factory_mutex);
  351. if (cnt >= TIMEOUT_CNT) {
  352. pr_err("[FACTORY] %s: Timeout!!!\n", __func__);
  353. return snprintf(buf, PAGE_SIZE, "%d\n", (int)success);
  354. }
  355. pr_info("[FACTORY]: %s - %d\n", __func__,
  356. data->msg_buf[MSG_ACCEL][0]);
  357. if (data->msg_buf[MSG_ACCEL][0] == 0)
  358. success = true;
  359. else
  360. panic("sensor accel interrupt check fail!!");
  361. return snprintf(buf, PAGE_SIZE, "%d\n", (int)success);
  362. }
  363. static ssize_t accel_reactive_store(struct device *dev,
  364. struct device_attribute *attr, const char *buf, size_t size)
  365. {
  366. struct adsp_data *data = dev_get_drvdata(dev);
  367. int32_t msg_buf;
  368. uint8_t cnt = 0;
  369. if (sysfs_streq(buf, "1"))
  370. pr_info("[FACTORY]: %s - on\n", __func__);
  371. else if (sysfs_streq(buf, "0"))
  372. pr_info("[FACTORY]: %s - off\n", __func__);
  373. else if (sysfs_streq(buf, "2")) {
  374. pr_info("[FACTORY]: %s - factory\n", __func__);
  375. msg_buf = 1;
  376. mutex_lock(&data->accel_factory_mutex);
  377. adsp_unicast(&msg_buf, sizeof(int32_t), MSG_ACCEL,
  378. 0, MSG_TYPE_GET_REGISTER);
  379. while (!(data->ready_flag[MSG_TYPE_GET_REGISTER] & 1 << MSG_ACCEL) &&
  380. cnt++ < TIMEOUT_CNT)
  381. usleep_range(500, 550);
  382. data->ready_flag[MSG_TYPE_GET_REGISTER] &= ~(1 << MSG_ACCEL);
  383. mutex_unlock(&data->accel_factory_mutex);
  384. if (cnt >= TIMEOUT_CNT) {
  385. pr_err("[FACTORY] %s: Timeout!!!\n", __func__);
  386. return size;
  387. }
  388. if (data->msg_buf[MSG_ACCEL][0] == STM_LSM6DSO_INT_CHECK_RUNNING)
  389. pr_info("[FACTORY]: %s - STM_LSM6DSx_INT_CHECK_RUNNING\n", __func__);
  390. else
  391. pr_info("[FACTORY]: %s - Something wrong\n", __func__);
  392. }
  393. return size;
  394. }
  395. bool sns_check_ignore_crash(void)
  396. {
  397. return is_ignore_crash_factory;
  398. }
  399. EXPORT_SYMBOL(sns_check_ignore_crash);
  400. static ssize_t accel_lowpassfilter_store(struct device *dev,
  401. struct device_attribute *attr, const char *buf, size_t size)
  402. {
  403. struct adsp_data *data = dev_get_drvdata(dev);
  404. uint8_t cnt = 0;
  405. int32_t msg_buf;
  406. if (sysfs_streq(buf, "1")) {
  407. msg_buf = 1;
  408. is_ignore_crash_factory = false;
  409. } else if (sysfs_streq(buf, "0")) {
  410. msg_buf = 0;
  411. is_ignore_crash_factory = false;
  412. #ifdef CONFIG_SEC_FACTORY
  413. } else if (sysfs_streq(buf, "2")) {
  414. msg_buf = 2;
  415. is_ignore_crash_factory = true;
  416. pr_info("[FACTORY] %s: Pretest\n", __func__);
  417. } else if (sysfs_streq(buf, "3")) {
  418. msg_buf = 3;
  419. is_ignore_crash_factory = true;
  420. pr_info("[FACTORY] %s: Questt\n", __func__);
  421. return size;
  422. #endif
  423. } else {
  424. is_ignore_crash_factory = false;
  425. pr_info("[FACTORY] %s: wrong value\n", __func__);
  426. return size;
  427. }
  428. mutex_lock(&data->accel_factory_mutex);
  429. adsp_unicast(&msg_buf, sizeof(int32_t), MSG_ACCEL,
  430. 0, MSG_TYPE_SET_ACCEL_LPF);
  431. while (!(data->ready_flag[MSG_TYPE_SET_ACCEL_LPF] & 1 << MSG_ACCEL) &&
  432. cnt++ < TIMEOUT_CNT)
  433. usleep_range(500, 550);
  434. data->ready_flag[MSG_TYPE_SET_ACCEL_LPF] &= ~(1 << MSG_ACCEL);
  435. mutex_unlock(&data->accel_factory_mutex);
  436. if (cnt >= TIMEOUT_CNT) {
  437. pr_err("[FACTORY] %s: Timeout!!!\n", __func__);
  438. return size;
  439. }
  440. pdata->lpf_onoff = (bool)data->msg_buf[MSG_ACCEL][0];
  441. #if IS_ENABLED(CONFIG_LSM6DSV_FACTORY)
  442. pr_info("[FACTORY] %s: %d, 0x0A:%02x 0x0D:%02x 0x18:%02x\n", __func__,
  443. data->msg_buf[MSG_ACCEL][0], data->msg_buf[MSG_ACCEL][1],
  444. data->msg_buf[MSG_ACCEL][2], data->msg_buf[MSG_ACCEL][3]);
  445. #else
  446. pr_info("[FACTORY] %s: %d, 0x0A:%02x 0x0D:%02x 0x10:%02x\n", __func__,
  447. data->msg_buf[MSG_ACCEL][0], data->msg_buf[MSG_ACCEL][1],
  448. data->msg_buf[MSG_ACCEL][2], data->msg_buf[MSG_ACCEL][3]);
  449. #endif
  450. return size;
  451. }
  452. #ifdef CONFIG_SEC_VIB_NOTIFIER
  453. uint64_t motor_stop_timeout(int timeout_ms)
  454. {
  455. uint64_t timeout_ns = timeout_ms * NSEC_PER_MSEC;
  456. if (timeout_ns > MAX_MOTOR_STOP_TIMEOUT)
  457. return timeout_ns;
  458. else
  459. return MAX_MOTOR_STOP_TIMEOUT;
  460. }
  461. int ssc_motor_notify(struct notifier_block *nb,
  462. unsigned long enable, void *v)
  463. {
  464. struct vib_notifier_context *vib = (struct vib_notifier_context *)v;
  465. uint64_t timeout_ns = 0;
  466. pr_info("[FACTORY] %s: %s, idx: %d timeout: %d\n",
  467. __func__, enable ? "ON" : "OFF", vib->index, vib->timeout);
  468. if(enable == 1) {
  469. pdata_motor->idx = vib->index;
  470. pdata_motor->timeout = vib->timeout;
  471. if (pdata_motor->idx == 0)
  472. timeout_ns = motor_stop_timeout(pdata_motor->timeout);
  473. else
  474. timeout_ns = MAX_MOTOR_STOP_TIMEOUT;
  475. if (atomic_read(&pdata_motor->motor_state) == MOTOR_OFF) {
  476. atomic_set(&pdata_motor->motor_state, MOTOR_ON);
  477. queue_work(pdata_motor->slpi_motor_wq,
  478. &pdata_motor->work_slpi_motor);
  479. } else {
  480. hrtimer_cancel(&pdata_motor->motor_stop_timer);
  481. if (pdata_motor->idx == CALL_VIB_IDX) {
  482. queue_work(pdata_motor->slpi_motor_wq,
  483. &pdata_motor->work_slpi_motor);
  484. return 0;
  485. }
  486. hrtimer_start(&pdata_motor->motor_stop_timer,
  487. ns_to_ktime(timeout_ns),
  488. HRTIMER_MODE_REL);
  489. }
  490. } else {
  491. if (pdata_motor->idx == CALL_VIB_IDX) {
  492. atomic_set(&pdata_motor->motor_state, MOTOR_OFF);
  493. queue_work(pdata_motor->slpi_motor_wq,
  494. &pdata_motor->work_slpi_motor);
  495. } else
  496. pr_info("[FACTORY] %s: Not support OFF\n", __func__);
  497. }
  498. return 0;
  499. }
  500. static enum hrtimer_restart motor_stop_timer_func(struct hrtimer *timer)
  501. {
  502. pr_info("[FACTORY] %s\n", __func__);
  503. atomic_set(&pdata_motor->motor_state, MOTOR_OFF);
  504. queue_work(pdata_motor->slpi_motor_wq, &pdata_motor->work_slpi_motor);
  505. return HRTIMER_NORESTART;
  506. }
  507. void slpi_motor_work_func(struct work_struct *work)
  508. {
  509. int32_t msg_buf = 0;
  510. uint64_t timeout_ns = 0;
  511. if (pdata_motor->idx == 0)
  512. timeout_ns = motor_stop_timeout(pdata_motor->timeout);
  513. else
  514. timeout_ns = MAX_MOTOR_STOP_TIMEOUT;
  515. if (atomic_read(&pdata_motor->motor_state) == MOTOR_ON) {
  516. if (pdata_motor->idx != CALL_VIB_IDX)
  517. hrtimer_start(&pdata_motor->motor_stop_timer,
  518. ns_to_ktime(timeout_ns),
  519. HRTIMER_MODE_REL);
  520. msg_buf = 1;
  521. } else if (atomic_read(&pdata_motor->motor_state) == MOTOR_OFF) {
  522. if (pdata_motor->idx != CALL_VIB_IDX)
  523. hrtimer_cancel(&pdata_motor->motor_stop_timer);
  524. msg_buf = 0;
  525. } else {
  526. pr_info("[FACTORY] %s: invalid state %d\n",
  527. __func__, (int)atomic_read(&pdata_motor->motor_state));
  528. }
  529. pr_info("[FACTORY] %s: msg_buf = %d, idx/timeout = %d/%d\n",
  530. __func__, msg_buf, pdata_motor->idx,
  531. (int)(timeout_ns / NSEC_PER_MSEC));
  532. adsp_unicast(&msg_buf, sizeof(int32_t), MSG_ACCEL,
  533. 0, MSG_TYPE_SET_ACCEL_MOTOR);
  534. #ifdef CONFIG_SUPPORT_DUAL_6AXIS
  535. usleep_range(500, 550);
  536. adsp_unicast(&msg_buf, sizeof(int32_t), MSG_ACCEL_SUB,
  537. 0, MSG_TYPE_SET_ACCEL_MOTOR);
  538. #endif
  539. }
  540. #endif
  541. static ssize_t accel_dhr_sensor_info_show(struct device *dev,
  542. struct device_attribute *attr, char *buf)
  543. {
  544. struct adsp_data *data = dev_get_drvdata(dev);
  545. uint8_t cnt = 0;
  546. char ctrl1_xl = 0;
  547. uint8_t fullscale = 0;
  548. adsp_unicast(NULL, 0, MSG_ACCEL, 0, MSG_TYPE_GET_DHR_INFO);
  549. while (!(data->ready_flag[MSG_TYPE_GET_DHR_INFO] & 1 << MSG_ACCEL) &&
  550. cnt++ < TIMEOUT_CNT)
  551. usleep_range(500, 550);
  552. data->ready_flag[MSG_TYPE_GET_DHR_INFO] &= ~(1 << MSG_ACCEL);
  553. if (cnt >= TIMEOUT_CNT) {
  554. pr_err("[FACTORY] %s: Timeout!!!\n", __func__);
  555. } else {
  556. ctrl1_xl = data->msg_buf[MSG_ACCEL][16];
  557. ctrl1_xl &= 0xC;
  558. switch (ctrl1_xl) {
  559. case 0xC:
  560. fullscale = 8;
  561. break;
  562. case 0x8:
  563. fullscale = 4;
  564. break;
  565. case 0x4:
  566. fullscale = 16;
  567. break;
  568. case 0:
  569. fullscale = 2;
  570. break;
  571. default:
  572. break;
  573. }
  574. }
  575. pr_info("[FACTORY] %s: f/s %u\n", __func__, fullscale);
  576. return snprintf(buf, PAGE_SIZE, "\"FULL_SCALE\":\"%uG\"\n", fullscale);
  577. }
  578. static ssize_t accel_turn_over_crash_show(struct device *dev,
  579. struct device_attribute *attr, char *buf)
  580. {
  581. struct adsp_data *data = dev_get_drvdata(dev);
  582. pr_info("[FACTORY] %s: %d, \n", __func__, data->turn_over_crash);
  583. return snprintf(buf, PAGE_SIZE, "%d\n", data->turn_over_crash);
  584. }
  585. static ssize_t accel_turn_over_crash_store(struct device *dev,
  586. struct device_attribute *attr, const char *buf, size_t size)
  587. {
  588. struct adsp_data *data = dev_get_drvdata(dev);
  589. int32_t msg_buf[2] = {0, };
  590. if (sysfs_streq(buf, "1")) {
  591. data->turn_over_crash = 1;
  592. msg_buf[1] = 1;
  593. } else if (sysfs_streq(buf, "2")) {
  594. data->turn_over_crash = 2;
  595. msg_buf[1] = 2;
  596. } else {
  597. data->turn_over_crash = 0;
  598. msg_buf[1] = 0;
  599. }
  600. adsp_unicast(msg_buf, sizeof(msg_buf), MSG_ACCEL,
  601. 0, MSG_TYPE_OPTION_DEFINE);
  602. pr_info("[FACTORY] %s: %d, \n", __func__, msg_buf[1]);
  603. return size;
  604. }
  605. static DEVICE_ATTR(name, 0444, accel_name_show, NULL);
  606. static DEVICE_ATTR(vendor, 0444, accel_vendor_show, NULL);
  607. static DEVICE_ATTR(type, 0444, sensor_type_show, NULL);
  608. static DEVICE_ATTR(calibration, 0664,
  609. accel_calibration_show, accel_calibration_store);
  610. static DEVICE_ATTR(selftest, 0440,
  611. accel_selftest_show, NULL);
  612. static DEVICE_ATTR(raw_data, 0444, accel_raw_data_show, NULL);
  613. static DEVICE_ATTR(reactive_alert, 0664,
  614. accel_reactive_show, accel_reactive_store);
  615. static DEVICE_ATTR(lowpassfilter, 0220,
  616. NULL, accel_lowpassfilter_store);
  617. #ifdef CONFIG_SEC_FACTORY
  618. static DEVICE_ATTR(dhr_sensor_info, 0444,
  619. accel_dhr_sensor_info_show, NULL);
  620. #else
  621. static DEVICE_ATTR(dhr_sensor_info, 0440,
  622. accel_dhr_sensor_info_show, NULL);
  623. #endif
  624. static DEVICE_ATTR(turn_over_crash, 0664,
  625. accel_turn_over_crash_show, accel_turn_over_crash_store);
  626. static struct device_attribute *acc_attrs[] = {
  627. &dev_attr_name,
  628. &dev_attr_vendor,
  629. &dev_attr_type,
  630. &dev_attr_calibration,
  631. &dev_attr_selftest,
  632. &dev_attr_raw_data,
  633. &dev_attr_reactive_alert,
  634. &dev_attr_lowpassfilter,
  635. &dev_attr_dhr_sensor_info,
  636. &dev_attr_turn_over_crash,
  637. NULL,
  638. };
  639. void accel_factory_init_work(struct adsp_data *data)
  640. {
  641. schedule_delayed_work(&data->accel_cal_work, msecs_to_jiffies(8000));
  642. }
  643. EXPORT_SYMBOL(accel_factory_init_work);
  644. int __init lsm6dso_accel_factory_init(void)
  645. {
  646. adsp_factory_register(MSG_ACCEL, acc_attrs);
  647. #ifdef CONFIG_SEC_VIB_NOTIFIER
  648. pdata_motor = kzalloc(sizeof(*pdata_motor), GFP_KERNEL);
  649. if (pdata_motor == NULL)
  650. return -ENOMEM;
  651. pdata_motor->motor_nb.notifier_call = ssc_motor_notify,
  652. pdata_motor->motor_nb.priority = 1,
  653. sec_vib_notifier_register(&pdata_motor->motor_nb);
  654. hrtimer_init(&pdata_motor->motor_stop_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
  655. pdata_motor->motor_stop_timer.function = motor_stop_timer_func;
  656. pdata_motor->slpi_motor_wq =
  657. create_singlethread_workqueue("slpi_motor_wq");
  658. if (pdata_motor->slpi_motor_wq == NULL) {
  659. pr_err("[FACTORY]: %s - could not create motor wq\n", __func__);
  660. kfree(pdata_motor);
  661. return -ENOMEM;
  662. }
  663. INIT_WORK(&pdata_motor->work_slpi_motor, slpi_motor_work_func);
  664. atomic_set(&pdata_motor->motor_state, MOTOR_OFF);
  665. #endif
  666. pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
  667. pdata->accel_wq = create_singlethread_workqueue("accel_wq");
  668. INIT_WORK(&pdata->work_accel, accel_work_func);
  669. pdata->lpf_onoff = true;
  670. pdata->st_complete = true;
  671. pr_info("[FACTORY] %s\n", __func__);
  672. return 0;
  673. }
  674. void __exit lsm6dso_accel_factory_exit(void)
  675. {
  676. adsp_factory_unregister(MSG_ACCEL);
  677. #ifdef CONFIG_SEC_VIB_NOTIFIER
  678. if (atomic_read(&pdata_motor->motor_state) == MOTOR_ON)
  679. hrtimer_cancel(&pdata_motor->motor_stop_timer);
  680. if (pdata_motor != NULL && pdata_motor->slpi_motor_wq != NULL) {
  681. cancel_work_sync(&pdata_motor->work_slpi_motor);
  682. destroy_workqueue(pdata_motor->slpi_motor_wq);
  683. pdata_motor->slpi_motor_wq = NULL;
  684. kfree(pdata_motor);
  685. }
  686. #endif
  687. pr_info("[FACTORY] %s\n", __func__);
  688. }