ssp_dev.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715
  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 "ssp.h"
  16. #ifdef CONFIG_OF
  17. #include <linux/of_gpio.h>
  18. #endif
  19. #include <mach/sec_debug.h>
  20. #ifdef CONFIG_HAS_EARLYSUSPEND
  21. static void ssp_early_suspend(struct early_suspend *handler);
  22. static void ssp_late_resume(struct early_suspend *handler);
  23. #endif
  24. void ssp_enable(struct ssp_data *data, bool enable)
  25. {
  26. pr_info("[SSP] %s, enable = %d, old enable = %d\n",
  27. __func__, enable, data->bSspShutdown);
  28. if (enable && data->bSspShutdown) {
  29. data->bSspShutdown = false;
  30. enable_irq(data->iIrq);
  31. enable_irq_wake(data->iIrq);
  32. } else if (!enable && !data->bSspShutdown) {
  33. data->bSspShutdown = true;
  34. disable_irq(data->iIrq);
  35. disable_irq_wake(data->iIrq);
  36. } else
  37. pr_err("%s, enable error\n", __func__);
  38. }
  39. /************************************************************************/
  40. /* interrupt happened due to transition/change of SSP MCU */
  41. /************************************************************************/
  42. static irqreturn_t sensordata_irq_thread_fn(int iIrq, void *dev_id)
  43. {
  44. struct ssp_data *data = dev_id;
  45. struct timespec ts;
  46. get_monotonic_boottime(&ts);
  47. data->timestamp = ts.tv_sec * 1000000000ULL + ts.tv_nsec;
  48. if(gpio_get_value(data->mcu_int1)) {
  49. pr_info("[SSP] MCU int HIGH");
  50. return IRQ_HANDLED;
  51. }
  52. select_irq_msg(data);
  53. data->uIrqCnt++;
  54. return IRQ_HANDLED;
  55. }
  56. /*************************************************************************/
  57. /* initialize sensor hub */
  58. /*************************************************************************/
  59. static void initialize_variable(struct ssp_data *data)
  60. {
  61. int iSensorIndex;
  62. for (iSensorIndex = 0; iSensorIndex < SENSOR_MAX; iSensorIndex++) {
  63. data->adDelayBuf[iSensorIndex] = DEFUALT_POLLING_DELAY;
  64. data->batchLatencyBuf[iSensorIndex] = 0;
  65. data->batchOptBuf[iSensorIndex] = 0;
  66. data->aiCheckStatus[iSensorIndex] = INITIALIZATION_STATE;
  67. data->lastTimestamp[iSensorIndex] = 0;
  68. data->reportedData[iSensorIndex] = false;
  69. }
  70. atomic_set(&data->aSensorEnable, 0);
  71. data->iLibraryLength = 0;
  72. data->uSensorState = 0;
  73. data->uFactoryProxAvg[0] = 0;
  74. data->uResetCnt = 0;
  75. data->uInstFailCnt = 0;
  76. data->uTimeOutCnt = 0;
  77. data->uSsdFailCnt = 0;
  78. data->uBusyCnt = 0;
  79. data->uIrqCnt = 0;
  80. data->uIrqFailCnt = 0;
  81. data->uMissSensorCnt = 0;
  82. data->bSspShutdown = true;
  83. data->bProximityRawEnabled = false;
  84. data->bGeomagneticRawEnabled = false;
  85. data->bBarcodeEnabled = false;
  86. data->bAccelAlert = false;
  87. data->bTimeSyncing = true;
  88. data->accelcal.x = 0;
  89. data->accelcal.y = 0;
  90. data->accelcal.z = 0;
  91. data->gyrocal.x = 0;
  92. data->gyrocal.y = 0;
  93. data->gyrocal.z = 0;
  94. data->magoffset.x = 0;
  95. data->magoffset.y = 0;
  96. data->magoffset.z = 0;
  97. data->iPressureCal = 0;
  98. data->uProxCanc = 0;
  99. data->uProxHiThresh = 0;
  100. data->uProxLoThresh = 0;
  101. data->uGyroDps = GYROSCOPE_DPS500;
  102. data->uIr_Current = 0;
  103. data->mcu_device = NULL;
  104. data->acc_device = NULL;
  105. data->gyro_device = NULL;
  106. data->mag_device = NULL;
  107. data->prs_device = NULL;
  108. data->prox_device = NULL;
  109. data->light_device = NULL;
  110. data->ges_device = NULL;
  111. data->voice_device = NULL;
  112. data->bMcuDumpMode = sec_debug_is_enabled();
  113. INIT_LIST_HEAD(&data->pending_list);
  114. initialize_function_pointer(data);
  115. }
  116. int initialize_mcu(struct ssp_data *data)
  117. {
  118. int iRet = 0;
  119. iRet = get_chipid(data);
  120. pr_info("[SSP] MCU device ID = %d, reading ID = %d\n", DEVICE_ID, iRet);
  121. if (iRet != DEVICE_ID) {
  122. if (iRet < 0) {
  123. pr_err("[SSP]: %s - MCU is not working : 0x%x\n",
  124. __func__, iRet);
  125. } else {
  126. pr_err("[SSP]: %s - MCU identification failed\n",
  127. __func__);
  128. iRet = -ENODEV;
  129. }
  130. goto out;
  131. }
  132. iRet = set_sensor_position(data);
  133. if (iRet < 0) {
  134. pr_err("[SSP]: %s - set_sensor_position failed\n", __func__);
  135. goto out;
  136. }
  137. #if defined(CONFIG_SENSORS_SSP_BOUNCE_FIRMWARE)
  138. iRet = set_sensor_tilt(data);
  139. if (iRet < 0) {
  140. pr_err("[SSP]: %s - set_sensor_tilt failed\n", __func__);
  141. goto out;
  142. }
  143. #endif
  144. data->uSensorState = get_sensor_scanning_info(data);
  145. if (data->uSensorState == 0) {
  146. pr_err("[SSP]: %s - get_sensor_scanning_info failed\n",
  147. __func__);
  148. iRet = ERROR;
  149. goto out;
  150. }
  151. #if defined (CONFIG_SENSORS_SSP_YAS532)
  152. iRet = set_static_matrix(data);
  153. if (iRet < 0)
  154. pr_err("[SSP]: %s - yas set static matrix failed\n", __func__);
  155. #endif
  156. iRet = SUCCESS;
  157. out:
  158. return iRet;
  159. }
  160. static int initialize_irq(struct ssp_data *data)
  161. {
  162. int iRet, iIrq;
  163. iIrq = gpio_to_irq(data->mcu_int1);
  164. pr_info("[SSP]: requesting IRQ %d\n", iIrq);
  165. iRet = request_threaded_irq(iIrq, NULL, sensordata_irq_thread_fn,
  166. IRQF_TRIGGER_FALLING, "SSP_Int", data);
  167. if (iRet < 0) {
  168. pr_err("[SSP]: %s - request_irq(%d) failed for gpio %d (%d)\n",
  169. __func__, iIrq, iIrq, iRet);
  170. goto err_request_irq;
  171. }
  172. /* start with interrupts disabled */
  173. data->iIrq = iIrq;
  174. disable_irq(data->iIrq);
  175. return 0;
  176. err_request_irq:
  177. gpio_free(data->mcu_int1);
  178. return iRet;
  179. }
  180. static void work_function_firmware_update(struct work_struct *work)
  181. {
  182. struct ssp_data *data = container_of((struct delayed_work *)work,
  183. struct ssp_data, work_firmware);
  184. int iRet = 0;
  185. pr_info("[SSP] : %s\n", __func__);
  186. iRet = forced_to_download_binary(data, KERNEL_BINARY);
  187. if (iRet < 0) {
  188. ssp_dbg("[SSP]: %s - forced_to_download_binary failed!\n",
  189. __func__);
  190. return;
  191. }
  192. data->uCurFirmRev = get_firmware_rev(data);
  193. pr_info("[SSP] MCU Firm Rev : New = %8u\n",
  194. data->uCurFirmRev);
  195. }
  196. static int ssp_parse_dt(struct device *dev,
  197. struct ssp_data *data)
  198. {
  199. struct device_node *np = dev->of_node;
  200. enum of_gpio_flags flags;
  201. int errorno = 0;
  202. data->mcu_int1 = of_get_named_gpio_flags(np, "ssp,mcu_int1-gpio",
  203. 0, &flags);
  204. if (data->mcu_int1 < 0) {
  205. errorno = data->mcu_int1;
  206. goto dt_exit;
  207. }
  208. data->mcu_int2 = of_get_named_gpio_flags(np, "ssp,mcu_int2-gpio",
  209. 0, &flags);
  210. if (data->mcu_int2 < 0) {
  211. errorno = data->mcu_int2;
  212. goto dt_exit;
  213. }
  214. data->ap_int = of_get_named_gpio_flags(np, "ssp,ap_int-gpio",
  215. 0, &flags);
  216. if (data->ap_int < 0) {
  217. errorno = data->ap_int;
  218. goto dt_exit;
  219. }
  220. data->rst = of_get_named_gpio_flags(np, "ssp,rst-gpio",
  221. 0, &flags);
  222. if (data->rst < 0) {
  223. errorno = data->rst ;
  224. goto dt_exit;
  225. }
  226. if (of_property_read_u32(np, "ssp,acc-position", &data->accel_position))
  227. data->accel_position = 0;
  228. if (of_property_read_u32(np, "ssp,mag-position", &data->mag_position))
  229. data->mag_position = 0;
  230. if (of_property_read_u32(np, "ssp,sns-combination", &data->sns_combination))
  231. data->sns_combination = 0;
  232. if (of_property_read_u32(np, "ssp,ap-rev", &data->ap_rev))
  233. data->ap_rev = 0;
  234. if (of_property_read_u32(np, "ssp,rotation-direction", &data->rot_direction))
  235. data->rot_direction = 0;
  236. errorno = gpio_request(data->mcu_int1, "mpu_ap_int1");
  237. if (errorno) {
  238. printk(KERN_ERR "failed to request MCU_INT2 for SSP\n");
  239. goto dt_exit;
  240. }
  241. errorno = gpio_direction_input(data->mcu_int1);
  242. if (errorno) {
  243. printk(KERN_ERR "failed to set mcu_int1 as input\n");
  244. goto dt_exit;
  245. }
  246. errorno = gpio_request(data->mcu_int2, "MCU_INT2");
  247. if (errorno) {
  248. printk(KERN_ERR "failed to request MCU_INT2 for SSP\n");
  249. goto dt_exit;
  250. }
  251. gpio_direction_input(data->mcu_int2);
  252. errorno = gpio_request(data->ap_int, "AP_MCU_INT");
  253. if (errorno) {
  254. printk(KERN_ERR "failed to request AP_INT for SSP\n");
  255. goto dt_exit;
  256. }
  257. gpio_direction_output(data->ap_int, 1);
  258. errorno = gpio_request(data->rst, "MCU_RST");
  259. if (errorno) {
  260. printk(KERN_ERR "failed to request MCU_RST for SSP\n");
  261. goto dt_exit;
  262. }
  263. gpio_direction_output(data->rst, 1);
  264. data->reg_hub = devm_regulator_get(dev, "hub_vreg");
  265. if (IS_ERR(data->reg_hub)) {
  266. pr_err("[SSP] could not get hub_vreg, %ld\n",
  267. PTR_ERR(data->reg_hub));
  268. } else {
  269. regulator_enable(data->reg_hub);
  270. }
  271. data->reg_sns= devm_regulator_get(dev, "psns_vreg");
  272. if (IS_ERR(data->reg_hub)) {
  273. pr_err("[SSP] could not get psns_vreg, %ld\n",
  274. PTR_ERR(data->reg_sns));
  275. } else {
  276. regulator_enable(data->reg_sns);
  277. }
  278. dt_exit:
  279. return errorno;
  280. }
  281. static int ssp_probe(struct spi_device *spi_dev)
  282. {
  283. int iRet = 0;
  284. struct ssp_data *data;
  285. struct ssp_platform_data *pdata;
  286. if (poweroff_charging == 1) {
  287. pr_err("[SSP] probe exit : lpm %d\n", poweroff_charging);
  288. return -ENODEV;
  289. }
  290. data = kzalloc(sizeof(*data), GFP_KERNEL);
  291. if (data == NULL) {
  292. pr_err("[SSP]: %s - failed to allocate memory for data\n",
  293. __func__);
  294. iRet = -ENOMEM;
  295. goto exit;
  296. }
  297. #if defined (CONFIG_MACH_VIKALCU)
  298. proximity_ldo_enable(1);
  299. #endif
  300. if (spi_dev->dev.of_node) {
  301. iRet = ssp_parse_dt(&spi_dev->dev, data);
  302. if (iRet) {
  303. pr_err("[SSP]: %s - Failed to parse DT\n", __func__);
  304. goto err_setup;
  305. }
  306. data->ssp_changes = SSP_MCU_L5; /* K330, MPU L5*/
  307. } else {
  308. pdata = spi_dev->dev.platform_data;
  309. if (pdata == NULL) {
  310. pr_err("[SSP]: %s - platform_data is null\n", __func__);
  311. iRet = -ENOMEM;
  312. goto err_setup;
  313. }
  314. data->wakeup_mcu = pdata->wakeup_mcu;
  315. data->check_mcu_ready = pdata->check_mcu_ready;
  316. data->check_mcu_busy = pdata->check_mcu_busy;
  317. data->set_mcu_reset = pdata->set_mcu_reset;
  318. data->read_chg = pdata->read_chg;
  319. /* AP system_rev */
  320. if (pdata->check_ap_rev)
  321. data->ap_rev = pdata->check_ap_rev();
  322. else
  323. data->ap_rev = 0;
  324. /* For changed devices */
  325. if (pdata->check_changes)
  326. data->ssp_changes = pdata->check_changes();
  327. else
  328. data->ssp_changes = SSP_MCU_L5; /* K330, MPU L5*/
  329. /* Get sensor positions */
  330. if (pdata->get_positions)
  331. pdata->get_positions(&data->accel_position,
  332. &data->mag_position);
  333. else if (spi_dev->dev.of_node == NULL) {
  334. data->accel_position = 0;
  335. data->mag_position = 0;
  336. }
  337. }
  338. spi_dev->mode = SPI_MODE_1;
  339. if (spi_setup(spi_dev)) {
  340. pr_err("failed to setup spi for ssp_spi\n");
  341. goto err_setup;
  342. }
  343. data->bProbeIsDone = false;
  344. data->fw_dl_state = FW_DL_STATE_NONE;
  345. data->spi = spi_dev;
  346. spi_set_drvdata(spi_dev, data);
  347. #ifdef CONFIG_SENSORS_SSP_SHTC1
  348. mutex_init(&data->cp_temp_adc_lock);
  349. mutex_init(&data->bulk_temp_read_lock);
  350. #endif
  351. mutex_init(&data->comm_mutex);
  352. mutex_init(&data->pending_mutex);
  353. if (((data->wakeup_mcu == NULL)
  354. || (data->check_mcu_ready == NULL)
  355. || (data->check_mcu_busy == NULL)
  356. || (data->set_mcu_reset == NULL)
  357. || (data->read_chg == NULL))
  358. && (spi_dev->dev.of_node == NULL)) {
  359. pr_err("[SSP]: %s - function callback is null\n", __func__);
  360. iRet = -EIO;
  361. goto err_reset_null;
  362. }
  363. pr_info("\n#####################################################\n");
  364. INIT_DELAYED_WORK(&data->work_firmware, work_function_firmware_update);
  365. wake_lock_init(&data->ssp_wake_lock,
  366. WAKE_LOCK_SUSPEND, "ssp_wake_lock");
  367. iRet = initialize_input_dev(data);
  368. if (iRet < 0) {
  369. pr_err("[SSP]: %s - could not create input device\n", __func__);
  370. goto err_input_register_device;
  371. }
  372. iRet = initialize_debug_timer(data);
  373. if (iRet < 0) {
  374. pr_err("[SSP]: %s - could not create workqueue\n", __func__);
  375. goto err_create_workqueue;
  376. }
  377. iRet = initialize_irq(data);
  378. if (iRet < 0) {
  379. pr_err("[SSP]: %s - could not create irq\n", __func__);
  380. goto err_setup_irq;
  381. }
  382. iRet = initialize_sysfs(data);
  383. if (iRet < 0) {
  384. pr_err("[SSP]: %s - could not create sysfs\n", __func__);
  385. goto err_sysfs_create;
  386. }
  387. iRet = initialize_event_symlink(data);
  388. if (iRet < 0) {
  389. pr_err("[SSP]: %s - could not create symlink\n", __func__);
  390. goto err_symlink_create;
  391. }
  392. initialize_variable(data);
  393. ssp_enable(data, true);
  394. /* check boot loader binary */
  395. data->fw_dl_state = check_fwbl(data);
  396. if (data->fw_dl_state == FW_DL_STATE_NONE) {
  397. iRet = initialize_mcu(data);
  398. if (iRet == ERROR) {
  399. data->uResetCnt++;
  400. toggle_mcu_reset(data);
  401. msleep(SSP_SW_RESET_TIME);
  402. initialize_mcu(data);
  403. } else if (iRet < ERROR) {
  404. pr_err("[SSP]: %s - initialize_mcu failed\n", __func__);
  405. goto err_read_reg;
  406. }
  407. }
  408. #ifdef CONFIG_HAS_EARLYSUSPEND
  409. data->early_suspend.suspend = ssp_early_suspend;
  410. data->early_suspend.resume = ssp_late_resume;
  411. register_early_suspend(&data->early_suspend);
  412. #endif
  413. #ifdef CONFIG_SENSORS_SSP_SENSORHUB
  414. /* init sensorhub device */
  415. iRet = ssp_sensorhub_initialize(data);
  416. if (iRet < 0) {
  417. pr_err("%s: ssp_sensorhub_initialize err(%d)", __func__, iRet);
  418. ssp_sensorhub_remove(data);
  419. }
  420. #endif
  421. data->bMcuDumpMode = sec_debug_is_enabled();
  422. pr_info("[SSP]: %s - setup debuglevel %d!\n", __func__,data->bMcuDumpMode);
  423. pr_info("[SSP]: %s - probe success!\n", __func__);
  424. enable_debug_timer(data);
  425. iRet = 0;
  426. if (data->fw_dl_state == FW_DL_STATE_NEED_TO_SCHEDULE) {
  427. pr_info("[SSP]: Firmware update is scheduled\n");
  428. schedule_delayed_work(&data->work_firmware,
  429. msecs_to_jiffies(1000));
  430. data->fw_dl_state = FW_DL_STATE_SCHEDULED;
  431. } else if (data->fw_dl_state == FW_DL_STATE_FAIL)
  432. data->bSspShutdown = true;
  433. data->bProbeIsDone = true;
  434. goto exit;
  435. err_read_reg:
  436. err_symlink_create:
  437. remove_sysfs(data);
  438. err_sysfs_create:
  439. free_irq(data->iIrq, data);
  440. gpio_free(data->mcu_int1);
  441. err_setup_irq:
  442. destroy_workqueue(data->debug_wq);
  443. err_create_workqueue:
  444. remove_input_dev(data);
  445. err_input_register_device:
  446. wake_lock_destroy(&data->ssp_wake_lock);
  447. err_reset_null:
  448. #ifdef CONFIG_SENSORS_SSP_SHTC1
  449. mutex_destroy(&data->cp_temp_adc_lock);
  450. mutex_destroy(&data->bulk_temp_read_lock);
  451. #endif
  452. mutex_destroy(&data->comm_mutex);
  453. mutex_destroy(&data->pending_mutex);
  454. err_setup:
  455. kfree(data);
  456. pr_err("[SSP]: %s - probe failed!\n", __func__);
  457. exit:
  458. pr_info("#####################################################\n\n");
  459. return iRet;
  460. }
  461. static void ssp_shutdown(struct spi_device *spi_dev)
  462. {
  463. struct ssp_data *data = spi_get_drvdata(spi_dev);
  464. func_dbg();
  465. if (data->bProbeIsDone == false)
  466. goto exit;
  467. if (data->fw_dl_state >= FW_DL_STATE_SCHEDULED &&
  468. data->fw_dl_state < FW_DL_STATE_DONE) {
  469. pr_err("%s, cancel_delayed_work_sync state = %d\n",
  470. __func__, data->fw_dl_state);
  471. cancel_delayed_work_sync(&data->work_firmware);
  472. }
  473. ssp_enable(data, false);
  474. clean_pending_list(data);
  475. #ifdef CONFIG_HAS_EARLYSUSPEND
  476. unregister_early_suspend(&data->early_suspend);
  477. #endif
  478. disable_debug_timer(data);
  479. free_irq(data->iIrq, data);
  480. gpio_free(data->mcu_int1);
  481. remove_event_symlink(data);
  482. remove_sysfs(data);
  483. remove_input_dev(data);
  484. #ifdef CONFIG_SENSORS_SSP_SENSORHUB
  485. ssp_sensorhub_remove(data);
  486. #endif
  487. del_timer_sync(&data->debug_timer);
  488. cancel_work_sync(&data->work_debug);
  489. destroy_workqueue(data->debug_wq);
  490. wake_lock_destroy(&data->ssp_wake_lock);
  491. #ifdef CONFIG_SENSORS_SSP_SHTC1
  492. mutex_destroy(&data->cp_temp_adc_lock);
  493. mutex_destroy(&data->bulk_temp_read_lock);
  494. #endif
  495. mutex_destroy(&data->comm_mutex);
  496. mutex_destroy(&data->pending_mutex);
  497. #if defined(CONFIG_MACH_VIKALCU)
  498. proximity_ldo_enable(0);
  499. #endif
  500. toggle_mcu_reset(data);
  501. /* gpio_set_value_cansleep(data->rst, 0); */
  502. pr_info("[SSP]: %s done\n", __func__);
  503. exit:
  504. kfree(data);
  505. }
  506. #ifdef CONFIG_HAS_EARLYSUSPEND
  507. static void ssp_early_suspend(struct early_suspend *handler)
  508. {
  509. struct ssp_data *data;
  510. data = container_of(handler, struct ssp_data, early_suspend);
  511. func_dbg();
  512. disable_debug_timer(data);
  513. #ifdef CONFIG_SENSORS_SSP_SENSORHUB
  514. /* give notice to user that AP goes to sleep */
  515. ssp_sensorhub_report_notice(data, MSG2SSP_AP_STATUS_SLEEP);
  516. ssp_sleep_mode(data);
  517. data->uLastAPState = MSG2SSP_AP_STATUS_SLEEP;
  518. #else
  519. if (atomic_read(&data->aSensorEnable) > 0)
  520. ssp_sleep_mode(data);
  521. #endif
  522. }
  523. static void ssp_late_resume(struct early_suspend *handler)
  524. {
  525. struct ssp_data *data;
  526. data = container_of(handler, struct ssp_data, early_suspend);
  527. func_dbg();
  528. enable_debug_timer(data);
  529. #ifdef CONFIG_SENSORS_SSP_SENSORHUB
  530. /* give notice to user that AP goes to sleep */
  531. ssp_sensorhub_report_notice(data, MSG2SSP_AP_STATUS_WAKEUP);
  532. ssp_resume_mode(data);
  533. data->uLastAPState = MSG2SSP_AP_STATUS_WAKEUP;
  534. #else
  535. if (atomic_read(&data->aSensorEnable) > 0)
  536. ssp_resume_mode(data);
  537. #endif
  538. }
  539. #else /* CONFIG_HAS_EARLYSUSPEND */
  540. static int ssp_suspend(struct device *dev)
  541. {
  542. struct spi_device *spi_dev = to_spi_device(dev);
  543. struct ssp_data *data = spi_get_drvdata(spi_dev);
  544. func_dbg();
  545. data->uLastResumeState = MSG2SSP_AP_STATUS_SUSPEND;
  546. disable_debug_timer(data);
  547. if (SUCCESS != ssp_send_cmd(data, MSG2SSP_AP_STATUS_SUSPEND, 0))
  548. pr_err("[SSP]: %s MSG2SSP_AP_STATUS_SUSPEND failed\n",
  549. __func__);
  550. data->bTimeSyncing = false;
  551. disable_irq(data->iIrq);
  552. return 0;
  553. }
  554. static int ssp_resume(struct device *dev)
  555. {
  556. struct spi_device *spi_dev = to_spi_device(dev);
  557. struct ssp_data *data = spi_get_drvdata(spi_dev);
  558. enable_irq(data->iIrq);
  559. func_dbg();
  560. enable_debug_timer(data);
  561. if (SUCCESS != ssp_send_cmd(data, MSG2SSP_AP_STATUS_RESUME, 0))
  562. pr_err("[SSP]: %s MSG2SSP_AP_STATUS_RESUME failed\n",
  563. __func__);
  564. data->uLastResumeState = MSG2SSP_AP_STATUS_RESUME;
  565. return 0;
  566. }
  567. static const struct dev_pm_ops ssp_pm_ops = {
  568. .suspend = ssp_suspend,
  569. .resume = ssp_resume
  570. };
  571. #endif /* CONFIG_HAS_EARLYSUSPEND */
  572. static const struct spi_device_id ssp_id[] = {
  573. {"ssp", 0},
  574. {}
  575. };
  576. MODULE_DEVICE_TABLE(spi, ssp_id);
  577. #ifdef CONFIG_OF
  578. static struct of_device_id ssp_match_table[] = {
  579. { .compatible = "ssp,STM32F",},
  580. {},
  581. };
  582. #else
  583. #define mpu6500_match_table NULL
  584. #endif
  585. static struct spi_driver ssp_driver = {
  586. .probe = ssp_probe,
  587. .shutdown = ssp_shutdown,
  588. .id_table = ssp_id,
  589. .driver = {
  590. #ifndef CONFIG_HAS_EARLYSUSPEND
  591. .pm = &ssp_pm_ops,
  592. #endif
  593. .owner = THIS_MODULE,
  594. .name = "ssp",
  595. .of_match_table = ssp_match_table
  596. },
  597. };
  598. module_spi_driver(ssp_driver);
  599. MODULE_DESCRIPTION("ssp driver");
  600. MODULE_AUTHOR("Samsung Electronics");
  601. MODULE_LICENSE("GPL");